Skip to content

Commit

Permalink
feat(gas-adjuster): gas adjuster for EIP4844 (#1255)
Browse files Browse the repository at this point in the history
## What ❔

<!-- What are the changes this PR brings about? -->
<!-- Example: This PR adds a PR template to the repo. -->
<!-- (For bigger PRs adding more context is appreciated) -->

## Why ❔

<!-- Why are these changes done? What goal do they contribute to? What
are the principles behind them? -->
<!-- Example: PR templates ensure PR reviewers, observers, and future
iterators are in context about the evolution of repos. -->

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [ ] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] Code has been formatted via `zk fmt` and `zk lint`.
- [ ] Spellcheck has been run via `zk spellcheck`.
- [ ] Linkcheck has been run via `zk linkcheck`.

---------

Co-authored-by: Fedor Sakharov <fedor.sakharov@gmail.com>
  • Loading branch information
perekopskiy and montekki committed Feb 28, 2024
1 parent cebf55a commit 1da97ed
Show file tree
Hide file tree
Showing 23 changed files with 595 additions and 88 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 24 additions & 1 deletion core/lib/config/src/configs/eth_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ impl ETHSenderConfig {
internal_enforced_l1_gas_price: None,
poll_period: 5,
max_l1_gas_price: None,
num_samples_for_blob_base_fee_estimate: 10,
internal_pubdata_pricing_multiplier: 1.0,
max_blob_base_fee: None,
},
}
}
Expand Down Expand Up @@ -151,8 +154,16 @@ pub struct GasAdjusterConfig {
pub internal_enforced_l1_gas_price: Option<u64>,
/// Node polling period in seconds
pub poll_period: u64,
/// Max number of l1 gas price that is allowed to be used in state keeper.
/// Max number of l1 gas price that is allowed to be used.
pub max_l1_gas_price: Option<u64>,
/// Number of blocks collected by GasAdjuster from which `blob_base_fee` median is taken
#[serde(default = "GasAdjusterConfig::default_num_samples_for_blob_base_fee_estimate")]
pub num_samples_for_blob_base_fee_estimate: usize,
/// Parameter by which the pubdata fee will be multiplied for internal purposes
#[serde(default = "GasAdjusterConfig::default_internal_pubdata_pricing_multiplier")]
pub internal_pubdata_pricing_multiplier: f64,
/// Max blob base fee that is allowed to be used.
pub max_blob_base_fee: Option<u64>,
}

impl GasAdjusterConfig {
Expand All @@ -164,4 +175,16 @@ impl GasAdjusterConfig {
pub fn max_l1_gas_price(&self) -> u64 {
self.max_l1_gas_price.unwrap_or(u64::MAX)
}

pub fn max_blob_base_fee(&self) -> u64 {
self.max_blob_base_fee.unwrap_or(u64::MAX)
}

pub const fn default_num_samples_for_blob_base_fee_estimate() -> usize {
10
}

pub const fn default_internal_pubdata_pricing_multiplier() -> f64 {
1.0
}
}
3 changes: 3 additions & 0 deletions core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ impl RandomConfig for configs::eth_sender::GasAdjusterConfig {
internal_enforced_l1_gas_price: g.gen(),
poll_period: g.gen(),
max_l1_gas_price: g.gen(),
num_samples_for_blob_base_fee_estimate: g.gen(),
internal_pubdata_pricing_multiplier: g.gen(),
max_blob_base_fee: g.gen(),
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions core/lib/env_config/src/eth_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ mod tests {
internal_enforced_l1_gas_price: None,
poll_period: 15,
max_l1_gas_price: Some(100000000),
num_samples_for_blob_base_fee_estimate: 10,
internal_pubdata_pricing_multiplier: 1.0,
max_blob_base_fee: None,
},
}
}
Expand All @@ -88,6 +91,8 @@ mod tests {
ETH_SENDER_GAS_ADJUSTER_INTERNAL_L1_PRICING_MULTIPLIER="0.8"
ETH_SENDER_GAS_ADJUSTER_POLL_PERIOD="15"
ETH_SENDER_GAS_ADJUSTER_MAX_L1_GAS_PRICE="100000000"
ETH_SENDER_GAS_ADJUSTER_MAX_BLOB_BASE_FEE_SAMPLES="10"
ETH_SENDER_GAS_ADJUSTER_INTERNAL_PUBDATA_PRICING_MULTIPLIER="1.0"
ETH_SENDER_WAIT_FOR_PROOFS="false"
ETH_SENDER_SENDER_AGGREGATED_PROOF_SIZES="1,5"
ETH_SENDER_SENDER_MAX_AGGREGATED_BLOCKS_TO_COMMIT="3"
Expand Down
1 change: 1 addition & 0 deletions core/lib/eth_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ static_assertions = "1.1.0"
tokio = { version = "1", features = ["full"] }
pretty_assertions = "1"
hex = "0.4.2"
serde_json = "1.0"
8 changes: 4 additions & 4 deletions core/lib/eth_client/src/clients/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ use zksync_types::{
web3::{
ethabi,
types::{
Address, Block, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt,
H160, H256, U256, U64,
Address, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt, H160,
H256, U256, U64,
},
},
L1ChainId,
};

use crate::{
BoundEthInterface, ContractCall, Error, EthInterface, ExecutedTxStatus, FailureInfo, Options,
RawTransactionBytes, SignedCallResult,
Block, BoundEthInterface, ContractCall, Error, EthInterface, ExecutedTxStatus, FailureInfo,
Options, RawTransactionBytes, SignedCallResult,
};

#[async_trait]
Expand Down
32 changes: 27 additions & 5 deletions core/lib/eth_client/src/clients/http/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ use async_trait::async_trait;
use zksync_types::web3::{
self,
contract::Contract,
ethabi,
ethabi, helpers,
helpers::CallFuture,
transports::Http,
types::{
Address, Block, BlockId, BlockNumber, Bytes, Filter, Log, Transaction, TransactionId,
Address, BlockId, BlockNumber, Bytes, Filter, Log, Transaction, TransactionId,
TransactionReceipt, H256, U256, U64,
},
Web3,
Transport, Web3,
};

use crate::{
clients::http::{Method, COUNTERS, LATENCIES},
types::{Error, ExecutedTxStatus, FailureInfo, RawTokens},
ContractCall, EthInterface, RawTransactionBytes,
Block, ContractCall, EthInterface, RawTransactionBytes,
};

/// An "anonymous" Ethereum client that can invoke read-only methods that aren't
Expand Down Expand Up @@ -284,7 +285,28 @@ impl EthInterface for QueryClient {
) -> Result<Option<Block<H256>>, Error> {
COUNTERS.call[&(Method::Block, component)].inc();
let latency = LATENCIES.direct[&Method::Block].start();
let block = self.web3.eth().block(block_id).await?;
// Copy of `web3::block` implementation. It's required to deserialize response as `crate::types::Block`
// that has EIP-4844 fields.
let block = {
let include_txs = helpers::serialize(&false);

let result = match block_id {
BlockId::Hash(hash) => {
let hash = helpers::serialize(&hash);
self.web3
.transport()
.execute("eth_getBlockByHash", vec![hash, include_txs])
}
BlockId::Number(num) => {
let num = helpers::serialize(&num);
self.web3
.transport()
.execute("eth_getBlockByNumber", vec![num, include_txs])
}
};

CallFuture::new(result).await?
};
latency.observe();
Ok(block)
}
Expand Down
7 changes: 4 additions & 3 deletions core/lib/eth_client/src/clients/http/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use zksync_types::{
ethabi,
transports::Http,
types::{
Address, Block, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt,
H160, H256, U256, U64,
Address, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt, H160,
H256, U256, U64,
},
},
L1ChainId, PackedEthSignature, EIP_4844_TX_TYPE,
Expand All @@ -21,7 +21,8 @@ use zksync_types::{
use super::{query::QueryClient, Method, LATENCIES};
use crate::{
types::{encode_blob_tx_with_sidecar, Error, ExecutedTxStatus, FailureInfo, SignedCallResult},
BoundEthInterface, CallFunctionArgs, ContractCall, EthInterface, Options, RawTransactionBytes,
Block, BoundEthInterface, CallFunctionArgs, ContractCall, EthInterface, Options,
RawTransactionBytes,
};

/// HTTP-based Ethereum client, backed by a private key to sign transactions.
Expand Down
36 changes: 32 additions & 4 deletions core/lib/eth_client/src/clients/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use zksync_types::{
web3::{
contract::tokens::Tokenize,
ethabi,
types::{Block, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt, U64},
types::{BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt, U64},
Error as Web3Error,
},
Address, L1ChainId, ProtocolVersionId, H160, H256, U256,
};

use crate::{
types::{Error, ExecutedTxStatus, FailureInfo, SignedCallResult},
BoundEthInterface, ContractCall, EthInterface, Options, RawTransactionBytes,
Block, BoundEthInterface, ContractCall, EthInterface, Options, RawTransactionBytes,
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -118,6 +118,7 @@ pub struct MockEthereum {
max_fee_per_gas: U256,
max_priority_fee_per_gas: U256,
base_fee_history: Vec<u64>,
excess_blob_gas_history: Vec<u64>,
/// If true, the mock will not check the ordering nonces of the transactions.
/// This is useful for testing the cases when the transactions are executed out of order.
non_ordering_confirmations: bool,
Expand All @@ -131,6 +132,7 @@ impl Default for MockEthereum {
max_fee_per_gas: 100.into(),
max_priority_fee_per_gas: 10.into(),
base_fee_history: vec![],
excess_blob_gas_history: vec![],
non_ordering_confirmations: false,
multicall_address: Address::default(),
inner: RwLock::default(),
Expand Down Expand Up @@ -209,6 +211,13 @@ impl MockEthereum {
}
}

pub fn with_excess_blob_gas_history(self, history: Vec<u64>) -> Self {
Self {
excess_blob_gas_history: history,
..self
}
}

pub fn with_non_ordering_confirmation(self, non_ordering_confirmations: bool) -> Self {
Self {
non_ordering_confirmations,
Expand Down Expand Up @@ -359,10 +368,29 @@ impl EthInterface for MockEthereum {

async fn block(
&self,
_block_id: BlockId,
block_id: BlockId,
_component: &'static str,
) -> Result<Option<Block<H256>>, Error> {
unimplemented!("Not needed right now")
match block_id {
BlockId::Number(BlockNumber::Number(number)) => {
let excess_blob_gas = self
.excess_blob_gas_history
.get(number.as_usize())
.map(|excess_blob_gas| (*excess_blob_gas).into());
let base_fee_per_gas = self
.base_fee_history
.get(number.as_usize())
.map(|base_fee| (*base_fee).into());

Ok(Some(Block {
number: Some(number),
excess_blob_gas,
base_fee_per_gas,
..Default::default()
}))
}
_ => unimplemented!("Not needed right now"),
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions core/lib/eth_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ use zksync_types::{
web3::{
ethabi,
types::{
AccessList, Address, Block, BlockId, BlockNumber, Filter, Log, Transaction,
AccessList, Address, BlockId, BlockNumber, Filter, Log, Transaction,
TransactionCondition, TransactionReceipt, H160, H256, U256, U64,
},
},
L1ChainId,
};

pub use crate::types::{
CallFunctionArgs, ContractCall, Error, ExecutedTxStatus, FailureInfo, RawTransactionBytes,
SignedCallResult,
Block, CallFunctionArgs, ContractCall, Error, ExecutedTxStatus, FailureInfo,
RawTransactionBytes, SignedCallResult,
};

pub mod clients;
Expand Down
Loading

0 comments on commit 1da97ed

Please sign in to comment.