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

feat(api): add pessimistic overhead for L1->L2 transactions #858

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
16 changes: 16 additions & 0 deletions core/bin/external_node/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ pub struct OptionalENConfig {
/// The max possible number of gas that `eth_estimateGas` is allowed to overestimate.
#[serde(default = "OptionalENConfig::default_estimate_gas_acceptable_overestimation")]
pub estimate_gas_acceptable_overestimation: u32,
/// Whether to use the compatibility mode for gas estimation for L1->L2 transactions.
/// During the migration to the 1.4.1 fee model, there will be a period, when the server
/// will already have the 1.4.1 fee model, while the L1 contracts will still expect the transactions
/// to use the previous fee model with much higher overhead.
///
/// When set to `true`, the API will ensure to return gasLimit is high enough overhead for both the old
/// and the new fee model when estimating L1->L2 transactions.
#[serde(default = "OptionalENConfig::default_l1_to_l2_transactions_compatibility_mode")]
pub l1_to_l2_transactions_compatibility_mode: bool,
/// The multiplier to use when suggesting gas price. Should be higher than one,
/// otherwise if the L1 prices soar, the suggested gas price won't be sufficient to be included in block
#[serde(default = "OptionalENConfig::default_gas_price_scale_factor")]
Expand Down Expand Up @@ -214,6 +223,10 @@ impl OptionalENConfig {
1_000
}

const fn default_l1_to_l2_transactions_compatibility_mode() -> bool {
true
}

const fn default_gas_price_scale_factor() -> f64 {
1.2
}
Expand Down Expand Up @@ -521,6 +534,9 @@ impl From<ExternalNodeConfig> for TxSenderConfig {
max_allowed_l2_tx_gas_limit: u32::MAX,
validation_computational_gas_limit: u32::MAX,
chain_id: config.remote.l2_chain_id,
l1_to_l2_transactions_compatibility_mode: config
.optional
.l1_to_l2_transactions_compatibility_mode,
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions core/lib/config/src/configs/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ pub struct Web3JsonRpcConfig {
pub estimate_gas_scale_factor: f64,
/// The max possible number of gas that `eth_estimateGas` is allowed to overestimate.
pub estimate_gas_acceptable_overestimation: u32,
/// Whether to use the compatibility mode for gas estimation for L1->L2 transactions.
/// During the migration to the 1.4.1 fee model, there will be a period, when the server
/// will already have the 1.4.1 fee model, while the L1 contracts will still expect the transactions
/// to use the previous fee model with much higher overhead.
///
/// When set to `true`, the API will ensure to return gasLimit is high enough overhead for both the old
/// and the new fee model when estimating L1->L2 transactions.
pub l1_to_l2_transactions_compatibility_mode: bool,
/// Max possible size of an ABI encoded tx (in bytes).
pub max_tx_size: usize,
/// Max number of cache misses during one VM execution. If the number of cache misses exceeds this value, the API server panics.
Expand Down Expand Up @@ -101,6 +109,7 @@ impl Web3JsonRpcConfig {
account_pks: Default::default(),
estimate_gas_scale_factor: 1.2,
estimate_gas_acceptable_overestimation: 1000,
l1_to_l2_transactions_compatibility_mode: true,
max_tx_size: 1000000,
vm_execution_cache_misses_limit: Default::default(),
vm_concurrency_limit: Default::default(),
Expand Down
2 changes: 2 additions & 0 deletions core/lib/env_config/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ mod tests {
estimate_gas_scale_factor: 1.0f64,
gas_price_scale_factor: 1.2,
estimate_gas_acceptable_overestimation: 1000,
l1_to_l2_transactions_compatibility_mode: true,
max_tx_size: 1000000,
vm_execution_cache_misses_limit: None,
vm_concurrency_limit: Some(512),
Expand Down Expand Up @@ -119,6 +120,7 @@ mod tests {
API_WEB3_JSON_RPC_ACCOUNT_PKS="0x0000000000000000000000000000000000000000000000000000000000000001,0x0000000000000000000000000000000000000000000000000000000000000002"
API_WEB3_JSON_RPC_ESTIMATE_GAS_SCALE_FACTOR=1.0
API_WEB3_JSON_RPC_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION=1000
API_WEB3_JSON_RPC_L1_TO_L2_TRANSACTIONS_COMPATIBILITY_MODE=true
API_WEB3_JSON_RPC_MAX_TX_SIZE=1000000
API_WEB3_JSON_RPC_VM_CONCURRENCY_LIMIT=512
API_WEB3_JSON_RPC_FACTORY_DEPS_CACHE_SIZE_MB=128
Expand Down
71 changes: 64 additions & 7 deletions core/lib/zksync_core/src/api_server/tx_sender/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use zksync_types::{
fee::{Fee, TransactionExecutionMetrics},
fee_model::BatchFeeInput,
get_code_key, get_intrinsic_constants,
l1::is_l1_tx_type,
l2::{error::TxCheckError::TxDuplication, L2Tx},
utils::storage_key_for_eth_balance,
AccountTreeId, Address, ExecuteTransactionCommon, L2ChainId, Nonce, PackedEthSignature,
Expand Down Expand Up @@ -211,6 +212,7 @@ pub struct TxSenderConfig {
pub max_allowed_l2_tx_gas_limit: u32,
pub vm_execution_cache_misses_limit: Option<usize>,
pub validation_computational_gas_limit: u32,
pub l1_to_l2_transactions_compatibility_mode: bool,
pub chain_id: L2ChainId,
}

Expand All @@ -228,6 +230,8 @@ impl TxSenderConfig {
vm_execution_cache_misses_limit: web3_json_config.vm_execution_cache_misses_limit,
validation_computational_gas_limit: state_keeper_config
.validation_computational_gas_limit,
l1_to_l2_transactions_compatibility_mode: web3_json_config
.l1_to_l2_transactions_compatibility_mode,
chain_id,
}
}
Expand Down Expand Up @@ -815,13 +819,29 @@ impl TxSender {
result.into_api_call_result()?;
self.ensure_tx_executable(tx.clone(), &tx_metrics, false)?;

let overhead = derive_overhead(
suggested_gas_limit,
gas_per_pubdata_byte as u32,
tx.encoding_len(),
tx.tx_format() as u8,
protocol_version.into(),
);
// Now, we need to calculate the final overhead for the transaction. We need to take into accoutn the fact
// that the migration of 1.4.1 may be still going on.
let overhead = if self
.0
.sender_config
.l1_to_l2_transactions_compatibility_mode
{
derive_pessimistic_overhead(
suggested_gas_limit,
gas_per_pubdata_byte as u32,
tx.encoding_len(),
tx.tx_format() as u8,
protocol_version.into(),
)
} else {
derive_overhead(
suggested_gas_limit,
gas_per_pubdata_byte as u32,
tx.encoding_len(),
tx.tx_format() as u8,
protocol_version.into(),
)
};

let full_gas_limit =
match tx_body_gas_limit.overflowing_add(gas_for_bytecodes_pubdata + overhead) {
Expand Down Expand Up @@ -925,3 +945,40 @@ impl TxSender {
Ok(())
}
}

/// During switch to the 1.4.1 protocol version, there will be a moment of discrepancy, when while
/// the L2 has already upgraded to 1.4.1 (and thus suggests smaller overhead), the L1 is still on the previous version.
///
/// This might lead to situations when L1->L2 transactions estimated with the new versions would work on the state keeper side,
/// but they won't even make it there, but the protection mechanisms for L1->L2 transactions will reject them on L1.
/// TODO(X): remove this function after the upgrade is complete
fn derive_pessimistic_overhead(
gas_limit: u32,
gas_price_per_pubdata: u32,
encoded_len: usize,
tx_type: u8,
vm_version: VmVersion,
) -> u32 {
let current_overhead = derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
tx_type,
vm_version,
);

if is_l1_tx_type(tx_type) {
// We are in the L1->L2 transaction, so we need to account for the fact that the L1 is still on the previous version.
// We assume that the overhead will be the same as for the previous version.
let previous_overhead = derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
tx_type,
VmVersion::VmBoojumIntegration,
);
current_overhead.max(previous_overhead)
} else {
current_overhead
}
}
1 change: 1 addition & 0 deletions etc/env/base/api.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pubsub_polling_interval=200
threads_per_server=128
max_nonce_ahead=50
gas_price_scale_factor=1.2
l1_to_l2_transactions_compatibility_mode=true
request_timeout=10
account_pks=[
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
Expand Down
Loading