From 89324050801ff09991b067746ebe568506b4e868 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Thu, 20 Jul 2023 14:44:40 +0300 Subject: [PATCH 01/59] block hash test pseudocodes --- testgen/generators.go | 175 +++++++++++++++++++++++++++++++++++++++++- testgen/utils.go | 23 ++++++ 2 files changed, 196 insertions(+), 2 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index d19489b..e228ba4 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -577,8 +577,96 @@ var EthMulticall = MethodTests{ }, }, Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("6057361d0000000000000000000000000000000000000000000000000000000000000005"), + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + return nil + }, + }, + { + "multicall-blockhash-simple", + "gets blockhash of previous block (included in original chain)", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + + checkBlockNumber(res[0].number, 1) + + if len(res[0].calls) != 1 { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].calls), 1) + } + checkBlockhash(res[0].calls[0].returnData, ???) + return nil + }, + }, + { + "multicall-blockhash-complex", + "gets blockhash of simulated block", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode(), + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode(), + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(20)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), + }}, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode() + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(30)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }} res := make([][]interface{}, 0) @@ -588,6 +676,89 @@ var EthMulticall = MethodTests{ if len(res) != len(params) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) } + + for i := 0; i < len(res); i++ { + if len(res[i].calls) != 1 { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].calls), 1) + } + if res[i].calls[0].status != "0x1" { + return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].status, "0x1") + } + } + checkBlockNumber(res[0].number, 10) + checkBlockNumber(res[1].number, 20) + checkBlockNumber(res[2].number, 30) + // should get generated blockhash for that block + checkBlockhash(res[0].hash, ???) + // hash should equal keccack256(rlp([blockhash_10, 20])) + checkBlockhash(res[1].hash, keccack256(rlp([blockhash_10, 20]))) + // hash shuld equal keccack256(rlp([blockhash_20, 30])) + checkBlockhash(res[2].hash, keccack256(rlp([blockhash_20, 30]))) + + // should equal to real heads blockhash + checkBlockhash(res[0].calls[0].returnData, ???) + // should equal first generated blocks hash + checkBlockhash(res[1].calls[0].returnData, ???) + // should equal keccack256(rlp([blockhash_20, 29])) + checkBlockhash(res[2].calls[0].returnData, keccack256(rlp([blockhash_20, 29]))) + return nil + }, + }, + { + "multicall-blockhash-start-before-head", + "gets blockhash of simulated block", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode() + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode() + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(20)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), + }}, + }, 2 }, //todo, we need some initial blocks for this, so that we can start before head + res := make([][]interface{}, 0) + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + + for i := 0; i < len(res); i++ { + if len(res[i].calls) != 1 { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].calls), 1) + } + if res[i].calls[0].status != "0x1" { + return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].status, "0x1") + } + } + checkBlockNumber(res[0].number, 10) + checkBlockNumber(res[1].number, 20) + // should get generated blockhash for block 3 + checkBlockhash(res[0].hash, ???) + // hash should equal keccack256(rlp([blockhash_10, 20])) + checkBlockhash(res[1].hash, keccack256(rlp([blockhash_10, 20]))) + // should equal to blockhash of block 2 + checkBlockhash(res[0].calls[0].returnData, ???) + // should equal first generated blocks hash + checkBlockhash(res[1].calls[0].returnData, ???) + return nil }, }, diff --git a/testgen/utils.go b/testgen/utils.go index 073a848..0f85a96 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -36,3 +36,26 @@ func checkBlockRLP(t *T, n uint64, got []byte) error { } return nil } + +// I guess Go doesn't have uint256 type? +func checkBlockNumber(value uint256, expected uint256) error { + if value != expected { + return fmt.Errorf("unexpected block number value(have: %d, want: %d)", value, expected) + } +} + +func checkBlockHash(value uint256, expected uint256) error { + if value != expected { + return fmt.Errorf("unexpected block hash value(have: %d, want: %d)", value, expected) + } +} + +func blockHashCallerByteCode() { + //Solidity code: + //contract blockHashCaller { + // function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { + // blockHash = blockhash(blockNumber); + // } + //} + return hex2Bytes("0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") +} From 2ce83b35522e35242053a6c54660e6c47c9dbc9d Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 21 Jul 2023 10:09:13 +0300 Subject: [PATCH 02/59] update tets, for generated tests we don't use block hash computation but instead blockhash is actually computed --- testgen/generators.go | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index e228ba4..8de1ccc 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -621,7 +621,7 @@ var EthMulticall = MethodTests{ if len(res[0].calls) != 1 { return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].calls), 1) } - checkBlockhash(res[0].calls[0].returnData, ???) + checkBlockhash(res[0].calls[0].returnData, head_hash) return nil }, }, @@ -643,11 +643,6 @@ var EthMulticall = MethodTests{ Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }, { - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: blockHashCallerByteCode(), - }, - }, BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(20)), }, @@ -656,11 +651,6 @@ var EthMulticall = MethodTests{ Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), }}, }, { - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: blockHashCallerByteCode() - }, - }, BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(30)), }, @@ -688,19 +678,14 @@ var EthMulticall = MethodTests{ checkBlockNumber(res[0].number, 10) checkBlockNumber(res[1].number, 20) checkBlockNumber(res[2].number, 30) - // should get generated blockhash for that block - checkBlockhash(res[0].hash, ???) - // hash should equal keccack256(rlp([blockhash_10, 20])) - checkBlockhash(res[1].hash, keccack256(rlp([blockhash_10, 20]))) - // hash shuld equal keccack256(rlp([blockhash_20, 30])) - checkBlockhash(res[2].hash, keccack256(rlp([blockhash_20, 30]))) + checkBlockhash(res[0].hash, head_hash) // should equal to real heads blockhash - checkBlockhash(res[0].calls[0].returnData, ???) + checkBlockhash(res[0].calls[0].returnData, head_hash) // should equal first generated blocks hash - checkBlockhash(res[1].calls[0].returnData, ???) + checkBlockhash(res[1].calls[0].returnData, res[0].hash) // should equal keccack256(rlp([blockhash_20, 29])) - checkBlockhash(res[2].calls[0].returnData, keccack256(rlp([blockhash_20, 29]))) + checkBlockhash(res[2].calls[0].returnData, keccack256(rlp([res[0].hash, 29]))) return nil }, }, @@ -722,17 +707,12 @@ var EthMulticall = MethodTests{ Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }, { - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: blockHashCallerByteCode() - }, - }, BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(20)), }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }, 2 }, //todo, we need some initial blocks for this, so that we can start before head res := make([][]interface{}, 0) @@ -750,14 +730,8 @@ var EthMulticall = MethodTests{ } checkBlockNumber(res[0].number, 10) checkBlockNumber(res[1].number, 20) - // should get generated blockhash for block 3 - checkBlockhash(res[0].hash, ???) - // hash should equal keccack256(rlp([blockhash_10, 20])) - checkBlockhash(res[1].hash, keccack256(rlp([blockhash_10, 20]))) - // should equal to blockhash of block 2 - checkBlockhash(res[0].calls[0].returnData, ???) - // should equal first generated blocks hash - checkBlockhash(res[1].calls[0].returnData, ???) + checkBlockhash(res[0].calls[0].returnData, block_2_hash) + checkBlockhash(res[1].calls[0].returnData, keccack256(rlp([res[0].hash, 19]))) return nil }, From 0bd0fb92fc59f0db23348eae4f4e68a1fc553934 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 21 Jul 2023 11:54:22 +0300 Subject: [PATCH 03/59] add couple of more tests (selfdestruct, out of gas, eth logs) --- testgen/generators.go | 129 +++++++++++++++++++++++++++++++++++++++++- testgen/utils.go | 42 ++++++++++++++ 2 files changed, 170 insertions(+), 1 deletion(-) diff --git a/testgen/generators.go b/testgen/generators.go index 8de1ccc..33d17b9 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -640,6 +640,7 @@ var EthMulticall = MethodTests{ }, Calls: []TransactionArgs{{ From: &common.Address{0xc1}, + To: &common.Address{0xc2}, Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }, { @@ -648,6 +649,7 @@ var EthMulticall = MethodTests{ }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, + To: &common.Address{0xc2}, Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), }}, }, { @@ -656,6 +658,7 @@ var EthMulticall = MethodTests{ }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, + To: &common.Address{0xc2}, Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }} @@ -675,6 +678,7 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].status, "0x1") } } + head_hash = 0x0 // TODO checkBlockNumber(res[0].number, 10) checkBlockNumber(res[1].number, 20) checkBlockNumber(res[2].number, 30) @@ -685,7 +689,7 @@ var EthMulticall = MethodTests{ // should equal first generated blocks hash checkBlockhash(res[1].calls[0].returnData, res[0].hash) // should equal keccack256(rlp([blockhash_20, 29])) - checkBlockhash(res[2].calls[0].returnData, keccack256(rlp([res[0].hash, 29]))) + checkBlockhash(res[2].calls[0].returnData, keccack256(rlp([res[1].hash, 29]))) return nil }, }, @@ -704,6 +708,7 @@ var EthMulticall = MethodTests{ }, Calls: []TransactionArgs{{ From: &common.Address{0xc1}, + To: &common.Address{0xc2}, Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }, { @@ -712,6 +717,7 @@ var EthMulticall = MethodTests{ }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, + To: &common.Address{0xc2}, Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }, 2 }, //todo, we need some initial blocks for this, so that we can start before head @@ -728,6 +734,7 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].status, "0x1") } } + block_2_hash = 0x0 // TODO checkBlockNumber(res[0].number, 10) checkBlockNumber(res[1].number, 20) checkBlockhash(res[0].calls[0].returnData, block_2_hash) @@ -736,6 +743,126 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "selfdestructing-state-override", + "when selfdestructing a state override, the state override should go away", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: selfDestructor() + }, + common.Address{0xc3}: OverrideAccount{ + Code: getCode() + }, + }, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + }}, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + Input: hex2Bytes("0x83197ef0"), //destroy() + }}, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + }}, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: selfDestructor() + }, + }, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + }}, + }} + res := make([][]interface{}, 0) + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + if len(res[1].calls[0].returnData) > 0 { + return fmt.Errorf("overrided contract does not have contract code") + } + if len(res[3].calls[0].returnData) == 0 { + return fmt.Errorf("self destructed code does have contract code") + } + if len(res[5].calls[0].returnData) > 0 { + return fmt.Errorf("overrided contract does not have contract code") + } + return nil + }, + }, + { + "run-out-of-gas-in-block", + "we should get out of gas error if a block consumes too much gas", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: gasSpender() + }, + }, + BlockOverrides: &BlockOverrides{ + gasLimit: (*hexutil.Big)(big.NewInt(1500000)), + }, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + }}, + }} + res := make([][]interface{}, 0) + //TODO: should result out of gas error for block (but not to a single transaction) + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + return nil + }, + }, + //TODO, add test on how to overflow the multicall, but not single transaction / block. To achieve this, we need to know what is the limit set to the node + { + "eth-send-should-produce-logs", + "when sending eth we should get eth logs", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + if len(res[0].calls[0].logs) != 1 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res), 1) + } + return nil + }, + }, }, } diff --git a/testgen/utils.go b/testgen/utils.go index 0f85a96..2c6d811 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -59,3 +59,45 @@ func blockHashCallerByteCode() { //} return hex2Bytes("0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") } + +func selfDestructor() { + //Solidity code: + //contract SelfDestructor { + // function destroy() public { + // selfdestruct(payable(0x0)); + // } + //} + return hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033") +} + +func getCode() { + //library GetCode { + // function at(address addr) public view returns (bytes memory code) { + // assembly { + // // retrieve the size of the code, this needs assembly + // let size := extcodesize(addr) + // // allocate output byte array - this could also be done without assembly + // // by using code = new bytes(size) + // code := mload(0x40) + // // new "memory end" including padding + // mstore(0x40, add(code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + // // store length in memory + // mstore(code, size) + // // actually retrieve the code, this needs assembly + // extcodecopy(addr, add(code, 0x20), 0, size) + // } + // } + //} + return hex2Bytes("73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063dce4a4471461003a575b600080fd5b610054600480360381019061004f91906100f8565b61006a565b60405161006191906101b5565b60405180910390f35b6060813b6040519150601f19601f602083010116820160405280825280600060208401853c50919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100c58261009a565b9050919050565b6100d5816100ba565b81146100e057600080fd5b50565b6000813590506100f2816100cc565b92915050565b60006020828403121561010e5761010d610095565b5b600061011c848285016100e3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561015f578082015181840152602081019050610144565b60008484015250505050565b6000601f19601f8301169050919050565b600061018782610125565b6101918185610130565b93506101a1818560208601610141565b6101aa8161016b565b840191505092915050565b600060208201905081810360008301526101cf818461017c565b90509291505056fea26469706673582212206a5f0cd9f230619fa520fc4b9d4b518643258cad412f2fa33945ce528b4b895164736f6c63430008120033") +} +func gasSpender() { + //contract GasSpender { + // function spendGas(gasToSpend: uint) view external { + // uint public gasLeftInitially = gasleft(); + // while(true) { + // if (gasLeftInitially - gasleft() >= gasToSpend) return; + // } + // } + //} + return hex2Bytes("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033") +} From f6b18ed7c50ed8c16fe5a9a2be608b4c78c79579 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 21 Jul 2023 13:55:33 +0300 Subject: [PATCH 04/59] add tests for various errors --- testgen/generators.go | 157 ++++++++++++++++++++++++++++++++++++++++++ testgen/utils.go | 12 ++++ 2 files changed, 169 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index 33d17b9..00c0a29 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -525,6 +525,32 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-block-timestamp-order", + "simulates calls with invalid timestamp num order", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + BlockOverrides: &BlockOverrides{ + Time: (*hexutil.Big)(big.NewInt(12)), + }, + }, { + BlockOverrides: &BlockOverrides{ + Time: (*hexutil.Big)(big.NewInt(11)), + }, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + if res[0].errors.code != -38021 { + return fmt.Errorf("expected error code (have: %d, want: %d)", res[0].errors.code, -38021) + } + return nil + }, + }, { "multicall-set-read-storage", "simulates calls setting and reading from storage contract", @@ -863,6 +889,137 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-transaction-too-low-nonce", + "Nonce too low", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Nonce: 10}, + }, + Calls: []TransactionArgs{{ + Nonce: big.NewInt(0), + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + checkStatus(res[0].status, "0x2") + checkError(res[0].errors.code, -38010) + return nil + }, + }, + { + "multicall-transaction-too-high-nonce", + "Nonce too high", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + Calls: []TransactionArgs{{ + Nonce: big.NewInt(100),, + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + checkStatus(res[0].status, "0x2") + checkError(res[0].errors.code, -38011) + return nil + }, + }, + { + "multicall-basefee-too-low", + "BaseFee too low", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + BlockOverrides: &BlockOverrides{ + BaseFee: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + MaxFeePerGas: (*hexutil.Big)(big.NewInt(0)), + MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(0)), + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + checkStatus(res[0].status, "0x2") + checkError(res[0].errors.code, -38012) + return nil + }, + }, + { + "multicall-instrict-gas", + "Not enough gas provided to pay for intrinsic gas", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + gasLimit: (*hexutil.Big)(big.NewInt(0)), + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + checkStatus(res[0].status, "0x2") + checkError(res[0].errors.code, -38013) + return nil + }, + }, + { + "multicall-gas-fees-and-value-error", + "Insufficient funds to pay for gas fees and value", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + checkStatus(res[0].status, "0x2") + checkError(res[0].errors.code, -38014) + return nil + }, + }, + { + "multicall-move-to-address-itself-reference", + "MoveToAddress referenced itself in replacement", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{moveToAddress: 0xc0}, + }, + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + checkStatus(res[0].status, "0x2") + checkError(res[0].errors.code, -38022) + return nil + }, + }, }, } diff --git a/testgen/utils.go b/testgen/utils.go index 2c6d811..d2ee602 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -50,6 +50,18 @@ func checkBlockHash(value uint256, expected uint256) error { } } +func checkStatus(value type?, expected type?) error { + if value != expected { + return fmt.Errorf("expected status (have: %d, want: %d)", value, expected) + } +} + +func checkError(value number, expected number) error { + if value != expected { + return fmt.Errorf("expected error (have: %d, want: %d)", value, expected) + } +} + func blockHashCallerByteCode() { //Solidity code: //contract blockHashCaller { From c10c88cf191914c47de63c4285b1d51894699698 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 21 Jul 2023 14:24:40 +0300 Subject: [PATCH 05/59] add multiple account override --- testgen/generators.go | 67 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 00c0a29..19f5c31 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -527,7 +527,7 @@ var EthMulticall = MethodTests{ }, { "multicall-block-timestamp-order", - "simulates calls with invalid timestamp num order", + "Error: simulates calls with invalid timestamp num order", func(ctx context.Context, t *T) error { params := []CallBatch{{ BlockOverrides: &BlockOverrides{ @@ -891,7 +891,7 @@ var EthMulticall = MethodTests{ }, { "multicall-transaction-too-low-nonce", - "Nonce too low", + "Error: Nonce too low", func(ctx context.Context, t *T) error { params := []CallBatch{{ StateOverrides: &StateOverride{ @@ -914,7 +914,7 @@ var EthMulticall = MethodTests{ }, { "multicall-transaction-too-high-nonce", - "Nonce too high", + "Error: Nonce too high", func(ctx context.Context, t *T) error { params := []CallBatch{{ Calls: []TransactionArgs{{ @@ -937,7 +937,7 @@ var EthMulticall = MethodTests{ }, { "multicall-basefee-too-low", - "BaseFee too low", + "Error: BaseFee too low", func(ctx context.Context, t *T) error { params := []CallBatch{{ StateOverrides: &StateOverride{ @@ -964,7 +964,7 @@ var EthMulticall = MethodTests{ }, { "multicall-instrict-gas", - "Not enough gas provided to pay for intrinsic gas", + "Error: Not enough gas provided to pay for intrinsic gas", func(ctx context.Context, t *T) error { params := []CallBatch{{ Calls: []TransactionArgs{{ @@ -984,7 +984,7 @@ var EthMulticall = MethodTests{ }, { "multicall-gas-fees-and-value-error", - "Insufficient funds to pay for gas fees and value", + "Error: Insufficient funds to pay for gas fees and value", func(ctx context.Context, t *T) error { params := []CallBatch{{ Calls: []TransactionArgs{{ @@ -1004,7 +1004,7 @@ var EthMulticall = MethodTests{ }, { "multicall-move-to-address-itself-reference", - "MoveToAddress referenced itself in replacement", + "Error: MoveToAddress referenced itself in replacement", func(ctx context.Context, t *T) error { params := []CallBatch{{ StateOverrides: &StateOverride{ @@ -1020,6 +1020,59 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-multiple-account-overrides", + "override an account multple times", + func(ctx context.Context, t *T) error { + params := []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + moveToAddress: 0xc2, + code: selfDestructor(), + }, + common.Address{0xc0}: OverrideAccount{ + moveToAddress: 0xc1, + code: selfDestructor(), + }, + common.Address{0xc3}: OverrideAccount{ + Code: getCode() + }, + }, + { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c0"), //at(0xc0) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c1"), //at(0xc1) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c2"), //at(0xc2) + }}, + } + }} + res := make([][]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + + if len(res[0].calls[0].returnData) > 0 { + return fmt.Errorf("overrided contract does not have contract code") + } + if len(res[0].calls[1].returnData) > 0 { + return fmt.Errorf("overrided contract does not have contract code") + } + if len(res[0].calls[2].returnData) == 0 { + return fmt.Errorf("overrided contract haves contract code") + } + return nil + }, + }, }, } From 9d277f8d2a5984677a5d8f6d548c8aee67692be9 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 26 Jul 2023 12:04:00 +0300 Subject: [PATCH 06/59] compiles and generates tests --- testgen/generators.go | 682 ++++++++++++++++++++++-------------------- testgen/utils.go | 34 ++- 2 files changed, 383 insertions(+), 333 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 3c2987d..99bf4f6 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -537,25 +537,25 @@ var EthMulticall = MethodTests{ "multicall-block-timestamp-order", "Error: simulates calls with invalid timestamp num order", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - BlockOverrides: &BlockOverrides{ - Time: (*hexutil.Big)(big.NewInt(12)), - }, - }, { - BlockOverrides: &BlockOverrides{ - Time: (*hexutil.Big)(big.NewInt(11)), + params := multicallOpts{ + Blocks: []CallBatch{ + { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(12), + }, + }, { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(11), + }, + }, }, - }} - res := make([][]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err } - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) - } - if res[0].errors.code != -38021 { - return fmt.Errorf("expected error code (have: %d, want: %d)", res[0].errors.code, -38021) + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } + checkError(err, -38021) return nil }, }, @@ -602,7 +602,7 @@ var EthMulticall = MethodTests{ Blocks: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc2}: OverrideAccount{ - // Yul code: + // Yul Code: // object "Test" { // code { // let hash:u256 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff @@ -613,19 +613,19 @@ var EthMulticall = MethodTests{ Code: hex2Bytes("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80600080a1600080f3"), }, }, - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("6057361d0000000000000000000000000000000000000000000000000000000000000005"), + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("6057361d0000000000000000000000000000000000000000000000000000000000000005"), + }}, }}, - }} - res := make([][]interface{}, 0) + } + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } return nil }, @@ -634,19 +634,21 @@ var EthMulticall = MethodTests{ "multicall-blockhash-simple", "gets blockhash of previous block (included in original chain)", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: blockHashCallerByteCode(), + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode(), + }, }, - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, }}, } - res := make([]interface{}, 0) + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } @@ -654,12 +656,13 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } - checkBlockNumber(res[0].number, 1) + checkBlockNumber(res[0].Number, 1) - if len(res[0].calls) != 1 { - return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].calls), 1) + if len(res[0].Calls) != 1 { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), 1) } - checkBlockhash(res[0].calls[0].returnData, head_hash) + head_hash := common.Hash{0x1} + checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), head_hash) //todo how to get type right? return nil }, }, @@ -667,67 +670,69 @@ var EthMulticall = MethodTests{ "multicall-blockhash-complex", "gets blockhash of simulated block", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: blockHashCallerByteCode(), + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode(), + }, }, - }, - BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc1}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), - }}, - }, { - BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(20)), - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), - }}, - }, { - BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(30)), - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, + }, { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(20)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), + }}, + }, { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(30)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, }}, - }} - res := make([][]interface{}, 0) + } + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } for i := 0; i < len(res); i++ { - if len(res[i].calls) != 1 { - return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].calls), 1) + if len(res[i].Calls) != 1 { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].Calls), 1) } - if res[i].calls[0].status != "0x1" { - return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].status, "0x1") + if res[i].Calls[0].Status != 0x1 { + return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].Calls[0].Status, 0x1) } } - head_hash = 0x0 // TODO - checkBlockNumber(res[0].number, 10) - checkBlockNumber(res[1].number, 20) - checkBlockNumber(res[2].number, 30) - checkBlockhash(res[0].hash, head_hash) + head_hash := common.Hash{0x1} // TODO + checkBlockNumber(res[0].Number, 10) + checkBlockNumber(res[1].Number, 20) + checkBlockNumber(res[2].Number, 30) + checkBlockHash(res[0].Hash, head_hash) // should equal to real heads blockhash - checkBlockhash(res[0].calls[0].returnData, head_hash) + checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), head_hash) // should equal first generated blocks hash - checkBlockhash(res[1].calls[0].returnData, res[0].hash) + checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), res[0].Hash) // should equal keccack256(rlp([blockhash_20, 29])) - checkBlockhash(res[2].calls[0].returnData, keccack256(rlp([res[1].hash, 29]))) + checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnValue), common.Hash{0x1}) return nil }, }, @@ -735,49 +740,54 @@ var EthMulticall = MethodTests{ "multicall-blockhash-start-before-head", "gets blockhash of simulated block", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: blockHashCallerByteCode() + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: blockHashCallerByteCode(), + }, }, - }, - BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc1}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), - }}, - }, { - BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(20)), - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, + }, { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(20)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }}, }}, - }, 2 }, //todo, we need some initial blocks for this, so that we can start before head - res := make([][]interface{}, 0) - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + } + res := make([]blockResult, 0) //todo, we need some initial blocks for this, so that we can start before head + if err := t.rpc.Call(&res, "eth_multicallV1", params, 2); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } for i := 0; i < len(res); i++ { - if len(res[i].calls) != 1 { - return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].calls), 1) + if len(res[i].Calls) != 1 { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].Calls), 1) } - if res[i].calls[0].status != "0x1" { - return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].status, "0x1") + if res[i].Calls[0].Status != 0x1 { + return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].Calls[0].Status, 0x1) } } - block_2_hash = 0x0 // TODO - checkBlockNumber(res[0].number, 10) - checkBlockNumber(res[1].number, 20) - checkBlockhash(res[0].calls[0].returnData, block_2_hash) - checkBlockhash(res[1].calls[0].returnData, keccack256(rlp([res[0].hash, 19]))) - + block_2_hash := common.Hash{0x0} // TODO + checkBlockNumber(res[0].Number, 10) + checkBlockNumber(res[1].Number, 20) + checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), block_2_hash) + checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), common.Hash{0x2}) //keccack256(rlp([res[0].hash, 19]) + return nil }, }, @@ -785,56 +795,58 @@ var EthMulticall = MethodTests{ "selfdestructing-state-override", "when selfdestructing a state override, the state override should go away", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: selfDestructor() - }, - common.Address{0xc3}: OverrideAccount{ - Code: getCode() + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: selfDestructor(), + }, + common.Address{0xc3}: OverrideAccount{ + Code: getCode(), + }, }, - }, - }, { - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) - }}, - }, { - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - Input: hex2Bytes("0x83197ef0"), //destroy() - }}, - }, { - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) - }}, - }, { - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: selfDestructor() + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + }}, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + Input: hex2Bytes("0x83197ef0"), //destroy() + }}, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + }}, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: selfDestructor(), + }, }, - }, - }, { - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + }}, }}, - }} - res := make([][]interface{}, 0) - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) } - if len(res[1].calls[0].returnData) > 0 { + res := make([]blockResult, 0) + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[1].Calls[0].ReturnValue) > 0 { return fmt.Errorf("overrided contract does not have contract code") } - if len(res[3].calls[0].returnData) == 0 { + if len(res[3].Calls[0].ReturnValue) == 0 { return fmt.Errorf("self destructed code does have contract code") } - if len(res[5].calls[0].returnData) > 0 { + if len(res[5].Calls[0].ReturnValue) > 0 { return fmt.Errorf("overrided contract does not have contract code") } return nil @@ -844,31 +856,33 @@ var EthMulticall = MethodTests{ "run-out-of-gas-in-block", "we should get out of gas error if a block consumes too much gas", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{ - Code: gasSpender() + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: gasSpender(), + }, }, - }, - BlockOverrides: &BlockOverrides{ - gasLimit: (*hexutil.Big)(big.NewInt(1500000)), - }, - }, { - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + BlockOverrides: &BlockOverrides{ + GasLimit: getUint64Ptr(1500000), + }, + }, { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + }}, }}, - }} - res := make([][]interface{}, 0) + } + res := make([]blockResult, 0) //TODO: should result out of gas error for block (but not to a single transaction) - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } return nil }, @@ -878,24 +892,26 @@ var EthMulticall = MethodTests{ "eth-send-should-produce-logs", "when sending eth we should get eth logs", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, }}, - }} - res := make([][]interface{}, 0) + } + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } - if len(res[0].calls[0].logs) != 1 { + if len(res[0].Calls[0].Logs) != 1 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res), 1) } return nil @@ -905,22 +921,22 @@ var EthMulticall = MethodTests{ "multicall-transaction-too-low-nonce", "Error: Nonce too low", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{Nonce: 10}, - }, - Calls: []TransactionArgs{{ - Nonce: big.NewInt(0), - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(10)}, + }, + Calls: []TransactionArgs{{ + Nonce: getUint64Ptr(0), + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + }}, }}, - }} - res := make([][]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err } - checkStatus(res[0].status, "0x2") - checkError(res[0].errors.code, -38010) + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + checkError(err, -38010) + checkStatus(res[0].Calls[0].Status, 0x2) return nil }, }, @@ -928,22 +944,22 @@ var EthMulticall = MethodTests{ "multicall-transaction-too-high-nonce", "Error: Nonce too high", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - Calls: []TransactionArgs{{ - Nonce: big.NewInt(100),, - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, + params := multicallOpts{ + Blocks: []CallBatch{{ + Calls: []TransactionArgs{{ + Nonce: getUint64Ptr(100), + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + }}, }}, - }} - res := make([][]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err } - if len(res) != len(params) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params)) + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + checkError(err, -38011) + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } - checkStatus(res[0].status, "0x2") - checkError(res[0].errors.code, -38011) + checkStatus(res[0].Calls[0].Status, 0x2) return nil }, }, @@ -951,26 +967,26 @@ var EthMulticall = MethodTests{ "multicall-basefee-too-low", "Error: BaseFee too low", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, - }, - BlockOverrides: &BlockOverrides{ - BaseFee: (*hexutil.Big)(big.NewInt(10)), - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, - MaxFeePerGas: (*hexutil.Big)(big.NewInt(0)), - MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(0)), + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + BlockOverrides: &BlockOverrides{ + BaseFee: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + MaxFeePerGas: (*hexutil.Big)(big.NewInt(0)), + MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(0)), + }}, }}, - }} - res := make([][]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err } - checkStatus(res[0].status, "0x2") - checkError(res[0].errors.code, -38012) + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + checkError(err, -38012) + checkStatus(res[0].Calls[0].Status, 0x2) return nil }, }, @@ -978,19 +994,19 @@ var EthMulticall = MethodTests{ "multicall-instrict-gas", "Error: Not enough gas provided to pay for intrinsic gas", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - Calls: []TransactionArgs{{ - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, - gasLimit: (*hexutil.Big)(big.NewInt(0)), + params := multicallOpts{ + Blocks: []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + Gas: getUint64Ptr(0), + }}, }}, - }} - res := make([][]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err } - checkStatus(res[0].status, "0x2") - checkError(res[0].errors.code, -38013) + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + checkError(err, -38013) + checkStatus(res[0].Calls[0].Status, 0x2) return nil }, }, @@ -998,19 +1014,19 @@ var EthMulticall = MethodTests{ "multicall-gas-fees-and-value-error", "Error: Insufficient funds to pay for gas fees and value", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + params := multicallOpts{ + Blocks: []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, }}, - }} - res := make([][]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err } - checkStatus(res[0].status, "0x2") - checkError(res[0].errors.code, -38014) + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + checkStatus(res[0].Calls[0].Status, 0x2) + checkError(err, -38014) return nil }, }, @@ -1018,17 +1034,23 @@ var EthMulticall = MethodTests{ "multicall-move-to-address-itself-reference", "Error: MoveToAddress referenced itself in replacement", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{moveToAddress: 0xc0}, - }, - }} - res := make([][]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(200000)}, + common.Address{0xc1}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1)), + }}, + }}, } - checkStatus(res[0].status, "0x2") - checkError(res[0].errors.code, -38022) + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + checkError(err, -38022) + checkStatus(res[0].Calls[0].Status, 0x2) return nil }, }, @@ -1036,50 +1058,52 @@ var EthMulticall = MethodTests{ "multicall-multiple-account-overrides", "override an account multple times", func(ctx context.Context, t *T) error { - params := []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{ - moveToAddress: 0xc2, - code: selfDestructor(), - }, - common.Address{0xc0}: OverrideAccount{ - moveToAddress: 0xc1, - code: selfDestructor(), - }, - common.Address{0xc3}: OverrideAccount{ - Code: getCode() - }, - }, - { - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c0"), //at(0xc0) + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + MoveToAddress: &common.Address{0xc2}, + Code: selfDestructor(), + }, + common.Address{0xc0}: OverrideAccount{ + MoveToAddress: &common.Address{0xc1}, + Code: selfDestructor(), + }, + common.Address{0xc3}: OverrideAccount{ + Code: getCode(), + }, }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c1"), //at(0xc1) + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c0"), //at(0xc0) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c1"), //at(0xc1) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c2"), //at(0xc2) + }, }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c2"), //at(0xc2) - }}, - } - }} - res := make([][]interface{}, 0) + }}, + } + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - - if len(res[0].calls[0].returnData) > 0 { + + if len(res[0].Calls[0].ReturnValue) > 0 { return fmt.Errorf("overrided contract does not have contract code") } - if len(res[0].calls[1].returnData) > 0 { + if len(res[0].Calls[1].ReturnValue) > 0 { return fmt.Errorf("overrided contract does not have contract code") } - if len(res[0].calls[2].returnData) == 0 { + if len(res[0].Calls[2].ReturnValue) == 0 { return fmt.Errorf("overrided contract haves contract code") } return nil @@ -1764,11 +1788,12 @@ type BlockOverrides struct { // if statDiff is set, all diff will be applied first and then execute the call // message. type OverrideAccount struct { - Nonce *hexutil.Uint64 `json:"nonce,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` - Balance **hexutil.Big `json:"balance,omitempty"` - State *map[common.Hash]common.Hash `json:"state,omitempty"` - StateDiff *map[common.Hash]common.Hash `json:"stateDiff,omitempty"` + Nonce *hexutil.Uint64 `json:"nonce,omitempty"` + Code *hexutil.Bytes `json:"code,omitempty"` + Balance **hexutil.Big `json:"balance,omitempty"` + State *map[common.Hash]common.Hash `json:"state,omitempty"` + StateDiff *map[common.Hash]common.Hash `json:"stateDiff,omitempty"` + MoveToAddress *common.Address `json:"moveToAddress,omitempty"` } // StateOverride is the collection of overridden accounts. @@ -1789,14 +1814,14 @@ type CallBatch struct { } type blockResult struct { - Number hexutil.Uint64 `json:"number"` - Hash common.Hash `json:"hash"` - Time hexutil.Uint64 `json:"timestamp"` - GasLimit hexutil.Uint64 `json:"gasLimit"` - GasUsed hexutil.Uint64 `json:"gasUsed"` - FeeRecipient common.Address `json:"feeRecipient"` - BaseFee *hexutil.Big `json:"baseFeePerGas"` - Calls []callResult `json:"calls"` + Number hexutil.Uint64 `json:"number"` + Hash common.Hash `json:"hash"` + Time hexutil.Uint64 `json:"timestamp"` + GasLimit hexutil.Uint64 `json:"gasLimit"` + GasUsed hexutil.Uint64 `json:"gasUsed"` + FeeRecipient common.Address `json:"feeRecipient"` + BaseFeePerGas *hexutil.Big `json:"baseFeePerGas"` + Calls []callResult `json:"calls"` } type callResult struct { @@ -1808,6 +1833,17 @@ type callResult struct { Error *string `json:"error,omitempty"` } +/* +type multicallBlockResponse struct { + Data []blockResult `json:"data,omitempty"` + Error *Error `json:"error,omitempty"` +} + +type Error struct { + Code int `json:"code"` + Message string `json:"message"` +}*/ + type transfer struct { From common.Address `json:"from"` To common.Address `json:"to"` diff --git a/testgen/utils.go b/testgen/utils.go index d2ee602..af565ce 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -1,10 +1,13 @@ package testgen import ( + "errors" "fmt" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" ) func checkHeaderRLP(t *T, n uint64, got []byte) error { @@ -38,31 +41,36 @@ func checkBlockRLP(t *T, n uint64, got []byte) error { } // I guess Go doesn't have uint256 type? -func checkBlockNumber(value uint256, expected uint256) error { +func checkBlockNumber(value hexutil.Uint64, expected hexutil.Uint64) error { if value != expected { return fmt.Errorf("unexpected block number value(have: %d, want: %d)", value, expected) } + return nil } -func checkBlockHash(value uint256, expected uint256) error { +func checkBlockHash(value common.Hash, expected common.Hash) error { if value != expected { return fmt.Errorf("unexpected block hash value(have: %d, want: %d)", value, expected) } + return nil } -func checkStatus(value type?, expected type?) error { +func checkStatus(value hexutil.Uint64, expected hexutil.Uint64) error { if value != expected { return fmt.Errorf("expected status (have: %d, want: %d)", value, expected) } + return nil } -func checkError(value number, expected number) error { - if value != expected { - return fmt.Errorf("expected error (have: %d, want: %d)", value, expected) +func checkError(err error, expectedErrorCode int) error { + var ec rpc.Error + if errors.As(err, &ec) && ec.ErrorCode() != expectedErrorCode { + return fmt.Errorf("expected error (have: %d, want: %d)", ec.ErrorCode(), expectedErrorCode) } + return nil } -func blockHashCallerByteCode() { +func blockHashCallerByteCode() *hexutil.Bytes { //Solidity code: //contract blockHashCaller { // function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { @@ -72,7 +80,7 @@ func blockHashCallerByteCode() { return hex2Bytes("0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") } -func selfDestructor() { +func selfDestructor() *hexutil.Bytes { //Solidity code: //contract SelfDestructor { // function destroy() public { @@ -82,7 +90,7 @@ func selfDestructor() { return hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033") } -func getCode() { +func getCode() *hexutil.Bytes { //library GetCode { // function at(address addr) public view returns (bytes memory code) { // assembly { @@ -102,7 +110,7 @@ func getCode() { //} return hex2Bytes("73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063dce4a4471461003a575b600080fd5b610054600480360381019061004f91906100f8565b61006a565b60405161006191906101b5565b60405180910390f35b6060813b6040519150601f19601f602083010116820160405280825280600060208401853c50919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100c58261009a565b9050919050565b6100d5816100ba565b81146100e057600080fd5b50565b6000813590506100f2816100cc565b92915050565b60006020828403121561010e5761010d610095565b5b600061011c848285016100e3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561015f578082015181840152602081019050610144565b60008484015250505050565b6000601f19601f8301169050919050565b600061018782610125565b6101918185610130565b93506101a1818560208601610141565b6101aa8161016b565b840191505092915050565b600060208201905081810360008301526101cf818461017c565b90509291505056fea26469706673582212206a5f0cd9f230619fa520fc4b9d4b518643258cad412f2fa33945ce528b4b895164736f6c63430008120033") } -func gasSpender() { +func gasSpender() *hexutil.Bytes { //contract GasSpender { // function spendGas(gasToSpend: uint) view external { // uint public gasLeftInitially = gasleft(); @@ -113,3 +121,9 @@ func gasSpender() { //} return hex2Bytes("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033") } + +func getUint64Ptr(value hexutil.Uint64) *hexutil.Uint64 { + newUint64 := new(hexutil.Uint64) + newUint64 = &value + return newUint64 +} From 3d33b7bf6c07f4ca62b67cbda6bafa697d189b22 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Thu, 27 Jul 2023 12:11:58 +0300 Subject: [PATCH 07/59] test fixing --- testgen/generators.go | 219 ++++++++++++++++++++++++------------------ testgen/utils.go | 5 +- 2 files changed, 129 insertions(+), 95 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 99bf4f6..e90141c 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -392,7 +392,7 @@ var EthMulticall = MethodTests{ }, }, } - res := make([]interface{}, 0) + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } @@ -439,7 +439,7 @@ var EthMulticall = MethodTests{ }, }}, } - res := make([]interface{}, 0) + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } @@ -482,7 +482,7 @@ var EthMulticall = MethodTests{ }}, }}, } - res := make([]interface{}, 0) + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } @@ -523,7 +523,7 @@ var EthMulticall = MethodTests{ }}, }}, } - res := make([]interface{}, 0) + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } @@ -555,8 +555,10 @@ var EthMulticall = MethodTests{ if len(res) != len(params.Blocks) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } - checkError(err, -38021) - return nil + if err := checkError(err, -38021); err != nil { + return err + } + return err }, }, { @@ -655,14 +657,15 @@ var EthMulticall = MethodTests{ if len(res) != len(params.Blocks) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } - - checkBlockNumber(res[0].Number, 1) - + if err := checkBlockNumber(res[0].Number, 3); err != nil { + return err + } if len(res[0].Calls) != 1 { return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), 1) } - head_hash := common.Hash{0x1} - checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), head_hash) //todo how to get type right? + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), t.chain.GetHeaderByNumber(1).Hash()); err != nil { + return err + } return nil }, }, @@ -673,6 +676,9 @@ var EthMulticall = MethodTests{ params := multicallOpts{ Blocks: []CallBatch{{ StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, common.Address{0xc2}: OverrideAccount{ Code: blockHashCallerByteCode(), }, @@ -681,7 +687,7 @@ var EthMulticall = MethodTests{ Number: (*hexutil.Big)(big.NewInt(10)), }, Calls: []TransactionArgs{{ - From: &common.Address{0xc1}, + From: &common.Address{0xc0}, To: &common.Address{0xc2}, Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, @@ -722,17 +728,32 @@ var EthMulticall = MethodTests{ } } head_hash := common.Hash{0x1} // TODO - checkBlockNumber(res[0].Number, 10) - checkBlockNumber(res[1].Number, 20) - checkBlockNumber(res[2].Number, 30) - checkBlockHash(res[0].Hash, head_hash) + + if err := checkBlockNumber(res[0].Number, 10); err != nil { + return err + } + if err := checkBlockNumber(res[1].Number, 20); err != nil { + return err + } + if err := checkBlockNumber(res[2].Number, 30); err != nil { + return err + } + if err := checkBlockHash(res[0].Hash, head_hash); err != nil { + return err + } // should equal to real heads blockhash - checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), head_hash) + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), head_hash); err != nil { + return err + } // should equal first generated blocks hash - checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), res[0].Hash) + if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), res[0].Hash); err != nil { + return err + } // should equal keccack256(rlp([blockhash_20, 29])) - checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnValue), common.Hash{0x1}) + if err := checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnValue), common.Hash{0x1}); err != nil { + return err + } return nil }, }, @@ -743,6 +764,9 @@ var EthMulticall = MethodTests{ params := multicallOpts{ Blocks: []CallBatch{{ StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, common.Address{0xc2}: OverrideAccount{ Code: blockHashCallerByteCode(), }, @@ -751,7 +775,7 @@ var EthMulticall = MethodTests{ Number: (*hexutil.Big)(big.NewInt(10)), }, Calls: []TransactionArgs{{ - From: &common.Address{0xc1}, + From: &common.Address{0xc0}, To: &common.Address{0xc2}, Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, @@ -767,7 +791,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) //todo, we need some initial blocks for this, so that we can start before head - if err := t.rpc.Call(&res, "eth_multicallV1", params, 2); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { return err } if len(res) != len(params.Blocks) { @@ -782,22 +806,34 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].Calls[0].Status, 0x1) } } - block_2_hash := common.Hash{0x0} // TODO - checkBlockNumber(res[0].Number, 10) - checkBlockNumber(res[1].Number, 20) - checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), block_2_hash) - checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), common.Hash{0x2}) //keccack256(rlp([res[0].hash, 19]) + + if err := checkBlockNumber(res[0].Number, 10); err != nil { + return err + } + if err := checkBlockNumber(res[1].Number, 20); err != nil { + return err + } + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), t.chain.GetHeaderByNumber(2).Hash()); err != nil { + return err + } + //keccack256(rlp([res[0].hash, 19]) + if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), common.Hash{0x2}); err != nil { + return err + } return nil }, }, { - "selfdestructing-state-override", + "multicall-self-destructing-state-override", "when selfdestructing a state override, the state override should go away", func(ctx context.Context, t *T) error { params := multicallOpts{ Blocks: []CallBatch{{ StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, common.Address{0xc2}: OverrideAccount{ Code: selfDestructor(), }, @@ -837,6 +873,9 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { + return err + } if len(res) != len(params.Blocks) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } @@ -853,12 +892,15 @@ var EthMulticall = MethodTests{ }, }, { - "run-out-of-gas-in-block", + "multicall-run-out-of-gas-in-block", "we should get out of gas error if a block consumes too much gas", func(ctx context.Context, t *T) error { params := multicallOpts{ Blocks: []CallBatch{{ StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, common.Address{0xc2}: OverrideAccount{ Code: gasSpender(), }, @@ -867,29 +909,30 @@ var EthMulticall = MethodTests{ GasLimit: getUint64Ptr(1500000), }, }, { - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) - }, + Calls: []TransactionArgs{ { From: &common.Address{0xc0}, To: &common.Address{0xc2}, Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) - }}, - }}, + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + }, + }}, + }, } res := make([]blockResult, 0) - //TODO: should result out of gas error for block (but not to a single transaction) - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err } return nil }, }, //TODO, add test on how to overflow the multicall, but not single transaction / block. To achieve this, we need to know what is the limit set to the node { - "eth-send-should-produce-logs", + "multicall-eth-send-should-produce-logs", "when sending eth we should get eth logs", func(ctx context.Context, t *T) error { params := multicallOpts{ @@ -912,7 +955,7 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } if len(res[0].Calls[0].Logs) != 1 { - return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res), 1) + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 1) } return nil }, @@ -935,9 +978,13 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - checkError(err, -38010) - checkStatus(res[0].Calls[0].Status, 0x2) - return nil + if err := checkError(err, -38010); err != nil { + return err + } + if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { + return err + } + return err }, }, { @@ -955,12 +1002,16 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - checkError(err, -38011) + if err := checkError(err, -38011); err != nil { + return err + } if len(res) != len(params.Blocks) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } - checkStatus(res[0].Calls[0].Status, 0x2) - return nil + if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { + return err + } + return err }, }, { @@ -985,9 +1036,13 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - checkError(err, -38012) - checkStatus(res[0].Calls[0].Status, 0x2) - return nil + if err := checkError(err, -38012); err != nil { + return err + } + if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { + return err + } + return err }, }, { @@ -1005,9 +1060,13 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - checkError(err, -38013) - checkStatus(res[0].Calls[0].Status, 0x2) - return nil + if err := checkError(err, -38013); err != nil { + return err + } + if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { + return err + } + return err }, }, { @@ -1025,9 +1084,10 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - checkStatus(res[0].Calls[0].Status, 0x2) - checkError(err, -38014) - return nil + if err := checkError(err, -38014); err != nil { + return err + } + return err }, }, { @@ -1049,9 +1109,10 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - checkError(err, -38022) - checkStatus(res[0].Calls[0].Status, 0x2) - return nil + if err := checkError(err, -38022); err != nil { + return err + } + return err }, }, { @@ -1062,51 +1123,21 @@ var EthMulticall = MethodTests{ Blocks: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000), MoveToAddress: &common.Address{0xc2}, - Code: selfDestructor(), - }, - common.Address{0xc0}: OverrideAccount{ - MoveToAddress: &common.Address{0xc1}, - Code: selfDestructor(), - }, - common.Address{0xc3}: OverrideAccount{ - Code: getCode(), - }, - }, - Calls: []TransactionArgs{ - { - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c0"), //at(0xc0) - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c1"), //at(0xc1) }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a44700000000000000000000000000000000000000000000000000000000000000c2"), //at(0xc2) + common.Address{0xc1}: OverrideAccount{ + MoveToAddress: &common.Address{0xc2}, }, }, }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + if err := checkError(err, -38023); err != nil { return err } - - if len(res[0].Calls[0].ReturnValue) > 0 { - return fmt.Errorf("overrided contract does not have contract code") - } - if len(res[0].Calls[1].ReturnValue) > 0 { - return fmt.Errorf("overrided contract does not have contract code") - } - if len(res[0].Calls[2].ReturnValue) == 0 { - return fmt.Errorf("overrided contract haves contract code") - } - return nil + return err }, }, }, diff --git a/testgen/utils.go b/testgen/utils.go index af565ce..d929841 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -64,6 +64,9 @@ func checkStatus(value hexutil.Uint64, expected hexutil.Uint64) error { func checkError(err error, expectedErrorCode int) error { var ec rpc.Error + if !errors.As(err, &ec) { + return fmt.Errorf("expected error (have: some other output, want: %d)", expectedErrorCode) + } if errors.As(err, &ec) && ec.ErrorCode() != expectedErrorCode { return fmt.Errorf("expected error (have: %d, want: %d)", ec.ErrorCode(), expectedErrorCode) } @@ -77,7 +80,7 @@ func blockHashCallerByteCode() *hexutil.Bytes { // blockHash = blockhash(blockNumber); // } //} - return hex2Bytes("0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") + return hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") } func selfDestructor() *hexutil.Bytes { From afc141bd16d6bfd91e64d405e75f88bc72c76f39 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Thu, 27 Jul 2023 13:57:06 +0300 Subject: [PATCH 08/59] remove 0x where its not needed --- testgen/generators.go | 44 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index e90141c..72101f6 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -646,7 +646,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }}, } @@ -689,7 +689,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), }}, }, { BlockOverrides: &BlockOverrides{ @@ -698,7 +698,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), + Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), }}, }, { BlockOverrides: &BlockOverrides{ @@ -707,7 +707,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + Input: hex2Bytes("ee82ac5e000000000000000000000000000000000000000000000000000000000000001D"), }}, }}, } @@ -727,8 +727,6 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].Calls[0].Status, 0x1) } } - head_hash := common.Hash{0x1} // TODO - if err := checkBlockNumber(res[0].Number, 10); err != nil { return err } @@ -738,12 +736,9 @@ var EthMulticall = MethodTests{ if err := checkBlockNumber(res[2].Number, 30); err != nil { return err } - if err := checkBlockHash(res[0].Hash, head_hash); err != nil { - return err - } - // should equal to real heads blockhash - if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), head_hash); err != nil { + // should equal to block number ones hash + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), t.chain.GetHeaderByNumber(1).Hash()); err != nil { return err } // should equal first generated blocks hash @@ -751,7 +746,7 @@ var EthMulticall = MethodTests{ return err } // should equal keccack256(rlp([blockhash_20, 29])) - if err := checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnValue), common.Hash{0x1}); err != nil { + if err := checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnValue), common.BytesToHash(*hex2Bytes("9f77a47d3fbad17b981f2f21022effd528670e580382921735559c1f31774191"))); err != nil { return err } return nil @@ -777,7 +772,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000002"), }}, }, { BlockOverrides: &BlockOverrides{ @@ -786,11 +781,11 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000013"), }}, }}, } - res := make([]blockResult, 0) //todo, we need some initial blocks for this, so that we can start before head + res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { return err } @@ -813,11 +808,12 @@ var EthMulticall = MethodTests{ if err := checkBlockNumber(res[1].Number, 20); err != nil { return err } - if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), t.chain.GetHeaderByNumber(2).Hash()); err != nil { + //keccack256(rlp([blockhash_1, 2]) + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), common.BytesToHash(*hex2Bytes("b71624aa776736b9a340cae6a536e93c71e376907a5b23c196aa056450a2b983"))); err != nil { return err } - //keccack256(rlp([res[0].hash, 19]) - if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), common.Hash{0x2}); err != nil { + //keccack256(rlp([blockhash_10, 19]) + if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), common.BytesToHash(*hex2Bytes("5679ee58a0ff6a8fa7b177db27c76774f1ddc04464d1999aad7aba7ac911593b"))); err != nil { return err } @@ -845,18 +841,18 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + Input: hex2Bytes("dce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) }}, }, { Calls: []TransactionArgs{{ From: &common.Address{0xc0}, - Input: hex2Bytes("0x83197ef0"), //destroy() + Input: hex2Bytes("83197ef0"), //destroy() }}, }, { Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + Input: hex2Bytes("dce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) }}, }, { StateOverrides: &StateOverride{ @@ -868,7 +864,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Input: hex2Bytes("0xdce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + Input: hex2Bytes("dce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) }}, }}, } @@ -913,12 +909,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + Input: hex2Bytes("815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) }, { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + Input: hex2Bytes("815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) }, }}, }, From 2d5ea06ea27d813fdf32f1715926b656d1abcf91 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Thu, 27 Jul 2023 15:32:25 +0300 Subject: [PATCH 09/59] add test to check that fields have been set --- testgen/generators.go | 59 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 72101f6..16743b8 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1136,6 +1136,51 @@ var EthMulticall = MethodTests{ return err }, }, + { + "multicall-override-all-in-blocks", + "override all values in block and see that they are set in return value", + func(ctx context.Context, t *T) error { + feeRecipient := common.Address{0xc2} + params := multicallOpts{ + Blocks: []CallBatch{{ + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(1001)), + Time: getUint64Ptr(1003), + GasLimit: getUint64Ptr(1004), + FeeRecipient: &feeRecipient, + PrevRandao: &common.Hash{0xc3}, + BaseFee: (*hexutil.Big)(big.NewInt(1007)), + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if res[0].Number != 1001 { + return fmt.Errorf("unexpected Number (have: %d, want: %d)", res[0].Number, 1001) + } + if res[0].Time != 1003 { + return fmt.Errorf("unexpectedTime (have: %d, want: %d)", res[0].Time, 1003) + } + if res[0].GasLimit != 1004 { + return fmt.Errorf("unexpected GasLimit (have: %d, want: %d)", res[0].GasLimit, 1004) + } + if res[0].FeeRecipient != feeRecipient { + return fmt.Errorf("unexpected FeeRecipient (have: %d, want: %d)", res[0].FeeRecipient, feeRecipient) + } + if res[0].PrevRandao != &(common.Hash{0xc3}) { + return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, 0xc3) + } + if res[0].BaseFeePerGas != (*hexutil.Big)(big.NewInt(1007)) { + return fmt.Errorf("unexpected BaseFeePerGas (have: %d, want: %d)", res[0].BaseFeePerGas.ToInt(), 1007) + } + return nil + }, + }, }, } @@ -1799,13 +1844,12 @@ type TransactionArgs struct { // BlockOverrides is a set of header fields to override. type BlockOverrides struct { - Number *hexutil.Big `json:"number,omitempty"` - Difficulty *hexutil.Big `json:"difficulty,omitempty"` - Time *hexutil.Uint64 `json:"time,omitempty"` - GasLimit *hexutil.Uint64 `json:"gasLimit,omitempty"` - Coinbase *common.Address `json:"coinbase,omitempty"` - Random *common.Hash `json:"random,omitempty"` - BaseFee *hexutil.Big `json:"baseFee,omitempty"` + Number *hexutil.Big `json:"number,omitempty"` + Time *hexutil.Uint64 `json:"time,omitempty"` + GasLimit *hexutil.Uint64 `json:"gasLimit,omitempty"` + FeeRecipient *common.Address `json:"feeRecipient,omitempty"` + PrevRandao *common.Hash `json:"prevRandao,omitempty"` + BaseFee *hexutil.Big `json:"baseFeePerGas,omitempty"` } // OverrideAccount indicates the overriding fields of account during the execution @@ -1848,6 +1892,7 @@ type blockResult struct { GasUsed hexutil.Uint64 `json:"gasUsed"` FeeRecipient common.Address `json:"feeRecipient"` BaseFeePerGas *hexutil.Big `json:"baseFeePerGas"` + PrevRandao *common.Hash `json:"prevRandao,omitempty"` Calls []callResult `json:"calls"` } From 3f42054d6be5e3b6702ca19215a4d1a190a31c3a Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 28 Jul 2023 17:10:58 +0300 Subject: [PATCH 10/59] add more tests --- testgen/generators.go | 312 ++++++++++++++++++++++++++++++++++++++---- testgen/utils.go | 72 ++++++++++ 2 files changed, 357 insertions(+), 27 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 16743b8..f17c6f8 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -841,18 +841,19 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Input: hex2Bytes("dce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + Input: hex2Bytes("dce4a447000000000000000000000000c200000000000000000000000000000000000000"), //at(0xc2) }}, }, { Calls: []TransactionArgs{{ From: &common.Address{0xc0}, + To: &common.Address{0xc2}, Input: hex2Bytes("83197ef0"), //destroy() }}, }, { Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Input: hex2Bytes("dce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + Input: hex2Bytes("dce4a447000000000000000000000000c200000000000000000000000000000000000000"), //at(0xc2) }}, }, { StateOverrides: &StateOverride{ @@ -864,7 +865,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Input: hex2Bytes("dce4a4470000000000000000000000000000000000000000000000000000000000000002"), //at(0x2) + Input: hex2Bytes("dce4a447000000000000000000000000c200000000000000000000000000000000000000"), //at(0xc2) }}, }}, } @@ -875,14 +876,15 @@ var EthMulticall = MethodTests{ if len(res) != len(params.Blocks) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) } - if len(res[1].Calls[0].ReturnValue) > 0 { - return fmt.Errorf("overrided contract does not have contract code") + noCode := "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000" + if res[1].Calls[0].ReturnValue.String() == noCode { + return fmt.Errorf("res 1 overrided contract does not have contract code: %s", res[1].Calls[0].ReturnValue.String()) } - if len(res[3].Calls[0].ReturnValue) == 0 { - return fmt.Errorf("self destructed code does have contract code") + if res[3].Calls[0].ReturnValue.String() != noCode { + return fmt.Errorf("res 3 self destructed code does have contract code: %s", res[3].Calls[0].ReturnValue.String()) } - if len(res[5].Calls[0].ReturnValue) > 0 { - return fmt.Errorf("overrided contract does not have contract code") + if res[5].Calls[0].ReturnValue.String() == noCode { + return fmt.Errorf("res 5 overrided contract does not have contract code: %s", res[5].Calls[0].ReturnValue.String()) } return nil }, @@ -926,10 +928,9 @@ var EthMulticall = MethodTests{ return nil }, }, - //TODO, add test on how to overflow the multicall, but not single transaction / block. To achieve this, we need to know what is the limit set to the node { "multicall-eth-send-should-produce-logs", - "when sending eth we should get eth logs", + "when sending eth we should get ETH logs when traceTransfers is set", func(ctx context.Context, t *T) error { params := multicallOpts{ Blocks: []CallBatch{{ @@ -942,6 +943,7 @@ var EthMulticall = MethodTests{ Value: (*hexutil.Big)(big.NewInt(1000)), }}, }}, + TraceTransfers: true, } res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { @@ -956,6 +958,131 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-eth-send-should-not-produce-logs-on-revert", + "we should not be producing eth logs if the transaction reverts and ETH is not sent", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + common.Address{0xc1}: OverrideAccount{Code: getRevertingContract()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[0].Calls[0].Logs) != 0 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 0) + } + return nil + }, + }, + { + "multicall-eth-send-should--produce-more-logs-on-forward", + "we should be getting more logs if eth is forwarded", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + common.Address{0xc1}: OverrideAccount{Code: getEthForwarder()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), + }}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[0].Calls[0].Logs) != 2 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 2) + } + return nil + }, + }, + { + "multicall-eth-send-should--produce-no-logs-on-forward-revert", + "we should be getting no logs if eth is forwarded but then the tx reverts", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + common.Address{0xc1}: OverrideAccount{Code: getEthForwarder()}, + common.Address{0xc2}: OverrideAccount{Code: getRevertingContract()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + Input: hex2Bytes("4b64e49200000000000000000000000000000000000000000000000000000000000000c2"), //foward(0xc2) + }}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[0].Calls[0].Logs) != 0 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 0) + } + return nil + }, + }, + { + "multicall-eth-send-should-not-produce-logs-by-default", + "when sending eth we should not get ETH logs by default", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[0].Calls[0].Logs) != 0 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 0) + } + return nil + }, + }, { "multicall-transaction-too-low-nonce", "Error: Nonce too low", @@ -1113,7 +1240,7 @@ var EthMulticall = MethodTests{ }, { "multicall-multiple-account-overrides", - "override an account multple times", + "override an account multiple times", func(ctx context.Context, t *T) error { params := multicallOpts{ Blocks: []CallBatch{{ @@ -1136,6 +1263,45 @@ var EthMulticall = MethodTests{ return err }, }, + { + "multicall-moved-contract-should-be-useable", + "when contract is moved, the moved contract should still work", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + common.Address{0xc2}: OverrideAccount{Code: getEthForwarder()}, + }, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), + }}, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[1].Calls[0].Logs) != 2 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[1].Calls[0].Logs), 2) + } + return nil + }, + }, { "multicall-override-all-in-blocks", "override all values in block and see that they are set in return value", @@ -1181,6 +1347,110 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-override-ecrecover", + "override ecrecover", + func(ctx context.Context, t *T) error { + ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) + ecRecoverMovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + ecRecoverAddress: OverrideAccount{ + Code: getEcRecoverOverride(), + MoveToAddress: &ecRecoverMovedToAddress, + }, + common.Address{0xc1}: OverrideAccount{Balance: newRPCBalance(200000)}, + common.Address{0xc2}: OverrideAccount{Code: getEcRecoverCaller()}, + }, + Calls: []TransactionArgs{ + { // call with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Input: hex2Bytes("265dc68c4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Input: hex2Bytes("265dc68c1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + { // add override + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("c00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045"), + }, + { // now it should resolve to 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Input: hex2Bytes("265dc68c4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Input: hex2Bytes("265dc68c1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + { // call with new invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Input: hex2Bytes("265dc68c4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000"), + }, + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[0].Calls) != len(params.Blocks[0].Calls) { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.Blocks[0].Calls)) + } + zeroAddr := common.Address{0x0} + if common.BytesToAddress(res[0].Calls[0].ReturnValue) != zeroAddr { + return fmt.Errorf("unexpected returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[0].ReturnValue), zeroAddr) + } + successReturn := common.BytesToAddress(*hex2Bytes("b11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a")) + if common.BytesToAddress(res[0].Calls[1].ReturnValue) != successReturn { + return fmt.Errorf("unexpected calls 1 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[1].ReturnValue), successReturn) + } + vitalikReturn := common.BytesToAddress(*hex2Bytes("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045")) + if common.BytesToAddress(res[0].Calls[3].ReturnValue) != vitalikReturn { + return fmt.Errorf("unexpected calls 3 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[3].ReturnValue), vitalikReturn) + } + if common.BytesToAddress(res[0].Calls[4].ReturnValue) != successReturn { + return fmt.Errorf("unexpected calls 4 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[4].ReturnValue), successReturn) + } + if common.BytesToAddress(res[0].Calls[5].ReturnValue) != zeroAddr { + return fmt.Errorf("unexpected calls 5 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[5].ReturnValue), zeroAddr) + } + return nil + }, + }, + { + "multicall-override-sha256", + "override sha256 precompile", + func(ctx context.Context, t *T) error { + sha256Address := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000002")) + sha256MovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + sha256Address: OverrideAccount{ + Code: hex2Bytes(""), + MoveToAddress: &sha256MovedToAddress, + }, + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, }, } @@ -1878,10 +2148,9 @@ type multicallOpts struct { // CallBatch is a batch of calls to be simulated sequentially. type CallBatch struct { - BlockOverrides *BlockOverrides `json:"blockOverrides,omitempty"` - StateOverrides *StateOverride `json:"stateOverrides,omitempty"` - ECRecoverOverride *hexutil.Bytes `json:"ecrecoverOverride,omitempty"` - Calls []TransactionArgs `json:"calls,omitempty"` + BlockOverrides *BlockOverrides `json:"blockOverrides,omitempty"` + StateOverrides *StateOverride `json:"stateOverrides,omitempty"` + Calls []TransactionArgs `json:"calls,omitempty"` } type blockResult struct { @@ -1905,17 +2174,6 @@ type callResult struct { Error *string `json:"error,omitempty"` } -/* -type multicallBlockResponse struct { - Data []blockResult `json:"data,omitempty"` - Error *Error `json:"error,omitempty"` -} - -type Error struct { - Code int `json:"code"` - Message string `json:"message"` -}*/ - type transfer struct { From common.Address `json:"from"` To common.Address `json:"to"` diff --git a/testgen/utils.go b/testgen/utils.go index d929841..16c0e53 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -125,6 +125,78 @@ func gasSpender() *hexutil.Bytes { return hex2Bytes("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033") } +func getRevertingContract() *hexutil.Bytes { + //contract RevertingContract { + // fallback() payable external { + // require(false, "Always reverting contract"); + // } + //} + return hex2Bytes("608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033") +} + +func getEthForwarder() *hexutil.Bytes { + //contract EthForwarder { + // function execute(address payable forwardTo) payable external { + // bool sent = forwardTo.send(msg.value); + // require(sent, "Failed to send Ether"); + // } + //} + return hex2Bytes("60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033") +} + +func getEcRecoverOverride() *hexutil.Bytes { + /* + pragma solidity ^0.8.18; + + contract ecRecoverOverride { + struct EcRecoverOverrideParams { + bytes32 hash; + uint8 v; + bytes32 r; + bytes32 s; + address returnAddress; + } + mapping(bytes32 => address) overrideToAddress; + address movedEcRecoverAddress = address(0x123456); + + function setOverride(bytes32 hash, uint8 v, bytes32 r, bytes32 s, address returnAddress) public { + require(returnAddress != address(0x0), 'return address cannot be 0x0'); + overrideToAddress[keccak256(abi.encodePacked(hash, v, r, s))] = returnAddress; + } + + function setOverrides(EcRecoverOverrideParams[] memory overrides) public { + for (uint i = 0; i < overrides.length; i++) { + setOverride(overrides[i].hash, overrides[i].v, overrides[i].r, overrides[i].s, overrides[i].returnAddress); + } + } + + fallback (bytes calldata input) external returns (bytes memory) { + (bytes32 hash, uint8 v, bytes32 r, bytes32 s) = abi.decode(input, (bytes32, uint8, bytes32, bytes32)); + address overridedAddress = overrideToAddress[keccak256(abi.encodePacked(hash, v, r, s))]; + if (overridedAddress == address(0x0)) { + (bool success, bytes memory data) = movedEcRecoverAddress.call(input); + require(success, 'failed to call moved ecrecover at address 0x123456'); + return data; + } else { + return abi.encodePacked(overridedAddress); + } + } + } + */ + return hex2Bytes("608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc8114610209578063c0069260146102255761003b565b5b60003660606000806000808686810190610055919061047d565b9350935093509350600080600086868686604051602001610079949392919061053b565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101d657600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168a8a6040516101409291906105c8565b6000604051808303816000865af19150503d806000811461017d576040519150601f19603f3d011682016040523d82523d6000602084013e610182565b606091505b5091509150816101c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101be90610664565b60405180910390fd5b809750505050505050506101fe565b806040516020016101e791906106fe565b604051602081830303815290604052955050505050505b915050805190602001f35b610223600480360381019061021e919061092f565b610241565b005b61023f600480360381019061023a9190610978565b610307565b005b60005b8151811015610303576102f0828281518110610263576102626109f3565b5b602002602001015160000151838381518110610282576102816109f3565b5b6020026020010151602001518484815181106102a1576102a06109f3565b5b6020026020010151604001518585815181106102c0576102bf6109f3565b5b6020026020010151606001518686815181106102df576102de6109f3565b5b602002602001015160800151610307565b80806102fb90610a5b565b915050610244565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161036d90610aef565b60405180910390fd5b8060008087878787604051602001610391949392919061053b565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6104218161040e565b811461042c57600080fd5b50565b60008135905061043e81610418565b92915050565b600060ff82169050919050565b61045a81610444565b811461046557600080fd5b50565b60008135905061047781610451565b92915050565b6000806000806080858703121561049757610496610404565b5b60006104a58782880161042f565b94505060206104b687828801610468565b93505060406104c78782880161042f565b92505060606104d88782880161042f565b91505092959194509250565b6000819050919050565b6104ff6104fa8261040e565b6104e4565b82525050565b60008160f81b9050919050565b600061051d82610505565b9050919050565b61053561053082610444565b610512565b82525050565b600061054782876104ee565b6020820191506105578286610524565b60018201915061056782856104ee565b60208201915061057782846104ee565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b60006105af8385610589565b93506105bc838584610594565b82840190509392505050565b60006105d58284866105a3565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f7420616464726573732030783132333435360000000000000000000000000000602082015250565b600061064e6032836105e1565b9150610659826105f2565b604082019050919050565b6000602082019050818103600083015261067d81610641565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106af82610684565b9050919050565b60008160601b9050919050565b60006106ce826106b6565b9050919050565b60006106e0826106c3565b9050919050565b6106f86106f3826106a4565b6106d5565b82525050565b600061070a82846106e7565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6107678261071e565b810181811067ffffffffffffffff821117156107865761078561072f565b5b80604052505050565b60006107996103fa565b90506107a5828261075e565b919050565b600067ffffffffffffffff8211156107c5576107c461072f565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107e9816106a4565b81146107f457600080fd5b50565b600081359050610806816107e0565b92915050565b600060a08284031215610822576108216107db565b5b61082c60a061078f565b9050600061083c8482850161042f565b600083015250602061085084828501610468565b60208301525060406108648482850161042f565b60408301525060606108788482850161042f565b606083015250608061088c848285016107f7565b60808301525092915050565b60006108ab6108a6846107aa565b61078f565b90508083825260208201905060a084028301858111156108ce576108cd6107d6565b5b835b818110156108f757806108e3888261080c565b84526020840193505060a0810190506108d0565b5050509392505050565b600082601f83011261091657610915610719565b5b8135610926848260208601610898565b91505092915050565b60006020828403121561094557610944610404565b5b600082013567ffffffffffffffff81111561096357610962610409565b5b61096f84828501610901565b91505092915050565b600080600080600060a0868803121561099457610993610404565b5b60006109a28882890161042f565b95505060206109b388828901610468565b94505060406109c48882890161042f565b93505060606109d58882890161042f565b92505060806109e6888289016107f7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a6682610a51565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a9857610a97610a22565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ad9601c836105e1565b9150610ae482610aa3565b602082019050919050565b60006020820190508181036000830152610b0881610acc565b905091905056fea26469706673582212202fa837f70cfab8ede041106e92528882f950de3f9900cfcba0f560e8bf8eb85764736f6c63430008120033") +} + +func getEcRecoverCaller() *hexutil.Bytes { + /* + contract EcRecoverCaller { + function callEcRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) pure external returns (address) { + return ecrecover(hash, v, r, s); + } + } + */ + return hex2Bytes("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063265dc68c14610030575b600080fd5b61004a6004803603810190610045919061012f565b610060565b60405161005791906101d7565b60405180910390f35b6000600185858585604051600081526020016040526040516100859493929190610210565b6020604051602081039080840390855afa1580156100a7573d6000803e3d6000fd5b505050602060405103519050949350505050565b600080fd5b6000819050919050565b6100d3816100c0565b81146100de57600080fd5b50565b6000813590506100f0816100ca565b92915050565b600060ff82169050919050565b61010c816100f6565b811461011757600080fd5b50565b60008135905061012981610103565b92915050565b60008060008060808587031215610149576101486100bb565b5b6000610157878288016100e1565b94505060206101688782880161011a565b9350506040610179878288016100e1565b925050606061018a878288016100e1565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c182610196565b9050919050565b6101d1816101b6565b82525050565b60006020820190506101ec60008301846101c8565b92915050565b6101fb816100c0565b82525050565b61020a816100f6565b82525050565b600060808201905061022560008301876101f2565b6102326020830186610201565b61023f60408301856101f2565b61024c60608301846101f2565b9594505050505056fea26469706673582212206c520c25fdd1108030611d622b1aa1038ff1b4820f27608d6867d249c1e3ed7664736f6c63430008120033") +} + func getUint64Ptr(value hexutil.Uint64) *hexutil.Uint64 { newUint64 := new(hexutil.Uint64) newUint64 = &value From a5bebbb63846deea8e114e4878154ebe01e0e6b4 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 31 Jul 2023 09:35:48 +0300 Subject: [PATCH 11/59] add eth sending tests with validation --- testgen/generators.go | 145 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index f17c6f8..702e352 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -402,6 +402,150 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-simple-no-funds", + "simulates a simple multicall transfer when account has no funds", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }, { + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Value: *newRPCBalance(1000), + }}, + }, + }, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-simple-no-funds-with-validation", + "simulates a simple multicall transfer when account has no funds with validation", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }, { + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Value: *newRPCBalance(1000), + }}, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-simple-send-from-contract", + "Sending eth from contract", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(1000), Code: getEthForwarder()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-simple-send-from-contract-no-balance", + "Sending eth from contract without balance", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Code: getEthForwarder()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-simple-send-from-contract-with-validation", + "Sending eth from contract with validation enabled", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(1000), Code: getEthForwarder()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }}, + }}, + TraceTransfers: true, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, { "multicall-transfer-over-blocks", "simulates a transfering value over multiple blocks", @@ -2144,6 +2288,7 @@ type StateOverride map[common.Address]OverrideAccount type multicallOpts struct { Blocks []CallBatch `json:"blocks,omitempty"` TraceTransfers bool `json:"traceTransfers,omitempty"` + Validation bool `json:"validation,omitempty"` } // CallBatch is a batch of calls to be simulated sequentially. From db922041242ff8eac2bb2b4e3bba421398cb5862 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 31 Jul 2023 12:21:23 +0300 Subject: [PATCH 12/59] state override testing --- testgen/generators.go | 209 +++++++++++++++++++++++++++++++++++++++++- testgen/utils.go | 32 +++++++ 2 files changed, 239 insertions(+), 2 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 702e352..83f00f0 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1102,6 +1102,67 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-override-address-twice", + "override address twice", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + common.Address{0xc0}: OverrideAccount{Code: getRevertingContract()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-override-address-twice-in-separate-blocks", + "override address twice in separate blocks", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, { "multicall-eth-send-should-not-produce-logs-on-revert", "we should not be producing eth logs if the transaction reverts and ETH is not sent", @@ -1282,8 +1343,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-basefee-too-low", - "Error: BaseFee too low", + "multicall-basefee-too-low-with-validation", + "Error: BaseFee too low with validation", func(ctx context.Context, t *T) error { params := multicallOpts{ Blocks: []CallBatch{{ @@ -1300,6 +1361,39 @@ var EthMulticall = MethodTests{ MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(0)), }}, }}, + Validation: true, + } + res := make([]blockResult, 0) + err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + if err := checkError(err, -38012); err != nil { + return err + } + if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { + return err + } + return err + }, + }, + { + "multicall-basefee-too-low-without-validation", + "Error: BaseFee too low with no validation", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + }, + BlockOverrides: &BlockOverrides{ + BaseFee: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + MaxFeePerGas: (*hexutil.Big)(big.NewInt(0)), + MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(0)), + }}, + }}, + Validation: false, } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") @@ -1595,6 +1689,117 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-override-storage-slots", + "override storage slots", + func(ctx context.Context, t *T) error { + stateChanges := make(map[common.Hash]common.Hash) + stateChanges[common.BytesToHash(*hex2Bytes("bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a"))] = common.Hash{0x12} //slot 0 -> 0x12 + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: getStorageTester(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"), // set storage slot 0 -> 1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), // set storage slot 1 -> 2 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 2 + }, + }, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + StateDiff: &stateChanges, // state diff override + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 as overrided + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 2 + }, + }, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + State: &stateChanges, // whole state override + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 as overrided + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 0 as the whole storage was replaced + }, + }, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if res[0].Calls[2].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000001" { + return fmt.Errorf("unexpected call result (res[0].Calls[2]) (have: %s, want: %s)", res[0].Calls[2].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000001") + } + if res[0].Calls[3].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { + return fmt.Errorf("unexpected call result (res[0].Calls[3]) (have: %s, want: %s)", res[0].Calls[3].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") + } + + if res[1].Calls[0].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000012" { + return fmt.Errorf("unexpected call result (res[1].Calls[0]) (have: %s, want: %s)", res[0].Calls[3].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000012") + } + if res[1].Calls[1].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { + return fmt.Errorf("unexpected call result (res[1].Calls[1]) (have: %s, want: %s)", res[0].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") + } + + if res[2].Calls[0].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000012" { + return fmt.Errorf("unexpected call result (res[2].Calls[0]) (have: %s, want: %s)", res[2].Calls[0].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000012") + } + if res[2].Calls[1].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000000" { + return fmt.Errorf("unexpected call result (res[2].Calls[1]) (have: %s, want: %s)", res[2].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000000") + } + return nil + }, + }, }, } diff --git a/testgen/utils.go b/testgen/utils.go index 16c0e53..5a78f77 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -197,6 +197,38 @@ func getEcRecoverCaller() *hexutil.Bytes { return hex2Bytes("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063265dc68c14610030575b600080fd5b61004a6004803603810190610045919061012f565b610060565b60405161005791906101d7565b60405180910390f35b6000600185858585604051600081526020016040526040516100859493929190610210565b6020604051602081039080840390855afa1580156100a7573d6000803e3d6000fd5b505050602060405103519050949350505050565b600080fd5b6000819050919050565b6100d3816100c0565b81146100de57600080fd5b50565b6000813590506100f0816100ca565b92915050565b600060ff82169050919050565b61010c816100f6565b811461011757600080fd5b50565b60008135905061012981610103565b92915050565b60008060008060808587031215610149576101486100bb565b5b6000610157878288016100e1565b94505060206101688782880161011a565b9350506040610179878288016100e1565b925050606061018a878288016100e1565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c182610196565b9050919050565b6101d1816101b6565b82525050565b60006020820190506101ec60008301846101c8565b92915050565b6101fb816100c0565b82525050565b61020a816100f6565b82525050565b600060808201905061022560008301876101f2565b6102326020830186610201565b61023f60408301856101f2565b61024c60608301846101f2565b9594505050505056fea26469706673582212206c520c25fdd1108030611d622b1aa1038ff1b4820f27608d6867d249c1e3ed7664736f6c63430008120033") } +func getStorageTester() *hexutil.Bytes { + /* + pragma solidity ^0.8.18; + + contract StorageTester { + uint256 public value0; + uint256 public value1; + uint256 public value2; + uint256 public value3; + uint256 public value4; + + function setValue(uint256 slot, uint256 value) external { + require(slot < 5, "too big slot"); + if (slot == 0) { value0 = value; return; } + if (slot == 1) { value1 = value; return; } + if (slot == 2) { value2 = value; return; } + if (slot == 3) { value3 = value; return; } + if (slot == 4) { value4 = value; return; } + } + function getValue(uint256 slot) view external returns (uint256 returnValue) { + require(slot < 5, "too big slot"); + if (slot == 0) { returnValue = value0; } + if (slot == 1) { returnValue = value1; } + if (slot == 2) { returnValue = value2; } + if (slot == 3) { returnValue = value3; } + if (slot == 4) { returnValue = value4; } + } + } + */ + return hex2Bytes("608060405234801561001057600080fd5b506004361061007d5760003560e01c8063517f5fa71161005b578063517f5fa7146100ee5780635d33a27f1461010c5780637b8d56e31461012a578063aef52a2c146101465761007d565b80630ff4c916146100825780633033413b146100b257806344e12f87146100d0575b600080fd5b61009c600480360381019061009791906102f9565b610164565b6040516100a99190610335565b60405180910390f35b6100ba6101f4565b6040516100c79190610335565b60405180910390f35b6100d86101fa565b6040516100e59190610335565b60405180910390f35b6100f6610200565b6040516101039190610335565b60405180910390f35b610114610206565b6040516101219190610335565b60405180910390f35b610144600480360381019061013f9190610350565b61020c565b005b61014e6102b8565b60405161015b9190610335565b60405180910390f35b6000600582106101a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a0906103ed565b60405180910390fd5b600082036101b75760005490505b600182036101c55760015490505b600282036101d35760025490505b600382036101e15760035490505b600482036101ef5760045490505b919050565b60015481565b60005481565b60045481565b60025481565b6005821061024f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610246906103ed565b60405180910390fd5b6000820361026357806000819055506102b4565b6001820361027757806001819055506102b4565b6002820361028b57806002819055506102b4565b6003820361029f57806003819055506102b4565b600482036102b357806004819055506102b4565b5b5050565b60035481565b600080fd5b6000819050919050565b6102d6816102c3565b81146102e157600080fd5b50565b6000813590506102f3816102cd565b92915050565b60006020828403121561030f5761030e6102be565b5b600061031d848285016102e4565b91505092915050565b61032f816102c3565b82525050565b600060208201905061034a6000830184610326565b92915050565b60008060408385031215610367576103666102be565b5b6000610375858286016102e4565b9250506020610386858286016102e4565b9150509250929050565b600082825260208201905092915050565b7f746f6f2062696720736c6f740000000000000000000000000000000000000000600082015250565b60006103d7600c83610390565b91506103e2826103a1565b602082019050919050565b60006020820190508181036000830152610406816103ca565b905091905056fea2646970667358221220296d10b0ee57c8822e4a836385ae2cd16cf00165545a3eac34305871894f143a64736f6c63430008120033") +} + func getUint64Ptr(value hexutil.Uint64) *hexutil.Uint64 { newUint64 := new(hexutil.Uint64) newUint64 = &value From fb7a02603ef2219260fca5329a549d12f32decc9 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 31 Jul 2023 14:23:53 +0300 Subject: [PATCH 13/59] balance checking --- testgen/generators.go | 205 +++++++++++++++++++++++++++++++++++++++++- testgen/utils.go | 13 +++ 2 files changed, 217 insertions(+), 1 deletion(-) diff --git a/testgen/generators.go b/testgen/generators.go index 83f00f0..6fbc2c7 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -432,6 +432,62 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-simple-no-funds-queying", + "simulates a simple multicall transfer when account has no funds with querying balances before and after", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: getBalanceGetter(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + }, + { + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Value: *newRPCBalance(1000), + }, + }, + }}, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, { "multicall-simple-no-funds-with-validation", "simulates a simple multicall transfer when account has no funds with validation", @@ -1694,7 +1750,7 @@ var EthMulticall = MethodTests{ "override storage slots", func(ctx context.Context, t *T) error { stateChanges := make(map[common.Hash]common.Hash) - stateChanges[common.BytesToHash(*hex2Bytes("bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a"))] = common.Hash{0x12} //slot 0 -> 0x12 + stateChanges[common.BytesToHash(*hex2Bytes("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"))] = common.Hash{0x12} //slot 0 -> 0x12 params := multicallOpts{ Blocks: []CallBatch{ { @@ -1800,6 +1856,153 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-move-storage", + "move contract with storage slots being set", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: getStorageTester(), + Balance: newRPCBalance(1000), + }, + common.Address{0xc3}: OverrideAccount{ + Code: getBalanceGetter(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"), // set storage slot 0 -> 1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), // set storage slot 1 -> 2 + }, + }, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + MoveToAddress: &common.Address{0xc2}, + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should return error as there should not be code there anymore + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 2 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc3}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 + }, + }, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-override-move-storage", + "move contract with storage slots being overriden", + func(ctx context.Context, t *T) error { + stateChanges := make(map[common.Hash]common.Hash) + stateChanges[common.BytesToHash(*hex2Bytes("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"))] = common.Hash{0x12} //slot 0 -> 0x12 + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: getStorageTester(), + State: &stateChanges, + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 0 + }, + }, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + MoveToAddress: &common.Address{0xc2}, + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should return error as there should not be code there anymore + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 0 + }, + }, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, }, } diff --git a/testgen/utils.go b/testgen/utils.go index 5a78f77..8779930 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -186,6 +186,19 @@ func getEcRecoverOverride() *hexutil.Bytes { return hex2Bytes("608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc8114610209578063c0069260146102255761003b565b5b60003660606000806000808686810190610055919061047d565b9350935093509350600080600086868686604051602001610079949392919061053b565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101d657600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168a8a6040516101409291906105c8565b6000604051808303816000865af19150503d806000811461017d576040519150601f19603f3d011682016040523d82523d6000602084013e610182565b606091505b5091509150816101c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101be90610664565b60405180910390fd5b809750505050505050506101fe565b806040516020016101e791906106fe565b604051602081830303815290604052955050505050505b915050805190602001f35b610223600480360381019061021e919061092f565b610241565b005b61023f600480360381019061023a9190610978565b610307565b005b60005b8151811015610303576102f0828281518110610263576102626109f3565b5b602002602001015160000151838381518110610282576102816109f3565b5b6020026020010151602001518484815181106102a1576102a06109f3565b5b6020026020010151604001518585815181106102c0576102bf6109f3565b5b6020026020010151606001518686815181106102df576102de6109f3565b5b602002602001015160800151610307565b80806102fb90610a5b565b915050610244565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161036d90610aef565b60405180910390fd5b8060008087878787604051602001610391949392919061053b565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6104218161040e565b811461042c57600080fd5b50565b60008135905061043e81610418565b92915050565b600060ff82169050919050565b61045a81610444565b811461046557600080fd5b50565b60008135905061047781610451565b92915050565b6000806000806080858703121561049757610496610404565b5b60006104a58782880161042f565b94505060206104b687828801610468565b93505060406104c78782880161042f565b92505060606104d88782880161042f565b91505092959194509250565b6000819050919050565b6104ff6104fa8261040e565b6104e4565b82525050565b60008160f81b9050919050565b600061051d82610505565b9050919050565b61053561053082610444565b610512565b82525050565b600061054782876104ee565b6020820191506105578286610524565b60018201915061056782856104ee565b60208201915061057782846104ee565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b60006105af8385610589565b93506105bc838584610594565b82840190509392505050565b60006105d58284866105a3565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f7420616464726573732030783132333435360000000000000000000000000000602082015250565b600061064e6032836105e1565b9150610659826105f2565b604082019050919050565b6000602082019050818103600083015261067d81610641565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106af82610684565b9050919050565b60008160601b9050919050565b60006106ce826106b6565b9050919050565b60006106e0826106c3565b9050919050565b6106f86106f3826106a4565b6106d5565b82525050565b600061070a82846106e7565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6107678261071e565b810181811067ffffffffffffffff821117156107865761078561072f565b5b80604052505050565b60006107996103fa565b90506107a5828261075e565b919050565b600067ffffffffffffffff8211156107c5576107c461072f565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107e9816106a4565b81146107f457600080fd5b50565b600081359050610806816107e0565b92915050565b600060a08284031215610822576108216107db565b5b61082c60a061078f565b9050600061083c8482850161042f565b600083015250602061085084828501610468565b60208301525060406108648482850161042f565b60408301525060606108788482850161042f565b606083015250608061088c848285016107f7565b60808301525092915050565b60006108ab6108a6846107aa565b61078f565b90508083825260208201905060a084028301858111156108ce576108cd6107d6565b5b835b818110156108f757806108e3888261080c565b84526020840193505060a0810190506108d0565b5050509392505050565b600082601f83011261091657610915610719565b5b8135610926848260208601610898565b91505092915050565b60006020828403121561094557610944610404565b5b600082013567ffffffffffffffff81111561096357610962610409565b5b61096f84828501610901565b91505092915050565b600080600080600060a0868803121561099457610993610404565b5b60006109a28882890161042f565b95505060206109b388828901610468565b94505060406109c48882890161042f565b93505060606109d58882890161042f565b92505060806109e6888289016107f7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a6682610a51565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a9857610a97610a22565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ad9601c836105e1565b9150610ae482610aa3565b602082019050919050565b60006020820190508181036000830152610b0881610acc565b905091905056fea26469706673582212202fa837f70cfab8ede041106e92528882f950de3f9900cfcba0f560e8bf8eb85764736f6c63430008120033") } +func getBalanceGetter() *hexutil.Bytes { + /* + pragma solidity ^0.8.18; + + contract BalanceGetter { + function getBalance(address addr) view external returns (uint256) { + return address(addr).balance; + } + } + */ + return hex2Bytes("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033") +} + func getEcRecoverCaller() *hexutil.Bytes { /* contract EcRecoverCaller { From bce514599ca72a693b7431174e00e30a467db210 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 31 Jul 2023 14:39:10 +0300 Subject: [PATCH 14/59] should be lowercase --- testgen/generators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testgen/generators.go b/testgen/generators.go index 6fbc2c7..9878ea9 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -907,7 +907,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("ee82ac5e000000000000000000000000000000000000000000000000000000000000001D"), + Input: hex2Bytes("ee82ac5e000000000000000000000000000000000000000000000000000000000000001d"), }}, }}, } From 690b3885fa8de9fc927b701319ff6266cb632329 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 31 Jul 2023 14:57:38 +0300 Subject: [PATCH 15/59] nonce with moveToAddress --- testgen/generators.go | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index 9878ea9..be80c0e 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1557,6 +1557,81 @@ var EthMulticall = MethodTests{ return err }, }, + { + "multicall-move-to-address-with-nonce", + "move address with nonce", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(5)}, + }, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, + Nonce: getUint64Ptr(0), + }, + { + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + Nonce: getUint64Ptr(5), + }, + }, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-move-to-address-with-nonce", + "Error: MoveToAddress referenced itself in replacement", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(5)}, + }, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Nonce: getUint64Ptr(5), //should fail + }, + }, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, { "multicall-moved-contract-should-be-useable", "when contract is moved, the moved contract should still work", From d928d978df24345719bde76860c8593f6f41a2e8 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 31 Jul 2023 16:10:54 +0300 Subject: [PATCH 16/59] 0x12' are 0x12...'s --- testgen/generators.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index be80c0e..1425b04 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1825,7 +1825,7 @@ var EthMulticall = MethodTests{ "override storage slots", func(ctx context.Context, t *T) error { stateChanges := make(map[common.Hash]common.Hash) - stateChanges[common.BytesToHash(*hex2Bytes("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"))] = common.Hash{0x12} //slot 0 -> 0x12 + stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 params := multicallOpts{ Blocks: []CallBatch{ { @@ -1915,15 +1915,15 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected call result (res[0].Calls[3]) (have: %s, want: %s)", res[0].Calls[3].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") } - if res[1].Calls[0].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000012" { - return fmt.Errorf("unexpected call result (res[1].Calls[0]) (have: %s, want: %s)", res[0].Calls[3].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000012") + if res[1].Calls[0].ReturnValue.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { + return fmt.Errorf("unexpected call result (res[1].Calls[0]) (have: %s, want: %s)", res[0].Calls[3].ReturnValue.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") } if res[1].Calls[1].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { return fmt.Errorf("unexpected call result (res[1].Calls[1]) (have: %s, want: %s)", res[0].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") } - if res[2].Calls[0].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000012" { - return fmt.Errorf("unexpected call result (res[2].Calls[0]) (have: %s, want: %s)", res[2].Calls[0].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000012") + if res[2].Calls[0].ReturnValue.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { + return fmt.Errorf("unexpected call result (res[2].Calls[0]) (have: %s, want: %s)", res[2].Calls[0].ReturnValue.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") } if res[2].Calls[1].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000000" { return fmt.Errorf("unexpected call result (res[2].Calls[1]) (have: %s, want: %s)", res[2].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000000") @@ -2015,7 +2015,7 @@ var EthMulticall = MethodTests{ "move contract with storage slots being overriden", func(ctx context.Context, t *T) error { stateChanges := make(map[common.Hash]common.Hash) - stateChanges[common.BytesToHash(*hex2Bytes("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"))] = common.Hash{0x12} //slot 0 -> 0x12 + stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 params := multicallOpts{ Blocks: []CallBatch{ { @@ -2051,7 +2051,7 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should return error as there should not be code there anymore + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should'nt return anything }, { From: &common.Address{0xc0}, From 1a322dbbb7504f7b2ac205082c690cca01706374 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 1 Aug 2023 13:51:24 +0300 Subject: [PATCH 17/59] fix couple tests and add another simpler ecrecover test --- testgen/generators.go | 78 +++++++++++++++++++++++++++++++++++-------- testgen/utils.go | 9 +++-- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 1425b04..d256826 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1716,6 +1716,59 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-move-ecrecover-and_call", + "move ecrecover and try calling it", + func(ctx context.Context, t *T) error { + ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) + ecRecoverMovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) + params := multicallOpts{ + Blocks: []CallBatch{{ + Calls: []TransactionArgs{ // just call ecrecover normally + { // call with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + }, + }, { + StateOverrides: &StateOverride{ // move ecRecover and call it in new address + ecRecoverAddress: OverrideAccount{ + MoveToAddress: &ecRecoverMovedToAddress, + }, + }, + Calls: []TransactionArgs{ + { // call with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + if len(res[0].Calls) != len(params.Blocks[0].Calls) { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.Blocks[0].Calls)) + } + return nil + }, + }, { "multicall-override-ecrecover", "override ecrecover", @@ -1730,18 +1783,17 @@ var EthMulticall = MethodTests{ MoveToAddress: &ecRecoverMovedToAddress, }, common.Address{0xc1}: OverrideAccount{Balance: newRPCBalance(200000)}, - common.Address{0xc2}: OverrideAccount{Code: getEcRecoverCaller()}, }, Calls: []TransactionArgs{ { // call with invalid params, should fail (resolve to 0x0) From: &common.Address{0xc1}, - To: &common.Address{0xc2}, - Input: hex2Bytes("265dc68c4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), }, { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a From: &common.Address{0xc1}, - To: &common.Address{0xc2}, - Input: hex2Bytes("265dc68c1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), }, { // add override From: &common.Address{0xc1}, @@ -1750,18 +1802,18 @@ var EthMulticall = MethodTests{ }, { // now it should resolve to 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 From: &common.Address{0xc1}, - To: &common.Address{0xc2}, - Input: hex2Bytes("265dc68c4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + To: &ecRecoverAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), }, { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a From: &common.Address{0xc1}, - To: &common.Address{0xc2}, - Input: hex2Bytes("265dc68c1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + To: &ecRecoverAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), }, { // call with new invalid params, should fail (resolve to 0x0) From: &common.Address{0xc1}, - To: &common.Address{0xc2}, - Input: hex2Bytes("265dc68c4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000"), + To: &ecRecoverAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000"), }, }, }}, @@ -1916,10 +1968,10 @@ var EthMulticall = MethodTests{ } if res[1].Calls[0].ReturnValue.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { - return fmt.Errorf("unexpected call result (res[1].Calls[0]) (have: %s, want: %s)", res[0].Calls[3].ReturnValue.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") + return fmt.Errorf("unexpected call result (res[1].Calls[0]) (have: %s, want: %s)", res[1].Calls[0].ReturnValue.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") } if res[1].Calls[1].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { - return fmt.Errorf("unexpected call result (res[1].Calls[1]) (have: %s, want: %s)", res[0].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") + return fmt.Errorf("unexpected call result (res[1].Calls[1]) (have: %s, want: %s)", res[1].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") } if res[2].Calls[0].ReturnValue.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { diff --git a/testgen/utils.go b/testgen/utils.go index 8779930..4b233f5 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -157,7 +157,6 @@ func getEcRecoverOverride() *hexutil.Bytes { address returnAddress; } mapping(bytes32 => address) overrideToAddress; - address movedEcRecoverAddress = address(0x123456); function setOverride(bytes32 hash, uint8 v, bytes32 r, bytes32 s, address returnAddress) public { require(returnAddress != address(0x0), 'return address cannot be 0x0'); @@ -169,13 +168,12 @@ func getEcRecoverOverride() *hexutil.Bytes { setOverride(overrides[i].hash, overrides[i].v, overrides[i].r, overrides[i].s, overrides[i].returnAddress); } } - fallback (bytes calldata input) external returns (bytes memory) { (bytes32 hash, uint8 v, bytes32 r, bytes32 s) = abi.decode(input, (bytes32, uint8, bytes32, bytes32)); address overridedAddress = overrideToAddress[keccak256(abi.encodePacked(hash, v, r, s))]; if (overridedAddress == address(0x0)) { - (bool success, bytes memory data) = movedEcRecoverAddress.call(input); - require(success, 'failed to call moved ecrecover at address 0x123456'); + (bool success, bytes memory data) = address(0x0000000000000000000000000000000000123456).call{gas: 10000}(input); + require(success, 'failed to call moved ecrecover at address 0x0000000000000000000000000000000000123456'); return data; } else { return abi.encodePacked(overridedAddress); @@ -183,7 +181,8 @@ func getEcRecoverOverride() *hexutil.Bytes { } } */ - return hex2Bytes("608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc8114610209578063c0069260146102255761003b565b5b60003660606000806000808686810190610055919061047d565b9350935093509350600080600086868686604051602001610079949392919061053b565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101d657600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168a8a6040516101409291906105c8565b6000604051808303816000865af19150503d806000811461017d576040519150601f19603f3d011682016040523d82523d6000602084013e610182565b606091505b5091509150816101c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101be90610664565b60405180910390fd5b809750505050505050506101fe565b806040516020016101e791906106fe565b604051602081830303815290604052955050505050505b915050805190602001f35b610223600480360381019061021e919061092f565b610241565b005b61023f600480360381019061023a9190610978565b610307565b005b60005b8151811015610303576102f0828281518110610263576102626109f3565b5b602002602001015160000151838381518110610282576102816109f3565b5b6020026020010151602001518484815181106102a1576102a06109f3565b5b6020026020010151604001518585815181106102c0576102bf6109f3565b5b6020026020010151606001518686815181106102df576102de6109f3565b5b602002602001015160800151610307565b80806102fb90610a5b565b915050610244565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161036d90610aef565b60405180910390fd5b8060008087878787604051602001610391949392919061053b565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6104218161040e565b811461042c57600080fd5b50565b60008135905061043e81610418565b92915050565b600060ff82169050919050565b61045a81610444565b811461046557600080fd5b50565b60008135905061047781610451565b92915050565b6000806000806080858703121561049757610496610404565b5b60006104a58782880161042f565b94505060206104b687828801610468565b93505060406104c78782880161042f565b92505060606104d88782880161042f565b91505092959194509250565b6000819050919050565b6104ff6104fa8261040e565b6104e4565b82525050565b60008160f81b9050919050565b600061051d82610505565b9050919050565b61053561053082610444565b610512565b82525050565b600061054782876104ee565b6020820191506105578286610524565b60018201915061056782856104ee565b60208201915061057782846104ee565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b60006105af8385610589565b93506105bc838584610594565b82840190509392505050565b60006105d58284866105a3565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f7420616464726573732030783132333435360000000000000000000000000000602082015250565b600061064e6032836105e1565b9150610659826105f2565b604082019050919050565b6000602082019050818103600083015261067d81610641565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106af82610684565b9050919050565b60008160601b9050919050565b60006106ce826106b6565b9050919050565b60006106e0826106c3565b9050919050565b6106f86106f3826106a4565b6106d5565b82525050565b600061070a82846106e7565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6107678261071e565b810181811067ffffffffffffffff821117156107865761078561072f565b5b80604052505050565b60006107996103fa565b90506107a5828261075e565b919050565b600067ffffffffffffffff8211156107c5576107c461072f565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107e9816106a4565b81146107f457600080fd5b50565b600081359050610806816107e0565b92915050565b600060a08284031215610822576108216107db565b5b61082c60a061078f565b9050600061083c8482850161042f565b600083015250602061085084828501610468565b60208301525060406108648482850161042f565b60408301525060606108788482850161042f565b606083015250608061088c848285016107f7565b60808301525092915050565b60006108ab6108a6846107aa565b61078f565b90508083825260208201905060a084028301858111156108ce576108cd6107d6565b5b835b818110156108f757806108e3888261080c565b84526020840193505060a0810190506108d0565b5050509392505050565b600082601f83011261091657610915610719565b5b8135610926848260208601610898565b91505092915050565b60006020828403121561094557610944610404565b5b600082013567ffffffffffffffff81111561096357610962610409565b5b61096f84828501610901565b91505092915050565b600080600080600060a0868803121561099457610993610404565b5b60006109a28882890161042f565b95505060206109b388828901610468565b94505060406109c48882890161042f565b93505060606109d58882890161042f565b92505060806109e6888289016107f7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a6682610a51565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a9857610a97610a22565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ad9601c836105e1565b9150610ae482610aa3565b602082019050919050565b60006020820190508181036000830152610b0881610acc565b905091905056fea26469706673582212202fa837f70cfab8ede041106e92528882f950de3f9900cfcba0f560e8bf8eb85764736f6c63430008120033") + return hex2Bytes("608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033") + } func getBalanceGetter() *hexutil.Bytes { From 9550ffa9baaa2627bf8b1b3b2a1fd0bc77bc7d43 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 1 Aug 2023 20:51:07 +0300 Subject: [PATCH 18/59] add block properties test --- testgen/generators.go | 365 +++++++++++++++++++++++++++++++++++++++++- testgen/utils.go | 38 +++-- 2 files changed, 384 insertions(+), 19 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index d256826..b466398 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -433,7 +433,7 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-simple-no-funds-queying", + "multicall-simple-no-funds-with-balance-querying", "simulates a simple multicall transfer when account has no funds with querying balances before and after", func(ctx context.Context, t *T) error { params := multicallOpts{ @@ -470,10 +470,20 @@ var EthMulticall = MethodTests{ Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 }, { - From: &common.Address{0xc1}, - To: &common.Address{0xc2}, + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, Value: *newRPCBalance(1000), }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + }, }, }}, Validation: false, @@ -488,6 +498,68 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-check-that-balance-is-there-after-new-block", + "checks that balances are kept to next block", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(10000), + }, + common.Address{0xc2}: OverrideAccount{ + Code: getBalanceGetter(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }, + }, + }, { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }, + }, + }}, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, { "multicall-simple-no-funds-with-validation", "simulates a simple multicall transfer when account has no funds with validation", @@ -1183,6 +1255,18 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-empty-multicall", + "multicall without parameters", + func(ctx context.Context, t *T) error { + params := multicallOpts{} + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, { "multicall-override-address-twice-in-separate-blocks", "override address twice in separate blocks", @@ -1533,8 +1617,68 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-multiple-account-overrides", - "override an account multiple times", + "multicall-move-account-twice", + "Move one account twice", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(1000), + }, + common.Address{0xc2}: OverrideAccount{ + Balance: newRPCBalance(2000), + }, + common.Address{0xc3}: OverrideAccount{ + Balance: newRPCBalance(3000), + }, + common.Address{0xc4}: OverrideAccount{ + Code: getBalanceGetter(), + }, + }, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(3000), + MoveToAddress: &common.Address{0xc2}, + }, + common.Address{0xc2}: OverrideAccount{ + Balance: newRPCBalance(4000), + MoveToAddress: &common.Address{0xc3}, + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc4}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc4}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc4}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c300000000000000000000000000000000000000"), // gets balance of c3 + }, + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-move-to-accounts-to-same", + "Move two accounts to the same destination", func(ctx context.Context, t *T) error { params := multicallOpts{ Blocks: []CallBatch{{ @@ -1599,7 +1743,7 @@ var EthMulticall = MethodTests{ }, { "multicall-move-to-address-with-nonce", - "Error: MoveToAddress referenced itself in replacement", + "check that nonce is moved with address", func(ctx context.Context, t *T) error { params := multicallOpts{ Blocks: []CallBatch{ @@ -1717,7 +1861,7 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-move-ecrecover-and_call", + "multicall-move-ecrecover-and-call", "move ecrecover and try calling it", func(ctx context.Context, t *T) error { ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) @@ -1863,6 +2007,18 @@ var EthMulticall = MethodTests{ MoveToAddress: &sha256MovedToAddress, }, }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &sha256MovedToAddress, + Input: hex2Bytes("1234"), + }, + { + From: &common.Address{0xc0}, + To: &sha256Address, + Input: hex2Bytes("1234"), + }, + }, }}, } res := make([]blockResult, 0) @@ -1872,6 +2028,124 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-simple-state-diff", + "override one state variable with statediff", + func(ctx context.Context, t *T) error { + stateChanges := make(map[common.Hash]common.Hash) + stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: getStorageTester(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"), // set storage slot 0 -> 1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), // set storage slot 1 -> 2 + }, + }, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + StateDiff: &stateChanges, // state diff override + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 as overrided + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 2 + }, + }, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-simple-state-diff", + "override one state variable with state", + func(ctx context.Context, t *T) error { + stateChanges := make(map[common.Hash]common.Hash) + stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: getStorageTester(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"), // set storage slot 0 -> 1 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), // set storage slot 1 -> 2 + }, + }, + }, + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + State: &stateChanges, // state diff override + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 as overrided + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 0 + }, + }, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, { "multicall-override-storage-slots", "override storage slots", @@ -2130,6 +2404,83 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-block-override-reflected-in-contract", + "Checks that block overrides are true in contract", + func(ctx context.Context, t *T) error { + prevRandDao1 := common.BytesToHash(*hex2Bytes("123")) + prevRandDao2 := common.BytesToHash(*hex2Bytes("1234")) + prevRandDao3 := common.BytesToHash(*hex2Bytes("12345")) + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + Time: getUint64Ptr(10), + GasLimit: getUint64Ptr(10), + FeeRecipient: &common.Address{0xc0}, + PrevRandao: &prevRandDao1, + BaseFee: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(20)), + Time: getUint64Ptr(20), + GasLimit: getUint64Ptr(20), + FeeRecipient: &common.Address{0xc1}, + PrevRandao: &prevRandDao2, + BaseFee: (*hexutil.Big)(big.NewInt(20)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(21)), + Time: getUint64Ptr(21), + GasLimit: getUint64Ptr(21), + FeeRecipient: &common.Address{0xc2}, + PrevRandao: &prevRandDao3, + BaseFee: (*hexutil.Big)(big.NewInt(30)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + }, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, }, } diff --git a/testgen/utils.go b/testgen/utils.go index 4b233f5..795b0ae 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -216,29 +216,43 @@ func getStorageTester() *hexutil.Bytes { contract StorageTester { uint256 public value0; uint256 public value1; - uint256 public value2; - uint256 public value3; - uint256 public value4; function setValue(uint256 slot, uint256 value) external { - require(slot < 5, "too big slot"); + require(slot < 2, "too big slot"); if (slot == 0) { value0 = value; return; } if (slot == 1) { value1 = value; return; } - if (slot == 2) { value2 = value; return; } - if (slot == 3) { value3 = value; return; } - if (slot == 4) { value4 = value; return; } } function getValue(uint256 slot) view external returns (uint256 returnValue) { - require(slot < 5, "too big slot"); + require(slot < 2, "too big slot"); if (slot == 0) { returnValue = value0; } if (slot == 1) { returnValue = value1; } - if (slot == 2) { returnValue = value2; } - if (slot == 3) { returnValue = value3; } - if (slot == 4) { returnValue = value4; } } } */ - return hex2Bytes("608060405234801561001057600080fd5b506004361061007d5760003560e01c8063517f5fa71161005b578063517f5fa7146100ee5780635d33a27f1461010c5780637b8d56e31461012a578063aef52a2c146101465761007d565b80630ff4c916146100825780633033413b146100b257806344e12f87146100d0575b600080fd5b61009c600480360381019061009791906102f9565b610164565b6040516100a99190610335565b60405180910390f35b6100ba6101f4565b6040516100c79190610335565b60405180910390f35b6100d86101fa565b6040516100e59190610335565b60405180910390f35b6100f6610200565b6040516101039190610335565b60405180910390f35b610114610206565b6040516101219190610335565b60405180910390f35b610144600480360381019061013f9190610350565b61020c565b005b61014e6102b8565b60405161015b9190610335565b60405180910390f35b6000600582106101a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a0906103ed565b60405180910390fd5b600082036101b75760005490505b600182036101c55760015490505b600282036101d35760025490505b600382036101e15760035490505b600482036101ef5760045490505b919050565b60015481565b60005481565b60045481565b60025481565b6005821061024f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610246906103ed565b60405180910390fd5b6000820361026357806000819055506102b4565b6001820361027757806001819055506102b4565b6002820361028b57806002819055506102b4565b6003820361029f57806003819055506102b4565b600482036102b357806004819055506102b4565b5b5050565b60035481565b600080fd5b6000819050919050565b6102d6816102c3565b81146102e157600080fd5b50565b6000813590506102f3816102cd565b92915050565b60006020828403121561030f5761030e6102be565b5b600061031d848285016102e4565b91505092915050565b61032f816102c3565b82525050565b600060208201905061034a6000830184610326565b92915050565b60008060408385031215610367576103666102be565b5b6000610375858286016102e4565b9250506020610386858286016102e4565b9150509250929050565b600082825260208201905092915050565b7f746f6f2062696720736c6f740000000000000000000000000000000000000000600082015250565b60006103d7600c83610390565b91506103e2826103a1565b602082019050919050565b60006020820190508181036000830152610406816103ca565b905091905056fea2646970667358221220296d10b0ee57c8822e4a836385ae2cd16cf00165545a3eac34305871894f143a64736f6c63430008120033") + return hex2Bytes("608060405234801561001057600080fd5b506004361061004c5760003560e01c80630ff4c916146100515780633033413b1461008157806344e12f871461009f5780637b8d56e3146100bd575b600080fd5b61006b600480360381019061006691906101f6565b6100d9565b6040516100789190610232565b60405180910390f35b61008961013f565b6040516100969190610232565b60405180910390f35b6100a7610145565b6040516100b49190610232565b60405180910390f35b6100d760048036038101906100d2919061024d565b61014b565b005b60006002821061011e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610115906102ea565b60405180910390fd5b6000820361012c5760005490505b6001820361013a5760015490505b919050565b60015481565b60005481565b6002821061018e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610185906102ea565b60405180910390fd5b600082036101a257806000819055506101b7565b600182036101b657806001819055506101b7565b5b5050565b600080fd5b6000819050919050565b6101d3816101c0565b81146101de57600080fd5b50565b6000813590506101f0816101ca565b92915050565b60006020828403121561020c5761020b6101bb565b5b600061021a848285016101e1565b91505092915050565b61022c816101c0565b82525050565b60006020820190506102476000830184610223565b92915050565b60008060408385031215610264576102636101bb565b5b6000610272858286016101e1565b9250506020610283858286016101e1565b9150509250929050565b600082825260208201905092915050565b7f746f6f2062696720736c6f740000000000000000000000000000000000000000600082015250565b60006102d4600c8361028d565b91506102df8261029e565b602082019050919050565b60006020820190508181036000830152610303816102c7565b905091905056fea2646970667358221220ceea194bb66b5b9f52c83e5bf5a1989255de8cb7157838eff98f970c3a04cb3064736f6c63430008120033") +} + +func getBlockProperties() *hexutil.Bytes { + /* + pragma solidity ^0.8.18; + contract blockProperties { + fallback (bytes calldata input) external returns (bytes memory) { + return abi.encode( + block.basefee, + block.chainid, + block.coinbase, + block.difficulty, + block.gaslimit, + block.number, + block.timestamp, + gasleft(), + tx.gasprice, + blockhash(block.number - 1) + ); + } + } + */ + return hex2Bytes("608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033") } func getUint64Ptr(value hexutil.Uint64) *hexutil.Uint64 { From 9a4e92e90d7af619324ab0f7e56f80cf897b988b Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 1 Aug 2023 21:14:25 +0300 Subject: [PATCH 19/59] fee recipient test --- testgen/generators.go | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index b466398..c0dc9e3 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2481,6 +2481,60 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-fee-recipient-receiving-funds", + "Check that fee recipient gets funds", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: getBalanceGetter(), + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + FeeRecipient: &common.Address{0xc2}, + BaseFee: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + MaxFeePerGas: (*hexutil.Big)(big.NewInt(10)), + MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(10)), + Input: hex2Bytes(""), + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 + }, + }, + }, + }, + Validation: true, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, }, } From 0fee7dd420f82397f8af58a8578df9a91b04a5f9 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 1 Aug 2023 21:37:16 +0300 Subject: [PATCH 20/59] nonce and block tests --- testgen/generators.go | 158 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index c0dc9e3..c0cf267 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1741,6 +1741,90 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-check-that-nonce-increases", + "check that nonce increases", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(20000)}, + }, + }, { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, + Nonce: getUint64Ptr(0), + }, + { + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + Nonce: getUint64Ptr(1), + }, + { + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + Nonce: getUint64Ptr(2), + }, + }, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, + { + "multicall-check-invalid-nonce", + "check that nonce cannot decrease", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(20000)}, + }, + }, { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, + Nonce: getUint64Ptr(0), + }, + { + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + Nonce: getUint64Ptr(1), + }, + { + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + Nonce: getUint64Ptr(0), + }, + }, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, { "multicall-move-to-address-with-nonce", "check that nonce is moved with address", @@ -2481,6 +2565,80 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-add-more-non-defined-blocks-than-fit", + "Add more blocks between two blocks than it actually fits there", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + Blocks: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(11)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + }, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.Blocks) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + } + return nil + }, + }, { "multicall-fee-recipient-receiving-funds", "Check that fee recipient gets funds", From 91d33c947e0d87a5e3b491ed0121e0123c8f15af Mon Sep 17 00:00:00 2001 From: KillariDev Date: Thu, 3 Aug 2023 17:12:30 +0300 Subject: [PATCH 21/59] use BlockStateCalls --- testgen/generators.go | 290 +++++++++++++++++++++--------------------- 1 file changed, 145 insertions(+), 145 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index c0cf267..31c5e2b 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -375,7 +375,7 @@ var EthMulticall = MethodTests{ "simulates a multicall transfer", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(1000)}, @@ -396,8 +396,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -407,7 +407,7 @@ var EthMulticall = MethodTests{ "simulates a simple multicall transfer when account has no funds", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { Calls: []TransactionArgs{{ From: &common.Address{0xc0}, @@ -426,8 +426,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -437,7 +437,7 @@ var EthMulticall = MethodTests{ "simulates a simple multicall transfer when account has no funds with querying balances before and after", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc2}: OverrideAccount{ Code: getBalanceGetter(), @@ -492,8 +492,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -503,7 +503,7 @@ var EthMulticall = MethodTests{ "checks that balances are kept to next block", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ Balance: newRPCBalance(10000), @@ -554,8 +554,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -565,7 +565,7 @@ var EthMulticall = MethodTests{ "simulates a simple multicall transfer when account has no funds with validation", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { Calls: []TransactionArgs{{ From: &common.Address{0xc0}, @@ -584,8 +584,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -595,7 +595,7 @@ var EthMulticall = MethodTests{ "Sending eth from contract", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(1000), Code: getEthForwarder()}, }, @@ -612,8 +612,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -623,7 +623,7 @@ var EthMulticall = MethodTests{ "Sending eth from contract without balance", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Code: getEthForwarder()}, }, @@ -640,8 +640,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -651,7 +651,7 @@ var EthMulticall = MethodTests{ "Sending eth from contract with validation enabled", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(1000), Code: getEthForwarder()}, }, @@ -668,18 +668,18 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, }, { - "multicall-transfer-over-blocks", - "simulates a transfering value over multiple blocks", + "multicall-transfer-over-BlockStateCalls", + "simulates a transfering value over multiple BlockStateCalls", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, }, @@ -715,8 +715,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -726,7 +726,7 @@ var EthMulticall = MethodTests{ "simulates calls overriding the block num", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(11)), }, @@ -758,8 +758,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -769,7 +769,7 @@ var EthMulticall = MethodTests{ "simulates calls with invalid block num order", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(12)), }, @@ -799,8 +799,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -810,7 +810,7 @@ var EthMulticall = MethodTests{ "Error: simulates calls with invalid timestamp num order", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { BlockOverrides: &BlockOverrides{ Time: getUint64Ptr(12), @@ -824,8 +824,8 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if err := checkError(err, -38021); err != nil { return err @@ -838,7 +838,7 @@ var EthMulticall = MethodTests{ "simulates calls setting and reading from storage contract", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc2}: OverrideAccount{ Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"), @@ -862,8 +862,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -873,7 +873,7 @@ var EthMulticall = MethodTests{ "simulates calls with logs", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc2}: OverrideAccount{ // Yul Code: @@ -898,8 +898,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -909,7 +909,7 @@ var EthMulticall = MethodTests{ "gets blockhash of previous block (included in original chain)", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc2}: OverrideAccount{ Code: blockHashCallerByteCode(), @@ -926,8 +926,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if err := checkBlockNumber(res[0].Number, 3); err != nil { return err @@ -946,7 +946,7 @@ var EthMulticall = MethodTests{ "gets blockhash of simulated block", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ Balance: newRPCBalance(2000000), @@ -987,8 +987,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } for i := 0; i < len(res); i++ { @@ -1013,7 +1013,7 @@ var EthMulticall = MethodTests{ if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), t.chain.GetHeaderByNumber(1).Hash()); err != nil { return err } - // should equal first generated blocks hash + // should equal first generated BlockStateCalls hash if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), res[0].Hash); err != nil { return err } @@ -1029,7 +1029,7 @@ var EthMulticall = MethodTests{ "gets blockhash of simulated block", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ Balance: newRPCBalance(2000000), @@ -1061,8 +1061,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } for i := 0; i < len(res); i++ { @@ -1097,7 +1097,7 @@ var EthMulticall = MethodTests{ "when selfdestructing a state override, the state override should go away", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ Balance: newRPCBalance(2000000), @@ -1145,8 +1145,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } noCode := "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000" if res[1].Calls[0].ReturnValue.String() == noCode { @@ -1166,7 +1166,7 @@ var EthMulticall = MethodTests{ "we should get out of gas error if a block consumes too much gas", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ Balance: newRPCBalance(2000000), @@ -1205,7 +1205,7 @@ var EthMulticall = MethodTests{ "when sending eth we should get ETH logs when traceTransfers is set", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, }, @@ -1221,8 +1221,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if len(res[0].Calls[0].Logs) != 1 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 1) @@ -1235,7 +1235,7 @@ var EthMulticall = MethodTests{ "override address twice", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, common.Address{0xc0}: OverrideAccount{Code: getRevertingContract()}, @@ -1268,11 +1268,11 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-override-address-twice-in-separate-blocks", - "override address twice in separate blocks", + "multicall-override-address-twice-in-separate-BlockStateCalls", + "override address twice in separate BlockStateCalls", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, @@ -1308,7 +1308,7 @@ var EthMulticall = MethodTests{ "we should not be producing eth logs if the transaction reverts and ETH is not sent", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, common.Address{0xc1}: OverrideAccount{Code: getRevertingContract()}, @@ -1325,8 +1325,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if len(res[0].Calls[0].Logs) != 0 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 0) @@ -1339,7 +1339,7 @@ var EthMulticall = MethodTests{ "we should be getting more logs if eth is forwarded", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, common.Address{0xc1}: OverrideAccount{Code: getEthForwarder()}, @@ -1357,8 +1357,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if len(res[0].Calls[0].Logs) != 2 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 2) @@ -1371,7 +1371,7 @@ var EthMulticall = MethodTests{ "we should be getting no logs if eth is forwarded but then the tx reverts", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, common.Address{0xc1}: OverrideAccount{Code: getEthForwarder()}, @@ -1390,8 +1390,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if len(res[0].Calls[0].Logs) != 0 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 0) @@ -1404,7 +1404,7 @@ var EthMulticall = MethodTests{ "when sending eth we should not get ETH logs by default", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, }, @@ -1419,8 +1419,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if len(res[0].Calls[0].Logs) != 0 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 0) @@ -1433,7 +1433,7 @@ var EthMulticall = MethodTests{ "Error: Nonce too low", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(10)}, }, @@ -1460,7 +1460,7 @@ var EthMulticall = MethodTests{ "Error: Nonce too high", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ Calls: []TransactionArgs{{ Nonce: getUint64Ptr(100), From: &common.Address{0xc1}, @@ -1473,8 +1473,8 @@ var EthMulticall = MethodTests{ if err := checkError(err, -38011); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { return err @@ -1487,7 +1487,7 @@ var EthMulticall = MethodTests{ "Error: BaseFee too low with validation", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, }, @@ -1519,7 +1519,7 @@ var EthMulticall = MethodTests{ "Error: BaseFee too low with no validation", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, }, @@ -1551,7 +1551,7 @@ var EthMulticall = MethodTests{ "Error: Not enough gas provided to pay for intrinsic gas", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ Calls: []TransactionArgs{{ From: &common.Address{0xc1}, To: &common.Address{0xc1}, @@ -1575,7 +1575,7 @@ var EthMulticall = MethodTests{ "Error: Insufficient funds to pay for gas fees and value", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, @@ -1596,7 +1596,7 @@ var EthMulticall = MethodTests{ "Error: MoveToAddress referenced itself in replacement", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(200000)}, common.Address{0xc1}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, @@ -1621,7 +1621,7 @@ var EthMulticall = MethodTests{ "Move one account twice", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ Balance: newRPCBalance(1000), @@ -1670,8 +1670,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -1681,7 +1681,7 @@ var EthMulticall = MethodTests{ "Move two accounts to the same destination", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ Balance: newRPCBalance(2000), @@ -1706,7 +1706,7 @@ var EthMulticall = MethodTests{ "move address with nonce", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(5)}, @@ -1735,8 +1735,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -1746,7 +1746,7 @@ var EthMulticall = MethodTests{ "check that nonce increases", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(20000)}, @@ -1777,8 +1777,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -1788,7 +1788,7 @@ var EthMulticall = MethodTests{ "check that nonce cannot decrease", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(20000)}, @@ -1819,8 +1819,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -1830,7 +1830,7 @@ var EthMulticall = MethodTests{ "check that nonce is moved with address", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(5)}, @@ -1854,8 +1854,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -1865,7 +1865,7 @@ var EthMulticall = MethodTests{ "when contract is moved, the moved contract should still work", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, @@ -1890,8 +1890,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if len(res[1].Calls[0].Logs) != 2 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[1].Calls[0].Logs), 2) @@ -1900,12 +1900,12 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-override-all-in-blocks", + "multicall-override-all-in-BlockStateCalls", "override all values in block and see that they are set in return value", func(ctx context.Context, t *T) error { feeRecipient := common.Address{0xc2} params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(1001)), Time: getUint64Ptr(1003), @@ -1920,8 +1920,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if res[0].Number != 1001 { return fmt.Errorf("unexpected Number (have: %d, want: %d)", res[0].Number, 1001) @@ -1951,7 +1951,7 @@ var EthMulticall = MethodTests{ ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) ecRecoverMovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ Calls: []TransactionArgs{ // just call ecrecover normally { // call with invalid params, should fail (resolve to 0x0) From: &common.Address{0xc1}, @@ -1988,11 +1988,11 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if len(res[0].Calls) != len(params.Blocks[0].Calls) { - return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.Blocks[0].Calls)) + if len(res[0].Calls) != len(params.BlockStateCalls[0].Calls) { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.BlockStateCalls[0].Calls)) } return nil }, @@ -2004,7 +2004,7 @@ var EthMulticall = MethodTests{ ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) ecRecoverMovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ ecRecoverAddress: OverrideAccount{ Code: getEcRecoverOverride(), @@ -2050,11 +2050,11 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if len(res[0].Calls) != len(params.Blocks[0].Calls) { - return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.Blocks[0].Calls)) + if len(res[0].Calls) != len(params.BlockStateCalls[0].Calls) { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.BlockStateCalls[0].Calls)) } zeroAddr := common.Address{0x0} if common.BytesToAddress(res[0].Calls[0].ReturnValue) != zeroAddr { @@ -2084,7 +2084,7 @@ var EthMulticall = MethodTests{ sha256Address := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000002")) sha256MovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) params := multicallOpts{ - Blocks: []CallBatch{{ + BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ sha256Address: OverrideAccount{ Code: hex2Bytes(""), @@ -2119,7 +2119,7 @@ var EthMulticall = MethodTests{ stateChanges := make(map[common.Hash]common.Hash) stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ @@ -2178,7 +2178,7 @@ var EthMulticall = MethodTests{ stateChanges := make(map[common.Hash]common.Hash) stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ @@ -2237,7 +2237,7 @@ var EthMulticall = MethodTests{ stateChanges := make(map[common.Hash]common.Hash) stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ @@ -2315,8 +2315,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } if res[0].Calls[2].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000001" { return fmt.Errorf("unexpected call result (res[0].Calls[2]) (have: %s, want: %s)", res[0].Calls[2].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000001") @@ -2346,7 +2346,7 @@ var EthMulticall = MethodTests{ "move contract with storage slots being set", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ @@ -2414,8 +2414,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -2427,7 +2427,7 @@ var EthMulticall = MethodTests{ stateChanges := make(map[common.Hash]common.Hash) stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ @@ -2482,8 +2482,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -2496,7 +2496,7 @@ var EthMulticall = MethodTests{ prevRandDao2 := common.BytesToHash(*hex2Bytes("1234")) prevRandDao3 := common.BytesToHash(*hex2Bytes("12345")) params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc1}: OverrideAccount{ @@ -2559,18 +2559,18 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, }, { - "multicall-add-more-non-defined-blocks-than-fit", - "Add more blocks between two blocks than it actually fits there", + "multicall-add-more-non-defined-BlockStateCalls-than-fit", + "Add more BlockStateCalls between two BlockStateCalls than it actually fits there", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc1}: OverrideAccount{ @@ -2633,8 +2633,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -2644,7 +2644,7 @@ var EthMulticall = MethodTests{ "Check that fee recipient gets funds", func(ctx context.Context, t *T) error { params := multicallOpts{ - Blocks: []CallBatch{ + BlockStateCalls: []CallBatch{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ @@ -2687,8 +2687,8 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.Blocks) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.Blocks)) + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } return nil }, @@ -3384,9 +3384,9 @@ type StateOverride map[common.Address]OverrideAccount // multicallOpts is the wrapper for multicall parameters. type multicallOpts struct { - Blocks []CallBatch `json:"blocks,omitempty"` - TraceTransfers bool `json:"traceTransfers,omitempty"` - Validation bool `json:"validation,omitempty"` + BlockStateCalls []CallBatch `json:"blockStateCalls,omitempty"` + TraceTransfers bool `json:"traceTransfers,omitempty"` + Validation bool `json:"validation,omitempty"` } // CallBatch is a batch of calls to be simulated sequentially. From ba6651499dce40c70e54c8b3b3f8fdc1a6fdc8aa Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 7 Aug 2023 16:31:05 +0300 Subject: [PATCH 22/59] add some timestamp and blocknumber tests --- testgen/generators.go | 112 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 2 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 31c5e2b..323fb58 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -807,7 +807,7 @@ var EthMulticall = MethodTests{ }, { "multicall-block-timestamp-order", - "Error: simulates calls with invalid timestamp num order", + "Error: simulates calls with invalid timestamp order", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{ @@ -833,6 +833,67 @@ var EthMulticall = MethodTests{ return err }, }, + { + "multicall-block-timestamp-non-incement", + "Error: simulates calls with timestamp staying the same", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(12), + }, + }, { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(12), + }, + }, + }, + } + res := make([]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, + { + "multicall-block-timestamp-non-incement", + "Error: simulates calls with timestamp incrementing over another", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(11), + }, + }, + { + BlockOverrides: &BlockOverrides{}, + }, + { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(12), + }, + }, + { + BlockOverrides: &BlockOverrides{}, + }, + }, + } + res := make([]interface{}, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, { "multicall-set-read-storage", "simulates calls setting and reading from storage contract", @@ -2598,6 +2659,44 @@ var EthMulticall = MethodTests{ }, }, { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(11)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + }, + }, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, + { + "multicall-add-more-non-defined-BlockStateCalls-than-fit", + "Not all block numbers are defined", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + }, Calls: []TransactionArgs{ { From: &common.Address{0xc0}, @@ -2617,8 +2716,17 @@ var EthMulticall = MethodTests{ }, { BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(11)), + Number: (*hexutil.Big)(big.NewInt(20)), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, }, + }, + { Calls: []TransactionArgs{ { From: &common.Address{0xc0}, From c78b37850b1cd6a9116a7cc83fc40dbe61dccf90 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 4 Sep 2023 14:38:31 +0300 Subject: [PATCH 23/59] add tests --- testgen/generators.go | 222 +++++++++++++++++++++++++++++++----------- 1 file changed, 163 insertions(+), 59 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 323fb58..e0163cc 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -765,8 +765,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-block-num-order", - "simulates calls with invalid block num order", + "multicall-block-num-order-38020", + "simulates calls with invalid block num order (-38020)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -806,8 +806,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-block-timestamp-order", - "Error: simulates calls with invalid timestamp order", + "multicall-block-timestamp-order-38021", + "Error: simulates calls with invalid timestamp order (-38021)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{ @@ -823,14 +823,13 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if err := checkError(err, -38021); err != nil { - return err - } - return err + return nil }, }, { @@ -1223,8 +1222,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-run-out-of-gas-in-block", - "we should get out of gas error if a block consumes too much gas", + "multicall-run-out-of-gas-in-block-38015", + "we should get out of gas error if a block consumes too much gas (-38015)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1328,6 +1327,30 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-empty-calls-and-overrides-multicall", + "multicall with state overrides and calls but they are empty", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{}, + Calls: []TransactionArgs{{}}, + }, + { + StateOverrides: &StateOverride{}, + Calls: []TransactionArgs{{}}, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, { "multicall-override-address-twice-in-separate-BlockStateCalls", "override address twice in separate BlockStateCalls", @@ -1490,8 +1513,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-transaction-too-low-nonce", - "Error: Nonce too low", + "multicall-transaction-too-low-nonce-38010", + "Error: Nonce too low (-38010)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1506,14 +1529,13 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38010); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { - return err + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - return err + return nil }, }, { @@ -1530,22 +1552,18 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38011); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { - return err - } - return err + return nil }, }, { - "multicall-basefee-too-low-with-validation", - "Error: BaseFee too low with validation", + "multicall-basefee-too-low-with-validation-38012", + "Error: BaseFee too low with validation (-38012)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1565,19 +1583,18 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38012); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { - return err + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - return err + return nil }, }, { - "multicall-basefee-too-low-without-validation", - "Error: BaseFee too low with no validation", + "multicall-basefee-too-low-without-validation-38012", + "Error: BaseFee too low with no validation (-38012)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1597,19 +1614,18 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38012); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { - return err + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - return err + return nil }, }, { - "multicall-instrict-gas", - "Error: Not enough gas provided to pay for intrinsic gas", + "multicall-instrict-gas-38013", + "Error: Not enough gas provided to pay for intrinsic gas (-38013)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1621,19 +1637,41 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38013); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if err := checkStatus(res[0].Calls[0].Status, 0x2); err != nil { + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, + { + "multicall-gas-fees-and-value-error-38014", + "Error: Insufficient funds to pay for gas fees and value (-38014)", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: (*hexutil.Big)(big.NewInt(1000)), + }}, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - return err + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil }, }, { - "multicall-gas-fees-and-value-error", - "Error: Insufficient funds to pay for gas fees and value", + "multicall-gas-fees-and-value-error-38014-with-validation", + "Error: Insufficient funds to pay for gas fees and value (-38014) with validation", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1643,18 +1681,21 @@ var EthMulticall = MethodTests{ Value: (*hexutil.Big)(big.NewInt(1000)), }}, }}, + Validation: true, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38014); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - return err + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil }, }, { - "multicall-move-to-address-itself-reference", - "Error: MoveToAddress referenced itself in replacement", + "multicall-move-to-address-itself-reference-38022", + "Error: MoveToAddress referenced itself in replacement (-38022)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1670,11 +1711,13 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38022); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - return err + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil }, }, { @@ -1738,8 +1781,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-move-to-accounts-to-same", - "Move two accounts to the same destination", + "multicall-move-to-accounts-to-same-38023", + "Move two accounts to the same destination (-38023)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1755,11 +1798,13 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - err := t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if err := checkError(err, -38023); err != nil { + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - return err + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil }, }, { @@ -2173,6 +2218,65 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-override-identity", + "override identity precompile", + func(ctx context.Context, t *T) error { + identityAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000004")) + identityMovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + identityAddress: OverrideAccount{ + Code: hex2Bytes(""), + MoveToAddress: &identityMovedToAddress, + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &identityMovedToAddress, + Input: hex2Bytes("1234"), + }, + { + From: &common.Address{0xc0}, + To: &identityAddress, + Input: hex2Bytes("1234"), + }, + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-precompile-is-sending-transaction", + "send transaction from a precompile", + func(ctx context.Context, t *T) error { + identityAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000004")) + sha256Address := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000002")) + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + Calls: []TransactionArgs{ + { + From: &identityAddress, + To: &sha256Address, + Input: hex2Bytes("1234"), + }, + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, { "multicall-simple-state-diff", "override one state variable with statediff", From 04f252b320870035223b341d2cd8c3fd0d476ecd Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 5 Sep 2023 14:03:00 +0300 Subject: [PATCH 24/59] generate tests that output errors --- testgen/generators.go | 83 +++++++------------------------------------ 1 file changed, 13 insertions(+), 70 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index e0163cc..fb3f1ec 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -796,12 +796,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -823,12 +818,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -849,13 +839,8 @@ var EthMulticall = MethodTests{ }, }, } - res := make([]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1254,9 +1239,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1529,12 +1512,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1583,12 +1561,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1614,12 +1587,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1637,12 +1605,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1660,12 +1623,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1684,12 +1642,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1711,12 +1664,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1798,12 +1746,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, From f04b7bdf4b86d30dbfa0dde648b4a86f6e190188 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 5 Sep 2023 14:58:22 +0300 Subject: [PATCH 25/59] fix couple tests --- testgen/generators.go | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index fb3f1ec..ac54d40 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -845,7 +845,29 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-block-timestamp-non-incement", + "multicall-block-timestamps-incrementing", + "checks that you can set timestamp and increment it in next block", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(11), + }, + }, { + BlockOverrides: &BlockOverrides{ + Time: getUint64Ptr(12), + }, + }, + }, + } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") + return nil + }, + }, + { + "multicall-block-timestamp-auto-increment", "Error: simulates calls with timestamp incrementing over another", func(ctx context.Context, t *T) error { params := multicallOpts{ @@ -868,13 +890,8 @@ var EthMulticall = MethodTests{ }, }, } - res := make([]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -974,7 +991,7 @@ var EthMulticall = MethodTests{ if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if err := checkBlockNumber(res[0].Number, 3); err != nil { + if err := checkBlockNumber(res[0].Number, 4); err != nil { return err } if len(res[0].Calls) != 1 { From 04f58b29d5f1ab2d5fe783108f34dad5c19721f5 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 5 Sep 2023 15:12:20 +0300 Subject: [PATCH 26/59] more tests --- testgen/generators.go | 44 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index ac54d40..7550454 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2613,6 +2613,42 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-block-override-reflected-in-contract-simple", + "Checks that block overrides are true in contract for block number and time", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + Time: getUint64Ptr(100), + }, + }, + { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(20)), + Time: getUint64Ptr(200), + }, + }, + { + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(21)), + Time: getUint64Ptr(300), + }, + }, + }, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, { "multicall-block-override-reflected-in-contract", "Checks that block overrides are true in contract", @@ -2740,14 +2776,11 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, { - "multicall-add-more-non-defined-BlockStateCalls-than-fit", + "multicall-add-more-non-defined-BlockStateCalls-than-fit-but-now-with-fit", "Not all block numbers are defined", func(ctx context.Context, t *T) error { params := multicallOpts{ @@ -2805,9 +2838,6 @@ var EthMulticall = MethodTests{ if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { return err } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, From 0e6800a82f22b8a66165dbb60bd3f34c224973f0 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 5 Sep 2023 15:30:58 +0300 Subject: [PATCH 27/59] fix timestamps --- testgen/generators.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 7550454..ac96608 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2628,13 +2628,13 @@ var EthMulticall = MethodTests{ { BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(20)), - Time: getUint64Ptr(200), + Time: getUint64Ptr(101), }, }, { BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(21)), - Time: getUint64Ptr(300), + Time: getUint64Ptr(200), }, }, }, @@ -2666,7 +2666,7 @@ var EthMulticall = MethodTests{ }, BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(10)), - Time: getUint64Ptr(10), + Time: getUint64Ptr(100), GasLimit: getUint64Ptr(10), FeeRecipient: &common.Address{0xc0}, PrevRandao: &prevRandDao1, @@ -2683,7 +2683,7 @@ var EthMulticall = MethodTests{ { BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(20)), - Time: getUint64Ptr(20), + Time: getUint64Ptr(200), GasLimit: getUint64Ptr(20), FeeRecipient: &common.Address{0xc1}, PrevRandao: &prevRandDao2, @@ -2700,7 +2700,7 @@ var EthMulticall = MethodTests{ { BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(21)), - Time: getUint64Ptr(21), + Time: getUint64Ptr(300), GasLimit: getUint64Ptr(21), FeeRecipient: &common.Address{0xc2}, PrevRandao: &prevRandDao3, @@ -2773,9 +2773,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, From 5cf1e5780d45c95c0e6ee56fcb41ae5135aa2023 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 09:59:57 +0300 Subject: [PATCH 28/59] test fixing --- testgen/generators.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index ac96608..b43b0cd 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1944,7 +1944,7 @@ var EthMulticall = MethodTests{ }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, - To: &common.Address{0xc1}, + To: &common.Address{0xc2}, Value: (*hexutil.Big)(big.NewInt(1000)), Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), }}, @@ -1970,6 +1970,7 @@ var EthMulticall = MethodTests{ "override all values in block and see that they are set in return value", func(ctx context.Context, t *T) error { feeRecipient := common.Address{0xc2} + randDao := &common.Hash{0xc3} params := multicallOpts{ BlockStateCalls: []CallBatch{{ BlockOverrides: &BlockOverrides{ @@ -1977,7 +1978,7 @@ var EthMulticall = MethodTests{ Time: getUint64Ptr(1003), GasLimit: getUint64Ptr(1004), FeeRecipient: &feeRecipient, - PrevRandao: &common.Hash{0xc3}, + PrevRandao: randDao, BaseFee: (*hexutil.Big)(big.NewInt(1007)), }, }}, @@ -2001,8 +2002,8 @@ var EthMulticall = MethodTests{ if res[0].FeeRecipient != feeRecipient { return fmt.Errorf("unexpected FeeRecipient (have: %d, want: %d)", res[0].FeeRecipient, feeRecipient) } - if res[0].PrevRandao != &(common.Hash{0xc3}) { - return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, 0xc3) + if res[0].PrevRandao != randDao { + return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } if res[0].BaseFeePerGas != (*hexutil.Big)(big.NewInt(1007)) { return fmt.Errorf("unexpected BaseFeePerGas (have: %d, want: %d)", res[0].BaseFeePerGas.ToInt(), 1007) From b02efd5a3640661c385d080ae1c540badd048c90 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 10:14:41 +0300 Subject: [PATCH 29/59] fix value field --- testgen/generators.go | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index b43b0cd..44f1e09 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -687,11 +687,11 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }, { From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }, }, }, { @@ -1272,7 +1272,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }}, TraceTransfers: true, @@ -1303,7 +1303,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }}, TraceTransfers: true, @@ -1364,7 +1364,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }, { @@ -1374,7 +1374,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }, }, @@ -1400,7 +1400,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }}, TraceTransfers: true, @@ -1419,7 +1419,7 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-eth-send-should--produce-more-logs-on-forward", + "multicall-eth-send-should-produce-more-logs-on-forward", "we should be getting more logs if eth is forwarded", func(ctx context.Context, t *T) error { params := multicallOpts{ @@ -1431,7 +1431,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), }}, }}, @@ -1451,7 +1451,7 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-eth-send-should--produce-no-logs-on-forward-revert", + "multicall-eth-send-should-produce-no-logs-on-forward-revert", "we should be getting no logs if eth is forwarded but then the tx reverts", func(ctx context.Context, t *T) error { params := multicallOpts{ @@ -1464,7 +1464,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), Input: hex2Bytes("4b64e49200000000000000000000000000000000000000000000000000000000000000c2"), //foward(0xc2) }}, }}, @@ -1495,7 +1495,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }}, } @@ -1635,7 +1635,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }}, } @@ -1653,7 +1653,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), }}, }}, Validation: true, @@ -1676,7 +1676,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: (*hexutil.Big)(big.NewInt(1)), + Value: *newRPCBalance(1), }}, }}, } @@ -1945,7 +1945,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Value: (*hexutil.Big)(big.NewInt(1000)), + Value: *newRPCBalance(1000), Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), }}, }, From ea8e34b43528dbb43ad8e68fa58e6efd31e2ccaf Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 10:39:18 +0300 Subject: [PATCH 30/59] test fixing --- testgen/generators.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 44f1e09..7cd57cc 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1944,7 +1944,7 @@ var EthMulticall = MethodTests{ }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, - To: &common.Address{0xc2}, + To: &common.Address{0xc1}, Value: *newRPCBalance(1000), Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), }}, @@ -2002,7 +2002,7 @@ var EthMulticall = MethodTests{ if res[0].FeeRecipient != feeRecipient { return fmt.Errorf("unexpected FeeRecipient (have: %d, want: %d)", res[0].FeeRecipient, feeRecipient) } - if res[0].PrevRandao != randDao { + if *res[0].PrevRandao != *randDao { return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } if res[0].BaseFeePerGas != (*hexutil.Big)(big.NewInt(1007)) { From 58e22df4c8c5525529055610ec030fc64f12f80f Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 11:17:58 +0300 Subject: [PATCH 31/59] test fixing --- testgen/generators.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 7cd57cc..e0b1be6 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1465,7 +1465,7 @@ var EthMulticall = MethodTests{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, Value: *newRPCBalance(1000), - Input: hex2Bytes("4b64e49200000000000000000000000000000000000000000000000000000000000000c2"), //foward(0xc2) + Input: hex2Bytes("4b64e492c200000000000000000000000000000000000000000000000000000000000000"), //foward(0xc2) }}, }}, TraceTransfers: true, @@ -1971,6 +1971,7 @@ var EthMulticall = MethodTests{ func(ctx context.Context, t *T) error { feeRecipient := common.Address{0xc2} randDao := &common.Hash{0xc3} + baseFee := (*hexutil.Big)(big.NewInt(1007)) params := multicallOpts{ BlockStateCalls: []CallBatch{{ BlockOverrides: &BlockOverrides{ @@ -1979,7 +1980,7 @@ var EthMulticall = MethodTests{ GasLimit: getUint64Ptr(1004), FeeRecipient: &feeRecipient, PrevRandao: randDao, - BaseFee: (*hexutil.Big)(big.NewInt(1007)), + BaseFee: baseFee, }, }}, } @@ -2005,7 +2006,7 @@ var EthMulticall = MethodTests{ if *res[0].PrevRandao != *randDao { return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } - if res[0].BaseFeePerGas != (*hexutil.Big)(big.NewInt(1007)) { + if res[0].BaseFeePerGas.ToInt() != baseFee.ToInt() { return fmt.Errorf("unexpected BaseFeePerGas (have: %d, want: %d)", res[0].BaseFeePerGas.ToInt(), 1007) } return nil From ce1a65e8170666b8ac4df9f5aaacdada7cbf42f2 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 11:34:57 +0300 Subject: [PATCH 32/59] seems like sends to precompile fails, so lets not send eth to them, but to some other addr --- testgen/generators.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index e0b1be6..7c7f1a6 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1432,7 +1432,7 @@ var EthMulticall = MethodTests{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, Value: *newRPCBalance(1000), - Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), + Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000100"), }}, }}, TraceTransfers: true, @@ -1946,7 +1946,7 @@ var EthMulticall = MethodTests{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, Value: *newRPCBalance(1000), - Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000001"), + Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000100"), }}, }, }, @@ -2006,8 +2006,8 @@ var EthMulticall = MethodTests{ if *res[0].PrevRandao != *randDao { return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } - if res[0].BaseFeePerGas.ToInt() != baseFee.ToInt() { - return fmt.Errorf("unexpected BaseFeePerGas (have: %d, want: %d)", res[0].BaseFeePerGas.ToInt(), 1007) + if res[0].BaseFeePerGas.ToInt() != big.NewInt(1007) { + return fmt.Errorf("unexpected BaseFeePerGas (have: %d, want: %d)", res[0].BaseFeePerGas.ToInt(), big.NewInt(1007)) } return nil }, From 6e1bffa372b5ec4e82c2384b4bfc4d4ec990227c Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 13:18:44 +0300 Subject: [PATCH 33/59] fix comparison --- testgen/generators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testgen/generators.go b/testgen/generators.go index 7c7f1a6..42e3ca6 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2006,7 +2006,7 @@ var EthMulticall = MethodTests{ if *res[0].PrevRandao != *randDao { return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } - if res[0].BaseFeePerGas.ToInt() != big.NewInt(1007) { + if res[0].BaseFeePerGas.ToInt().Cmp(baseFee.ToInt()) == 0 { return fmt.Errorf("unexpected BaseFeePerGas (have: %d, want: %d)", res[0].BaseFeePerGas.ToInt(), big.NewInt(1007)) } return nil From d8d41bc0c07d465006c3345eb921b0efccac2c24 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 13:45:20 +0300 Subject: [PATCH 34/59] hexbytes fixing --- testgen/generators.go | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 42e3ca6..3bb464f 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -447,12 +447,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 }, { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 }, { From: &common.Address{0xc0}, @@ -462,12 +462,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 }, { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 }, { From: &common.Address{0xc0}, @@ -477,12 +477,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 }, { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 }, }, }}, @@ -516,12 +516,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 }, { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 }, { From: &common.Address{0xc0}, @@ -534,12 +534,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 }, { From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 }, { From: &common.Address{0xc0}, @@ -1720,17 +1720,17 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc4}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 }, { From: &common.Address{0xc0}, To: &common.Address{0xc4}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 }, { From: &common.Address{0xc0}, To: &common.Address{0xc4}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c300000000000000000000000000000000000000"), // gets balance of c3 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c300000000000000000000000000000000000000"), // gets balance of c3 }, }, }}, @@ -1971,7 +1971,6 @@ var EthMulticall = MethodTests{ func(ctx context.Context, t *T) error { feeRecipient := common.Address{0xc2} randDao := &common.Hash{0xc3} - baseFee := (*hexutil.Big)(big.NewInt(1007)) params := multicallOpts{ BlockStateCalls: []CallBatch{{ BlockOverrides: &BlockOverrides{ @@ -1980,7 +1979,7 @@ var EthMulticall = MethodTests{ GasLimit: getUint64Ptr(1004), FeeRecipient: &feeRecipient, PrevRandao: randDao, - BaseFee: baseFee, + BaseFee: (*hexutil.Big)(big.NewInt(1007)), }, }}, } @@ -2006,7 +2005,7 @@ var EthMulticall = MethodTests{ if *res[0].PrevRandao != *randDao { return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } - if res[0].BaseFeePerGas.ToInt().Cmp(baseFee.ToInt()) == 0 { + if res[0].BaseFeePerGas.ToInt().Cmp(big.NewInt(1007)) != 0 { return fmt.Errorf("unexpected BaseFeePerGas (have: %d, want: %d)", res[0].BaseFeePerGas.ToInt(), big.NewInt(1007)) } return nil @@ -2525,12 +2524,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 }, { From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 }, }, }, @@ -2872,12 +2871,12 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 }, { From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Input: hex2Bytes("0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 + Input: hex2Bytes("f8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 }, }, }, From 33adec9de6ab2dbd0eddfb9d547cb7edc27adcd6 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 6 Sep 2023 15:39:29 +0300 Subject: [PATCH 35/59] add nonces to validated queries --- testgen/generators.go | 44 +++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 3bb464f..46351c7 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -548,7 +548,6 @@ var EthMulticall = MethodTests{ }, }, }}, - Validation: true, } res := make([]blockResult, 0) if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { @@ -571,10 +570,12 @@ var EthMulticall = MethodTests{ From: &common.Address{0xc0}, To: &common.Address{0xc1}, Value: *newRPCBalance(1000), + Nonce: getUint64Ptr(0), }, { From: &common.Address{0xc1}, To: &common.Address{0xc2}, Value: *newRPCBalance(1000), + Nonce: getUint64Ptr(1), }}, }, }, @@ -590,6 +591,32 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-simple-no-funds-with-validation-without-nonces", + "simulates a simple multicall transfer when account has no funds with validation. This should fail as the nonce is not set for the second transaction.", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + Nonce: getUint64Ptr(0), + }, { + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Value: *newRPCBalance(1000), + }}, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") + return nil + }, + }, { "multicall-simple-send-from-contract", "Sending eth from contract", @@ -1309,9 +1336,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1321,9 +1346,7 @@ var EthMulticall = MethodTests{ func(ctx context.Context, t *T) error { params := multicallOpts{} res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1345,9 +1368,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -2867,16 +2888,19 @@ var EthMulticall = MethodTests{ MaxFeePerGas: (*hexutil.Big)(big.NewInt(10)), MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(10)), Input: hex2Bytes(""), + Nonce: getUint64Ptr(0), }, { From: &common.Address{0xc0}, To: &common.Address{0xc1}, Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 + Nonce: getUint64Ptr(1), }, { From: &common.Address{0xc0}, To: &common.Address{0xc1}, Input: hex2Bytes("f8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 + Nonce: getUint64Ptr(2), }, }, }, From d2c8cd70812c88219a4655f5a2b9b50eb9160918 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 26 Sep 2023 10:10:56 +0300 Subject: [PATCH 36/59] fix tests to new spec --- testgen/generators.go | 287 +++++------------------------------------- testgen/utils.go | 6 - 2 files changed, 30 insertions(+), 263 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 46351c7..e88c8e9 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1686,13 +1686,13 @@ var EthMulticall = MethodTests{ }, { "multicall-move-to-address-itself-reference-38022", - "Error: MoveToAddress referenced itself in replacement (-38022)", + "Error: MovePrecompileToAddress referenced itself in replacement (-38022)", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(200000)}, - common.Address{0xc1}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, + common.Address{0xc1}: OverrideAccount{MovePrecompileToAddress: &common.Address{0xc1}}, }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, @@ -1729,12 +1729,12 @@ var EthMulticall = MethodTests{ }, { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(3000), - MoveToAddress: &common.Address{0xc2}, + Balance: newRPCBalance(3000), + MovePrecompileToAddress: &common.Address{0xc2}, }, common.Address{0xc2}: OverrideAccount{ - Balance: newRPCBalance(4000), - MoveToAddress: &common.Address{0xc3}, + Balance: newRPCBalance(4000), + MovePrecompileToAddress: &common.Address{0xc3}, }, }, Calls: []TransactionArgs{ @@ -1773,12 +1773,11 @@ var EthMulticall = MethodTests{ params := multicallOpts{ BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(2000), - MoveToAddress: &common.Address{0xc2}, + common.Address{0x1}: OverrideAccount{ + MovePrecompileToAddress: &common.Address{0xc2}, }, - common.Address{0xc1}: OverrideAccount{ - MoveToAddress: &common.Address{0xc2}, + common.Address{0x2}: OverrideAccount{ + MovePrecompileToAddress: &common.Address{0xc2}, }, }, }}, @@ -1789,8 +1788,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-move-to-address-with-nonce", - "move address with nonce", + "multicall-try-to-move-non-precompile", + "try to move non-precompile", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{ @@ -1800,7 +1799,7 @@ var EthMulticall = MethodTests{ }, }, { StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, + common.Address{0xc0}: OverrideAccount{MovePrecompileToAddress: &common.Address{0xc1}}, }, Calls: []TransactionArgs{ { @@ -1819,12 +1818,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1912,86 +1906,12 @@ var EthMulticall = MethodTests{ return nil }, }, - { - "multicall-move-to-address-with-nonce", - "check that nonce is moved with address", - func(ctx context.Context, t *T) error { - params := multicallOpts{ - BlockStateCalls: []CallBatch{ - { - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(5)}, - }, - }, { - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, - }, - Calls: []TransactionArgs{ - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Nonce: getUint64Ptr(5), //should fail - }, - }, - }, - }, - Validation: true, - } - res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } - return nil - }, - }, - { - "multicall-moved-contract-should-be-useable", - "when contract is moved, the moved contract should still work", - func(ctx context.Context, t *T) error { - params := multicallOpts{ - BlockStateCalls: []CallBatch{ - { - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, - common.Address{0xc2}: OverrideAccount{Code: getEthForwarder()}, - }, - }, - { - StateOverrides: &StateOverride{ - common.Address{0xc2}: OverrideAccount{MoveToAddress: &common.Address{0xc1}}, - }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Value: *newRPCBalance(1000), - Input: hex2Bytes("4b64e4920000000000000000000000000000000000000000000000000000000000000100"), - }}, - }, - }, - TraceTransfers: true, - } - res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } - if len(res[1].Calls[0].Logs) != 2 { - return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[1].Calls[0].Logs), 2) - } - return nil - }, - }, { "multicall-override-all-in-BlockStateCalls", "override all values in block and see that they are set in return value", func(ctx context.Context, t *T) error { feeRecipient := common.Address{0xc2} - randDao := &common.Hash{0xc3} + randDao := common.Hash{0xc3} params := multicallOpts{ BlockStateCalls: []CallBatch{{ BlockOverrides: &BlockOverrides{ @@ -1999,7 +1919,7 @@ var EthMulticall = MethodTests{ Time: getUint64Ptr(1003), GasLimit: getUint64Ptr(1004), FeeRecipient: &feeRecipient, - PrevRandao: randDao, + PrevRandao: &randDao, BaseFee: (*hexutil.Big)(big.NewInt(1007)), }, }}, @@ -2023,7 +1943,7 @@ var EthMulticall = MethodTests{ if res[0].FeeRecipient != feeRecipient { return fmt.Errorf("unexpected FeeRecipient (have: %d, want: %d)", res[0].FeeRecipient, feeRecipient) } - if *res[0].PrevRandao != *randDao { + if res[0].PrevRandao != &randDao { return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } if res[0].BaseFeePerGas.ToInt().Cmp(big.NewInt(1007)) != 0 { @@ -2055,7 +1975,7 @@ var EthMulticall = MethodTests{ }, { StateOverrides: &StateOverride{ // move ecRecover and call it in new address ecRecoverAddress: OverrideAccount{ - MoveToAddress: &ecRecoverMovedToAddress, + MovePrecompileToAddress: &ecRecoverMovedToAddress, }, }, Calls: []TransactionArgs{ @@ -2095,8 +2015,8 @@ var EthMulticall = MethodTests{ BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ ecRecoverAddress: OverrideAccount{ - Code: getEcRecoverOverride(), - MoveToAddress: &ecRecoverMovedToAddress, + Code: getEcRecoverOverride(), + MovePrecompileToAddress: &ecRecoverMovedToAddress, }, common.Address{0xc1}: OverrideAccount{Balance: newRPCBalance(200000)}, }, @@ -2175,8 +2095,8 @@ var EthMulticall = MethodTests{ BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ sha256Address: OverrideAccount{ - Code: hex2Bytes(""), - MoveToAddress: &sha256MovedToAddress, + Code: hex2Bytes(""), + MovePrecompileToAddress: &sha256MovedToAddress, }, }, Calls: []TransactionArgs{ @@ -2210,8 +2130,8 @@ var EthMulticall = MethodTests{ BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ identityAddress: OverrideAccount{ - Code: hex2Bytes(""), - MoveToAddress: &identityMovedToAddress, + Code: hex2Bytes(""), + MovePrecompileToAddress: &identityMovedToAddress, }, }, Calls: []TransactionArgs{ @@ -2488,153 +2408,6 @@ var EthMulticall = MethodTests{ return nil }, }, - { - "multicall-move-storage", - "move contract with storage slots being set", - func(ctx context.Context, t *T) error { - params := multicallOpts{ - BlockStateCalls: []CallBatch{ - { - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(2000), - }, - common.Address{0xc1}: OverrideAccount{ - Code: getStorageTester(), - Balance: newRPCBalance(1000), - }, - common.Address{0xc3}: OverrideAccount{ - Code: getBalanceGetter(), - }, - }, - Calls: []TransactionArgs{ - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"), // set storage slot 0 -> 1 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Input: hex2Bytes("7b8d56e300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), // set storage slot 1 -> 2 - }, - }, - }, - { - StateOverrides: &StateOverride{ - common.Address{0xc1}: OverrideAccount{ - MoveToAddress: &common.Address{0xc2}, - }, - }, - Calls: []TransactionArgs{ - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should return error as there should not be code there anymore - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 1 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 2 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Input: hex2Bytes("f8b2cb4f000000000000000000000000c100000000000000000000000000000000000000"), // gets balance of c1 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc3}, - Input: hex2Bytes("f8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 - }, - }, - }, - }, - TraceTransfers: true, - } - res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } - return nil - }, - }, - { - "multicall-override-move-storage", - "move contract with storage slots being overriden", - func(ctx context.Context, t *T) error { - stateChanges := make(map[common.Hash]common.Hash) - stateChanges[common.BytesToHash(*hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))] = common.Hash{0x12} //slot 0 -> 0x12 - params := multicallOpts{ - BlockStateCalls: []CallBatch{ - { - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(2000), - }, - common.Address{0xc1}: OverrideAccount{ - Code: getStorageTester(), - State: &stateChanges, - }, - }, - Calls: []TransactionArgs{ - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 0 - }, - }, - }, - { - StateOverrides: &StateOverride{ - common.Address{0xc1}: OverrideAccount{ - MoveToAddress: &common.Address{0xc2}, - }, - }, - Calls: []TransactionArgs{ - { - From: &common.Address{0xc0}, - To: &common.Address{0xc1}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should'nt return anything - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000000"), // gets storage slot 0, should be 0x12 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("0ff4c9160000000000000000000000000000000000000000000000000000000000000001"), // gets storage slot 1, should be 0 - }, - }, - }, - }, - TraceTransfers: true, - } - res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } - return nil - }, - }, { "multicall-block-override-reflected-in-contract-simple", "Checks that block overrides are true in contract for block number and time", @@ -3596,12 +3369,12 @@ type BlockOverrides struct { // if statDiff is set, all diff will be applied first and then execute the call // message. type OverrideAccount struct { - Nonce *hexutil.Uint64 `json:"nonce,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` - Balance **hexutil.Big `json:"balance,omitempty"` - State *map[common.Hash]common.Hash `json:"state,omitempty"` - StateDiff *map[common.Hash]common.Hash `json:"stateDiff,omitempty"` - MoveToAddress *common.Address `json:"moveToAddress,omitempty"` + Nonce *hexutil.Uint64 `json:"nonce,omitempty"` + Code *hexutil.Bytes `json:"code,omitempty"` + Balance **hexutil.Big `json:"balance,omitempty"` + State *map[common.Hash]common.Hash `json:"state,omitempty"` + StateDiff *map[common.Hash]common.Hash `json:"stateDiff,omitempty"` + MovePrecompileToAddress *common.Address `json:"MovePrecompileToAddress,omitempty"` } // StateOverride is the collection of overridden accounts. diff --git a/testgen/utils.go b/testgen/utils.go index 795b0ae..92eac1c 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -158,11 +158,6 @@ func getEcRecoverOverride() *hexutil.Bytes { } mapping(bytes32 => address) overrideToAddress; - function setOverride(bytes32 hash, uint8 v, bytes32 r, bytes32 s, address returnAddress) public { - require(returnAddress != address(0x0), 'return address cannot be 0x0'); - overrideToAddress[keccak256(abi.encodePacked(hash, v, r, s))] = returnAddress; - } - function setOverrides(EcRecoverOverrideParams[] memory overrides) public { for (uint i = 0; i < overrides.length; i++) { setOverride(overrides[i].hash, overrides[i].v, overrides[i].r, overrides[i].s, overrides[i].returnAddress); @@ -182,7 +177,6 @@ func getEcRecoverOverride() *hexutil.Bytes { } */ return hex2Bytes("608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033") - } func getBalanceGetter() *hexutil.Bytes { From 861c20ee58affc557be471946328c3339c5addab Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 26 Sep 2023 10:58:07 +0300 Subject: [PATCH 37/59] test fixing --- testgen/generators.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index e88c8e9..287ec90 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1757,12 +1757,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -1943,7 +1938,7 @@ var EthMulticall = MethodTests{ if res[0].FeeRecipient != feeRecipient { return fmt.Errorf("unexpected FeeRecipient (have: %d, want: %d)", res[0].FeeRecipient, feeRecipient) } - if res[0].PrevRandao != &randDao { + if *res[0].PrevRandao != randDao { return fmt.Errorf("unexpected PrevRandao (have: %d, want: %d)", res[0].PrevRandao, randDao) } if res[0].BaseFeePerGas.ToInt().Cmp(big.NewInt(1007)) != 0 { From 67414e68fb9876fb833f9ae3fc1fa3961f1bdbd4 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 26 Sep 2023 11:42:55 +0300 Subject: [PATCH 38/59] use ReturnValue --- testgen/generators.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 287ec90..9b12c61 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1188,9 +1188,6 @@ var EthMulticall = MethodTests{ params := multicallOpts{ BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(2000000), - }, common.Address{0xc2}: OverrideAccount{ Code: selfDestructor(), }, @@ -3402,7 +3399,7 @@ type blockResult struct { } type callResult struct { - ReturnValue hexutil.Bytes `json:"return"` + ReturnValue hexutil.Bytes `json:"ReturnValue"` Logs []*types.Log `json:"logs"` Transfers []transfer `json:"transfers,omitempty"` GasUsed hexutil.Uint64 `json:"gasUsed"` From 68ddcfa810998e4affae1ac079f82b952e84350a Mon Sep 17 00:00:00 2001 From: KillariDev Date: Sat, 14 Oct 2023 03:32:09 +0300 Subject: [PATCH 39/59] test fixing --- testgen/generators.go | 66 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 9b12c61..342dfd6 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1759,8 +1759,8 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-move-to-accounts-to-same-38023", - "Move two accounts to the same destination (-38023)", + "multicall-move-two-non-precompiles-accounts-to-same", + "Move two non-precompiles to same adddress", func(ctx context.Context, t *T) error { params := multicallOpts{ BlockStateCalls: []CallBatch{{ @@ -1779,6 +1779,29 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-move-two-accounts-to-same-38023", + "Move two accounts to the same destination (-38023)", + func(ctx context.Context, t *T) error { + ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) + keccakAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000002")) + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + ecRecoverAddress: OverrideAccount{ + MovePrecompileToAddress: &common.Address{0xc2}, + }, + keccakAddress: OverrideAccount{ + MovePrecompileToAddress: &common.Address{0xc2}, + }, + }, + }}, + } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") + return nil + }, + }, { "multicall-try-to-move-non-precompile", "try to move non-precompile", @@ -2436,6 +2459,38 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-get-block-properties", + "gets various block properties from chain", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + }, + }, + } + }, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, { "multicall-block-override-reflected-in-contract", "Checks that block overrides are true in contract", @@ -3404,7 +3459,12 @@ type callResult struct { Transfers []transfer `json:"transfers,omitempty"` GasUsed hexutil.Uint64 `json:"gasUsed"` Status hexutil.Uint64 `json:"status"` - Error *string `json:"error,omitempty"` + Error errorResult `json:"error,omitempty"` +} + +type errorResult struct { + Code hexutil.Uint64 `json:"code"` + Message *string `json:"message"` } type transfer struct { From 7bd3258b79e665d5e643834aaa20bc973f756dd7 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Sat, 14 Oct 2023 03:51:39 +0300 Subject: [PATCH 40/59] missing comma --- testgen/generators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testgen/generators.go b/testgen/generators.go index 342dfd6..10f262e 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2478,7 +2478,7 @@ var EthMulticall = MethodTests{ Input: hex2Bytes(""), }, }, - } + }, }, } res := make([]blockResult, 0) From 5beb4b743fc3e5b9a4d49b216c5503b1b171a7b6 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Sat, 14 Oct 2023 08:24:04 +0300 Subject: [PATCH 41/59] fix typos --- testgen/generators.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 10f262e..0f2fee2 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -850,7 +850,7 @@ var EthMulticall = MethodTests{ }, }, { - "multicall-block-timestamp-non-incement", + "multicall-block-timestamp-non-increment", "Error: simulates calls with timestamp staying the same", func(ctx context.Context, t *T) error { params := multicallOpts{ @@ -3463,8 +3463,8 @@ type callResult struct { } type errorResult struct { - Code hexutil.Uint64 `json:"code"` - Message *string `json:"message"` + Code *big.Int `json:"code"` + Message *string `json:"message"` } type transfer struct { From 668c5f70abbdcadf0f75fb784d74b3ee684e0f83 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Sat, 14 Oct 2023 09:28:16 +0300 Subject: [PATCH 42/59] use returnData instead of returnValue --- testgen/generators.go | 80 +++++++++++++++++++++---------------------- testgen/utils.go | 8 ++--- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 0f2fee2..d25ecd9 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1024,7 +1024,7 @@ var EthMulticall = MethodTests{ if len(res[0].Calls) != 1 { return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), 1) } - if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), t.chain.GetHeaderByNumber(1).Hash()); err != nil { + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnData), t.chain.GetHeaderByNumber(1).Hash()); err != nil { return err } return nil @@ -1099,15 +1099,15 @@ var EthMulticall = MethodTests{ } // should equal to block number ones hash - if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), t.chain.GetHeaderByNumber(1).Hash()); err != nil { + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnData), t.chain.GetHeaderByNumber(1).Hash()); err != nil { return err } // should equal first generated BlockStateCalls hash - if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), res[0].Hash); err != nil { + if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnData), res[0].Hash); err != nil { return err } // should equal keccack256(rlp([blockhash_20, 29])) - if err := checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnValue), common.BytesToHash(*hex2Bytes("9f77a47d3fbad17b981f2f21022effd528670e580382921735559c1f31774191"))); err != nil { + if err := checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnData), common.BytesToHash(*hex2Bytes("9f77a47d3fbad17b981f2f21022effd528670e580382921735559c1f31774191"))); err != nil { return err } return nil @@ -1170,11 +1170,11 @@ var EthMulticall = MethodTests{ return err } //keccack256(rlp([blockhash_1, 2]) - if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnValue), common.BytesToHash(*hex2Bytes("b71624aa776736b9a340cae6a536e93c71e376907a5b23c196aa056450a2b983"))); err != nil { + if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnData), common.BytesToHash(*hex2Bytes("b71624aa776736b9a340cae6a536e93c71e376907a5b23c196aa056450a2b983"))); err != nil { return err } //keccack256(rlp([blockhash_10, 19]) - if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnValue), common.BytesToHash(*hex2Bytes("5679ee58a0ff6a8fa7b177db27c76774f1ddc04464d1999aad7aba7ac911593b"))); err != nil { + if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnData), common.BytesToHash(*hex2Bytes("5679ee58a0ff6a8fa7b177db27c76774f1ddc04464d1999aad7aba7ac911593b"))); err != nil { return err } @@ -1235,14 +1235,14 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } noCode := "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000" - if res[1].Calls[0].ReturnValue.String() == noCode { - return fmt.Errorf("res 1 overrided contract does not have contract code: %s", res[1].Calls[0].ReturnValue.String()) + if res[1].Calls[0].ReturnData.String() == noCode { + return fmt.Errorf("res 1 overrided contract does not have contract code: %s", res[1].Calls[0].ReturnData.String()) } - if res[3].Calls[0].ReturnValue.String() != noCode { - return fmt.Errorf("res 3 self destructed code does have contract code: %s", res[3].Calls[0].ReturnValue.String()) + if res[3].Calls[0].ReturnData.String() != noCode { + return fmt.Errorf("res 3 self destructed code does have contract code: %s", res[3].Calls[0].ReturnData.String()) } - if res[5].Calls[0].ReturnValue.String() == noCode { - return fmt.Errorf("res 5 overrided contract does not have contract code: %s", res[5].Calls[0].ReturnValue.String()) + if res[5].Calls[0].ReturnData.String() == noCode { + return fmt.Errorf("res 5 overrided contract does not have contract code: %s", res[5].Calls[0].ReturnData.String()) } return nil }, @@ -2080,22 +2080,22 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.BlockStateCalls[0].Calls)) } zeroAddr := common.Address{0x0} - if common.BytesToAddress(res[0].Calls[0].ReturnValue) != zeroAddr { - return fmt.Errorf("unexpected returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[0].ReturnValue), zeroAddr) + if common.BytesToAddress(res[0].Calls[0].ReturnData) != zeroAddr { + return fmt.Errorf("unexpected ReturnData (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[0].ReturnData), zeroAddr) } successReturn := common.BytesToAddress(*hex2Bytes("b11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a")) - if common.BytesToAddress(res[0].Calls[1].ReturnValue) != successReturn { - return fmt.Errorf("unexpected calls 1 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[1].ReturnValue), successReturn) + if common.BytesToAddress(res[0].Calls[1].ReturnData) != successReturn { + return fmt.Errorf("unexpected calls 1 ReturnData (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[1].ReturnData), successReturn) } vitalikReturn := common.BytesToAddress(*hex2Bytes("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045")) - if common.BytesToAddress(res[0].Calls[3].ReturnValue) != vitalikReturn { - return fmt.Errorf("unexpected calls 3 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[3].ReturnValue), vitalikReturn) + if common.BytesToAddress(res[0].Calls[3].ReturnData) != vitalikReturn { + return fmt.Errorf("unexpected calls 3 ReturnData (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[3].ReturnData), vitalikReturn) } - if common.BytesToAddress(res[0].Calls[4].ReturnValue) != successReturn { - return fmt.Errorf("unexpected calls 4 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[4].ReturnValue), successReturn) + if common.BytesToAddress(res[0].Calls[4].ReturnData) != successReturn { + return fmt.Errorf("unexpected calls 4 ReturnData (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[4].ReturnData), successReturn) } - if common.BytesToAddress(res[0].Calls[5].ReturnValue) != zeroAddr { - return fmt.Errorf("unexpected calls 5 returnvalue (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[5].ReturnValue), zeroAddr) + if common.BytesToAddress(res[0].Calls[5].ReturnData) != zeroAddr { + return fmt.Errorf("unexpected calls 5 ReturnData (have: %d, want: %d)", common.BytesToAddress(res[0].Calls[5].ReturnData), zeroAddr) } return nil }, @@ -2400,25 +2400,25 @@ var EthMulticall = MethodTests{ if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if res[0].Calls[2].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000001" { - return fmt.Errorf("unexpected call result (res[0].Calls[2]) (have: %s, want: %s)", res[0].Calls[2].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000001") + if res[0].Calls[2].ReturnData.String() != "0x0000000000000000000000000000000000000000000000000000000000000001" { + return fmt.Errorf("unexpected call result (res[0].Calls[2]) (have: %s, want: %s)", res[0].Calls[2].ReturnData.String(), "0x0000000000000000000000000000000000000000000000000000000000000001") } - if res[0].Calls[3].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { - return fmt.Errorf("unexpected call result (res[0].Calls[3]) (have: %s, want: %s)", res[0].Calls[3].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") + if res[0].Calls[3].ReturnData.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { + return fmt.Errorf("unexpected call result (res[0].Calls[3]) (have: %s, want: %s)", res[0].Calls[3].ReturnData.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") } - if res[1].Calls[0].ReturnValue.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { - return fmt.Errorf("unexpected call result (res[1].Calls[0]) (have: %s, want: %s)", res[1].Calls[0].ReturnValue.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") + if res[1].Calls[0].ReturnData.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { + return fmt.Errorf("unexpected call result (res[1].Calls[0]) (have: %s, want: %s)", res[1].Calls[0].ReturnData.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") } - if res[1].Calls[1].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { - return fmt.Errorf("unexpected call result (res[1].Calls[1]) (have: %s, want: %s)", res[1].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") + if res[1].Calls[1].ReturnData.String() != "0x0000000000000000000000000000000000000000000000000000000000000002" { + return fmt.Errorf("unexpected call result (res[1].Calls[1]) (have: %s, want: %s)", res[1].Calls[1].ReturnData.String(), "0x0000000000000000000000000000000000000000000000000000000000000002") } - if res[2].Calls[0].ReturnValue.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { - return fmt.Errorf("unexpected call result (res[2].Calls[0]) (have: %s, want: %s)", res[2].Calls[0].ReturnValue.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") + if res[2].Calls[0].ReturnData.String() != "0x1200000000000000000000000000000000000000000000000000000000000000" { + return fmt.Errorf("unexpected call result (res[2].Calls[0]) (have: %s, want: %s)", res[2].Calls[0].ReturnData.String(), "0x1200000000000000000000000000000000000000000000000000000000000000") } - if res[2].Calls[1].ReturnValue.String() != "0x0000000000000000000000000000000000000000000000000000000000000000" { - return fmt.Errorf("unexpected call result (res[2].Calls[1]) (have: %s, want: %s)", res[2].Calls[1].ReturnValue.String(), "0x0000000000000000000000000000000000000000000000000000000000000000") + if res[2].Calls[1].ReturnData.String() != "0x0000000000000000000000000000000000000000000000000000000000000000" { + return fmt.Errorf("unexpected call result (res[2].Calls[1]) (have: %s, want: %s)", res[2].Calls[1].ReturnData.String(), "0x0000000000000000000000000000000000000000000000000000000000000000") } return nil }, @@ -3454,12 +3454,12 @@ type blockResult struct { } type callResult struct { - ReturnValue hexutil.Bytes `json:"ReturnValue"` - Logs []*types.Log `json:"logs"` - Transfers []transfer `json:"transfers,omitempty"` - GasUsed hexutil.Uint64 `json:"gasUsed"` - Status hexutil.Uint64 `json:"status"` - Error errorResult `json:"error,omitempty"` + ReturnData hexutil.Bytes `json:"ReturnData"` + Logs []*types.Log `json:"logs"` + Transfers []transfer `json:"transfers,omitempty"` + GasUsed hexutil.Uint64 `json:"gasUsed"` + Status hexutil.Uint64 `json:"status"` + Error errorResult `json:"error,omitempty"` } type errorResult struct { diff --git a/testgen/utils.go b/testgen/utils.go index 92eac1c..399e950 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -50,7 +50,7 @@ func checkBlockNumber(value hexutil.Uint64, expected hexutil.Uint64) error { func checkBlockHash(value common.Hash, expected common.Hash) error { if value != expected { - return fmt.Errorf("unexpected block hash value(have: %d, want: %d)", value, expected) + return fmt.Errorf("unexpected block hash value(have: %s, want: %s)", value.Hex(), expected.Hex()) } return nil } @@ -216,10 +216,10 @@ func getStorageTester() *hexutil.Bytes { if (slot == 0) { value0 = value; return; } if (slot == 1) { value1 = value; return; } } - function getValue(uint256 slot) view external returns (uint256 returnValue) { + function getValue(uint256 slot) view external returns (uint256 ReturnData) { require(slot < 2, "too big slot"); - if (slot == 0) { returnValue = value0; } - if (slot == 1) { returnValue = value1; } + if (slot == 0) { ReturnData = value0; } + if (slot == 1) { ReturnData = value1; } } } */ From 0e58d7a25eed2d74888689f24398a3d5293efe8e Mon Sep 17 00:00:00 2001 From: KillariDev Date: Sat, 14 Oct 2023 12:16:05 +0300 Subject: [PATCH 43/59] add more gas so the execution works --- testgen/generators.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index d25ecd9..4952292 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2509,7 +2509,7 @@ var EthMulticall = MethodTests{ BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(10)), Time: getUint64Ptr(100), - GasLimit: getUint64Ptr(10), + GasLimit: getUint64Ptr(190000), FeeRecipient: &common.Address{0xc0}, PrevRandao: &prevRandDao1, BaseFee: (*hexutil.Big)(big.NewInt(10)), @@ -2526,7 +2526,7 @@ var EthMulticall = MethodTests{ BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(20)), Time: getUint64Ptr(200), - GasLimit: getUint64Ptr(20), + GasLimit: getUint64Ptr(190001), FeeRecipient: &common.Address{0xc1}, PrevRandao: &prevRandDao2, BaseFee: (*hexutil.Big)(big.NewInt(20)), @@ -2543,7 +2543,7 @@ var EthMulticall = MethodTests{ BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(21)), Time: getUint64Ptr(300), - GasLimit: getUint64Ptr(21), + GasLimit: getUint64Ptr(190002), FeeRecipient: &common.Address{0xc2}, PrevRandao: &prevRandDao3, BaseFee: (*hexutil.Big)(big.NewInt(30)), From abac2822354f683ab4365e54483b4d073272b6cb Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 20 Oct 2023 03:47:29 +0300 Subject: [PATCH 44/59] 10 is 0xa in hex and not 0x10 --- testgen/generators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testgen/generators.go b/testgen/generators.go index 4952292..5960711 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1059,7 +1059,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000010"), + Input: hex2Bytes("ee82ac5e000000000000000000000000000000000000000000000000000000000000000a"), }}, }, { BlockOverrides: &BlockOverrides{ From 0a6ba084b98a79f5116d4638d4eaec98d23fa4d6 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 20 Oct 2023 15:19:03 +0300 Subject: [PATCH 45/59] fix blockhash calculations --- testgen/generators.go | 47 +++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 5960711..50a1d79 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -18,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient/gethclient" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" ) @@ -1107,7 +1108,11 @@ var EthMulticall = MethodTests{ return err } // should equal keccack256(rlp([blockhash_20, 29])) - if err := checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnData), common.BytesToHash(*hex2Bytes("9f77a47d3fbad17b981f2f21022effd528670e580382921735559c1f31774191"))); err != nil { + rlp, rlpError := rlp.EncodeToBytes([][]byte{res[1].Hash.Bytes(), big.NewInt(int64(29)).Bytes()}) + if rlpError != nil { + return rlpError + } + if err := checkBlockHash(common.BytesToHash(res[2].Calls[0].ReturnData), crypto.Keccak256Hash(rlp)); err != nil { return err } return nil @@ -1130,11 +1135,18 @@ var EthMulticall = MethodTests{ BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(10)), }, - Calls: []TransactionArgs{{ - From: &common.Address{0xc0}, - To: &common.Address{0xc2}, - Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000002"), - }}, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("ee82ac5e0000000000000000000000000000000000000000000000000000000000000002"), + }, + }, }, { BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(20)), @@ -1154,27 +1166,28 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - for i := 0; i < len(res); i++ { - if len(res[i].Calls) != 1 { - return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[i].Calls), 1) - } - if res[i].Calls[0].Status != 0x1 { - return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].Calls[0].Status, 0x1) - } - } - if err := checkBlockNumber(res[0].Number, 10); err != nil { return err } if err := checkBlockNumber(res[1].Number, 20); err != nil { return err } + + rlp_1, rlpError := rlp.EncodeToBytes([][]byte{res[0].Calls[0].ReturnData, big.NewInt(int64(2)).Bytes()}) + if rlpError != nil { + return rlpError + } //keccack256(rlp([blockhash_1, 2]) - if err := checkBlockHash(common.BytesToHash(res[0].Calls[0].ReturnData), common.BytesToHash(*hex2Bytes("b71624aa776736b9a340cae6a536e93c71e376907a5b23c196aa056450a2b983"))); err != nil { + if err := checkBlockHash(common.BytesToHash(res[0].Calls[1].ReturnData), crypto.Keccak256Hash(rlp_1)); err != nil { return err } + + rlp_10, rlpError := rlp.EncodeToBytes([][]byte{res[0].Hash.Bytes(), big.NewInt(int64(19)).Bytes()}) + if rlpError != nil { + return rlpError + } //keccack256(rlp([blockhash_10, 19]) - if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnData), common.BytesToHash(*hex2Bytes("5679ee58a0ff6a8fa7b177db27c76774f1ddc04464d1999aad7aba7ac911593b"))); err != nil { + if err := checkBlockHash(common.BytesToHash(res[1].Calls[0].ReturnData), crypto.Keccak256Hash(rlp_10)); err != nil { return err } From 990adf682211915abdb45dda4bb17f889af227c9 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 24 Oct 2023 04:58:50 +0300 Subject: [PATCH 46/59] add couple tests --- testgen/generators.go | 188 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index 50a1d79..2ec7ae9 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1297,6 +1297,67 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-run-gas-spending", + "spend a lot gas in separate blocks", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, + common.Address{0xc2}: OverrideAccount{ + Code: gasSpender(), + }, + }, + BlockOverrides: &BlockOverrides{ + GasLimit: getUint64Ptr(1500000), + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("815b8ab40000000000000000000000000000000000000000000000000000000000000000"), //spendGas(0) + }, + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("815b8ab40000000000000000000000000000000000000000000000000000000000000000"), //spendGas(0) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + }, + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("815b8ab40000000000000000000000000000000000000000000000000000000000000000"), //spendGas(0) + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("815b8ab400000000000000000000000000000000000000000000000000000000000f4240"), //spendGas(1000000) + }, + }, + }, + }, + } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") + return nil + }, + }, { "multicall-eth-send-should-produce-logs", "when sending eth we should get ETH logs when traceTransfers is set", @@ -2751,6 +2812,133 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-contract-calls-itself", + "contract calls itself", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, + }, + }, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-long-block-distances", + "check that parameters adjust the same way when there's big distances between block numbers", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc1}, + To: &common.Address{0xc0}, + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10)), + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc1}, + To: &common.Address{0xc0}, + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(100)), + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc1}, + To: &common.Address{0xc0}, + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(101)), + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc1}, + To: &common.Address{0xc0}, + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(1000)), + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc1}, + To: &common.Address{0xc0}, + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10000)), + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc1}, + To: &common.Address{0xc0}, + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(10001)), + }, + }, + { + Calls: []TransactionArgs{ + { + From: &common.Address{0xc1}, + To: &common.Address{0xc0}, + }, + }, + BlockOverrides: &BlockOverrides{ + Number: (*hexutil.Big)(big.NewInt(100000)), + }, + }, + }, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, }, } From d43c9cb0d502d973d714a1fe7904c77fabe4de20 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 24 Oct 2023 16:15:11 +0300 Subject: [PATCH 47/59] add couple more tests --- testgen/generators.go | 99 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index 2ec7ae9..98d808e 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2939,6 +2939,105 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-self-destructive-contract-produces-logs", + "self destructive contract produces logs", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: selfDestructor(), + Balance: newRPCBalance(2000000), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc2}, + Input: hex2Bytes("83197ef0"), //destroy() + }}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-no-fields-call", + "make a call with no fields", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + Calls: []TransactionArgs{{}}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-only-from-transaction", + "make a call with only from field", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + }}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-only-from-to-transaction", + "make a call with only from and to fields", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + }}, + }}, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, + { + "multicall-big-block-state-calls-array", + "Have a block state calls with 300 blocks", + func(ctx context.Context, t *T) error { + calls := make([]CallBatch, 300) + params := multicallOpts{ + BlockStateCalls: calls, + TraceTransfers: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + return nil + }, + }, }, } From c01f6062d9df976cd330b8c2f1b738093a0659ae Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 3 Nov 2023 05:16:23 +0200 Subject: [PATCH 48/59] test fixing --- testgen/generators.go | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 98d808e..79426dd 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -403,6 +403,39 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-simple-with-validation-no-funds", + "simulates a multicall transfer with validation and not enough funds", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(1000)}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Value: *newRPCBalance(1000), + }, { + From: &common.Address{0xc1}, + To: &common.Address{0xc2}, + Value: *newRPCBalance(1000), + }}, + }, + }, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, { "multicall-simple-no-funds", "simulates a simple multicall transfer when account has no funds", @@ -2977,9 +3010,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -2996,9 +3027,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, From acaa5d3dc122e40028ecbf1dd8c671c872b39217 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 17 Nov 2023 15:15:27 +0200 Subject: [PATCH 49/59] fix couple tests, add contract test, add nonce test --- testgen/generators.go | 132 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 119 insertions(+), 13 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 229415a..10fa794 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -545,6 +545,112 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-overwrite-existing-contract", + "overwrites existing contract with new contract", + func(ctx context.Context, t *T) error { + contractAddr := common.HexToAddress("0000000000000000000000000000000000031ec7") + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &contractAddr, + Input: hex2Bytes("a9059cbb0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000a"), // transfer(address,uint256) + }}, + }, + { + StateOverrides: &StateOverride{ + contractAddr: OverrideAccount{Code: getBlockProperties()}, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &contractAddr, + Input: hex2Bytes("a9059cbb0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000a"), // transfer(address,uint256) + }}, + }, + }, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, + + { + "multicall-overflow-nonce", + "test to overflow nonce", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(0xFFFFFFFFFFFFFFFF)}, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + }, + }, + }, + }, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, + { + "multicall-overflow-nonce-validation", + "test to overflow nonce-validation", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{Nonce: getUint64Ptr(0xFFFFFFFFFFFFFFFF)}, + }, + Calls: []TransactionArgs{ + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + }, + { + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + }, + }, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + return nil + }, + }, { "multicall-simple-no-funds-with-balance-querying", "simulates a simple multicall transfer when account has no funds with querying balances before and after", @@ -1131,7 +1237,7 @@ var EthMulticall = MethodTests{ if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if err := checkBlockNumber(res[0].Number, 4); err != nil { + if err := checkBlockNumber(res[0].Number, 10); err != nil { return err } if len(res[0].Calls) != 1 { @@ -1158,7 +1264,7 @@ var EthMulticall = MethodTests{ }, }, BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), }, Calls: []TransactionArgs{{ From: &common.Address{0xc0}, @@ -1172,7 +1278,7 @@ var EthMulticall = MethodTests{ Calls: []TransactionArgs{{ From: &common.Address{0xc0}, To: &common.Address{0xc2}, - Input: hex2Bytes("ee82ac5e000000000000000000000000000000000000000000000000000000000000000a"), + Input: hex2Bytes("ee82ac5e000000000000000000000000000000000000000000000000000000000000000f"), }}, }, { BlockOverrides: &BlockOverrides{ @@ -1201,7 +1307,7 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected status value(have: %d, want: %d)", res[i].Calls[0].Status, 0x1) } } - if err := checkBlockNumber(res[0].Number, 10); err != nil { + if err := checkBlockNumber(res[0].Number, 15); err != nil { return err } if err := checkBlockNumber(res[1].Number, 20); err != nil { @@ -1245,7 +1351,7 @@ var EthMulticall = MethodTests{ }, }, BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), }, Calls: []TransactionArgs{ { @@ -1278,7 +1384,7 @@ var EthMulticall = MethodTests{ return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } - if err := checkBlockNumber(res[0].Number, 10); err != nil { + if err := checkBlockNumber(res[0].Number, 15); err != nil { return err } if err := checkBlockNumber(res[1].Number, 20); err != nil { @@ -2617,7 +2723,7 @@ var EthMulticall = MethodTests{ BlockStateCalls: []CallBatch{ { BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), Time: getUint64Ptr(100), }, }, @@ -2693,7 +2799,7 @@ var EthMulticall = MethodTests{ }, }, BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), Time: getUint64Ptr(100), GasLimit: getUint64Ptr(190000), FeeRecipient: &common.Address{0xc0}, @@ -2767,7 +2873,7 @@ var EthMulticall = MethodTests{ }, }, BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), }, Calls: []TransactionArgs{ { @@ -2788,7 +2894,7 @@ var EthMulticall = MethodTests{ }, { BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(11)), + Number: (*hexutil.Big)(big.NewInt(16)), }, Calls: []TransactionArgs{ { @@ -2818,7 +2924,7 @@ var EthMulticall = MethodTests{ }, }, BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), }, Calls: []TransactionArgs{ { @@ -2883,7 +2989,7 @@ var EthMulticall = MethodTests{ }, }, BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), FeeRecipient: &common.Address{0xc2}, BaseFee: (*hexutil.Big)(big.NewInt(10)), }, @@ -2972,7 +3078,7 @@ var EthMulticall = MethodTests{ }, }, BlockOverrides: &BlockOverrides{ - Number: (*hexutil.Big)(big.NewInt(10)), + Number: (*hexutil.Big)(big.NewInt(15)), }, }, { From 959ae5543c5bd2eabd90ae0ffd2b6db461dd6df8 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Fri, 17 Nov 2023 15:55:30 +0200 Subject: [PATCH 50/59] add test for block that we don't have --- testgen/generators.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index 10fa794..f1b9f57 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2129,6 +2129,26 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-make-call-with-future-block", + "start multicall with future block", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{ + { + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, + }}, + }, + }, + Validation: true, + } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "0x111") + return nil + }, + }, { "multicall-check-that-nonce-increases", "check that nonce increases", From 8df084faa9ae3854d83376bbcec03f46b0dafc61 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 20 Nov 2023 22:02:41 +0200 Subject: [PATCH 51/59] fix some tests --- testgen/generators.go | 55 +++++++++++++------------------------------ 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index f1b9f57..7b01ed0 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -536,9 +536,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -708,9 +706,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -801,9 +797,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -883,9 +877,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -911,9 +903,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -933,11 +923,11 @@ var EthMulticall = MethodTests{ { From: &common.Address{0xc0}, To: &common.Address{0xc1}, - Value: *newRPCBalance(1000), + Value: *newRPCBalance(2000), }, { From: &common.Address{0xc0}, To: &common.Address{0xc3}, - Value: *newRPCBalance(1000), + Value: *newRPCBalance(2000), }, }, }, { @@ -958,9 +948,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -2167,13 +2155,13 @@ var EthMulticall = MethodTests{ Nonce: getUint64Ptr(0), }, { - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, Nonce: getUint64Ptr(1), }, { - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, Nonce: getUint64Ptr(2), }, }, @@ -2182,9 +2170,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -2224,9 +2210,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -3002,7 +2986,7 @@ var EthMulticall = MethodTests{ { StateOverrides: &StateOverride{ common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(2000000), + Balance: newRPCBalance(200000000), }, common.Address{0xc1}: OverrideAccount{ Code: getBalanceGetter(), @@ -3261,14 +3245,9 @@ var EthMulticall = MethodTests{ "Have a block state calls with 300 blocks", func(ctx context.Context, t *T) error { calls := make([]CallBatch, 300) - params := multicallOpts{ - BlockStateCalls: calls, - TraceTransfers: true, - } + params := multicallOpts{BlockStateCalls: calls} res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, From 23b2d3557c30a2214df2a4a5145fdb3b95d061a4 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 20 Nov 2023 22:15:40 +0200 Subject: [PATCH 52/59] test fixing --- testgen/generators.go | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 7b01ed0..11cf515 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -537,9 +537,6 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, @@ -640,12 +637,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { - return err - } - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } + t.rpc.Call(&res, "eth_multicallV1", params, "latest") return nil }, }, @@ -798,9 +790,6 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, @@ -878,9 +867,6 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, @@ -904,9 +890,6 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, @@ -917,7 +900,7 @@ var EthMulticall = MethodTests{ params := multicallOpts{ BlockStateCalls: []CallBatch{{ StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(2000)}, + common.Address{0xc0}: OverrideAccount{Balance: newRPCBalance(5000)}, }, Calls: []TransactionArgs{ { @@ -932,7 +915,7 @@ var EthMulticall = MethodTests{ }, }, { StateOverrides: &StateOverride{ - {0xc3}: OverrideAccount{Balance: newRPCBalance(0)}, + {0xc3}: OverrideAccount{Balance: newRPCBalance(5000)}, }, Calls: []TransactionArgs{ { @@ -949,9 +932,6 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, @@ -2195,13 +2175,13 @@ var EthMulticall = MethodTests{ Nonce: getUint64Ptr(0), }, { - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, Nonce: getUint64Ptr(1), }, { - From: &common.Address{0xc1}, - To: &common.Address{0xc1}, + From: &common.Address{0xc0}, + To: &common.Address{0xc0}, Nonce: getUint64Ptr(0), }, }, @@ -2211,9 +2191,6 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, From b5138d72d3873afaa599912d21a4ad7c99747fbc Mon Sep 17 00:00:00 2001 From: KillariDev Date: Mon, 27 Nov 2023 17:04:35 +0200 Subject: [PATCH 53/59] add ecrecover move test, increase gas limits and tmie --- testgen/generators.go | 56 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 11cf515..26bf75a 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -2798,8 +2798,8 @@ var EthMulticall = MethodTests{ { BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(20)), - Time: getUint64Ptr(200), - GasLimit: getUint64Ptr(190001), + Time: getUint64Ptr(2000), + GasLimit: getUint64Ptr(300000), FeeRecipient: &common.Address{0xc1}, PrevRandao: &prevRandDao2, BaseFee: (*hexutil.Big)(big.NewInt(20)), @@ -2815,7 +2815,7 @@ var EthMulticall = MethodTests{ { BlockOverrides: &BlockOverrides{ Number: (*hexutil.Big)(big.NewInt(21)), - Time: getUint64Ptr(300), + Time: getUint64Ptr(30000), GasLimit: getUint64Ptr(190002), FeeRecipient: &common.Address{0xc2}, PrevRandao: &prevRandDao3, @@ -3228,6 +3228,56 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-move-ecrecover-and-call-old-and-new", + "move ecrecover and try calling the moved and non-moved version", + func(ctx context.Context, t *T) error { + ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) + ecRecoverMovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ // move ecRecover and call it in new address + ecRecoverAddress: OverrideAccount{ + MovePrecompileToAddress: &ecRecoverMovedToAddress, + }, + }, + Calls: []TransactionArgs{ + { // call new address with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call new address with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + { // call old address with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call old address with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + }, + }}, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if len(res) != len(params.BlockStateCalls) { + return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) + } + if len(res[0].Calls) != len(params.BlockStateCalls[0].Calls) { + return fmt.Errorf("unexpected number of call results (have: %d, want: %d)", len(res[0].Calls), len(params.BlockStateCalls[0].Calls)) + } + return nil + }, + }, }, } From 6594bbd7c200e0397841070c674294052aad292e Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 12 Dec 2023 15:56:00 +0200 Subject: [PATCH 54/59] add delegate call tests --- testgen/generators.go | 117 ++++++++++++++++++++++++++++++++++++++++++ testgen/utils.go | 52 ++++++++++++++++++- 2 files changed, 168 insertions(+), 1 deletion(-) diff --git a/testgen/generators.go b/testgen/generators.go index 26bf75a..cf33e11 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -3138,6 +3138,123 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-send-eth-and-delegate-call", + "sending eth and delegate calling should only produce one log", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: delegateCaller(), + }, + common.Address{0xc2}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("5c19a95c000000000000000000000000c200000000000000000000000000000000000000"), + Value: *newRPCBalance(1000), + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if res[0].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if len(res[0].Calls[0].Logs) != 1 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 1) + } + return nil + }, + }, + { + "multicall-send-eth-and-delegate-call-to-payble-contract", + "sending eth and delegate calling a payable contract should only produce one log", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: delegateCaller2(), + }, + common.Address{0xc2}: OverrideAccount{ + Code: payableFallBack(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + Value: *newRPCBalance(1000), + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if res[0].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if len(res[0].Calls[0].Logs) != 1 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 1) + } + return nil + }, + }, + { + "multicall-send-eth-and-delegate-call-to-eoa", + "sending eth and delegate calling a eoa should only produce one log", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: delegateCaller2(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes(""), + Value: *newRPCBalance(1000), + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if res[0].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if len(res[0].Calls[0].Logs) != 1 { + return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 1) + } + return nil + }, + }, { "multicall-self-destructive-contract-produces-logs", "self destructive contract produces logs", diff --git a/testgen/utils.go b/testgen/utils.go index 2d25aea..aefa2bb 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -1,8 +1,8 @@ package testgen import ( - "errors" "bytes" + "errors" "fmt" "github.com/ethereum/go-ethereum/common" @@ -250,6 +250,56 @@ func getBlockProperties() *hexutil.Bytes { */ return hex2Bytes("608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033") } +func payableFallBack() *hexutil.Bytes { + /* + pragma solidity ^0.8.18; + contract payableFallBack { + fallback (bytes calldata input) external payable returns (bytes memory) {} + } + */ + return hex2Bytes("60806040525f366060915050805190602001f3fea2646970667358221220a6fbca1301e2861ff1227c7478f4351a0978cca210732aaf5d036123a0d2f68664736f6c63430008160033") +} + +func delegateCaller() *hexutil.Bytes { + /* + pragma solidity ^0.8.20; + + contract delegateCaller { + function delegate(address contract) public payable returns (bool success, bytes memory data) { + return contract.delegatecall(""); + } + } + */ + return hex2Bytes("60806040526004361061001d575f3560e01c80635c19a95c14610021575b5f80fd5b61003b6004803603810190610036919061011d565b610052565b6040516100499291906101ec565b60405180910390f35b5f60608273ffffffffffffffffffffffffffffffffffffffff1660405161007890610247565b5f60405180830381855af49150503d805f81146100b0576040519150601f19603f3d011682016040523d82523d5f602084013e6100b5565b606091505b5091509150915091565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100ec826100c3565b9050919050565b6100fc816100e2565b8114610106575f80fd5b50565b5f81359050610117816100f3565b92915050565b5f60208284031215610132576101316100bf565b5b5f61013f84828501610109565b91505092915050565b5f8115159050919050565b61015c81610148565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561019957808201518184015260208101905061017e565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6101be82610162565b6101c8818561016c565b93506101d881856020860161017c565b6101e1816101a4565b840191505092915050565b5f6040820190506101ff5f830185610153565b818103602083015261021181846101b4565b90509392505050565b5f81905092915050565b50565b5f6102325f8361021a565b915061023d82610224565b5f82019050919050565b5f61025182610227565b915081905091905056fea2646970667358221220c79623409cf56de66f689f36463cb9aa88ed853501e557889625b16b1a602b2764736f6c63430008160033") +} + +func delegateCaller2() *hexutil.Bytes { + /* + + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.20; + + contract delegateCaller2 { + fallback() external payable{ + // solium-disable-next-line security/no-inline-assembly + assembly { + let masterCopy := and(0x000000000000000000000000c200000000000000000000000000000000000000, 0xffffffffffffffffffffffffffffffffffffffff) + // 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s + if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) { + mstore(0, masterCopy) + return(0, 0x20) + } + calldatacopy(0, 0, calldatasize()) + let success := delegatecall(gas(), masterCopy, 0, calldatasize(), 0, 0) + returndatacopy(0, 0, returndatasize()) + if eq(success, 0) { revert(0, returndatasize()) } + return(0, returndatasize()) + } + } + } + */ + return hex2Bytes("608060405273ffffffffffffffffffffffffffffffffffffffff73c200000000000000000000000000000000000000167fa619486e000000000000000000000000000000000000000000000000000000005f3503605e57805f5260205ff35b365f80375f80365f845af43d5f803e5f81036077573d5ffd5b3d5ff3fea26469706673582212206b787fe3e60b14a5c449d37005afac7b1803ee7c87e12d2740b96a158f34802a64736f6c63430008160033") +} func getUint64Ptr(value hexutil.Uint64) *hexutil.Uint64 { newUint64 := new(hexutil.Uint64) From e927c41df66cd57907c2c5b368ca95463df3b3b5 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 12 Dec 2023 16:49:25 +0200 Subject: [PATCH 55/59] test for 0xeee eth log --- testgen/generators.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index cf33e11..bb1065f 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1571,6 +1571,9 @@ var EthMulticall = MethodTests{ if len(res[0].Calls[0].Logs) != 1 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 1) } + if res[0].Calls[0].Logs[0].Address.String() != "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" { + return fmt.Errorf("unexpected log address (have: %s, want: %s)", res[0].Calls[0].Logs[0].Address.String(), "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + } return nil }, }, From 3fd7d70ab18568aa5417e529074a797f3ae4a7a1 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Wed, 13 Dec 2023 11:59:28 +0200 Subject: [PATCH 56/59] add tests for extcodehash and precompiles --- testgen/generators.go | 285 ++++++++++++++++++++++++++++++++++-------- testgen/utils.go | 34 +++++ 2 files changed, 264 insertions(+), 55 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index bb1065f..a0d3465 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1966,61 +1966,6 @@ var EthMulticall = MethodTests{ return nil }, }, - { - "multicall-move-account-twice", - "Move one account twice", - func(ctx context.Context, t *T) error { - params := multicallOpts{ - BlockStateCalls: []CallBatch{{ - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(1000), - }, - common.Address{0xc2}: OverrideAccount{ - Balance: newRPCBalance(2000), - }, - common.Address{0xc3}: OverrideAccount{ - Balance: newRPCBalance(3000), - }, - common.Address{0xc4}: OverrideAccount{ - Code: getBalanceGetter(), - }, - }, - }, { - StateOverrides: &StateOverride{ - common.Address{0xc0}: OverrideAccount{ - Balance: newRPCBalance(3000), - MovePrecompileToAddress: &common.Address{0xc2}, - }, - common.Address{0xc2}: OverrideAccount{ - Balance: newRPCBalance(4000), - MovePrecompileToAddress: &common.Address{0xc3}, - }, - }, - Calls: []TransactionArgs{ - { - From: &common.Address{0xc0}, - To: &common.Address{0xc4}, - Input: hex2Bytes("f8b2cb4f000000000000000000000000c000000000000000000000000000000000000000"), // gets balance of c0 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc4}, - Input: hex2Bytes("f8b2cb4f000000000000000000000000c200000000000000000000000000000000000000"), // gets balance of c2 - }, - { - From: &common.Address{0xc0}, - To: &common.Address{0xc4}, - Input: hex2Bytes("f8b2cb4f000000000000000000000000c300000000000000000000000000000000000000"), // gets balance of c3 - }, - }, - }}, - } - res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") - return nil - }, - }, { "multicall-move-two-non-precompiles-accounts-to-same", "Move two non-precompiles to same adddress", @@ -2280,6 +2225,11 @@ var EthMulticall = MethodTests{ To: &ecRecoverMovedToAddress, Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), }, + { // call with valid params, the old address, should fail as it was moved + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, }, }}, } @@ -2296,6 +2246,85 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-move-ecrecover-twice-and-call", + "move ecrecover and try calling it, then move it again and call it", + func(ctx context.Context, t *T) error { + ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) + ecRecoverMovedToAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123456")) + ecRecoverMovedToAddress2 := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000123457")) + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + Calls: []TransactionArgs{ // just call ecrecover normally + { // call with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + }, + }, { + StateOverrides: &StateOverride{ // move ecRecover and call it in new address + ecRecoverAddress: OverrideAccount{ + MovePrecompileToAddress: &ecRecoverMovedToAddress, + }, + }, + Calls: []TransactionArgs{ + { // call with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + { // call with valid params, the old address, should fail as it was moved + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + }, + }, { + StateOverrides: &StateOverride{ // move ecRecover and call it in new address + ecRecoverAddress: OverrideAccount{ + MovePrecompileToAddress: &ecRecoverMovedToAddress2, + }, + }, + Calls: []TransactionArgs{ + { // call with invalid params, should fail (resolve to 0x0) + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + { // call with valid params, the old address, should fail as it was moved + From: &common.Address{0xc1}, + To: &ecRecoverAddress, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + { // call with valid params, should resolve to 0xb11CaD98Ad3F8114E0b3A1F6E7228bc8424dF48a + From: &common.Address{0xc1}, + To: &ecRecoverMovedToAddress2, + Input: hex2Bytes("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9"), + }, + }, + }}, + } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") + return nil + }, + }, { "multicall-override-ecrecover", "override ecrecover", @@ -3258,6 +3287,152 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-extcodehash-override", + "test extcodehash getting of overriden contract", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc0}: OverrideAccount{ + Balance: newRPCBalance(2000000), + }, + common.Address{0xc1}: OverrideAccount{ + Code: extCodeHashContract(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("b9724d63000000000000000000000000c200000000000000000000000000000000000000"), // getExtCodeHash(0xc2) + }}, + }, { + StateOverrides: &StateOverride{ + common.Address{0xc2}: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("b9724d63000000000000000000000000c200000000000000000000000000000000000000"), // getExtCodeHash(0xc2) + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if res[0].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if res[1].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if res[0].Calls[0].ReturnData.String() == res[1].Calls[0].ReturnData.String() { + return fmt.Errorf("returndata did not change (have: %s, want: %s)", res[0].Calls[0].ReturnData.String(), res[1].Calls[0].ReturnData.String()) + } + return nil + }, + }, + { + "multicall-extcodehash-existing-contract", + "test extcodehash getting of existing contract and then overriding it", + func(ctx context.Context, t *T) error { + contractAddr := common.HexToAddress("0000000000000000000000000000000000031ec7") + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + Code: extCodeHashContract(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("b9724d630000000000000000000000000000000000000000000000000000000000031ec7"), // getExtCodeHash(0000000000000000000000000000000000031ec7) + }}, + }, { + StateOverrides: &StateOverride{ + contractAddr: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("b9724d630000000000000000000000000000000000000000000000000000000000031ec7"), // getExtCodeHash(0000000000000000000000000000000000031ec7) + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if res[0].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if res[1].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if res[0].Calls[0].ReturnData.String() == res[1].Calls[0].ReturnData.String() { + return fmt.Errorf("returndata did not change (have: %s, want: %s)", res[0].Calls[0].ReturnData.String(), res[1].Calls[0].ReturnData.String()) + } + return nil + }, + }, + { + "multicall-extcodehash-precompile", + "test extcodehash getting of precompile and then again after override", + func(ctx context.Context, t *T) error { + ecRecoverAddress := common.BytesToAddress(*hex2Bytes("0000000000000000000000000000000000000001")) + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + StateOverrides: &StateOverride{ + common.Address{0xc1}: OverrideAccount{ + Code: extCodeHashContract(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("b9724d630000000000000000000000000000000000000000000000000000000000000001"), // getExtCodeHash(0x1) + }}, + }, { + StateOverrides: &StateOverride{ + ecRecoverAddress: OverrideAccount{ + Code: getBlockProperties(), + }, + }, + Calls: []TransactionArgs{{ + From: &common.Address{0xc0}, + To: &common.Address{0xc1}, + Input: hex2Bytes("b9724d630000000000000000000000000000000000000000000000000000000000000001"), // getExtCodeHash(0x1) + }}, + }}, + TraceTransfers: true, + Validation: false, + } + res := make([]blockResult, 0) + if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + return err + } + if res[0].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if res[1].Calls[0].Status != 1 { + return fmt.Errorf("unexpected call status (have: %d, want: %d)", res[0].Calls[0].Status, 1) + } + if res[0].Calls[0].ReturnData.String() == res[1].Calls[0].ReturnData.String() { + return fmt.Errorf("returndata did not change (have: %s, want: %s)", res[0].Calls[0].ReturnData.String(), res[1].Calls[0].ReturnData.String()) + } + return nil + }, + }, { "multicall-self-destructive-contract-produces-logs", "self destructive contract produces logs", diff --git a/testgen/utils.go b/testgen/utils.go index aefa2bb..cb7c083 100644 --- a/testgen/utils.go +++ b/testgen/utils.go @@ -301,6 +301,40 @@ func delegateCaller2() *hexutil.Bytes { return hex2Bytes("608060405273ffffffffffffffffffffffffffffffffffffffff73c200000000000000000000000000000000000000167fa619486e000000000000000000000000000000000000000000000000000000005f3503605e57805f5260205ff35b365f80375f80365f845af43d5f803e5f81036077573d5ffd5b3d5ff3fea26469706673582212206b787fe3e60b14a5c449d37005afac7b1803ee7c87e12d2740b96a158f34802a64736f6c63430008160033") } +func extCodeHashContract() *hexutil.Bytes { + /* + pragma solidity ^0.8.18; + contract exCodeHashContract { + function isContract(address account) public view returns (bool) { + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + bytes32 codeHash; + assembly { codeHash := extcodehash(account) } + return (codeHash != accountHash && codeHash != 0x0); + } + function getExtCodeHash(address account) public view returns (bytes32) { + bytes32 codeHash; + assembly { codeHash := extcodehash(account) } + return codeHash; + } + function at(address _addr) public view returns (bytes memory o_code) { + assembly { + // retrieve the size of the code, this needs assembly + let size := extcodesize(_addr) + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), xor(0x1f, not(0))))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(_addr, add(o_code, 0x20), 0, size) + } + } + */ + return hex2Bytes("608060405234801561000f575f80fd5b506004361061003f575f3560e01c80631627905514610043578063b9724d6314610073578063dce4a447146100a3575b5f80fd5b61005d600480360381019061005891906101b3565b6100d3565b60405161006a91906101f8565b60405180910390f35b61008d600480360381019061008891906101b3565b61011a565b60405161009a9190610229565b60405180910390f35b6100bd60048036038101906100b891906101b3565b610129565b6040516100ca91906102cc565b60405180910390f35b5f807fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4705f1b90505f833f905081811415801561011157505f801b8114155b92505050919050565b5f80823f905080915050919050565b6060813b60405191505f19601f18601f6020830101168201604052808252805f60208401853c50919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61018282610159565b9050919050565b61019281610178565b811461019c575f80fd5b50565b5f813590506101ad81610189565b92915050565b5f602082840312156101c8576101c7610155565b5b5f6101d58482850161019f565b91505092915050565b5f8115159050919050565b6101f2816101de565b82525050565b5f60208201905061020b5f8301846101e9565b92915050565b5f819050919050565b61022381610211565b82525050565b5f60208201905061023c5f83018461021a565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561027957808201518184015260208101905061025e565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61029e82610242565b6102a8818561024c565b93506102b881856020860161025c565b6102c181610284565b840191505092915050565b5f6020820190508181035f8301526102e48184610294565b90509291505056fea26469706673582212206a23e83d04cb5f5ab00353d719afd8181b39baa39277b8cfa111197637a4f26064736f6c63430008160033") +} + func getUint64Ptr(value hexutil.Uint64) *hexutil.Uint64 { newUint64 := new(hexutil.Uint64) newUint64 = &value From 7eb1a56fef4fc21d56198faa97ef95e57b544fb0 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Tue, 19 Dec 2023 09:54:33 +0200 Subject: [PATCH 57/59] test fixing --- testgen/generators.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index a0d3465..0073ad1 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -699,9 +699,6 @@ var EthMulticall = MethodTests{ } res := make([]blockResult, 0) t.rpc.Call(&res, "eth_multicallV1", params, "latest") - if len(res) != len(params.BlockStateCalls) { - return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) - } return nil }, }, @@ -1571,8 +1568,8 @@ var EthMulticall = MethodTests{ if len(res[0].Calls[0].Logs) != 1 { return fmt.Errorf("unexpected number of logs (have: %d, want: %d)", len(res[0].Calls[0].Logs), 1) } - if res[0].Calls[0].Logs[0].Address.String() != "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" { - return fmt.Errorf("unexpected log address (have: %s, want: %s)", res[0].Calls[0].Logs[0].Address.String(), "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") + if res[0].Calls[0].Logs[0].Address.String() != "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" { + return fmt.Errorf("unexpected log address (have: %s, want: %s)", res[0].Calls[0].Logs[0].Address.String(), "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE") } return nil }, From 266301255494b8f220093149117e311ca5442445 Mon Sep 17 00:00:00 2001 From: KillariDev Date: Thu, 11 Jan 2024 12:04:06 +0200 Subject: [PATCH 58/59] add a test for zero maxfeepergas --- testgen/generators.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/testgen/generators.go b/testgen/generators.go index 0073ad1..9ba3adb 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -1886,6 +1886,26 @@ var EthMulticall = MethodTests{ return nil }, }, + { + "multicall-basefee-too-low-without-validation-38012-without-basefee-override", + "tries to send transaction with zero basefee", + func(ctx context.Context, t *T) error { + params := multicallOpts{ + BlockStateCalls: []CallBatch{{ + Calls: []TransactionArgs{{ + From: &common.Address{0xc1}, + To: &common.Address{0xc1}, + MaxFeePerGas: (*hexutil.Big)(big.NewInt(0)), + MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(0)), + }}, + }}, + Validation: false, + } + res := make([]blockResult, 0) + t.rpc.Call(&res, "eth_multicallV1", params, "latest") + return nil + }, + }, { "multicall-instrict-gas-38013", "Error: Not enough gas provided to pay for intrinsic gas (-38013)", From e637159f3cb9dc77b2f80e33299de5b452f8356e Mon Sep 17 00:00:00 2001 From: KillariDev Date: Thu, 11 Jan 2024 13:29:18 +0200 Subject: [PATCH 59/59] rename to simulateV1 --- testgen/generators.go | 166 +++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/testgen/generators.go b/testgen/generators.go index 9ba3adb..0825d47 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -448,7 +448,7 @@ var EthCall = MethodTests{ // EthMulticall stores a list of all tests against the method. var EthMulticall = MethodTests{ - "eth_multicallV1", + "eth_simulateV1", []Test{ { "multicall-simple", @@ -473,7 +473,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -506,7 +506,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -536,7 +536,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -568,7 +568,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -603,7 +603,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -637,7 +637,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -698,7 +698,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -754,7 +754,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -786,7 +786,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -812,7 +812,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -835,7 +835,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -863,7 +863,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -886,7 +886,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -928,7 +928,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -966,7 +966,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1007,7 +1007,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1029,7 +1029,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1051,7 +1051,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1073,7 +1073,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1102,7 +1102,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1132,7 +1132,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]interface{}, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1168,7 +1168,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1196,7 +1196,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1257,7 +1257,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1342,7 +1342,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1424,7 +1424,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, (*hexutil.Big)(big.NewInt(1))); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1476,7 +1476,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1537,7 +1537,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1559,7 +1559,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1593,7 +1593,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1603,7 +1603,7 @@ var EthMulticall = MethodTests{ func(ctx context.Context, t *T) error { params := multicallOpts{} res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1625,7 +1625,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1659,7 +1659,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -1684,7 +1684,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1716,7 +1716,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1749,7 +1749,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1778,7 +1778,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1807,7 +1807,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1825,7 +1825,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -1856,7 +1856,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1882,7 +1882,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1902,7 +1902,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1920,7 +1920,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1938,7 +1938,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1957,7 +1957,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -1979,7 +1979,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -2000,7 +2000,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -2023,7 +2023,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -2058,7 +2058,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -2078,7 +2078,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "0x111") + t.rpc.Call(&res, "eth_simulateV1", params, "0x111") return nil }, }, @@ -2115,7 +2115,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") if len(res) != len(params.BlockStateCalls) { return fmt.Errorf("unexpected number of results (have: %d, want: %d)", len(res), len(params.BlockStateCalls)) } @@ -2155,7 +2155,7 @@ var EthMulticall = MethodTests{ Validation: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -2178,7 +2178,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -2251,7 +2251,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -2338,7 +2338,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -2392,7 +2392,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -2451,7 +2451,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -2486,7 +2486,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -2510,7 +2510,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -2569,7 +2569,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -2628,7 +2628,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -2716,7 +2716,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -2772,7 +2772,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -2804,7 +2804,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -2881,7 +2881,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -2937,7 +2937,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -2997,7 +2997,7 @@ var EthMulticall = MethodTests{ }, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -3051,7 +3051,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) { @@ -3083,7 +3083,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -3181,7 +3181,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -3215,7 +3215,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if res[0].Calls[0].Status != 1 { @@ -3255,7 +3255,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if res[0].Calls[0].Status != 1 { @@ -3292,7 +3292,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if res[0].Calls[0].Status != 1 { @@ -3339,7 +3339,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if res[0].Calls[0].Status != 1 { @@ -3387,7 +3387,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if res[0].Calls[0].Status != 1 { @@ -3435,7 +3435,7 @@ var EthMulticall = MethodTests{ Validation: false, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if res[0].Calls[0].Status != 1 { @@ -3471,7 +3471,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -3488,7 +3488,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -3505,7 +3505,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -3523,7 +3523,7 @@ var EthMulticall = MethodTests{ TraceTransfers: true, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } return nil @@ -3536,7 +3536,7 @@ var EthMulticall = MethodTests{ calls := make([]CallBatch, 300) params := multicallOpts{BlockStateCalls: calls} res := make([]blockResult, 0) - t.rpc.Call(&res, "eth_multicallV1", params, "latest") + t.rpc.Call(&res, "eth_simulateV1", params, "latest") return nil }, }, @@ -3578,7 +3578,7 @@ var EthMulticall = MethodTests{ }}, } res := make([]blockResult, 0) - if err := t.rpc.Call(&res, "eth_multicallV1", params, "latest"); err != nil { + if err := t.rpc.Call(&res, "eth_simulateV1", params, "latest"); err != nil { return err } if len(res) != len(params.BlockStateCalls) {