Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem: eth_sender transaction's base fee is not capped #96

Merged
merged 1 commit into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/lib/config/src/configs/eth_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl EthConfig {
tx_aggregation_only_prove_and_execute: false,
time_in_mempool_in_l1_blocks_cap: 1800,
signing_mode: SigningMode::PrivateKey,
max_acceptable_base_fee_in_wei: 100000000000,
}),
gas_adjuster: Some(GasAdjusterConfig {
default_priority_fee_per_gas: 1000000000,
Expand Down Expand Up @@ -133,6 +134,9 @@ pub struct SenderConfig {
pub time_in_mempool_in_l1_blocks_cap: u32,
/// Type of signing client for Ethereum transactions.
pub signing_mode: SigningMode,

/// Max acceptable base fee the sender is allowed to use to send L1 txs.
pub max_acceptable_base_fee_in_wei: u64,
}

impl SenderConfig {
Expand Down
1 change: 1 addition & 0 deletions core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ impl Distribution<configs::eth_sender::SenderConfig> for EncodeDist {
tx_aggregation_only_prove_and_execute: false,
time_in_mempool_in_l1_blocks_cap: self.sample(rng),
signing_mode: SigningMode::PrivateKey,
max_acceptable_base_fee_in_wei: self.sample(rng),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions core/lib/env_config/src/eth_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ mod tests {
tx_aggregation_paused: false,
time_in_mempool_in_l1_blocks_cap: 2000,
signing_mode: SigningMode::PrivateKey,
max_acceptable_base_fee_in_wei: 100_000_000_000,
}),
gas_adjuster: Some(GasAdjusterConfig {
default_priority_fee_per_gas: 20000000000,
Expand Down Expand Up @@ -141,6 +142,7 @@ mod tests {
ETH_WATCH_ETH_NODE_POLL_INTERVAL="300"
ETH_SENDER_SENDER_SIGNING_MODE="PrivateKey"
ETH_CLIENT_WEB3_URL="http://127.0.0.1:8545"
ETH_SENDER_SENDER_MAX_ACCEPTABLE_BASE_FEE_IN_WEI="100000000000"

"#;
lock.set_env(config);
Expand Down
3 changes: 3 additions & 0 deletions core/lib/protobuf_config/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ impl ProtoRepr for proto::Sender {
.and_then(|x| Ok(proto::SigningMode::try_from(*x)?))
.context("signing_mode")?
.parse(),
max_acceptable_base_fee_in_wei: *required(&self.max_acceptable_base_fee_in_wei)
.context("max_acceptable_base_fee_in_wei")?,
})
}

Expand Down Expand Up @@ -173,6 +175,7 @@ impl ProtoRepr for proto::Sender {
tx_aggregation_paused: Some(this.tx_aggregation_paused),
time_in_mempool_in_l1_blocks_cap: Some(this.time_in_mempool_in_l1_blocks_cap),
signing_mode: Some(proto::SigningMode::new(&this.signing_mode).into()),
max_acceptable_base_fee_in_wei: Some(this.max_acceptable_base_fee_in_wei),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions core/lib/protobuf_config/src/proto/config/eth_sender.proto
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ message Sender {
optional bool tx_aggregation_only_prove_and_execute = 21; // required
optional uint32 time_in_mempool_in_l1_blocks_cap = 22; // optional
optional SigningMode signing_mode = 99; // required
optional uint64 max_acceptable_base_fee_in_wei = 100; // required; wei
}

message GasAdjuster {
Expand Down
2 changes: 2 additions & 0 deletions core/node/eth_sender/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub enum EthSenderError {
ContractCall(#[from] ContractCallError),
#[error("Token parsing error: {0}")]
Parse(#[from] contract::Error),
#[error("Max base fee exceeded")]
ExceedMaxBaseFee,
}

impl EthSenderError {
Expand Down
25 changes: 24 additions & 1 deletion core/node/eth_sender/src/eth_fees_oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use zksync_eth_client::{ClientError, EnrichedClientError};
use zksync_node_fee_model::l1_gas_price::TxParamsProvider;
use zksync_types::eth_sender::TxHistory;

use crate::{abstract_l1_interface::OperatorType, EthSenderError};
use crate::{
abstract_l1_interface::OperatorType, EthSenderError, EthSenderError::ExceedMaxBaseFee,
};

#[derive(Debug)]
pub(crate) struct EthFees {
Expand All @@ -33,6 +35,7 @@ pub(crate) struct GasAdjusterFeesOracle {
pub gas_adjuster: Arc<dyn TxParamsProvider>,
pub max_acceptable_priority_fee_in_gwei: u64,
pub time_in_mempool_in_l1_blocks_cap: u32,
pub max_acceptable_base_fee_in_wei: u64,
}

impl GasAdjusterFeesOracle {
Expand All @@ -55,6 +58,16 @@ impl GasAdjusterFeesOracle {
self.assert_fee_is_not_zero(blob_base_fee_per_gas, "blob");
let blob_base_fee_per_gas = Some(blob_base_fee_per_gas);

if base_fee_per_gas > self.max_acceptable_base_fee_in_wei {
tracing::info!(
"base fee per gas: {} exceed max acceptable fee in configuration: {}, skip transaction",
base_fee_per_gas,
self.max_acceptable_base_fee_in_wei
);

return Err(ExceedMaxBaseFee);
}

if let Some(previous_sent_tx) = previous_sent_tx {
// for blob transactions on re-sending need to double all gas prices
return Ok(EthFees {
Expand Down Expand Up @@ -100,6 +113,16 @@ impl GasAdjusterFeesOracle {
)?;
}

if base_fee_per_gas > self.max_acceptable_base_fee_in_wei {
tracing::info!(
"base fee per gas: {} exceed max acceptable fee in configuration: {}, skip transaction",
base_fee_per_gas,
self.max_acceptable_base_fee_in_wei
);

return Err(ExceedMaxBaseFee);
}

let mut priority_fee_per_gas = self.gas_adjuster.get_priority_fee();

if let Some(previous_sent_tx) = previous_sent_tx {
Expand Down
1 change: 1 addition & 0 deletions core/node/eth_sender/src/eth_tx_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl EthTxManager {
gas_adjuster,
max_acceptable_priority_fee_in_gwei: config.max_acceptable_priority_fee_in_gwei,
time_in_mempool_in_l1_blocks_cap: config.time_in_mempool_in_l1_blocks_cap,
max_acceptable_base_fee_in_wei: config.max_acceptable_base_fee_in_wei,
};
let l1_interface = Box::new(RealL1Interface {
ethereum_gateway,
Expand Down
3 changes: 3 additions & 0 deletions etc/env/base/eth_sender.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ pubdata_sending_mode = "Blobs"

signing_mode = "PrivateKey"

# Max acceptable base fee for sending tx to L1
max_acceptable_base_fee_in_wei = 1000000000000

[eth_sender.gas_adjuster]
# Priority fee to be used by GasAdjuster (in wei).
default_priority_fee_per_gas = 1_000_000_000
Expand Down
1 change: 1 addition & 0 deletions etc/env/file_based/general.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ eth:
max_aggregated_tx_gas: 15000000
max_acceptable_priority_fee_in_gwei: 100000000000
pubdata_sending_mode: BLOBS
max_acceptable_base_fee_in_wei: 100000000000
gas_adjuster:
default_priority_fee_per_gas: 1000000000
max_base_fee_samples: 100
Expand Down
Loading