From b492ab5460be055d8fd7e48f06aedd16cd165a3b Mon Sep 17 00:00:00 2001 From: Goran Rojovic Date: Sat, 10 Feb 2024 16:30:55 +0100 Subject: [PATCH] Tests fix --- consensus/polybft/blockchain_wrapper.go | 2 - consensus/polybft/contracts_initializer.go | 3 +- consensus/polybft/sc_integration_test.go | 21 ++++----- consensus/polybft/system_state_test.go | 5 +- helper/predeployment/predeployment.go | 1 - state/executor.go | 1 + state/runtime/evm/evm_fuzz_test.go | 9 ++++ state/runtime/evm/evm_test.go | 28 ++++++++++- state/runtime/evm/instructions_test.go | 47 +++++++++++++++---- .../precompiled/native_transfer_test.go | 28 +++++++++++ 10 files changed, 114 insertions(+), 31 deletions(-) diff --git a/consensus/polybft/blockchain_wrapper.go b/consensus/polybft/blockchain_wrapper.go index dfee8b4761..902f2bca19 100644 --- a/consensus/polybft/blockchain_wrapper.go +++ b/consensus/polybft/blockchain_wrapper.go @@ -12,7 +12,6 @@ import ( "github.com/0xPolygon/polygon-edge/consensus" "github.com/0xPolygon/polygon-edge/contracts" "github.com/0xPolygon/polygon-edge/state" - "github.com/0xPolygon/polygon-edge/state/runtime" "github.com/0xPolygon/polygon-edge/types" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/contract" @@ -219,7 +218,6 @@ func (s *stateProvider) Call(addr ethgo.Address, input []byte, opts *contract.Ca input, big.NewInt(0), 10000000, - runtime.NewAccessList(), ) if result.Failed() { return nil, result.Err diff --git a/consensus/polybft/contracts_initializer.go b/consensus/polybft/contracts_initializer.go index 810421dc1d..7d70f59646 100644 --- a/consensus/polybft/contracts_initializer.go +++ b/consensus/polybft/contracts_initializer.go @@ -10,7 +10,6 @@ import ( "github.com/0xPolygon/polygon-edge/contracts" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/state" - "github.com/0xPolygon/polygon-edge/state/runtime" "github.com/0xPolygon/polygon-edge/types" "github.com/umbracle/ethgo/abi" ) @@ -413,7 +412,7 @@ func approveEpochManagerAsSpender(polyBFTConfig PolyBFTConfig, transition *state // callContract calls given smart contract function, encoded in input parameter func callContract(from, to types.Address, input []byte, contractName string, transition *state.Transition) error { - result := transition.Call2(from, to, input, big.NewInt(0), contractCallGasLimit, runtime.NewAccessList()) + result := transition.Call2(from, to, input, big.NewInt(0), contractCallGasLimit) if result.Failed() { if result.Reverted() { if revertReason, err := abi.UnpackRevertError(result.ReturnValue); err == nil { diff --git a/consensus/polybft/sc_integration_test.go b/consensus/polybft/sc_integration_test.go index eef1781b34..daebb6db7d 100644 --- a/consensus/polybft/sc_integration_test.go +++ b/consensus/polybft/sc_integration_test.go @@ -23,7 +23,6 @@ import ( "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/state" - "github.com/0xPolygon/polygon-edge/state/runtime" "github.com/0xPolygon/polygon-edge/types" ) @@ -58,7 +57,7 @@ func TestIntegration_PerformExit(t *testing.T) { input, err := abi.GetMethod(function).Encode(args) require.NoError(t, err) - result := transition.Call2(deployerAddress, addr, input, big.NewInt(0), gasLimit, runtime.NewAccessList()) + result := transition.Call2(deployerAddress, addr, input, big.NewInt(0), gasLimit) require.True(t, result.Succeeded()) return result.ReturnValue @@ -119,7 +118,7 @@ func TestIntegration_PerformExit(t *testing.T) { }).EncodeAbi() require.NoError(t, err) - result := transition.Call2(deployerAddress, rootERC20Addr, mintInput, nil, gasLimit, runtime.NewAccessList()) + result := transition.Call2(deployerAddress, rootERC20Addr, mintInput, nil, gasLimit) require.NoError(t, result.Err) // approve @@ -129,7 +128,7 @@ func TestIntegration_PerformExit(t *testing.T) { }).EncodeAbi() require.NoError(t, err) - result = transition.Call2(senderAddress, rootERC20Addr, approveInput, big.NewInt(0), gasLimit, runtime.NewAccessList()) + result = transition.Call2(senderAddress, rootERC20Addr, approveInput, big.NewInt(0), gasLimit) require.NoError(t, result.Err) // deposit @@ -141,7 +140,7 @@ func TestIntegration_PerformExit(t *testing.T) { require.NoError(t, err) // send sync events to childchain so that receiver can obtain tokens - result = transition.Call2(senderAddress, rootERC20PredicateAddr, depositInput, big.NewInt(0), gasLimit, runtime.NewAccessList()) + result = transition.Call2(senderAddress, rootERC20PredicateAddr, depositInput, big.NewInt(0), gasLimit) require.NoError(t, result.Err) // simulate withdrawal from childchain to rootchain @@ -229,7 +228,7 @@ func TestIntegration_PerformExit(t *testing.T) { submitCheckpointEncoded, err := cm.abiEncodeCheckpointBlock(blockNumber, blockHash, extra, accSet) require.NoError(t, err) - result = transition.Call2(senderAddress, checkpointManagerAddr, submitCheckpointEncoded, big.NewInt(0), gasLimit, runtime.NewAccessList()) + result = transition.Call2(senderAddress, checkpointManagerAddr, submitCheckpointEncoded, big.NewInt(0), gasLimit) require.NoError(t, result.Err) require.Equal(t, getField(checkpointManagerAddr, contractsapi.CheckpointManager.Abi, "currentCheckpointBlockNumber")[31], uint8(1)) @@ -254,7 +253,7 @@ func TestIntegration_PerformExit(t *testing.T) { }).EncodeAbi() require.NoError(t, err) - result = transition.Call2(senderAddress, exitHelperContractAddress, exitFnInput, big.NewInt(0), gasLimit, runtime.NewAccessList()) + result = transition.Call2(senderAddress, exitHelperContractAddress, exitFnInput, big.NewInt(0), gasLimit) require.NoError(t, result.Err) // check that first exit event is processed @@ -381,7 +380,7 @@ func TestIntegration_CommitEpoch(t *testing.T) { require.NoError(t, err) // call commit epoch - result := transition.Call2(contracts.SystemCaller, contracts.EpochManagerContract, input, big.NewInt(0), 10000000000, runtime.NewAccessList()) + result := transition.Call2(contracts.SystemCaller, contracts.EpochManagerContract, input, big.NewInt(0), 10000000000) require.NoError(t, result.Err) t.Logf("Number of validators %d on commit epoch, Gas used %+v\n", accSet.Len(), result.GasUsed) @@ -390,7 +389,7 @@ func TestIntegration_CommitEpoch(t *testing.T) { require.NoError(t, err) // call commit epoch - result = transition.Call2(contracts.SystemCaller, contracts.EpochManagerContract, input, big.NewInt(0), 10000000000, runtime.NewAccessList()) + result = transition.Call2(contracts.SystemCaller, contracts.EpochManagerContract, input, big.NewInt(0), 10000000000) require.NoError(t, result.Err) t.Logf("Number of validators %d on commit epoch, Gas used %+v\n", accSet.Len(), result.GasUsed) } @@ -400,14 +399,14 @@ func deployAndInitContract(t *testing.T, transition *state.Transition, bytecode initCallback func() ([]byte, error)) types.Address { t.Helper() - deployResult := transition.Create2(sender, bytecode, big.NewInt(0), 1e9, runtime.NewAccessList()) + deployResult := transition.Create2(sender, bytecode, big.NewInt(0), 1e9) assert.NoError(t, deployResult.Err) if initCallback != nil { initInput, err := initCallback() require.NoError(t, err) - result := transition.Call2(sender, deployResult.Address, initInput, big.NewInt(0), 1e9, runtime.NewAccessList()) + result := transition.Call2(sender, deployResult.Address, initInput, big.NewInt(0), 1e9) require.NoError(t, result.Err) } diff --git a/consensus/polybft/system_state_test.go b/consensus/polybft/system_state_test.go index 8be1195954..ea001fe48b 100644 --- a/consensus/polybft/system_state_test.go +++ b/consensus/polybft/system_state_test.go @@ -9,7 +9,6 @@ import ( "github.com/0xPolygon/polygon-edge/contracts" "github.com/0xPolygon/polygon-edge/state" itrie "github.com/0xPolygon/polygon-edge/state/immutable-trie" - "github.com/0xPolygon/polygon-edge/state/runtime" "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" @@ -46,7 +45,7 @@ func TestSystemState_GetNextCommittedIndex(t *testing.T) { transition := newTestTransition(t, nil) // deploy a contract - result := transition.Create2(types.Address{}, bin, big.NewInt(0), 1000000000, runtime.NewAccessList()) + result := transition.Create2(types.Address{}, bin, big.NewInt(0), 1000000000) assert.NoError(t, result.Err) provider := &stateProvider{ @@ -93,7 +92,7 @@ func TestSystemState_GetEpoch(t *testing.T) { transition := newTestTransition(t, nil) // deploy a contract - result := transition.Create2(types.Address{}, bin, big.NewInt(0), 1000000000, runtime.NewAccessList()) + result := transition.Create2(types.Address{}, bin, big.NewInt(0), 1000000000) assert.NoError(t, result.Err) provider := &stateProvider{ diff --git a/helper/predeployment/predeployment.go b/helper/predeployment/predeployment.go index a655b79d27..56a56553ca 100644 --- a/helper/predeployment/predeployment.go +++ b/helper/predeployment/predeployment.go @@ -61,7 +61,6 @@ func getPredeployAccount(address types.Address, input []byte, big.NewInt(0), math.MaxInt64, input, - runtime.NewAccessList(), ) // Enable all forks diff --git a/state/executor.go b/state/executor.go index 9d396499cc..64548af852 100644 --- a/state/executor.go +++ b/state/executor.go @@ -224,6 +224,7 @@ func (e *Executor) BeginTxn( precompiles: precompiled.NewPrecompiled(), PostHook: e.PostHook, journal: &runtime.Journal{}, + accessList: runtime.NewAccessList(), } // enable contract deployment allow list (if any) diff --git a/state/runtime/evm/evm_fuzz_test.go b/state/runtime/evm/evm_fuzz_test.go index 933768b993..ed611e443f 100644 --- a/state/runtime/evm/evm_fuzz_test.go +++ b/state/runtime/evm/evm_fuzz_test.go @@ -138,6 +138,15 @@ func (m *mockHostF) GetRefund() uint64 { return m.refund } +func (m *mockHostF) AddSlotToAccessList(addr types.Address, slot types.Hash) {} +func (m *mockHostF) AddAddressToAccessList(addr types.Address) {} +func (m *mockHostF) ContainsAccessListAddress(addr types.Address) bool { return false } +func (m *mockHostF) ContainsAccessListSlot(addr types.Address, slot types.Hash) (bool, bool) { + return false, false +} +func (m *mockHostF) DeleteAccessListAddress(addr types.Address) {} +func (m *mockHostF) DeleteAccessListSlot(addr types.Address, slot types.Hash) {} + func FuzzTestEVM(f *testing.F) { seed := []byte{ PUSH1, 0x01, PUSH1, 0x02, ADD, diff --git a/state/runtime/evm/evm_test.go b/state/runtime/evm/evm_test.go index 2613667a21..6b20b48e29 100644 --- a/state/runtime/evm/evm_test.go +++ b/state/runtime/evm/evm_test.go @@ -21,7 +21,6 @@ func newMockContract(value *big.Int, gas uint64, code []byte) *runtime.Contract value, gas, code, - runtime.NewAccessList(), ) } @@ -30,7 +29,8 @@ func newMockContract(value *big.Int, gas uint64, code []byte) *runtime.Contract type mockHost struct { mock.Mock - tracer runtime.VMTracer + tracer runtime.VMTracer + accessList *runtime.AccessList } func (m *mockHost) AccountExists(addr types.Address) bool { @@ -136,6 +136,30 @@ func (m *mockHost) GetRefund() uint64 { panic("Not implemented in tests") //nolint:gocritic } +func (m *mockHost) AddSlotToAccessList(addr types.Address, slot types.Hash) { + m.accessList.AddSlot(addr, slot) +} + +func (m *mockHost) AddAddressToAccessList(addr types.Address) { + m.accessList.AddAddress(addr) +} + +func (m *mockHost) ContainsAccessListAddress(addr types.Address) bool { + return m.accessList.ContainsAddress(addr) +} + +func (m *mockHost) ContainsAccessListSlot(addr types.Address, slot types.Hash) (bool, bool) { + return m.accessList.Contains(addr, slot) +} + +func (m *mockHost) DeleteAccessListAddress(addr types.Address) { + m.accessList.DeleteAddress(addr) +} + +func (m *mockHost) DeleteAccessListSlot(addr types.Address, slot types.Hash) { + m.accessList.DeleteSlot(addr, slot) +} + func TestRun(t *testing.T) { t.Parallel() diff --git a/state/runtime/evm/instructions_test.go b/state/runtime/evm/instructions_test.go index 208aea1f7a..9529aa1c97 100644 --- a/state/runtime/evm/instructions_test.go +++ b/state/runtime/evm/instructions_test.go @@ -1486,7 +1486,6 @@ func Test_opSload(t *testing.T) { op: SLOAD, contract: &runtime.Contract{ Address: address1, - Journal: &runtime.Journal{}, }, config: &chain.ForksInTime{ Berlin: true, @@ -1524,6 +1523,9 @@ func Test_opSload(t *testing.T) { key1: val1, }, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, { @@ -1531,7 +1533,6 @@ func Test_opSload(t *testing.T) { op: SLOAD, contract: &runtime.Contract{ Address: address1, - Journal: &runtime.Journal{}, }, config: &chain.ForksInTime{ Berlin: true, @@ -1573,6 +1574,9 @@ func Test_opSload(t *testing.T) { key1: val1, }, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, { @@ -1580,7 +1584,6 @@ func Test_opSload(t *testing.T) { op: SLOAD, contract: &runtime.Contract{ Address: address1, - Journal: &runtime.Journal{}, }, config: &chain.ForksInTime{ Berlin: false, @@ -1615,6 +1618,9 @@ func Test_opSload(t *testing.T) { key1: val1, }, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, } @@ -1631,14 +1637,14 @@ func Test_opSload(t *testing.T) { s.stack = tt.initState.stack s.memory = tt.initState.memory s.config = tt.config + tt.mockHost.accessList = tt.initState.accessList s.host = tt.mockHost - tt.contract.AccessList = tt.initState.accessList opSload(s) assert.Equal(t, tt.resultState.gas, s.gas, "gas in state after execution is not correct") assert.Equal(t, tt.resultState.sp, s.sp, "sp in state after execution is not correct") assert.Equal(t, tt.resultState.stack, s.stack, "stack in state after execution is not correct") assert.Equal(t, tt.resultState.memory, s.memory, "memory in state after execution is not correct") - assert.Equal(t, tt.resultState.accessList, tt.contract.AccessList, "accesslist in state after execution is not correct") + assert.Equal(t, tt.resultState.accessList, tt.mockHost.accessList, "accesslist in state after execution is not correct") assert.Equal(t, tt.resultState.stop, s.stop, "stop in state after execution is not correct") assert.Equal(t, tt.resultState.err, s.err, "err in state after execution is not correct") }) @@ -1706,6 +1712,9 @@ func TestCreate(t *testing.T) { GasLeft: 500, GasUsed: 500, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, { @@ -1744,7 +1753,11 @@ func TestCreate(t *testing.T) { stop: true, err: errWriteProtection, }, - mockHost: &mockHostForInstructions{}, + mockHost: &mockHostForInstructions{ + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, + }, }, { name: "should throw errOpCodeNotFound when op is CREATE2 and config.Constantinople is disabled", @@ -1782,7 +1795,11 @@ func TestCreate(t *testing.T) { stop: true, err: errOpCodeNotFound, }, - mockHost: &mockHostForInstructions{}, + mockHost: &mockHostForInstructions{ + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, + }, }, { name: "should set zero address if op is CREATE and contract call throws ErrCodeStoreOutOfGas", @@ -1830,6 +1847,9 @@ func TestCreate(t *testing.T) { GasLeft: 1000, Err: runtime.ErrCodeStoreOutOfGas, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, { @@ -1878,6 +1898,9 @@ func TestCreate(t *testing.T) { GasLeft: 1000, Err: errRevert, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, { @@ -1929,6 +1952,9 @@ func TestCreate(t *testing.T) { GasLeft: 0, Err: runtime.ErrCodeStoreOutOfGas, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, } @@ -2279,9 +2305,7 @@ func Test_opCall(t *testing.T) { name: "should not copy result into memory if outSize is 0", op: STATICCALL, contract: &runtime.Contract{ - Static: true, - Journal: &runtime.Journal{}, - AccessList: runtime.NewAccessList(), + Static: true, }, config: allEnabledForks, initState: &state{ @@ -2306,6 +2330,9 @@ func Test_opCall(t *testing.T) { callxResult: &runtime.ExecutionResult{ ReturnValue: []byte{0x03}, }, + mockHost: mockHost{ + accessList: runtime.NewAccessList(), + }, }, }, // { diff --git a/state/runtime/precompiled/native_transfer_test.go b/state/runtime/precompiled/native_transfer_test.go index a6309f6d42..4bdf95b4fa 100644 --- a/state/runtime/precompiled/native_transfer_test.go +++ b/state/runtime/precompiled/native_transfer_test.go @@ -171,6 +171,34 @@ func (d dummyHost) GetNonce(addr types.Address) uint64 { return 0 } +func (d *dummyHost) AddSlotToAccessList(addr types.Address, slot types.Hash) { + d.t.Fatalf("AddSlotToAccessList is not implemented") +} + +func (d *dummyHost) AddAddressToAccessList(addr types.Address) { + d.t.Fatalf("AddAddressToAccessList is not implemented") +} + +func (d *dummyHost) ContainsAccessListAddress(addr types.Address) bool { + d.t.Fatalf("ContainsAccessListAddress is not implemented") + + return false +} + +func (d *dummyHost) ContainsAccessListSlot(addr types.Address, slot types.Hash) (bool, bool) { + d.t.Fatalf("ContainsAccessListSlot is not implemented") + + return false, false +} + +func (d *dummyHost) DeleteAccessListAddress(addr types.Address) { + d.t.Fatalf("DeleteAccessListAddress is not implemented") +} + +func (d *dummyHost) DeleteAccessListSlot(addr types.Address, slot types.Hash) { + d.t.Fatalf("DeleteAccessListSlot is not implemented") +} + func (d dummyHost) Transfer(from types.Address, to types.Address, amount *big.Int) error { if d.balances == nil { d.balances = map[types.Address]*big.Int{}