Skip to content

Commit

Permalink
Test eth_feeHistory
Browse files Browse the repository at this point in the history
  • Loading branch information
slowli committed Oct 11, 2024
1 parent 7b1c749 commit 9b6cb6d
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 25 deletions.
123 changes: 122 additions & 1 deletion core/node/api_server/src/web3/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use zksync_multivm::interface::{
TransactionExecutionMetrics, TransactionExecutionResult, TxExecutionStatus, VmEvent,
VmExecutionMetrics,
};
use zksync_node_fee_model::BatchFeeModelInputProvider;
use zksync_node_genesis::{insert_genesis_batch, mock_genesis_config, GenesisParams};
use zksync_node_test_utils::{
create_l1_batch, create_l1_batch_metadata, create_l2_block, create_l2_transaction,
Expand All @@ -32,6 +33,7 @@ use zksync_system_constants::{
use zksync_types::{
api,
block::{pack_block_info, L2BlockHeader},
fee_model::{BatchFeeInput, FeeParams},
get_nonce_key,
l2::L2Tx,
storage::get_code_key,
Expand All @@ -50,7 +52,7 @@ use zksync_web3_decl::{
http_client::HttpClient,
rpc_params,
types::{
error::{ErrorCode, OVERSIZED_RESPONSE_CODE},
error::{ErrorCode, INVALID_PARAMS_CODE, OVERSIZED_RESPONSE_CODE},
ErrorObjectOwned,
},
},
Expand Down Expand Up @@ -428,6 +430,14 @@ async fn store_events(
Ok((tx_location, events))
}

fn scaled_sensible_fee_input(scale: f64) -> BatchFeeInput {
<dyn BatchFeeModelInputProvider>::default_batch_fee_input_scaled(
FeeParams::sensible_v1_default(),
scale,
scale,
)
}

#[derive(Debug)]
struct HttpServerBasicsTest;

Expand Down Expand Up @@ -1102,3 +1112,114 @@ impl HttpTest for GenesisConfigTest {
async fn tracing_genesis_config() {
test_http_server(GenesisConfigTest).await;
}

#[derive(Debug)]
struct FeeHistoryTest;

#[async_trait]
impl HttpTest for FeeHistoryTest {
async fn test(
&self,
client: &DynClient<L2>,
pool: &ConnectionPool<Core>,
) -> anyhow::Result<()> {
let mut connection = pool.connection().await?;
let block1 = L2BlockHeader {
batch_fee_input: scaled_sensible_fee_input(1.0),
base_fee_per_gas: 100,
..create_l2_block(1)
};
store_custom_l2_block(&mut connection, &block1, &[]).await?;
let block2 = L2BlockHeader {
batch_fee_input: scaled_sensible_fee_input(2.0),
base_fee_per_gas: 200,
..create_l2_block(2)
};
store_custom_l2_block(&mut connection, &block2, &[]).await?;

let all_pubdata_prices = [
0,
block1.batch_fee_input.fair_pubdata_price(),
block2.batch_fee_input.fair_pubdata_price(),
]
.map(U256::from);

let history = client
.fee_history(1_000.into(), api::BlockNumber::Latest, vec![])
.await?;
assert_eq!(history.inner.oldest_block, 0.into());
assert_eq!(
history.inner.base_fee_per_gas,
[0, 100, 200, 200].map(U256::from) // The latest value is duplicated
);
assert_eq!(history.l2_pubdata_price, all_pubdata_prices);
// Values below are not filled.
assert_eq!(history.inner.gas_used_ratio, [0.0; 3]);
assert_eq!(history.inner.base_fee_per_blob_gas, [U256::zero(); 4]);
assert_eq!(history.inner.blob_gas_used_ratio, [0.0; 3]);

// Check supplying hexadecimal block count
let hex_history: api::FeeHistory = client
.request(
"eth_feeHistory",
rpc_params!["0xaa", "latest", [] as [f64; 0]],
)
.await?;
assert_eq!(hex_history, history);

// ...and explicitly decimal count (which should've been supplied in the first call) for exhaustiveness
let dec_history: api::FeeHistory = client
.request(
"eth_feeHistory",
rpc_params![1_000, "latest", [] as [f64; 0]],
)
.await?;
assert_eq!(dec_history, history);

// Check partial histories: blocks 0..=1
let history = client
.fee_history(1_000.into(), api::BlockNumber::Number(1.into()), vec![])
.await?;
assert_eq!(history.inner.oldest_block, 0.into());
assert_eq!(
history.inner.base_fee_per_gas,
[0, 100, 100].map(U256::from)
);
assert_eq!(history.l2_pubdata_price, all_pubdata_prices[..2]);

// Blocks 1..=2
let history = client
.fee_history(2.into(), api::BlockNumber::Latest, vec![])
.await?;
assert_eq!(history.inner.oldest_block, 1.into());
assert_eq!(
history.inner.base_fee_per_gas,
[100, 200, 200].map(U256::from)
);
assert_eq!(history.l2_pubdata_price, all_pubdata_prices[1..]);

// Blocks 1..=1
let history = client
.fee_history(1.into(), api::BlockNumber::Number(1.into()), vec![])
.await?;
assert_eq!(history.inner.oldest_block, 1.into());
assert_eq!(history.inner.base_fee_per_gas, [100, 100].map(U256::from));
assert_eq!(history.l2_pubdata_price, all_pubdata_prices[1..2]);

// Non-existing newest block.
let err = client
.fee_history(1000.into(), api::BlockNumber::Number(100.into()), vec![])
.await
.unwrap_err();
assert_matches!(
err,
ClientError::Call(err) if err.code() == INVALID_PARAMS_CODE
);
Ok(())
}
}

#[tokio::test]
async fn getting_fee_history() {
test_http_server(FeeHistoryTest).await;
}
30 changes: 6 additions & 24 deletions core/node/api_server/src/web3/tests/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,10 @@ use api::state_override::{OverrideAccount, StateOverride};
use zksync_multivm::interface::{
ExecutionResult, VmExecutionLogs, VmExecutionResultAndLogs, VmRevertReason,
};
use zksync_node_fee_model::BatchFeeModelInputProvider;
use zksync_types::{
api::ApiStorageLog,
fee_model::{BatchFeeInput, FeeParams},
get_intrinsic_constants,
transaction_request::CallRequest,
K256PrivateKey, L2ChainId, PackedEthSignature, StorageLogKind, StorageLogWithPreviousValue,
U256,
api::ApiStorageLog, fee_model::BatchFeeInput, get_intrinsic_constants,
transaction_request::CallRequest, K256PrivateKey, L2ChainId, PackedEthSignature,
StorageLogKind, StorageLogWithPreviousValue, U256,
};
use zksync_utils::u256_to_h256;
use zksync_vm_executor::oneshot::MockOneshotExecutor;
Expand All @@ -42,11 +38,7 @@ impl ExpectedFeeInput {
fn expect_for_block(&self, number: api::BlockNumber, scale: f64) {
*self.0.lock().unwrap() = match number {
api::BlockNumber::Number(number) => create_l2_block(number.as_u32()).batch_fee_input,
_ => <dyn BatchFeeModelInputProvider>::default_batch_fee_input_scaled(
FeeParams::sensible_v1_default(),
scale,
scale,
),
_ => scaled_sensible_fee_input(scale),
};
}

Expand Down Expand Up @@ -165,12 +157,7 @@ impl HttpTest for CallTest {
// Check that the method handler fetches fee inputs for recent blocks. To do that, we create a new block
// with a large fee input; it should be loaded by `ApiFeeInputProvider` and override the input provided by the wrapped mock provider.
let mut block_header = create_l2_block(2);
block_header.batch_fee_input =
<dyn BatchFeeModelInputProvider>::default_batch_fee_input_scaled(
FeeParams::sensible_v1_default(),
2.5,
2.5,
);
block_header.batch_fee_input = scaled_sensible_fee_input(2.5);
store_custom_l2_block(&mut connection, &block_header, &[]).await?;
// Fee input is not scaled further as per `ApiFeeInputProvider` implementation
self.fee_input.expect_custom(block_header.batch_fee_input);
Expand Down Expand Up @@ -607,12 +594,7 @@ impl HttpTest for TraceCallTest {
// Check that the method handler fetches fee inputs for recent blocks. To do that, we create a new block
// with a large fee input; it should be loaded by `ApiFeeInputProvider` and override the input provided by the wrapped mock provider.
let mut block_header = create_l2_block(2);
block_header.batch_fee_input =
<dyn BatchFeeModelInputProvider>::default_batch_fee_input_scaled(
FeeParams::sensible_v1_default(),
3.0,
3.0,
);
block_header.batch_fee_input = scaled_sensible_fee_input(3.0);
store_custom_l2_block(&mut connection, &block_header, &[]).await?;
// Fee input is not scaled further as per `ApiFeeInputProvider` implementation
self.fee_input.expect_custom(block_header.batch_fee_input);
Expand Down

0 comments on commit 9b6cb6d

Please sign in to comment.