Skip to content

Commit

Permalink
Merge branch 'develop' into patch-3
Browse files Browse the repository at this point in the history
  • Loading branch information
Olexandr88 authored Oct 1, 2024
2 parents 6ab0f04 + fab9d65 commit 590cc2d
Show file tree
Hide file tree
Showing 14 changed files with 387 additions and 233 deletions.
2 changes: 1 addition & 1 deletion aggregator/data/test_batches/batch274.hex

Large diffs are not rendered by default.

45 changes: 24 additions & 21 deletions aggregator/src/tests/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,18 @@ fn check_circuit(circuit: &BlobCircuit) -> Result<(), Vec<VerifyFailure>> {

#[test]
fn blob_circuit_completeness() {
// TODO: enable this once we have another deterministic case of batch -> blob (fully packed).
// now batch274 is an deterministic case of batch -> blob (fully packed).
// Full blob test case
// batch274 contains batch bytes that will produce a full blob
// let full_blob = hex::decode(
// fs::read_to_string("./data/test_batches/batch274.hex")
// .expect("file path exists")
// .trim(),
// )
// .expect("should load full blob batch bytes");
// batch274 contains metadata
// let segmented_full_blob_src = BatchData::<MAX_AGG_SNARKS>::segment_with_metadata(full_blob);
let full_blob = hex::decode(
fs::read_to_string("./data/test_batches/batch274.hex")
.expect("file path exists")
.trim(),
)
.expect("should load full blob batch bytes");

// batch274 contains metadatas
let segmented_full_blob_src = BatchData::<MAX_AGG_SNARKS>::segment_with_metadata(full_blob);

let all_empty_chunks: Vec<Vec<u8>> = vec![vec![]; MAX_AGG_SNARKS];
let one_chunk = vec![vec![2, 3, 4, 100, 1]];
Expand All @@ -305,8 +306,8 @@ fn blob_circuit_completeness() {
.chain(std::iter::once(vec![3, 100, 24, 30]))
.collect::<Vec<_>>();

for blob in [
// segmented_full_blob_src,
for (idx, blob) in [
segmented_full_blob_src,
one_chunk,
two_chunks,
max_chunks,
Expand All @@ -317,19 +318,21 @@ fn blob_circuit_completeness() {
all_empty_except_last,
]
.into_iter()
.enumerate()
{
let batch_data = BatchData::from(&blob);

// TODO: enable this once we have another deterministic case of batch -> blob (fully
// packed).
// First blob is purposely constructed to take full blob space
// if idx == 0 {
// let blob_data_bytes_len = batch_data.get_blob_data_bytes().len();
// assert_eq!(
// blob_data_bytes_len, N_BLOB_BYTES,
// "should be full blob: expected={N_BLOB_BYTES}, got={blob_data_bytes_len}",
// );
// }
// First blob(batch274's blob data) is purposely constructed to take full blob space
if idx == 0 {
let batch_data_bytes = batch_data.get_batch_data_bytes();
let blob_data_bytes = get_blob_bytes(&batch_data_bytes);
let blob_data_bytes_len = blob_data_bytes.len();

assert_eq!(
blob_data_bytes_len, N_BLOB_BYTES,
"should be full blob: expected={N_BLOB_BYTES}, got={blob_data_bytes_len}",
);
}

assert_eq!(check_data(batch_data), Ok(()), "{:?}", blob);
}
Expand Down
6 changes: 6 additions & 0 deletions bus-mapping/src/circuit_input_builder/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,12 @@ impl Transaction {
);

let tx_type = TxType::get_tx_type(eth_tx);
log::debug!(
"{:?}th tx, tx hash {:?}, tx_type {:?}",
eth_tx.transaction_index,
eth_tx.hash(),
tx_type
);
let (l1_fee, l1_fee_committed) = if tx_type.is_l1_msg() {
Default::default()
} else {
Expand Down
14 changes: 13 additions & 1 deletion geth-utils/l2geth/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,20 @@ func transferTxs(txs []Transaction, chainID *big.Int) types.Transactions {
}
t_txs = append(t_txs, types.NewTx(l1msgTx))
} else {

switch tx.Type {
case "PreEip155":
t := &types.LegacyTx{
Nonce: uint64(tx.Nonce),
GasPrice: toBigInt(tx.GasPrice),
Gas: uint64(tx.GasLimit),
To: tx.To,
Value: toBigInt(tx.Value),
Data: tx.CallData,
V: big.NewInt(tx.V),
R: tx.R.ToInt(),
S: tx.S.ToInt(),
}
t_txs = append(t_txs, types.NewTx(t))
case "Eip155":
t := &types.LegacyTx{
Nonce: uint64(tx.Nonce),
Expand Down
8 changes: 8 additions & 0 deletions mock/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ impl MockTransaction {
.value(self.value)
.data(self.input.clone())
.gas(self.gas)
// Note: even pre-eip155 type transaction doesn't have chain_id field, here having chain_id won't
// result in negative effects, because eventually geth_type::Transaction decide the tx type by TxType::get_tx_type(tx)
// then trace.go will treat it as correct pre-eip155 type transaction. the additional chain_id
// is not used finally.
.chain_id(self.chain_id);

let tx = if let Some(gas_price) = self.gas_price {
Expand All @@ -359,6 +363,9 @@ impl MockTransaction {
};

match (self.v, self.r, self.s) {
(Some(_), Some(_), Some(_)) => {
// already have entire signature data, won't do anything.
}
(None, None, None) => {
// Compute sig params and set them in case we have a wallet as `from` attr.
if self.from.is_wallet() && self.hash.is_none() {
Expand All @@ -372,6 +379,7 @@ impl MockTransaction {
self.sig_data((sig.v, sig.r, sig.s));
}
}

_ => panic!("Either all or none of the SigData params have to be set"),
}

Expand Down
3 changes: 3 additions & 0 deletions zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ use strum::{EnumCount, IntoEnumIterator};
pub(crate) static CHECK_RW_LOOKUP: LazyLock<bool> =
LazyLock::new(|| read_env_var("CHECK_RW_LOOKUP", false));

#[cfg(any(feature = "test", test))]
mod tests;

mod add_sub;
mod addmod;
mod address;
Expand Down
37 changes: 37 additions & 0 deletions zkevm-circuits/src/evm_circuit/execution/tests/eip155.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// tests for eip155 tx
#[cfg(test)]
mod tx_type_test {
use crate::test_util::CircuitTestBuilder;
use eth_types::{Error, Word};
use ethers_signers::Signer;
use mock::{eth, gwei, TestContext, MOCK_ACCOUNTS, MOCK_WALLETS};

#[test]
fn test_eip155() {
let ctx = build_ctx(gwei(80_000)).unwrap();
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

fn build_ctx(sender_balance: Word) -> Result<TestContext<2, 1>, Error> {
TestContext::new(
None,
|accs| {
accs[0]
.address(MOCK_WALLETS[0].address())
.balance(sender_balance);
accs[1].address(MOCK_ACCOUNTS[0]).balance(eth(1));
},
|mut txs, _accs| {
txs[0]
.from(MOCK_WALLETS[0].clone())
.to(MOCK_ACCOUNTS[0])
.gas(40_000.into())
.gas_price(30_000.into())
.value(gwei(20_000))
// Set tx type to EIP-155.
.transaction_type(0);
},
|block, _tx| block.number(0xcafeu64),
)
}
}
107 changes: 107 additions & 0 deletions zkevm-circuits/src/evm_circuit/execution/tests/eip1559.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#[cfg(test)]
mod tx_type_test {
use crate::test_util::CircuitTestBuilder;
use eth_types::{Error, Word};
use ethers_signers::Signer;
use mock::{eth, gwei, TestContext, MOCK_ACCOUNTS, MOCK_WALLETS};

#[test]
fn test_eip1559_tx_for_equal_balance() {
let balance = if cfg!(feature = "scroll") {
// l1 fee
gwei(80_000) + Word::from(279u64)
} else {
gwei(80_000)
};
let ctx = build_ctx(balance, gwei(2), gwei(2)).unwrap();
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

#[test]
fn test_eip1559_tx_for_less_balance() {
let res = build_ctx(gwei(79_999), gwei(2), gwei(2));

#[cfg(not(feature = "scroll"))]
let expected_err = "Failed to run Trace, err: Failed to apply config.Transactions[0]: insufficient funds for gas * price + value: address 0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241 have 79999000000000 want 80000000000000";

// "80000000000279": 279 is l1 fee
#[cfg(feature = "scroll")]
let expected_err = "Failed to run Trace, err: insufficient funds for gas * price + value: address 0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241 have 79999000000000 want 80000000000279";

// Address `0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241` in error message comes from
// MOCK_WALLETS[0] in build_ctx.

// Return a tracing error if insufficient sender balance.
if let Error::TracingError(err) = res.unwrap_err() {
assert_eq!(err, expected_err);
} else {
panic!("Must be a tracing error");
}
}

#[test]
fn test_eip1559_tx_for_more_balance() {
let ctx = build_ctx(gwei(80_001), gwei(2), gwei(2)).unwrap();
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

#[test]
fn test_eip1559_tx_for_gas_fee_cap_gt_gas_tip_cap() {
// Should be successful if `max_fee_per_gas > max_priority_fee_per_gas`.
let balance = if cfg!(feature = "scroll") {
// l1 fee
gwei(80_000) + Word::from(279u64)
} else {
gwei(80_000)
};
let ctx = build_ctx(balance, gwei(2), gwei(1)).unwrap();

CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

#[test]
fn test_eip1559_tx_for_gas_fee_cap_lt_gas_tip_cap() {
let res = build_ctx(gwei(80_000), gwei(1), gwei(2));

#[cfg(not(feature = "scroll"))]
let expected_err = "Failed to run Trace, err: Failed to apply config.Transactions[0]: max priority fee per gas higher than max fee per gas: address 0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241, maxPriorityFeePerGas: 2000000000, maxFeePerGas: 1000000000";
#[cfg(feature = "scroll")]
let expected_err = "Failed to run Trace, err: max priority fee per gas higher than max fee per gas: address 0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241, maxPriorityFeePerGas: 2000000000, maxFeePerGas: 1000000000";
// Address `0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241` in error message comes from
// MOCK_WALLETS[0] in build_ctx.

// Return a tracing error if `max_fee_per_gas < max_priority_fee_per_gas`.
if let Error::TracingError(err) = res.unwrap_err() {
assert_eq!(err, expected_err);
} else {
panic!("Must be a tracing error");
}
}

fn build_ctx(
sender_balance: Word,
max_fee_per_gas: Word,
max_priority_fee_per_gas: Word,
) -> Result<TestContext<2, 1>, Error> {
TestContext::new(
None,
|accs| {
accs[0]
.address(MOCK_WALLETS[0].address())
.balance(sender_balance);
accs[1].address(MOCK_ACCOUNTS[0]).balance(eth(1));
},
|mut txs, _accs| {
txs[0]
.from(MOCK_WALLETS[0].clone())
.to(MOCK_ACCOUNTS[0])
.gas(30_000.into())
.value(gwei(20_000))
.max_fee_per_gas(max_fee_per_gas)
.max_priority_fee_per_gas(max_priority_fee_per_gas)
.transaction_type(2); // Set tx type to EIP-1559.
},
|block, _tx| block.number(0xcafeu64),
)
}
}
97 changes: 97 additions & 0 deletions zkevm-circuits/src/evm_circuit/execution/tests/eip2930.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// tests for eip2930
#[cfg(test)]
mod tx_type_test {
use crate::test_util::CircuitTestBuilder;
use eth_types::{address, AccessList, AccessListItem, Error, Word, H256};
use ethers_signers::Signer;
use mock::{eth, gwei, TestContext, MOCK_ACCOUNTS, MOCK_WALLETS};

// test with empty access list.
#[test]
fn test_eip2930_tx_for_empty_access_list() {
// CASE1: tx not set access list, `access_list` field is none.
let ctx = build_ctx(gwei(80_000), None).unwrap();
CircuitTestBuilder::new_from_test_ctx(ctx).run();

// CASE2: tx set empty (neither address nor storage keys at all) access list into
// `access_list` field. this field is not none.
let test_access_list: AccessList = AccessList(vec![]);

let ctx = build_ctx(gwei(80_000), Some(test_access_list)).unwrap();
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

// test with non empty access list(address + storage keys list)
#[test]
fn test_eip2930_non_empty_access_list() {
let test_access_list: AccessList = AccessList(vec![
AccessListItem {
address: address!("0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241"),
// one storage key
storage_keys: [10].map(H256::from_low_u64_be).to_vec(),
},
AccessListItem {
address: address!("0x0000000000000000000000000000000000001111"),
// two storage keys
storage_keys: [10, 11].map(H256::from_low_u64_be).to_vec(),
},
AccessListItem {
address: address!("0x0000000000000000000000000000000000002222"),
// three storage keys
storage_keys: [20, 22, 50].map(H256::from_low_u64_be).to_vec(),
},
]);

let ctx = build_ctx(gwei(80_000), Some(test_access_list)).unwrap();
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

// test with non empty access list(only address list)
#[test]
fn test_eip2930_only_address_access_list() {
let test_access_list: AccessList = AccessList(vec![
AccessListItem {
address: address!("0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241"),
// no storage keys
storage_keys: Vec::new(),
},
AccessListItem {
address: address!("0x0000000000000000000000000000000000001111"),
// no storage keys
storage_keys: Vec::new(),
},
]);

let ctx = build_ctx(gwei(80_000), Some(test_access_list)).unwrap();
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

fn build_ctx(
sender_balance: Word,
access_list: Option<AccessList>,
) -> Result<TestContext<2, 1>, Error> {
TestContext::new(
None,
|accs| {
accs[0]
.address(MOCK_WALLETS[0].address())
.balance(sender_balance);
accs[1].address(MOCK_ACCOUNTS[0]).balance(eth(1));
},
|mut txs, _accs| {
txs[0]
.from(MOCK_WALLETS[0].clone())
.to(MOCK_ACCOUNTS[0])
.gas(40_000.into())
.gas_price(30_000.into())
.value(gwei(20_000))
.transaction_type(1); // Set tx type to EIP-2930.

if let Some(acc_list) = access_list {
txs[0].access_list(acc_list);
}
},
|block, _tx| block.number(0xcafeu64),
)
}
}
7 changes: 7 additions & 0 deletions zkevm-circuits/src/evm_circuit/execution/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// this fold only contains tx type tests, for all opcode related tests are in
// each opcode gadget file.
mod eip155;
mod pre_eip155;

mod eip1559;
mod eip2930;
Loading

0 comments on commit 590cc2d

Please sign in to comment.