Skip to content

Commit d4a757d

Browse files
committed
feat(katana): starknet gas oracle placeholder (#2874)
Starknet doesn't yet provide a way to query the L2 gas prices from the current RPC specs (but soon will be in [RPC v0.80 ](https://github.com/starkware-libs/starknet-specs/blob/c94df2c5866e11c866abd3d234b0d5df681073c3/api/starknet_api_openrpc.json#L1603-L1607)), so this is merely a placeholder to make sure that we can run the node with Starknet as the settlement layer when specified in the `ChainSpec`. Reference: #2870
1 parent 7bc8c58 commit d4a757d

File tree

4 files changed

+42
-39
lines changed

4 files changed

+42
-39
lines changed

crates/katana/chain-spec/src/lib.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use katana_primitives::chain::ChainId;
1010
use katana_primitives::class::ClassHash;
1111
use katana_primitives::contract::ContractAddress;
1212
use katana_primitives::da::L1DataAvailabilityMode;
13-
use katana_primitives::eth::{self, Address as EthAddress};
1413
use katana_primitives::genesis::allocation::{DevAllocationsGenerator, GenesisAllocation};
1514
use katana_primitives::genesis::constant::{
1615
get_fee_token_balance_base_storage_address, DEFAULT_ACCOUNT_CLASS_PUBKEY_STORAGE_SLOT,
@@ -24,7 +23,7 @@ use katana_primitives::genesis::Genesis;
2423
use katana_primitives::state::StateUpdatesWithClasses;
2524
use katana_primitives::utils::split_u256;
2625
use katana_primitives::version::{ProtocolVersion, CURRENT_STARKNET_VERSION};
27-
use katana_primitives::Felt;
26+
use katana_primitives::{eth, Felt};
2827
use lazy_static::lazy_static;
2928
use serde::{Deserialize, Serialize};
3029
use starknet::core::utils::cairo_short_string_to_felt;
@@ -63,7 +62,7 @@ pub struct FeeContracts {
6362
}
6463

6564
#[derive(Debug, Clone, Serialize, Deserialize)]
66-
#[serde(rename_all = "camelCase")]
65+
#[serde(tag = "type", rename_all = "camelCase")]
6766
pub enum SettlementLayer {
6867
Ethereum {
6968
// The id of the settlement chain.
@@ -72,11 +71,11 @@ pub enum SettlementLayer {
7271
// url for ethereum rpc provider
7372
rpc_url: Url,
7473

75-
account: EthAddress,
74+
/// account on the ethereum network
75+
account: eth::Address,
7676

7777
// - The core appchain contract used to settlement
78-
// - This is deployed on the L1
79-
core_contract: EthAddress,
78+
core_contract: eth::Address,
8079
},
8180

8281
Starknet {
@@ -86,11 +85,10 @@ pub enum SettlementLayer {
8685
// url for starknet rpc provider
8786
rpc_url: Url,
8887

89-
// the account address that was used to initialized the l1 deployments
88+
/// account on the starknet network
9089
account: ContractAddress,
9190

9291
// - The core appchain contract used to settlement
93-
// - This is deployed on the L1
9492
core_contract: ContractAddress,
9593
},
9694
}

crates/katana/core/src/backend/gas_oracle.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,22 @@ const BUFFER_SIZE: usize = 60;
1616
const INTERVAL: Duration = Duration::from_secs(60);
1717
const ONE_GWEI: u128 = 1_000_000_000;
1818

19-
// TODO: implement a proper gas oracle function - sample the l1 gas and data gas prices
20-
// currently this just return the hardcoded value set from the cli or if not set, the default value.
2119
#[derive(Debug)]
22-
pub enum L1GasOracle {
23-
Fixed(FixedL1GasOracle),
24-
Sampled(SampledL1GasOracle),
20+
pub enum GasOracle {
21+
Fixed(FixedGasOracle),
22+
Sampled(EthereumSampledGasOracle),
2523
}
2624

2725
#[derive(Debug)]
28-
pub struct FixedL1GasOracle {
26+
pub struct FixedGasOracle {
2927
gas_prices: GasPrices,
3028
data_gas_prices: GasPrices,
3129
}
3230

3331
#[derive(Debug, Clone)]
34-
pub struct SampledL1GasOracle {
32+
pub struct EthereumSampledGasOracle {
3533
prices: Arc<Mutex<SampledPrices>>,
36-
l1_provider: Url,
34+
provider: Url,
3735
}
3836

3937
#[derive(Debug, Default)]
@@ -50,29 +48,39 @@ pub struct GasOracleWorker {
5048
pub data_gas_price_buffer: GasPriceBuffer,
5149
}
5250

53-
impl L1GasOracle {
51+
impl GasOracle {
5452
pub fn fixed(gas_prices: GasPrices, data_gas_prices: GasPrices) -> Self {
55-
L1GasOracle::Fixed(FixedL1GasOracle { gas_prices, data_gas_prices })
53+
GasOracle::Fixed(FixedGasOracle { gas_prices, data_gas_prices })
5654
}
5755

58-
pub fn sampled(l1_provider: Url) -> Self {
56+
/// Creates a new gas oracle that samples the gas prices from an Ethereum chain.
57+
pub fn sampled_ethereum(eth_provider: Url) -> Self {
5958
let prices: Arc<Mutex<SampledPrices>> = Arc::new(Mutex::new(SampledPrices::default()));
60-
L1GasOracle::Sampled(SampledL1GasOracle { prices, l1_provider })
59+
GasOracle::Sampled(EthereumSampledGasOracle { prices, provider: eth_provider })
60+
}
61+
62+
/// This is just placeholder for now, as Starknet doesn't provide a way to get the L2 gas
63+
/// prices, we just return a fixed gas price values of 0. This is equivalent to calling
64+
/// [`GasOracle::fixed`] with 0 values for both gas and data prices.
65+
///
66+
/// The result of this is the same as running the node with fee disabled.
67+
pub fn sampled_starknet() -> Self {
68+
Self::fixed(GasPrices { eth: 0, strk: 0 }, GasPrices { eth: 0, strk: 0 })
6169
}
6270

6371
/// Returns the current gas prices.
6472
pub fn current_gas_prices(&self) -> GasPrices {
6573
match self {
66-
L1GasOracle::Fixed(fixed) => fixed.current_gas_prices(),
67-
L1GasOracle::Sampled(sampled) => sampled.prices.lock().gas_prices.clone(),
74+
GasOracle::Fixed(fixed) => fixed.current_gas_prices(),
75+
GasOracle::Sampled(sampled) => sampled.prices.lock().gas_prices.clone(),
6876
}
6977
}
7078

7179
/// Returns the current data gas prices.
7280
pub fn current_data_gas_prices(&self) -> GasPrices {
7381
match self {
74-
L1GasOracle::Fixed(fixed) => fixed.current_data_gas_prices(),
75-
L1GasOracle::Sampled(sampled) => sampled.prices.lock().data_gas_prices.clone(),
82+
GasOracle::Fixed(fixed) => fixed.current_data_gas_prices(),
83+
GasOracle::Sampled(sampled) => sampled.prices.lock().data_gas_prices.clone(),
7684
}
7785
}
7886

@@ -81,7 +89,7 @@ impl L1GasOracle {
8189
Self::Fixed(..) => {}
8290
Self::Sampled(oracle) => {
8391
let prices = oracle.prices.clone();
84-
let l1_provider = oracle.l1_provider.clone();
92+
let l1_provider = oracle.provider.clone();
8593

8694
task_spawner.build_task().critical().name("L1 Gas Oracle Worker").spawn(
8795
async move {
@@ -97,7 +105,7 @@ impl L1GasOracle {
97105
}
98106
}
99107

100-
impl SampledL1GasOracle {
108+
impl EthereumSampledGasOracle {
101109
pub fn current_data_gas_prices(&self) -> GasPrices {
102110
self.prices.lock().data_gas_prices.clone()
103111
}
@@ -107,7 +115,7 @@ impl SampledL1GasOracle {
107115
}
108116
}
109117

110-
impl FixedL1GasOracle {
118+
impl FixedGasOracle {
111119
pub fn current_data_gas_prices(&self) -> GasPrices {
112120
self.data_gas_prices.clone()
113121
}
@@ -289,10 +297,10 @@ mod tests {
289297
#[ignore = "Requires external assumption"]
290298
async fn test_gas_oracle() {
291299
let url = Url::parse("https://eth.merkle.io/").expect("Invalid URL");
292-
let oracle = L1GasOracle::sampled(url.clone());
300+
let oracle = GasOracle::sampled_ethereum(url.clone());
293301

294302
let shared_prices = match &oracle {
295-
L1GasOracle::Sampled(sampled) => sampled.prices.clone(),
303+
GasOracle::Sampled(sampled) => sampled.prices.clone(),
296304
_ => panic!("Expected sampled oracle"),
297305
};
298306

crates/katana/core/src/backend/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use gas_oracle::L1GasOracle;
3+
use gas_oracle::GasOracle;
44
use katana_chain_spec::ChainSpec;
55
use katana_executor::{ExecutionOutput, ExecutionResult, ExecutorFactory};
66
use katana_primitives::block::{
@@ -41,7 +41,7 @@ pub struct Backend<EF: ExecutorFactory> {
4141

4242
pub executor_factory: Arc<EF>,
4343

44-
pub gas_oracle: L1GasOracle,
44+
pub gas_oracle: GasOracle,
4545
}
4646

4747
impl<EF: ExecutorFactory> Backend<EF> {

crates/katana/node/src/lib.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use dojo_metrics::{Report, Server as MetricsServer};
1818
use hyper::Method;
1919
use jsonrpsee::RpcModule;
2020
use katana_chain_spec::SettlementLayer;
21-
use katana_core::backend::gas_oracle::L1GasOracle;
21+
use katana_core::backend::gas_oracle::GasOracle;
2222
use katana_core::backend::storage::Blockchain;
2323
use katana_core::backend::Backend;
2424
use katana_core::env::BlockContextGenerator;
@@ -202,20 +202,17 @@ pub async fn build(mut config: Config) -> Result<Node> {
202202
// Check if the user specify a fixed gas price in the dev config.
203203
let gas_oracle = if let Some(fixed_prices) = &config.dev.fixed_gas_prices {
204204
// Use fixed gas prices if provided in the configuration
205-
L1GasOracle::fixed(fixed_prices.gas_price.clone(), fixed_prices.data_gas_price.clone())
205+
GasOracle::fixed(fixed_prices.gas_price.clone(), fixed_prices.data_gas_price.clone())
206206
} else if let Some(settlement) = &config.chain.settlement {
207207
match settlement {
208+
SettlementLayer::Starknet { .. } => GasOracle::sampled_starknet(),
208209
SettlementLayer::Ethereum { rpc_url, .. } => {
209-
// Default to a sampled gas oracle using the given provider
210-
L1GasOracle::sampled(rpc_url.clone())
211-
}
212-
SettlementLayer::Starknet { .. } => {
213-
todo!("starknet gas oracle")
210+
GasOracle::sampled_ethereum(rpc_url.clone())
214211
}
215212
}
216213
} else {
217214
// Use default fixed gas prices if no url and if no fixed prices are provided
218-
L1GasOracle::fixed(
215+
GasOracle::fixed(
219216
GasPrices { eth: DEFAULT_ETH_L1_GAS_PRICE, strk: DEFAULT_STRK_L1_GAS_PRICE },
220217
GasPrices { eth: DEFAULT_ETH_L1_DATA_GAS_PRICE, strk: DEFAULT_STRK_L1_DATA_GAS_PRICE },
221218
)

0 commit comments

Comments
 (0)