Skip to content

Commit fab9d65

Browse files
authored
Refactor: unify tx types(1559, 2930, pre155 etc) tests into dedicated folder (#1425)
* tests folder and move preeip155, 1559 tests into * move 2930 tests * add eip155 * rename * fix clippy * mod and clean * fix clippy * fmt fix
1 parent 2879c23 commit fab9d65

File tree

10 files changed

+337
-288
lines changed

10 files changed

+337
-288
lines changed

Diff for: zkevm-circuits/src/evm_circuit/execution.rs

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ use strum::{EnumCount, IntoEnumIterator};
5555
pub(crate) static CHECK_RW_LOOKUP: LazyLock<bool> =
5656
LazyLock::new(|| read_env_var("CHECK_RW_LOOKUP", false));
5757

58+
#[cfg(any(feature = "test", test))]
59+
mod tests;
60+
5861
mod add_sub;
5962
mod addmod;
6063
mod address;

Diff for: zkevm-circuits/src/evm_circuit/execution/begin_tx.rs

+2-78
Original file line numberDiff line numberDiff line change
@@ -1254,10 +1254,9 @@ mod test {
12541254
use std::{str::FromStr, vec};
12551255

12561256
use crate::{evm_circuit::test::rand_bytes, test_util::CircuitTestBuilder};
1257-
use bus_mapping::{circuit_input_builder::CircuitsParams, evm::OpcodeId};
1257+
use bus_mapping::evm::OpcodeId;
12581258
use eth_types::{
1259-
self, address, bytecode, evm_types::GasCost, word, Address, Bytecode, Error, Hash, Word,
1260-
U256,
1259+
self, address, bytecode, evm_types::GasCost, word, Address, Bytecode, Hash, Word, U256,
12611260
};
12621261
use ethers_core::{types::Bytes, utils::get_contract_address};
12631262
use mock::{eth, gwei, MockTransaction, TestContext, MOCK_ACCOUNTS};
@@ -1738,79 +1737,4 @@ mod test {
17381737
.block_modifier(Box::new(|block| block.circuits_params.max_txs = 3))
17391738
.run();
17401739
}
1741-
1742-
// Note: all pre-eip155 txs here for testing have signature data. don't need to generate signature dynamically
1743-
// because ethers-rs lib's helper `sign_transaction_sync` doesn't support pre-eip155 type.
1744-
#[test]
1745-
fn test_legacy_tx_pre_eip155() {
1746-
let mut tx1 = MockTransaction::default();
1747-
// pre-eip155 tx1 downloaded from [etherscan](https://etherscan.io/getRawTx?tx=0x9cd2288e69623b109e25edc46bc518156498b521e5c162d96e1ab392ff1d9dff)
1748-
// tx with signature::v =0x1c (28).
1749-
let sig_data1 = (
1750-
0x1c_u64,
1751-
word!("0x90b751c5870e9bc071c8d6b2bf1ee80f36ee7efd8e6fbabaa25bd3b8b68cfe9b"),
1752-
word!("0x79c25a01f12493a6d35f1330306d4e3c4e782fcbffc64c6809959577f41ff248"),
1753-
);
1754-
1755-
tx1
1756-
.from(address!("0xcf40d0d2b44f2b66e07cace1372ca42b73cf21a3"))
1757-
.nonce(word!("0x2ea8"))
1758-
.gas_price(word!("0x098bca5a00"))
1759-
.gas(word!("0x0249f0"))
1760-
.value(word!("0x00"))
1761-
// Set tx type to pre-eip155.
1762-
.transaction_type(0)
1763-
.input(hex::decode("606060405260008054600160a060020a0319163317905560f2806100236000396000f3606060405260e060020a6000350463f5537ede8114601c575b6002565b3460025760f06004356024356044356000805433600160a060020a039081169116141560ea5783905080600160a060020a031663a9059cbb84846000604051602001526040518360e060020a0281526004018083600160a060020a0316815260200182815260200192505050602060405180830381600087803b1560025760325a03f1156002575050604080518481529051600160a060020a0386811693508716917fd0ed88a3f042c6bbb1e3ea406079b5f2b4b198afccaa535d837f4c63abbc4de6919081900360200190a35b50505050565b00")
1764-
.expect("hex data can be decoded").into())
1765-
.sig_data(sig_data1);
1766-
1767-
// pre-eip155 tx2 refers to https://github.com/scroll-tech/go-ethereum/blob/develop/cmd/evm/testdata/3/txs.json.
1768-
let mut tx2 = MockTransaction::default();
1769-
// tx with signature::v =0x1b (27).
1770-
let sig_data2 = (
1771-
0x1b_u64,
1772-
word!("0x88544c93a564b4c28d2ffac2074a0c55fdd4658fe0d215596ed2e32e3ef7f56b"),
1773-
word!("0x7fb4075d54190f825d7c47bb820284757b34fd6293904a93cddb1d3aa961ac28"),
1774-
);
1775-
1776-
tx2.from(address!("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
1777-
.to(address!("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"))
1778-
.nonce(word!("0x0"))
1779-
.gas_price(word!("0x1"))
1780-
.gas(word!("0x5f5e100"))
1781-
.value(word!("0x186a0"))
1782-
// Set tx type to pre-eip155.
1783-
.transaction_type(0)
1784-
.sig_data(sig_data2);
1785-
1786-
for tx in [tx1, tx2] {
1787-
let ctx = build_legacy_ctx(gwei(8_000_000), &tx).unwrap();
1788-
CircuitTestBuilder::new_from_test_ctx(ctx)
1789-
.params(CircuitsParams {
1790-
max_calldata: 300,
1791-
..Default::default()
1792-
})
1793-
.run()
1794-
}
1795-
}
1796-
1797-
// build pre-eip155 tx
1798-
fn build_legacy_ctx(
1799-
sender_balance: Word,
1800-
tx: &MockTransaction,
1801-
) -> Result<TestContext<1, 1>, Error> {
1802-
TestContext::new(
1803-
None,
1804-
|accs| {
1805-
accs[0]
1806-
.address(tx.from.address())
1807-
.balance(sender_balance)
1808-
.nonce(tx.nonce);
1809-
},
1810-
|mut txs, _accs| {
1811-
txs[0].clone_from(tx);
1812-
},
1813-
|block, _tx| block.number(0xcafeu64),
1814-
)
1815-
}
18161740
}
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// tests for eip155 tx
2+
#[cfg(test)]
3+
mod tx_type_test {
4+
use crate::test_util::CircuitTestBuilder;
5+
use eth_types::{Error, Word};
6+
use ethers_signers::Signer;
7+
use mock::{eth, gwei, TestContext, MOCK_ACCOUNTS, MOCK_WALLETS};
8+
9+
#[test]
10+
fn test_eip155() {
11+
let ctx = build_ctx(gwei(80_000)).unwrap();
12+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
13+
}
14+
15+
fn build_ctx(sender_balance: Word) -> Result<TestContext<2, 1>, Error> {
16+
TestContext::new(
17+
None,
18+
|accs| {
19+
accs[0]
20+
.address(MOCK_WALLETS[0].address())
21+
.balance(sender_balance);
22+
accs[1].address(MOCK_ACCOUNTS[0]).balance(eth(1));
23+
},
24+
|mut txs, _accs| {
25+
txs[0]
26+
.from(MOCK_WALLETS[0].clone())
27+
.to(MOCK_ACCOUNTS[0])
28+
.gas(40_000.into())
29+
.gas_price(30_000.into())
30+
.value(gwei(20_000))
31+
// Set tx type to EIP-155.
32+
.transaction_type(0);
33+
},
34+
|block, _tx| block.number(0xcafeu64),
35+
)
36+
}
37+
}
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#[cfg(test)]
2+
mod tx_type_test {
3+
use crate::test_util::CircuitTestBuilder;
4+
use eth_types::{Error, Word};
5+
use ethers_signers::Signer;
6+
use mock::{eth, gwei, TestContext, MOCK_ACCOUNTS, MOCK_WALLETS};
7+
8+
#[test]
9+
fn test_eip1559_tx_for_equal_balance() {
10+
let balance = if cfg!(feature = "scroll") {
11+
// l1 fee
12+
gwei(80_000) + Word::from(279u64)
13+
} else {
14+
gwei(80_000)
15+
};
16+
let ctx = build_ctx(balance, gwei(2), gwei(2)).unwrap();
17+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
18+
}
19+
20+
#[test]
21+
fn test_eip1559_tx_for_less_balance() {
22+
let res = build_ctx(gwei(79_999), gwei(2), gwei(2));
23+
24+
#[cfg(not(feature = "scroll"))]
25+
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";
26+
27+
// "80000000000279": 279 is l1 fee
28+
#[cfg(feature = "scroll")]
29+
let expected_err = "Failed to run Trace, err: insufficient funds for gas * price + value: address 0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241 have 79999000000000 want 80000000000279";
30+
31+
// Address `0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241` in error message comes from
32+
// MOCK_WALLETS[0] in build_ctx.
33+
34+
// Return a tracing error if insufficient sender balance.
35+
if let Error::TracingError(err) = res.unwrap_err() {
36+
assert_eq!(err, expected_err);
37+
} else {
38+
panic!("Must be a tracing error");
39+
}
40+
}
41+
42+
#[test]
43+
fn test_eip1559_tx_for_more_balance() {
44+
let ctx = build_ctx(gwei(80_001), gwei(2), gwei(2)).unwrap();
45+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
46+
}
47+
48+
#[test]
49+
fn test_eip1559_tx_for_gas_fee_cap_gt_gas_tip_cap() {
50+
// Should be successful if `max_fee_per_gas > max_priority_fee_per_gas`.
51+
let balance = if cfg!(feature = "scroll") {
52+
// l1 fee
53+
gwei(80_000) + Word::from(279u64)
54+
} else {
55+
gwei(80_000)
56+
};
57+
let ctx = build_ctx(balance, gwei(2), gwei(1)).unwrap();
58+
59+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
60+
}
61+
62+
#[test]
63+
fn test_eip1559_tx_for_gas_fee_cap_lt_gas_tip_cap() {
64+
let res = build_ctx(gwei(80_000), gwei(1), gwei(2));
65+
66+
#[cfg(not(feature = "scroll"))]
67+
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";
68+
#[cfg(feature = "scroll")]
69+
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";
70+
// Address `0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241` in error message comes from
71+
// MOCK_WALLETS[0] in build_ctx.
72+
73+
// Return a tracing error if `max_fee_per_gas < max_priority_fee_per_gas`.
74+
if let Error::TracingError(err) = res.unwrap_err() {
75+
assert_eq!(err, expected_err);
76+
} else {
77+
panic!("Must be a tracing error");
78+
}
79+
}
80+
81+
fn build_ctx(
82+
sender_balance: Word,
83+
max_fee_per_gas: Word,
84+
max_priority_fee_per_gas: Word,
85+
) -> Result<TestContext<2, 1>, Error> {
86+
TestContext::new(
87+
None,
88+
|accs| {
89+
accs[0]
90+
.address(MOCK_WALLETS[0].address())
91+
.balance(sender_balance);
92+
accs[1].address(MOCK_ACCOUNTS[0]).balance(eth(1));
93+
},
94+
|mut txs, _accs| {
95+
txs[0]
96+
.from(MOCK_WALLETS[0].clone())
97+
.to(MOCK_ACCOUNTS[0])
98+
.gas(30_000.into())
99+
.value(gwei(20_000))
100+
.max_fee_per_gas(max_fee_per_gas)
101+
.max_priority_fee_per_gas(max_priority_fee_per_gas)
102+
.transaction_type(2); // Set tx type to EIP-1559.
103+
},
104+
|block, _tx| block.number(0xcafeu64),
105+
)
106+
}
107+
}
+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// tests for eip2930
2+
#[cfg(test)]
3+
mod tx_type_test {
4+
use crate::test_util::CircuitTestBuilder;
5+
use eth_types::{address, AccessList, AccessListItem, Error, Word, H256};
6+
use ethers_signers::Signer;
7+
use mock::{eth, gwei, TestContext, MOCK_ACCOUNTS, MOCK_WALLETS};
8+
9+
// test with empty access list.
10+
#[test]
11+
fn test_eip2930_tx_for_empty_access_list() {
12+
// CASE1: tx not set access list, `access_list` field is none.
13+
let ctx = build_ctx(gwei(80_000), None).unwrap();
14+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
15+
16+
// CASE2: tx set empty (neither address nor storage keys at all) access list into
17+
// `access_list` field. this field is not none.
18+
let test_access_list: AccessList = AccessList(vec![]);
19+
20+
let ctx = build_ctx(gwei(80_000), Some(test_access_list)).unwrap();
21+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
22+
}
23+
24+
// test with non empty access list(address + storage keys list)
25+
#[test]
26+
fn test_eip2930_non_empty_access_list() {
27+
let test_access_list: AccessList = AccessList(vec![
28+
AccessListItem {
29+
address: address!("0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241"),
30+
// one storage key
31+
storage_keys: [10].map(H256::from_low_u64_be).to_vec(),
32+
},
33+
AccessListItem {
34+
address: address!("0x0000000000000000000000000000000000001111"),
35+
// two storage keys
36+
storage_keys: [10, 11].map(H256::from_low_u64_be).to_vec(),
37+
},
38+
AccessListItem {
39+
address: address!("0x0000000000000000000000000000000000002222"),
40+
// three storage keys
41+
storage_keys: [20, 22, 50].map(H256::from_low_u64_be).to_vec(),
42+
},
43+
]);
44+
45+
let ctx = build_ctx(gwei(80_000), Some(test_access_list)).unwrap();
46+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
47+
}
48+
49+
// test with non empty access list(only address list)
50+
#[test]
51+
fn test_eip2930_only_address_access_list() {
52+
let test_access_list: AccessList = AccessList(vec![
53+
AccessListItem {
54+
address: address!("0xEeFca179F40D3B8b3D941E6A13e48835a3aF8241"),
55+
// no storage keys
56+
storage_keys: Vec::new(),
57+
},
58+
AccessListItem {
59+
address: address!("0x0000000000000000000000000000000000001111"),
60+
// no storage keys
61+
storage_keys: Vec::new(),
62+
},
63+
]);
64+
65+
let ctx = build_ctx(gwei(80_000), Some(test_access_list)).unwrap();
66+
CircuitTestBuilder::new_from_test_ctx(ctx).run();
67+
}
68+
69+
fn build_ctx(
70+
sender_balance: Word,
71+
access_list: Option<AccessList>,
72+
) -> Result<TestContext<2, 1>, Error> {
73+
TestContext::new(
74+
None,
75+
|accs| {
76+
accs[0]
77+
.address(MOCK_WALLETS[0].address())
78+
.balance(sender_balance);
79+
accs[1].address(MOCK_ACCOUNTS[0]).balance(eth(1));
80+
},
81+
|mut txs, _accs| {
82+
txs[0]
83+
.from(MOCK_WALLETS[0].clone())
84+
.to(MOCK_ACCOUNTS[0])
85+
.gas(40_000.into())
86+
.gas_price(30_000.into())
87+
.value(gwei(20_000))
88+
.transaction_type(1); // Set tx type to EIP-2930.
89+
90+
if let Some(acc_list) = access_list {
91+
txs[0].access_list(acc_list);
92+
}
93+
},
94+
|block, _tx| block.number(0xcafeu64),
95+
)
96+
}
97+
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// this fold only contains tx type tests, for all opcode related tests are in
2+
// each opcode gadget file.
3+
mod eip155;
4+
mod pre_eip155;
5+
6+
mod eip1559;
7+
mod eip2930;

0 commit comments

Comments
 (0)