Skip to content

Commit

Permalink
feat(katana): add l1 data price info in header (#2547)
Browse files Browse the repository at this point in the history
the values in the new fields are mostly dumb values rn bcs we arent sampling anything from the L1. so the next todo to make these changes correct, is to create a gas oracle that samples the actual values from the l1.

similar to PR #2543, the database format for `Header` is changed. considering we already bumped the db version in PR #2543, we can keep using the same version and defer bumping it again once this commit is included in a release.
  • Loading branch information
kariy authored Oct 16, 2024
1 parent 9fdd351 commit f9a559f
Show file tree
Hide file tree
Showing 19 changed files with 188 additions and 81 deletions.
8 changes: 7 additions & 1 deletion crates/katana/core/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use katana_primitives::block::{
Block, FinalityStatus, GasPrices, Header, PartialHeader, SealedBlockWithStatus,
};
use katana_primitives::chain_spec::ChainSpec;
use katana_primitives::da::L1DataAvailabilityMode;
use katana_primitives::env::BlockEnv;
use katana_primitives::transaction::TxHash;
use katana_primitives::Felt;
Expand Down Expand Up @@ -68,10 +69,15 @@ impl<EF: ExecutorFactory> Backend<EF> {
version: self.chain_spec.version.clone(),
timestamp: block_env.timestamp,
sequencer_address: block_env.sequencer_address,
gas_prices: GasPrices {
l1_da_mode: L1DataAvailabilityMode::Calldata,
l1_gas_prices: GasPrices {
eth: block_env.l1_gas_prices.eth,
strk: block_env.l1_gas_prices.strk,
},
l1_data_gas_prices: GasPrices {
eth: block_env.l1_data_gas_prices.eth,
strk: block_env.l1_data_gas_prices.strk,
},
};

let tx_hashes = txs.iter().map(|tx| tx.hash).collect::<Vec<TxHash>>();
Expand Down
41 changes: 29 additions & 12 deletions crates/katana/core/src/backend/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,33 +144,47 @@ impl Blockchain {
.await
.context("failed to fetch forked block")?;

let MaybePendingBlockWithTxHashes::Block(block) = block else {
let MaybePendingBlockWithTxHashes::Block(forked_block) = block else {
bail!("forking a pending block is not allowed")
};

chain.id = chain_id.into();
chain.version = ProtocolVersion::parse(&block.starknet_version)?;
chain.version = ProtocolVersion::parse(&forked_block.starknet_version)?;

// adjust the genesis to match the forked block
chain.genesis.timestamp = block.timestamp;
chain.genesis.number = block.block_number;
chain.genesis.state_root = block.new_root;
chain.genesis.parent_hash = block.parent_hash;
chain.genesis.sequencer_address = block.sequencer_address.into();
chain.genesis.timestamp = forked_block.timestamp;
chain.genesis.number = forked_block.block_number;
chain.genesis.state_root = forked_block.new_root;
chain.genesis.parent_hash = forked_block.parent_hash;
chain.genesis.sequencer_address = forked_block.sequencer_address.into();

// TODO: remove gas price from genesis
chain.genesis.gas_prices.eth =
block.l1_gas_price.price_in_wei.to_u128().expect("should fit in u128");
forked_block.l1_gas_price.price_in_wei.to_u128().expect("should fit in u128");
chain.genesis.gas_prices.strk =
block.l1_gas_price.price_in_fri.to_u128().expect("should fit in u128");
forked_block.l1_gas_price.price_in_fri.to_u128().expect("should fit in u128");

let status = match block.status {
let status = match forked_block.status {
BlockStatus::AcceptedOnL1 => FinalityStatus::AcceptedOnL1,
BlockStatus::AcceptedOnL2 => FinalityStatus::AcceptedOnL2,
// we already checked for pending block earlier. so this should never happen.
_ => bail!("qed; block status shouldn't be pending"),
};

let database = ForkedProvider::new(Arc::new(provider), block_id)?;
let block = chain.block().seal_with_hash_and_status(block.block_hash, status);

// update the genesis block with the forked block's data
// we dont update the `l1_gas_price` bcs its already done when we set the `gas_prices` in
// genesis. this flow is kinda flawed, we should probably refactor it out of the
// genesis.
let mut block = chain.block();
block.header.l1_data_gas_prices.eth =
forked_block.l1_data_gas_price.price_in_wei.to_u128().expect("should fit in u128");
block.header.l1_data_gas_prices.strk =
forked_block.l1_data_gas_price.price_in_fri.to_u128().expect("should fit in u128");
block.header.l1_da_mode = forked_block.l1_da_mode;

let block = block.seal_with_hash_and_status(forked_block.block_hash, status);
let state_updates = chain.state_updates();

Self::new_with_genesis_block_and_state(database, block, state_updates)
Expand Down Expand Up @@ -201,6 +215,7 @@ mod tests {
use katana_primitives::block::{
Block, FinalityStatus, GasPrices, Header, SealedBlockWithStatus,
};
use katana_primitives::da::L1DataAvailabilityMode;
use katana_primitives::fee::TxFeeInfo;
use katana_primitives::genesis::constant::{
DEFAULT_ETH_FEE_TOKEN_ADDRESS, DEFAULT_LEGACY_ERC20_CASM, DEFAULT_LEGACY_ERC20_CLASS_HASH,
Expand Down Expand Up @@ -255,7 +270,9 @@ mod tests {
header: Header {
parent_hash: Felt::ZERO,
number: 1,
gas_prices: GasPrices::default(),
l1_gas_prices: GasPrices::default(),
l1_data_gas_prices: GasPrices::default(),
l1_da_mode: L1DataAvailabilityMode::Calldata,
timestamp: 123456,
..Default::default()
},
Expand Down
9 changes: 7 additions & 2 deletions crates/katana/core/src/service/block_producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use futures::FutureExt;
use katana_executor::{BlockExecutor, ExecutionResult, ExecutionStats, ExecutorFactory};
use katana_pool::validation::stateful::TxValidator;
use katana_primitives::block::{BlockHashOrNumber, ExecutableBlock, PartialHeader};
use katana_primitives::da::L1DataAvailabilityMode;
use katana_primitives::receipt::Receipt;
use katana_primitives::trace::TxExecInfo;
use katana_primitives::transaction::{ExecutableTxWithHash, TxHash, TxWithHash};
Expand Down Expand Up @@ -563,6 +564,8 @@ impl<EF: ExecutorFactory> InstantBlockProducer<EF> {

let provider = backend.blockchain.provider();

// TODO: don't use the previous block env, we should create on based on the current state of
// the l1 (to determine the proper gas prices)
let latest_num = provider.latest_number()?;
let mut block_env = provider.block_env_at(BlockHashOrNumber::Num(latest_num))?.unwrap();
backend.update_block_env(&mut block_env);
Expand All @@ -578,9 +581,11 @@ impl<EF: ExecutorFactory> InstantBlockProducer<EF> {
parent_hash,
number: block_env.number,
timestamp: block_env.timestamp,
gas_prices: block_env.l1_gas_prices.clone(),
sequencer_address: block_env.sequencer_address,
version: backend.chain_spec.version.clone(),
sequencer_address: block_env.sequencer_address,
l1_da_mode: L1DataAvailabilityMode::Calldata,
l1_gas_prices: block_env.l1_gas_prices.clone(),
l1_data_gas_prices: block_env.l1_data_gas_prices.clone(),
},
};

Expand Down
8 changes: 6 additions & 2 deletions crates/katana/executor/src/implementation/blockifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ impl<'a> StarknetVMProcessor<'a> {
// TODO: should we enforce the gas price to not be 0,
// as there's a flag to disable gas uasge instead?
let eth_l1_gas_price =
NonZeroU128::new(header.gas_prices.eth).unwrap_or(NonZeroU128::new(1).unwrap());
NonZeroU128::new(header.l1_gas_prices.eth).unwrap_or(NonZeroU128::new(1).unwrap());
let strk_l1_gas_price =
NonZeroU128::new(header.gas_prices.strk).unwrap_or(NonZeroU128::new(1).unwrap());
NonZeroU128::new(header.l1_gas_prices.strk).unwrap_or(NonZeroU128::new(1).unwrap());

// TODO: which values is correct for those one?
let eth_l1_data_gas_price = eth_l1_gas_price;
Expand Down Expand Up @@ -239,6 +239,10 @@ impl<'a> BlockExecutor<'a> for StarknetVMProcessor<'a> {
eth: eth_l1_gas_price.into(),
strk: strk_l1_gas_price.into(),
},
l1_data_gas_prices: KatanaGasPrices {
eth: self.block_context.block_info().gas_prices.eth_l1_data_gas_price.into(),
strk: self.block_context.block_info().gas_prices.strk_l1_data_gas_price.into(),
},
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/katana/executor/tests/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn test_executor_with_valid_blocks_impl<EF: ExecutorFactory>(
let actual_block_env = executor.block_env();
assert_eq!(actual_block_env.number, block.header.number);
assert_eq!(actual_block_env.timestamp, block.header.timestamp);
assert_eq!(actual_block_env.l1_gas_prices, block.header.gas_prices);
assert_eq!(actual_block_env.l1_gas_prices, block.header.l1_gas_prices);
assert_eq!(actual_block_env.sequencer_address, block.header.sequencer_address);

let transactions = executor.transactions();
Expand Down Expand Up @@ -127,7 +127,7 @@ fn test_executor_with_valid_blocks_impl<EF: ExecutorFactory>(
let actual_block_env = executor.block_env();
assert_eq!(actual_block_env.number, block.header.number);
assert_eq!(actual_block_env.timestamp, block.header.timestamp);
assert_eq!(actual_block_env.l1_gas_prices, block.header.gas_prices);
assert_eq!(actual_block_env.l1_gas_prices, block.header.l1_gas_prices);
assert_eq!(actual_block_env.sequencer_address, block.header.sequencer_address);

let transactions = executor.transactions();
Expand Down Expand Up @@ -174,7 +174,7 @@ fn test_executor_with_valid_blocks_impl<EF: ExecutorFactory>(
let actual_block_env = executor.block_env();
assert_eq!(actual_block_env.number, block.header.number);
assert_eq!(actual_block_env.timestamp, block.header.timestamp);
assert_eq!(actual_block_env.l1_gas_prices, block.header.gas_prices);
assert_eq!(actual_block_env.l1_gas_prices, block.header.l1_gas_prices);
assert_eq!(actual_block_env.sequencer_address, block.header.sequencer_address);

let transactions = executor.transactions();
Expand Down
13 changes: 10 additions & 3 deletions crates/katana/executor/tests/fixtures/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use katana_primitives::chain::ChainId;
use katana_primitives::chain_spec::{self, ChainSpec};
use katana_primitives::class::{CompiledClass, FlattenedSierraClass};
use katana_primitives::contract::ContractAddress;
use katana_primitives::da::L1DataAvailabilityMode;
use katana_primitives::env::{CfgEnv, FeeTokenAddressses};
use katana_primitives::genesis::allocation::DevAllocationsGenerator;
use katana_primitives::genesis::constant::{
Expand Down Expand Up @@ -107,7 +108,9 @@ pub fn valid_blocks() -> [ExecutableBlock; 3] {
timestamp: 100,
sequencer_address,
parent_hash: 123u64.into(),
gas_prices: gas_prices.clone(),
l1_gas_prices: gas_prices.clone(),
l1_data_gas_prices: gas_prices.clone(),
l1_da_mode: L1DataAvailabilityMode::Calldata,
},
body: vec![
// fund the account to be deployed, sending 0x9999999999999 amount
Expand Down Expand Up @@ -155,7 +158,9 @@ pub fn valid_blocks() -> [ExecutableBlock; 3] {
timestamp: 200,
sequencer_address,
parent_hash: 1234u64.into(),
gas_prices: gas_prices.clone(),
l1_gas_prices: gas_prices.clone(),
l1_data_gas_prices: gas_prices.clone(),
l1_da_mode: L1DataAvailabilityMode::Calldata,
},
body: vec![
// deploy account tx with the default account class
Expand Down Expand Up @@ -186,7 +191,9 @@ pub fn valid_blocks() -> [ExecutableBlock; 3] {
timestamp: 300,
sequencer_address,
parent_hash: 12345u64.into(),
gas_prices: gas_prices.clone(),
l1_gas_prices: gas_prices.clone(),
l1_data_gas_prices: gas_prices.clone(),
l1_da_mode: L1DataAvailabilityMode::Calldata,
},
body: vec![
// deploy a erc20 contract using UDC
Expand Down
36 changes: 30 additions & 6 deletions crates/katana/primitives/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use starknet::core::crypto::compute_hash_on_elements;

use crate::contract::ContractAddress;
use crate::da::L1DataAvailabilityMode;
use crate::transaction::{ExecutableTxWithHash, TxHash, TxWithHash};
use crate::version::ProtocolVersion;
use crate::Felt;
Expand Down Expand Up @@ -43,12 +44,15 @@ pub enum FinalityStatus {
pub struct PartialHeader {
pub number: BlockNumber,
pub parent_hash: Felt,
pub gas_prices: GasPrices,
pub timestamp: u64,
pub sequencer_address: ContractAddress,
pub version: ProtocolVersion,
pub l1_gas_prices: GasPrices,
pub l1_data_gas_prices: GasPrices,
pub l1_da_mode: L1DataAvailabilityMode,
}

// TODO: change names to wei and fri
/// The L1 gas prices.
#[derive(Debug, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Expand All @@ -62,22 +66,40 @@ pub struct GasPrices {
}

impl GasPrices {
pub fn new(eth_gas_price: u128, strk_gas_price: u128) -> Self {
Self { eth: eth_gas_price, strk: strk_gas_price }
pub fn new(wei_gas_price: u128, fri_gas_price: u128) -> Self {
Self { eth: wei_gas_price, strk: fri_gas_price }
}
}

/// Represents a block header.
#[derive(Debug, Default, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Header {
pub parent_hash: BlockHash,
pub number: BlockNumber,
pub gas_prices: GasPrices,
pub timestamp: u64,
pub state_root: Felt,
pub sequencer_address: ContractAddress,
pub protocol_version: ProtocolVersion,
pub l1_gas_prices: GasPrices,
pub l1_data_gas_prices: GasPrices,
pub l1_da_mode: L1DataAvailabilityMode,
}

impl Default for Header {
fn default() -> Self {
Self {
timestamp: 0,
number: BlockNumber::default(),
state_root: Felt::default(),
parent_hash: BlockHash::default(),
l1_gas_prices: GasPrices::default(),
protocol_version: ProtocolVersion::default(),
sequencer_address: ContractAddress::default(),
l1_data_gas_prices: GasPrices::default(),
l1_da_mode: L1DataAvailabilityMode::Calldata,
}
}
}

impl Header {
Expand All @@ -87,9 +109,11 @@ impl Header {
number: partial_header.number,
protocol_version: partial_header.version,
timestamp: partial_header.timestamp,
gas_prices: partial_header.gas_prices,
parent_hash: partial_header.parent_hash,
sequencer_address: partial_header.sequencer_address,
l1_gas_prices: partial_header.l1_gas_prices,
l1_da_mode: partial_header.l1_da_mode,
l1_data_gas_prices: partial_header.l1_data_gas_prices,
}
}

Expand Down
17 changes: 14 additions & 3 deletions crates/katana/primitives/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::BTreeMap;

use alloy_primitives::U256;
use lazy_static::lazy_static;
use starknet::core::types::L1DataAvailabilityMode;
use starknet::core::utils::cairo_short_string_to_felt;
use starknet_crypto::Felt;

Expand Down Expand Up @@ -56,7 +57,9 @@ impl ChainSpec {
timestamp: self.genesis.timestamp,
state_root: self.genesis.state_root,
parent_hash: self.genesis.parent_hash,
gas_prices: self.genesis.gas_prices.clone(),
l1_da_mode: L1DataAvailabilityMode::Calldata,
l1_gas_prices: self.genesis.gas_prices.clone(),
l1_data_gas_prices: self.genesis.gas_prices.clone(),
sequencer_address: self.genesis.sequencer_address,
};
Block { header, body: Vec::new() }
Expand Down Expand Up @@ -216,6 +219,7 @@ mod tests {
use std::str::FromStr;

use alloy_primitives::U256;
use starknet::core::types::L1DataAvailabilityMode;
use starknet::macros::felt;

use super::*;
Expand Down Expand Up @@ -342,7 +346,9 @@ mod tests {
state_root: chain_spec.genesis.state_root,
parent_hash: chain_spec.genesis.parent_hash,
sequencer_address: chain_spec.genesis.sequencer_address,
gas_prices: chain_spec.genesis.gas_prices.clone(),
l1_gas_prices: chain_spec.genesis.gas_prices.clone(),
l1_data_gas_prices: chain_spec.genesis.gas_prices.clone(),
l1_da_mode: L1DataAvailabilityMode::Calldata,
protocol_version: CURRENT_STARKNET_VERSION,
},
body: Vec::new(),
Expand All @@ -358,7 +364,12 @@ mod tests {
assert_eq!(actual_block.header.state_root, expected_block.header.state_root);
assert_eq!(actual_block.header.parent_hash, expected_block.header.parent_hash);
assert_eq!(actual_block.header.sequencer_address, expected_block.header.sequencer_address);
assert_eq!(actual_block.header.gas_prices, expected_block.header.gas_prices);
assert_eq!(actual_block.header.l1_gas_prices, expected_block.header.l1_gas_prices);
assert_eq!(
actual_block.header.l1_data_gas_prices,
expected_block.header.l1_data_gas_prices
);
assert_eq!(actual_block.header.l1_da_mode, expected_block.header.l1_da_mode);
assert_eq!(actual_block.header.protocol_version, expected_block.header.protocol_version);
assert_eq!(actual_block.body, expected_block.body);

Expand Down
2 changes: 2 additions & 0 deletions crates/katana/primitives/src/da/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ pub mod eip4844;
pub mod encoding;
pub mod math;
pub mod serde;

pub use ::starknet::core::types::L1DataAvailabilityMode;
2 changes: 2 additions & 0 deletions crates/katana/primitives/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub struct BlockEnv {
pub timestamp: u64,
/// The L1 gas prices at this particular block.
pub l1_gas_prices: GasPrices,
/// The L1 data gas prices at this particular block.
pub l1_data_gas_prices: GasPrices,
/// The contract address of the sequencer.
pub sequencer_address: ContractAddress,
}
Expand Down
Loading

0 comments on commit f9a559f

Please sign in to comment.