Skip to content

Commit dbcb1dd

Browse files
committed
move to own module
1 parent df5a957 commit dbcb1dd

File tree

11 files changed

+508
-136
lines changed

11 files changed

+508
-136
lines changed

Cargo.lock

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ members = [
1616
"crates/metrics",
1717
"crates/node",
1818
"crates/node-bindings",
19+
"crates/oracle/gas",
1920
"crates/pool",
2021
"crates/primitives",
2122
"crates/rpc/rpc",
@@ -72,6 +73,7 @@ katana-executor = { path = "crates/executor" }
7273
katana-explorer = { path = "crates/explorer" }
7374
katana-feeder-gateway = { path = "crates/feeder-gateway" }
7475
katana-fork = { path = "crates/storage/fork" }
76+
katana-gas-oracle = { path = "crates/oracle/gas" }
7577
katana-log = { path = "crates/log" }
7678
katana-messaging = { path = "crates/messaging" }
7779
katana-metrics = { path = "crates/metrics" }
@@ -91,6 +93,7 @@ katana-stage = { path = "crates/sync/stage" }
9193
katana-tasks = { path = "crates/tasks" }
9294
katana-trie = { path = "crates/trie" }
9395
katana-utils = { path = "crates/utils" }
96+
9497
# cairo
9598
cairo-lang-casm = "2.11.2"
9699
cairo-lang-runner = "2.11.2"

crates/core/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ version.workspace = true
99
[dependencies]
1010
katana-chain-spec.workspace = true
1111
katana-db.workspace = true
12-
katana-executor = { workspace = true }
12+
katana-executor.workspace = true
13+
katana-gas-oracle.workspace = true
1314
katana-metrics.workspace = true
1415
katana-pool.workspace = true
1516
katana-primitives = { workspace = true, features = [ "arbitrary" ] }

crates/core/src/backend/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use std::collections::{BTreeMap, HashMap};
22
use std::sync::Arc;
33

44
use anyhow::{anyhow, Context};
5-
use gas_oracle::GasOracle;
65
use katana_chain_spec::ChainSpec;
76
use katana_executor::{ExecutionOutput, ExecutionResult, ExecutorFactory};
7+
use katana_gas_oracle::GasOracle;
88
use katana_primitives::block::{
99
BlockHash, BlockNumber, FinalityStatus, Header, PartialHeader, SealedBlock,
1010
SealedBlockWithStatus,
@@ -33,7 +33,6 @@ use starknet_types_core::hash::{self, StarkHash};
3333
use tracing::info;
3434

3535
pub mod contract;
36-
pub mod gas_oracle;
3736
pub mod storage;
3837

3938
use self::storage::Blockchain;

crates/core/tests/backend.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use katana_core::backend::Backend;
77
use katana_executor::implementation::blockifier::cache::ClassCache;
88
use katana_executor::implementation::blockifier::BlockifierFactory;
99
use katana_executor::BlockLimits;
10+
use katana_primitives::block::GasPrice;
1011
use katana_primitives::chain::ChainId;
1112
use katana_primitives::env::CfgEnv;
1213
use katana_primitives::felt;
@@ -40,7 +41,7 @@ fn backend_with_db(chain_spec: &ChainSpec, provider: impl Database) -> Backend<B
4041
Backend::new(
4142
chain_spec.clone().into(),
4243
Blockchain::new(provider),
43-
GasOracle::sampled_starknet(),
44+
GasOracle::fixed(GasPrice::MIN, GasPrice::MIN),
4445
executor(chain_spec),
4546
)
4647
}

crates/node/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ impl Node {
164164
GasOracle::fixed(fixed_prices.gas_price.clone(), fixed_prices.data_gas_price.clone())
165165
} else if let Some(settlement) = config.chain.settlement() {
166166
match settlement {
167-
SettlementLayer::Starknet { .. } => GasOracle::sampled_starknet(),
167+
SettlementLayer::Starknet { rpc_url, .. } => {
168+
GasOracle::sampled_starknet(rpc_url.clone())
169+
}
168170
SettlementLayer::Ethereum { rpc_url, .. } => {
169171
GasOracle::sampled_ethereum(rpc_url.clone())
170172
}

crates/oracle/gas/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
edition.workspace = true
3+
license.workspace = true
4+
license-file.workspace = true
5+
name = "katana-gas-oracle"
6+
repository.workspace = true
7+
version.workspace = true
8+
9+
[dependencies]
10+
katana-primitives.workspace = true
11+
katana-tasks.workspace = true
12+
13+
alloy-provider = { workspace = true, default-features = false, features = [ "reqwest", "reqwest-rustls-tls" ] }
14+
alloy-rpc-types-eth = { workspace = true, default-features = false }
15+
anyhow.workspace = true
16+
num-traits.workspace = true
17+
parking_lot.workspace = true
18+
starknet.workspace = true
19+
thiserror.workspace = true
20+
tokio.workspace = true
21+
tracing.workspace = true
22+
url.workspace = true

crates/oracle/gas/src/ethereum.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use std::collections::VecDeque;
2+
use std::fmt::Debug;
3+
use std::sync::Arc;
4+
5+
use alloy_provider::{Provider, ProviderBuilder};
6+
use alloy_rpc_types_eth::{BlockNumberOrTag, FeeHistory};
7+
use anyhow::{Context, Ok};
8+
use katana_primitives::block::GasPrice;
9+
use katana_tasks::TaskSpawner;
10+
use num_traits::ToPrimitive;
11+
use parking_lot::Mutex;
12+
use starknet::core::types::{BlockId, BlockTag, MaybePendingBlockWithTxHashes, ResourcePrice};
13+
use starknet::providers::jsonrpc::HttpTransport;
14+
use starknet::providers::{JsonRpcClient, Provider as StarknetProvider};
15+
use tokio::time::Duration;
16+
use tracing::error;
17+
use url::Url;
18+
19+
#[derive(Debug, Clone)]
20+
pub struct GasOracle {
21+
prices: Arc<Mutex<SampledPrices>>,
22+
provider: Url,
23+
}
24+
25+
impl GasOracle {
26+
pub fn new(provider: Url) -> Self {
27+
Self { prices: Default::default(), provider }
28+
}
29+
30+
pub fn current_l1_data_gas_prices(&self) -> GasPrice {
31+
self.prices.lock().l1_data_gas_prices.clone()
32+
}
33+
34+
pub fn current_l1_gas_prices(&self) -> GasPrice {
35+
self.prices.lock().l1_gas_prices.clone()
36+
}
37+
38+
pub fn current_l2_gas_prices(&self) -> GasPrice {
39+
GasPrice::MIN
40+
}
41+
}
42+
43+
#[derive(Debug, Clone)]
44+
pub struct EthereumGasOracleWorker {
45+
pub prices: Arc<Mutex<SampledPrices>>,
46+
pub l1_provider_url: Url,
47+
pub gas_price_buffer: GasPriceBuffer,
48+
pub data_gas_price_buffer: GasPriceBuffer,
49+
}
50+
51+
impl EthereumGasOracleWorker {
52+
pub fn new(prices: Arc<Mutex<SampledPrices>>, l1_provider_url: Url) -> Self {
53+
Self {
54+
prices,
55+
l1_provider_url,
56+
gas_price_buffer: GasPriceBuffer::new(),
57+
data_gas_price_buffer: GasPriceBuffer::new(),
58+
}
59+
}
60+
61+
pub async fn run(&mut self) -> anyhow::Result<()> {
62+
let provider = ProviderBuilder::new().on_http(self.l1_provider_url.clone());
63+
// every 60 seconds, Starknet samples the base price of gas and data gas on L1
64+
let mut interval = tokio::time::interval(INTERVAL);
65+
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
66+
67+
loop {
68+
// Wait for the interval to tick
69+
interval.tick().await;
70+
71+
{
72+
// Attempt to get the gas price from L1
73+
let last_block_number = provider.get_block_number().await?;
74+
75+
let fee_history = provider
76+
.get_fee_history(1, BlockNumberOrTag::Number(last_block_number), &[])
77+
.await?;
78+
79+
let mut prices = self.prices.lock();
80+
81+
if let Err(error) = update_gas_price(
82+
&mut prices,
83+
&mut self.gas_price_buffer,
84+
&mut self.data_gas_price_buffer,
85+
fee_history,
86+
) {
87+
error!(target: "gas_oracle", %error, "Error updating gas prices.");
88+
}
89+
}
90+
}
91+
}
92+
93+
pub async fn update_once(&mut self) -> anyhow::Result<()> {
94+
let provider = ProviderBuilder::new().on_http(self.l1_provider_url.clone());
95+
96+
// Attempt to get the gas price from L1
97+
let last_block_number = provider.get_block_number().await?;
98+
99+
let fee_history =
100+
provider.get_fee_history(1, BlockNumberOrTag::Number(last_block_number), &[]).await?;
101+
102+
let mut prices = self.prices.lock();
103+
104+
update_gas_price(
105+
&mut prices,
106+
&mut self.gas_price_buffer,
107+
&mut self.data_gas_price_buffer,
108+
fee_history,
109+
)
110+
}
111+
}

crates/oracle/gas/src/fixed.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use std::collections::VecDeque;
2+
use std::fmt::Debug;
3+
use std::sync::Arc;
4+
5+
use ::starknet::core::types::{BlockId, BlockTag, MaybePendingBlockWithTxHashes, ResourcePrice};
6+
use ::starknet::providers::jsonrpc::HttpTransport;
7+
use ::starknet::providers::{JsonRpcClient, Provider as StarknetProvider};
8+
use alloy_provider::{Provider, ProviderBuilder};
9+
use alloy_rpc_types_eth::{BlockNumberOrTag, FeeHistory};
10+
use anyhow::{Context, Ok};
11+
use katana_primitives::block::GasPrice;
12+
use katana_tasks::TaskSpawner;
13+
use num_traits::ToPrimitive;
14+
use parking_lot::Mutex;
15+
use tokio::time::Duration;
16+
use tracing::error;
17+
use url::Url;
18+
19+
#[derive(Debug)]
20+
pub struct FixedGasOracle {
21+
l2_gas_prices: GasPrice,
22+
l1_gas_prices: GasPrice,
23+
l1_data_gas_prices: GasPrice,
24+
}
25+
26+
impl FixedGasOracle {
27+
pub fn current_l1_data_gas_prices(&self) -> GasPrice {
28+
self.l1_data_gas_prices.clone()
29+
}
30+
31+
pub fn current_l1_gas_prices(&self) -> GasPrice {
32+
self.l1_gas_prices.clone()
33+
}
34+
35+
pub fn current_l2_gas_prices(&self) -> GasPrice {
36+
self.l2_gas_prices.clone()
37+
}
38+
}

0 commit comments

Comments
 (0)