Skip to content

Commit 42cbda8

Browse files
committedJan 23, 2025
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 8598616 commit 42cbda8

File tree

4 files changed

+42
-39
lines changed

4 files changed

+42
-39
lines changed
 

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

+6-8
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,
@@ -23,7 +22,7 @@ use katana_primitives::genesis::Genesis;
2322
use katana_primitives::state::StateUpdatesWithClasses;
2423
use katana_primitives::utils::split_u256;
2524
use katana_primitives::version::{ProtocolVersion, CURRENT_STARKNET_VERSION};
26-
use katana_primitives::Felt;
25+
use katana_primitives::{eth, Felt};
2726
use lazy_static::lazy_static;
2827
use serde::{Deserialize, Serialize};
2928
use starknet::core::utils::cairo_short_string_to_felt;
@@ -62,7 +61,7 @@ pub struct FeeContracts {
6261
}
6362

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

74-
account: EthAddress,
73+
/// account on the ethereum network
74+
account: eth::Address,
7575

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

8180
Starknet {
@@ -85,11 +84,10 @@ pub enum SettlementLayer {
8584
// url for starknet rpc provider
8685
rpc_url: Url,
8786

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

9190
// - The core appchain contract used to settlement
92-
// - This is deployed on the L1
9391
core_contract: ContractAddress,
9492
},
9593
}

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

+29-21
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

+2-2
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::{
@@ -42,7 +42,7 @@ pub struct Backend<EF: ExecutorFactory> {
4242

4343
pub executor_factory: Arc<EF>,
4444

45-
pub gas_oracle: L1GasOracle,
45+
pub gas_oracle: GasOracle,
4646
}
4747

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

‎crates/katana/node/src/lib.rs

+5-8
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::constants::{
@@ -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)