Skip to content

Commit

Permalink
fix: update run with dynamic fee params (#377)
Browse files Browse the repository at this point in the history
* chore: updated scaled factors

* fix: update scale factors

* feat: fetch fee params from mainnet to init era-test-node

* chore: cleanup

* fix: fixes gas params for run and updates scale factors

* chore: remove logs from override

* chore: update zks_estimateFee test
  • Loading branch information
dutterbutter authored Nov 11, 2024
1 parent c96509f commit 2cece10
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 44 deletions.
25 changes: 14 additions & 11 deletions e2e-tests/test/zks-apis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface Fee {
}

describe("zks_estimateFee", function () {
it("Should return fee estimation data for transfer of 1 ETH", async function () {
it("Should return valid fee estimation data for transfer of 1 ETH", async function () {
// Arrange
const wallet = new Wallet(RichAccounts[0].PrivateKey, provider);
const userWallet = Wallet.createRandom().connect(provider);
Expand All @@ -29,17 +29,20 @@ describe("zks_estimateFee", function () {

// Act
const response: Fee = await provider.send("zks_estimateFee", [transaction]);

// Assert
expect(ethers.BigNumber.from(response.gas_limit).toNumber()).to.eql(4048728, "Unexpected gas_limit");
expect(ethers.BigNumber.from(response.gas_per_pubdata_limit)).to.eql(
ethers.BigNumber.from("50000"),
"Unexpected gas_per_pubdata_limit"
);
expect(ethers.BigNumber.from(response.max_fee_per_gas).toNumber()).to.eql(37500000, "Unexpected max_fee_per_gas");
expect(ethers.BigNumber.from(response.max_priority_fee_per_gas)).to.eql(
ethers.BigNumber.from("0"),
"Unexpected max_priority_fee_per_gas"
);
expect(response).to.have.property("gas_limit");
expect(response).to.have.property("gas_per_pubdata_limit");
expect(response).to.have.property("max_fee_per_gas");
expect(response).to.have.property("max_priority_fee_per_gas");

const gasLimit = ethers.BigNumber.from(response.gas_limit);
const gasPerPubdataLimit = ethers.BigNumber.from(response.gas_per_pubdata_limit);
const maxFeePerGas = ethers.BigNumber.from(response.max_fee_per_gas);

expect(gasLimit.toNumber()).to.be.greaterThan(0, "gas_limit should be greater than 0");
expect(gasPerPubdataLimit.toNumber()).to.be.greaterThan(0, "gas_per_pubdata_limit should be greater than 0");
expect(maxFeePerGas.toNumber()).to.be.greaterThan(0, "max_fee_per_gas should be greater than 0");
});
});

Expand Down
7 changes: 6 additions & 1 deletion src/config/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ pub struct Cli {
/// Use a given chain id. If not set uses 260 (or the one from the forked network).
#[arg(long)]
pub chain_id: Option<u32>,

/// Run the node in offline mode. This will disable all network requests.
/// Can only be run alongside `run` command.
#[arg(long)]
pub offline: bool,
}

#[derive(Debug, Subcommand)]
Expand All @@ -125,7 +130,7 @@ pub struct ForkArgs {
/// If not set - will start a new network from genesis.
/// If set - will try to fork a remote network. Possible values:
/// - mainnet
/// - testnet
/// - sepolia-testnet
/// - http://XXX:YY
pub network: String,
// Fork at a given L2 miniblock height.
Expand Down
14 changes: 7 additions & 7 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,15 +301,13 @@ pub mod node {
pub mod gas {
use serde::Deserialize;

/// L1 Gas Price.
pub const DEFAULT_L1_GAS_PRICE: u64 = 50_000_000_000;
// TODO: for now, that's fine, as computation overhead is set to zero, but we may consider using calculated fee input everywhere.
pub const DEFAULT_L1_GAS_PRICE: u64 = 14_932_364_075;
/// The default L2 Gas Price to be used if not supplied via the CLI argument.
pub const DEFAULT_L2_GAS_PRICE: u64 = 25_000_000;
// Default fair pubdata price based on an average from Sepolia Testnet blocks
pub const DEFAULT_FAIR_PUBDATA_PRICE: u64 = 450_000_000_000;
pub const DEFAULT_L2_GAS_PRICE: u64 = 45_250_000;
/// Default fair pubdata price based on the provided value.
pub const DEFAULT_FAIR_PUBDATA_PRICE: u64 = 13_607_659_111;
/// L1 Gas Price Scale Factor for gas estimation.
pub const DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR: f64 = 1.5;
pub const DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR: f64 = 2.0;
/// The factor by which to scale the gasLimit.
pub const DEFAULT_ESTIMATE_GAS_SCALE_FACTOR: f32 = 1.3;

Expand All @@ -319,6 +317,8 @@ pub mod gas {
pub l1_gas_price: Option<u64>,
/// L2 gas price.
pub l2_gas_price: Option<u64>,
/// Fair pubdata price.
pub l1_pubdata_price: Option<u64>,
/// Factors used in estimating gas.
pub estimation: Option<Estimation>,
}
Expand Down
6 changes: 3 additions & 3 deletions src/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ impl ForkNetwork {
ForkNetwork::Other(url) => url,
}
}

// TODO: This needs to be dynamic based on the network.
/// Returns the local gas scale factors currently in use by the upstream network.
pub fn local_gas_scale_factors(&self) -> (f64, f32) {
match self {
ForkNetwork::Mainnet => (1.5, 1.2),
ForkNetwork::SepoliaTestnet => (2.0, 1.2),
ForkNetwork::Mainnet => (1.5, 1.4),
ForkNetwork::SepoliaTestnet => (2.0, 1.3),
ForkNetwork::GoerliTestnet => (1.2, 1.2),
ForkNetwork::Other(_) => (
DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
Expand Down
45 changes: 43 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use bytecode_override::override_bytecodes;
use clap::Parser;
use colored::Colorize;
use config::cli::{Cli, Command};
use config::gas::{
Estimation, GasConfig, DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
};
use config::TestNodeConfig;
use fork::{ForkDetails, ForkSource};
use http_fork_source::HttpForkSource;
Expand Down Expand Up @@ -31,13 +35,14 @@ mod testing;
mod utils;

use node::InMemoryNode;

use std::fs::File;
use std::{
env,
net::{IpAddr, Ipv4Addr, SocketAddr},
str::FromStr,
};
use zksync_types::fee_model::FeeParams;
use zksync_web3_decl::namespaces::ZksNamespaceClient;

use futures::{
channel::oneshot,
Expand Down Expand Up @@ -118,7 +123,43 @@ async fn main() -> anyhow::Result<()> {
// Use `Command::Run` as default.
let command = opt.command.as_ref().unwrap_or(&Command::Run);
let fork_details = match command {
Command::Run => None,
Command::Run => {
if opt.offline {
tracing::warn!(
"Running in offline mode: default fee parameters will be used. \
To override, specify values in `config.toml` and use the `--config` flag."
);
None
} else {
// Initialize the client to get the fee params
let (_, client) = ForkDetails::fork_network_and_client("mainnet")
.map_err(|e| anyhow!("Failed to initialize client: {:?}", e))?;

let fee = client.get_fee_params().await.map_err(|e| {
tracing::error!("Failed to fetch fee params: {:?}", e);
anyhow!(e)
})?;

let gas_config = match fee {
FeeParams::V2(fee_v2) => GasConfig {
l1_gas_price: Some(fee_v2.l1_gas_price()),
l2_gas_price: Some(fee_v2.config().minimal_l2_gas_price),
l1_pubdata_price: Some(fee_v2.l1_pubdata_price()),
estimation: Some(Estimation {
price_scale_factor: Some(DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR),
limit_scale_factor: Some(DEFAULT_ESTIMATE_GAS_SCALE_FACTOR),
}),
},
FeeParams::V1(_) => {
return Err(anyhow!("Unsupported FeeParams::V1 in this context"))
}
};

config.gas = Some(gas_config);

None
}
}
Command::Fork(fork) => {
match ForkDetails::from_network(&fork.network, fork.fork_block_number, config.cache)
.await
Expand Down
2 changes: 1 addition & 1 deletion src/node/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2400,7 +2400,7 @@ mod tests {
.await
.expect("failed getting filter changes")
{
FilterChanges::Logs(result) => assert_eq!(3, result.len()),
FilterChanges::Logs(result) => assert_eq!(4, result.len()),
changes => panic!("unexpected filter changes: {:?}", changes),
}

Expand Down
24 changes: 8 additions & 16 deletions src/node/fee_model.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use zksync_types::fee_model::{BatchFeeInput, FeeModelConfigV2, FeeParams, FeeParamsV2};
use zksync_types::L1_GAS_PER_PUBDATA_BYTE;

use crate::config::gas::{
GasConfig, DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR, DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
DEFAULT_L1_GAS_PRICE, DEFAULT_L2_GAS_PRICE,
DEFAULT_FAIR_PUBDATA_PRICE, DEFAULT_L1_GAS_PRICE, DEFAULT_L2_GAS_PRICE,
};
use crate::utils::to_human_size;

#[derive(Debug, Clone, PartialEq)]
pub struct TestNodeFeeInputProvider {
pub l1_gas_price: u64,
Expand Down Expand Up @@ -63,19 +60,14 @@ impl TestNodeFeeInputProvider {
};

if let Some(l1_gas_price) = gas_config.l1_gas_price {
tracing::info!(
"L1 gas price set to {} (overridden from {})",
to_human_size(l1_gas_price.into()),
to_human_size(self.l1_gas_price.into())
);
self.l1_gas_price = l1_gas_price;
}

if let Some(l1_pubdata_price) = gas_config.l1_pubdata_price {
self.l1_pubdata_price = l1_pubdata_price;
}

if let Some(l2_gas_price) = gas_config.l2_gas_price {
tracing::info!(
"L2 gas price set to {} (overridden from {})",
to_human_size(l2_gas_price.into()),
to_human_size(self.l2_gas_price.into())
);
self.l2_gas_price = l2_gas_price;
}

Expand Down Expand Up @@ -126,13 +118,13 @@ impl Default for TestNodeFeeInputProvider {
fn default() -> Self {
Self {
l1_gas_price: DEFAULT_L1_GAS_PRICE,
l1_pubdata_price: DEFAULT_L1_GAS_PRICE * L1_GAS_PER_PUBDATA_BYTE as u64,
l1_pubdata_price: DEFAULT_FAIR_PUBDATA_PRICE,
l2_gas_price: DEFAULT_L2_GAS_PRICE,
compute_overhead_part: 0.0,
pubdata_overhead_part: 1.0,
batch_overhead_l1_gas: 800000,
max_gas_per_batch: 200000000,
max_pubdata_per_batch: 100000,
max_pubdata_per_batch: 500000,
estimate_gas_price_scale_factor: DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
estimate_gas_scale_factor: DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
}
Expand Down
1 change: 1 addition & 0 deletions src/node/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
Ok(GasConfig {
l1_gas_price: Some(fee_input_provider.l1_gas_price),
l2_gas_price: Some(fee_input_provider.l2_gas_price),
l1_pubdata_price: Some(fee_input_provider.l1_pubdata_price),
estimation: Some(gas::Estimation {
price_scale_factor: Some(fee_input_provider.estimate_gas_price_scale_factor),
limit_scale_factor: Some(fee_input_provider.estimate_gas_scale_factor),
Expand Down
6 changes: 3 additions & 3 deletions src/node/zks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,10 +625,10 @@ mod tests {

let result = node.estimate_fee(mock_request).await.unwrap();

assert_eq!(result.gas_limit, U256::from(4490368));
assert_eq!(result.max_fee_per_gas, U256::from(37500000));
assert_eq!(result.gas_limit, U256::from(279779));
assert_eq!(result.max_fee_per_gas, U256::from(45250000));
assert_eq!(result.max_priority_fee_per_gas, U256::from(0));
assert_eq!(result.gas_per_pubdata_limit, U256::from(50000));
assert_eq!(result.gas_per_pubdata_limit, U256::from(1658));
}

#[tokio::test]
Expand Down

0 comments on commit 2cece10

Please sign in to comment.