diff --git a/core/vm/interface.go b/core/vm/interface.go index 0e4c53d779a3..fc1954d69bcc 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -24,6 +24,8 @@ import ( "github.com/holiman/uint256" ) +//go:generate mockgen -source interface.go -destination mock_state.go -package vm StateDB + // StateDB is an EVM database for full state querying. type StateDB interface { CreateAccount(common.Address) diff --git a/core/vm/lfvm/interpreter.go b/core/vm/lfvm/interpreter.go index e6c7d1422ca4..ad66fedd491f 100644 --- a/core/vm/lfvm/interpreter.go +++ b/core/vm/lfvm/interpreter.go @@ -387,6 +387,22 @@ func step(c *context) { func stepToEnd(c *context) { steps(c, false) } + +func checkStackBoundry(c *context, op OpCode) error { + stackLen := c.stack.len() + if stackLen < staticStackBoundry[op].stackMin { + c.err = &vm.ErrStackUnderflow{} + c.status = ERROR + return c.err + } + if stackLen > int(params.StackLimit)-1 && stackLen > staticStackBoundry[op].stackMax { + c.err = &vm.ErrStackOverflow{} + c.status = ERROR + return c.err + } + return nil +} + func steps(c *context, one_step_only bool) { // Idea: handle static gas price in static dispatch below (saves an array lookup) static_gas_prices := getStaticGasPrices(c.isBerlin) @@ -410,6 +426,11 @@ func steps(c *context, one_step_only bool) { return } + // Need to check Call stack boundry before using static gas + if op == CALL && checkStackBoundry(c, op) != nil { + return + } + // If the interpreter is operating in readonly mode, make sure no // state-modifying operation is performed. The 3rd stack item // for a call operation is the value. Transferring value from one @@ -426,15 +447,8 @@ func steps(c *context, one_step_only bool) { return } - stackLen := c.stack.len() - if stackLen < staticStackBoundry[op].stackMin { - c.err = &vm.ErrStackUnderflow{} - c.status = ERROR - return - } - if stackLen > int(params.StackLimit)-1 && stackLen > staticStackBoundry[op].stackMax { - c.err = &vm.ErrStackOverflow{} - c.status = ERROR + // Check stack boundry for every instruction + if checkStackBoundry(c, op) != nil { return } diff --git a/core/vm/lfvm/interpreter_test.go b/core/vm/lfvm/interpreter_test.go index 6f0e4441cd59..b3515d390bc3 100644 --- a/core/vm/lfvm/interpreter_test.go +++ b/core/vm/lfvm/interpreter_test.go @@ -6,7 +6,10 @@ import ( "math/big" "testing" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" + "github.com/golang/mock/gomock" "github.com/holiman/uint256" ) @@ -18,6 +21,431 @@ type example struct { function uint32 // The identifier of the function in the contract to be called } +const MAX_STACK_SIZE int = 1024 +const GAS_START uint64 = 1 << 32 + +var ( + HASH_0 = common.Hash{0} + HASH_1 = common.BigToHash(big.NewInt(1)) + HASH_2 = common.BigToHash(big.NewInt(2)) + ADDRESS_0 = common.Address{0} +) + +func getEmptyContext() context { + code := make([]Instruction, 0) + data := make([]byte, 0) + return getContext(code, data, 0, nil, GAS_START, false, false) +} + +func getContext(code Code, data []byte, stackPtr int, stateDB vm.StateDB, gas uint64, isBerlin bool, isLondon bool) context { + + // Create a dummy contract + addr := vm.AccountRef{} + contract := vm.NewContract(addr, addr, big.NewInt(0), gas) + + // Create execution context. + ctxt := context{ + code: code, + data: data, + callsize: *uint256.NewInt(uint64(len(data))), + stack: NewStack(), + memory: NewMemory(), + readOnly: false, + contract: contract, + stateDB: stateDB, + isBerlin: isBerlin, + isLondon: isLondon, + evm: &vm.EVM{StateDB: stateDB}, + } + + // Set start conditions + ctxt.pc = 0 + ctxt.status = RUNNING + ctxt.stack.stack_ptr = stackPtr + + return ctxt +} + +// Test UseGas function and correct status after running out of gas +func TestGasFunc(t *testing.T) { + ctx := getEmptyContext() + ctx.contract.Gas = 100 + ok := ctx.UseGas(10) + if !ok { + t.Errorf("expected not failed useGas function, got failed") + } + if ctx.contract.Gas != 90 { + t.Errorf("expected gas of contract in context is 90, got %d", ctx.contract.Gas) + } + ok = ctx.UseGas(100) + if ok { + t.Errorf("expected failed useGas function, got ok") + } + if ctx.contract.Gas != 90 { + t.Errorf("expected gas of contract in context is 90 also after failing, got %d", ctx.contract.Gas) + } + if ctx.status != OUT_OF_GAS { + t.Errorf("expected OUT_OF_GAS status 6, got %d", ctx.status) + } +} + +type OpcodeTest struct { + name string + code []Instruction + stackPtrPos int + argData uint16 + endStatus Status + isBerlin bool + isLondon bool + mockCalls func(mockStateDB *vm.MockStateDB) + gasStart uint64 + gasConsumed uint64 +} + +func getInstructions(start OpCode, end OpCode) (opCodes []OpCode) { + for i := start; i <= end; i++ { + opCodes = append(opCodes, OpCode(i)) + } + return +} + +func getInstructionsWithGas(start OpCode, end OpCode, gas uint64) (opCodes []OpCodeWithGas) { + for i := start; i <= end; i++ { + opCode := OpCodeWithGas{OpCode(i), gas} + opCodes = append(opCodes, opCode) + } + return +} + +var fullStackFailOpCodes = []OpCode{ + MSIZE, ADDRESS, ORIGIN, CALLER, CALLVALUE, CALLDATASIZE, + CODESIZE, GASPRICE, COINBASE, TIMESTAMP, NUMBER, + DIFFICULTY, GASLIMIT, PC, GAS, RETURNDATASIZE, + SELFBALANCE, CHAINID, BASEFEE, + PUSH1_PUSH1_PUSH1_SHL_SUB, + PUSH1_DUP1, PUSH1_PUSH1, PUSH1_PUSH4_DUP3, +} + +var emptyStackFailOpCodes = []OpCode{ + POP, ADD, SUB, MUL, DIV, SDIV, MOD, SMOD, EXP, SIGNEXTEND, + SHA3, LT, GT, SLT, SGT, EQ, AND, XOR, OR, BYTE, + SHL, SHR, SAR, ADDMOD, MULMOD, ISZERO, NOT, BALANCE, CALLDATALOAD, EXTCODESIZE, + BLOCKHASH, MLOAD, SLOAD, EXTCODEHASH, JUMP, SELFDESTRUCT, + MSTORE, MSTORE8, SSTORE, JUMPI, RETURN, REVERT, + CALLDATACOPY, CODECOPY, RETURNDATACOPY, + EXTCODECOPY, CREATE, CREATE2, CALL, CALLCODE, + STATICCALL, DELEGATECALL, POP_POP, POP_JUMP, + SWAP2_POP, PUSH1_ADD, PUSH1_SHL, SWAP2_SWAP1_POP_JUMP, + PUSH2_JUMPI, ISZERO_PUSH2_JUMPI, SWAP2_SWAP1, + DUP2_LT, SWAP1_POP_SWAP2_SWAP1, POP_SWAP2_SWAP1_POP, + AND_SWAP1_POP_SWAP2_SWAP1, SWAP1_POP, DUP2_MSTORE, +} + +func addFullStackFailOpCodes(tests []OpcodeTest) []OpcodeTest { + var addedTests []OpcodeTest + addedTests = append(addedTests, tests...) + var opCodes []OpCode + opCodes = append(opCodes, fullStackFailOpCodes...) + opCodes = append(opCodes, getInstructions(PUSH1, PUSH32)...) + opCodes = append(opCodes, getInstructions(DUP1, DUP16)...) + for _, opCode := range opCodes { + addedTests = append(addedTests, OpcodeTest{opCode.String(), []Instruction{{opCode, 1}}, MAX_STACK_SIZE, 0, ERROR, false, false, nil, GAS_START, 0}) + } + return addedTests +} + +func addEmptyStackFailOpCodes(tests []OpcodeTest) []OpcodeTest { + var addedTests []OpcodeTest + addedTests = append(addedTests, tests...) + var opCodes []OpCode + opCodes = append(opCodes, emptyStackFailOpCodes...) + opCodes = append(opCodes, getInstructions(DUP1, DUP16)...) + opCodes = append(opCodes, getInstructions(SWAP1, SWAP16)...) + opCodes = append(opCodes, getInstructions(LOG0, LOG4)...) + for _, opCode := range opCodes { + addedTests = append(addedTests, OpcodeTest{opCode.String(), []Instruction{{opCode, 1}}, 0, 0, ERROR, false, false, nil, GAS_START, 0}) + } + return addedTests +} +func TestContainsAllMaxStackBoundryInstructions(t *testing.T) { + set := make(map[OpCode]bool) + fullStackFailOpcodes := addFullStackFailOpCodes(nil) + for _, op := range fullStackFailOpcodes { + set[op.code[0].opcode] = true + } + for op := OpCode(0); op < NUM_OPCODES; op++ { + insStack := getStaticStackInternal(op) + if _, exists := set[op]; exists != (MAX_STACK_SIZE-insStack.stackMax > 0) { + t.Errorf("OpCode %v adding %v to stack, is not contained in FullStackFailOpCodes", op.String(), MAX_STACK_SIZE-insStack.stackMax) + } + } +} + +func TestContainsAllMinStackBoundryInstructions(t *testing.T) { + set := make(map[OpCode]bool) + emptyStackFailOpcodes := addEmptyStackFailOpCodes(nil) + for _, op := range emptyStackFailOpcodes { + set[op.code[0].opcode] = true + } + for op := OpCode(0); op < NUM_OPCODES; op++ { + insStack := getStaticStackInternal(op) + if _, exists := set[op]; exists != (insStack.stackMin > 0) { + t.Errorf("OpCode %v with minimum stack size of %v values, is not contained in EmptyStackFailOpcodes", op.String(), insStack.stackMin) + } + } +} + +func TestStackMinBoundry(t *testing.T) { + + // Add tests for execution + for _, test := range addEmptyStackFailOpCodes(nil) { + + // Create execution context. + ctxt := getEmptyContext() + ctxt.code = test.code + ctxt.stack.stack_ptr = test.stackPtrPos + + // Run testing code + run(&ctxt) + + // Check the result. + if ctxt.status != test.endStatus { + t.Errorf("execution failed %v: status is %v, wanted %v, error %v", test.name, ctxt.status, test.endStatus, ctxt.err) + } else { + t.Log("Success", test.name) + } + } +} + +func TestStackMaxBoundry(t *testing.T) { + + // Add tests for execution + for _, test := range addFullStackFailOpCodes(nil) { + + // Create execution context. + ctxt := getEmptyContext() + ctxt.code = test.code + ctxt.stack.stack_ptr = test.stackPtrPos + + // Run testing code + run(&ctxt) + + // Check the result. + if ctxt.status != test.endStatus { + t.Errorf("execution failed %v: status is %v, wanted %v, error %v", test.name, ctxt.status, test.endStatus, ctxt.err) + } else { + t.Log("Success", test.name) + } + } +} + +var opcodeTests = []OpcodeTest{ + {"POP", []Instruction{{PUSH1, 1 << 8}, {POP, 0}}, 0, 0, STOPPED, false, false, nil, GAS_START, 5}, + {"JUMP", []Instruction{{PUSH1, 2 << 8}, {JUMP, 0}, {JUMPDEST, 0}}, 0, 0, STOPPED, false, false, nil, GAS_START, 12}, + {"JUMPI", []Instruction{{PUSH1, 1 << 8}, {PUSH1, 3 << 8}, {JUMPI, 0}, {JUMPDEST, 0}}, 0, 0, STOPPED, false, false, nil, GAS_START, 17}, + {"JUMPDEST", []Instruction{{JUMPDEST, 0}}, 0, 0, STOPPED, false, false, nil, GAS_START, 1}, + {"RETURN", []Instruction{{RETURN, 0}}, 20, 0, RETURNED, false, false, nil, GAS_START, 0}, + {"REVERT", []Instruction{{REVERT, 0}}, 20, 0, REVERTED, false, false, nil, GAS_START, 0}, + {"PC", []Instruction{{PC, 0}}, 0, 0, STOPPED, false, false, nil, GAS_START, 2}, + {"STOP", []Instruction{{STOP, 0}}, 0, 0, STOPPED, false, false, nil, GAS_START, 0}, + {"SLOAD", []Instruction{{PUSH1, 0}, {SLOAD, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(common.Address{0}, common.Hash{0}).Return(common.Hash{0}) + }, GAS_START, 803}, + {"SLOAD Berlin", []Instruction{{PUSH1, 0}, {SLOAD, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(common.Address{0}, common.Hash{0}).Return(common.Hash{0}) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, common.Hash{0}).Return(true, true) + }, GAS_START, 103}, + {"SLOAD Berlin no slot", []Instruction{{PUSH1, 0}, {SLOAD, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(common.Address{0}, common.Hash{0}).Return(common.Hash{0}) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, common.Hash{0}).Return(false, false) + mockStateDB.EXPECT().AddSlotToAccessList(common.Address{0}, common.Hash{0}) + }, GAS_START, 2103}, + {"SSTORE same value", []Instruction{{PUSH1, 0}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_0) + }, GAS_START, 806}, + {"SSTORE diff value, same state as db, db is 0", []Instruction{{PUSH1, 1 << 8}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_1) + }, GAS_START, 20006}, + {"SSTORE diff value, same state as db, val is 0", []Instruction{{PUSH1, 0}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().AddRefund(params.SstoreClearsScheduleRefundEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_0) + }, GAS_START, 5006}, + {"SSTORE diff value, diff state as db, db it not 0, state is 0", []Instruction{{PUSH1, 1 << 8}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_2) + mockStateDB.EXPECT().SubRefund(params.SstoreClearsScheduleRefundEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_1) + }, GAS_START, 806}, + {"SSTORE diff value, diff state as db, db it not 0, val is 0", []Instruction{{PUSH1, 0}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_2) + mockStateDB.EXPECT().AddRefund(params.SstoreClearsScheduleRefundEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_0) + }, GAS_START, 806}, + {"SSTORE diff value, diff state as db, db same as val, db is 0", []Instruction{{PUSH1, 0}, {PUSH1, 1 << 8}, {SSTORE, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_1).Return(HASH_1) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_1).Return(HASH_0) + mockStateDB.EXPECT().AddRefund(params.SstoreSetGasEIP2200 - params.SloadGasEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_1, HASH_0) + }, GAS_START, 806}, + {"SSTORE diff value, diff state as db, db same as val, db is not 0", []Instruction{{PUSH1, 2 << 8}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, false, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_2) + mockStateDB.EXPECT().AddRefund(params.SstoreResetGasEIP2200 - params.SloadGasEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_2) + }, GAS_START, 806}, + {"SSTORE Berlin same value", []Instruction{{PUSH1, 0}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, HASH_0).Return(true, false) + mockStateDB.EXPECT().AddSlotToAccessList(ADDRESS_0, HASH_0) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_0) + }, GAS_START, 2206}, + {"SSTORE Berlin diff value, same state as db, db is 0", []Instruction{{PUSH1, 1 << 8}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, HASH_0).Return(true, true) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_1) + }, GAS_START, 20006}, + {"SSTORE Berlin diff value, same state as db, val is 0", []Instruction{{PUSH1, 0}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, HASH_0).Return(true, true) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().AddRefund(params.SstoreClearsScheduleRefundEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_0) + }, GAS_START, 2906}, + {"SSTORE Berlin diff value, diff state as db, db it not 0, state is 0", []Instruction{{PUSH1, 1 << 8}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_0) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, HASH_0).Return(true, true) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_2) + mockStateDB.EXPECT().SubRefund(params.SstoreClearsScheduleRefundEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_1) + }, GAS_START, 106}, + {"SSTORE Berlin diff value, diff state as db, db it not 0, val is 0", []Instruction{{PUSH1, 0}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, HASH_0).Return(true, true) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_2) + mockStateDB.EXPECT().AddRefund(params.SstoreClearsScheduleRefundEIP2200) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_0) + }, GAS_START, 106}, + {"SSTORE Berlin diff value, diff state as db, db same as val, db is 0", []Instruction{{PUSH1, 0}, {PUSH1, 1 << 8}, {SSTORE, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_1).Return(HASH_1) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, HASH_1).Return(true, true) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_1).Return(HASH_0) + mockStateDB.EXPECT().AddRefund(params.SstoreSetGasEIP2200 - params.WarmStorageReadCostEIP2929) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_1, HASH_0) + }, GAS_START, 106}, + {"SSTORE Berlin diff value, diff state as db, db same as val, db is not 0", []Instruction{{PUSH1, 2 << 8}, {PUSH1, 0}, {SSTORE, 0}}, 0, 0, STOPPED, true, false, + func(mockStateDB *vm.MockStateDB) { + mockStateDB.EXPECT().GetState(ADDRESS_0, HASH_0).Return(HASH_1) + mockStateDB.EXPECT().SlotInAccessList(common.Address{0}, HASH_0).Return(true, true) + mockStateDB.EXPECT().GetCommittedState(ADDRESS_0, HASH_0).Return(HASH_2) + mockStateDB.EXPECT().AddRefund((params.SstoreResetGasEIP2200 - params.ColdSloadCostEIP2929) - params.WarmStorageReadCostEIP2929) + mockStateDB.EXPECT().SetState(ADDRESS_0, HASH_0, HASH_2) + }, GAS_START, 106}, +} + +type OpCodeWithGas struct { + OpCode + gas uint64 +} + +func addOKOpCodes(tests []OpcodeTest) []OpcodeTest { + var addedTests []OpcodeTest + addedTests = append(addedTests, tests...) + for i := PUSH1; i <= PUSH32; i++ { + code := []Instruction{{i, 1}} + dataNum := int((i - PUSH1) / 2) + for j := 0; j < dataNum; j++ { + code = append(code, Instruction{DATA, 1}) + } + addedTests = append(addedTests, OpcodeTest{i.String(), code, 20, 0, STOPPED, false, false, nil, GAS_START, 3}) + } + var opCodes []OpCodeWithGas + opCodes = append(opCodes, getInstructionsWithGas(DUP1, SWAP16, 3)...) + opCodes = append(opCodes, getInstructionsWithGas(ADD, SUB, 3)...) + opCodes = append(opCodes, getInstructionsWithGas(MUL, SMOD, 5)...) + opCodes = append(opCodes, getInstructionsWithGas(ADDMOD, MULMOD, 8)...) + opCodes = append(opCodes, OpCodeWithGas{EXP, 10}) + opCodes = append(opCodes, OpCodeWithGas{SIGNEXTEND, 5}) + opCodes = append(opCodes, OpCodeWithGas{SHA3, 30}) + opCodes = append(opCodes, getInstructionsWithGas(LT, SAR, 3)...) + opCodes = append(opCodes, OpCodeWithGas{SWAP1_POP_SWAP2_SWAP1, 11}) + opCodes = append(opCodes, OpCodeWithGas{POP_SWAP2_SWAP1_POP, 10}) + opCodes = append(opCodes, OpCodeWithGas{POP_POP, 4}) + opCodes = append(opCodes, getInstructionsWithGas(PUSH1_SHL, PUSH1_DUP1, 6)...) + //opCodes = append(opCodes, OpCodeWithGas{PUSH2_JUMP, 11}) + opCodes = append(opCodes, OpCodeWithGas{PUSH2_JUMPI, 13}) + opCodes = append(opCodes, OpCodeWithGas{PUSH1_PUSH1, 6}) + opCodes = append(opCodes, OpCodeWithGas{SWAP1_POP, 5}) + opCodes = append(opCodes, OpCodeWithGas{SWAP2_SWAP1, 6}) + opCodes = append(opCodes, OpCodeWithGas{SWAP2_POP, 5}) + opCodes = append(opCodes, OpCodeWithGas{DUP2_MSTORE, 9}) + opCodes = append(opCodes, OpCodeWithGas{DUP2_LT, 6}) + for _, opCode := range opCodes { + code := []Instruction{{opCode.OpCode, 0}} + addedTests = append(addedTests, OpcodeTest{opCode.String(), code, 20, 0, STOPPED, false, false, nil, GAS_START, opCode.gas}) + } + return addedTests +} + +func TestOKInstructionPath(t *testing.T) { + + var mockCtrl *gomock.Controller + var mockStateDB *vm.MockStateDB + + for _, test := range addOKOpCodes(opcodeTests) { + t.Run(test.name, func(t *testing.T) { + + if test.mockCalls != nil { + mockCtrl = gomock.NewController(t) + mockStateDB = vm.NewMockStateDB(mockCtrl) + test.mockCalls(mockStateDB) + } else { + mockStateDB = nil + } + ctxt := getContext(test.code, make([]byte, 0), test.stackPtrPos, mockStateDB, test.gasStart, test.isBerlin, test.isLondon) + + // Run testing code + run(&ctxt) + + if test.mockCalls != nil { + mockCtrl.Finish() + } + + // Check the result. + if ctxt.status != test.endStatus { + t.Errorf("execution failed %v: status is %v, wanted %v, error %v", test.name, ctxt.status, test.endStatus, ctxt.err) + } + + // Check gas consumption + if test.gasStart-ctxt.contract.Gas != test.gasConsumed { + t.Errorf("execution failed %v: gas consumption is %v, wanted %v", test.name, test.gasStart-ctxt.contract.Gas, test.gasConsumed) + } + }) + } +} + func getFibExample() example { // An implementation of the fib function in EVM byte code. code, err := hex.DecodeString("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f9b7c7e514610030575b600080fd5b61004a600480360381019061004591906100f6565b610060565b6040516100579190610132565b60405180910390f35b600060018263ffffffff161161007957600190506100b0565b61008e600283610089919061017c565b610060565b6100a360018461009e919061017c565b610060565b6100ad91906101b4565b90505b919050565b600080fd5b600063ffffffff82169050919050565b6100d3816100ba565b81146100de57600080fd5b50565b6000813590506100f0816100ca565b92915050565b60006020828403121561010c5761010b6100b5565b5b600061011a848285016100e1565b91505092915050565b61012c816100ba565b82525050565b60006020820190506101476000830184610123565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610187826100ba565b9150610192836100ba565b9250828203905063ffffffff8111156101ae576101ad61014d565b5b92915050565b60006101bf826100ba565b91506101ca836100ba565b9250828201905063ffffffff8111156101e6576101e561014d565b5b9291505056fea26469706673582212207fd33e47e97ce5871bb05401e6710238af535ae8aeaab013ca9a9c29152b8a1b64736f6c637827302e382e31372d646576656c6f702e323032322e382e392b636f6d6d69742e62623161386466390058") diff --git a/core/vm/mock_state.go b/core/vm/mock_state.go new file mode 100644 index 000000000000..b2bcc30c7b6c --- /dev/null +++ b/core/vm/mock_state.go @@ -0,0 +1,552 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: interface.go + +// Package vm is a generated GoMock package. +package vm + +import ( + big "math/big" + reflect "reflect" + + common "github.com/ethereum/go-ethereum/common" + types "github.com/ethereum/go-ethereum/core/types" + gomock "github.com/golang/mock/gomock" + uint256 "github.com/holiman/uint256" +) + +// MockStateDB is a mock of StateDB interface. +type MockStateDB struct { + ctrl *gomock.Controller + recorder *MockStateDBMockRecorder +} + +// MockStateDBMockRecorder is the mock recorder for MockStateDB. +type MockStateDBMockRecorder struct { + mock *MockStateDB +} + +// NewMockStateDB creates a new mock instance. +func NewMockStateDB(ctrl *gomock.Controller) *MockStateDB { + mock := &MockStateDB{ctrl: ctrl} + mock.recorder = &MockStateDBMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStateDB) EXPECT() *MockStateDBMockRecorder { + return m.recorder +} + +// AddAddressToAccessList mocks base method. +func (m *MockStateDB) AddAddressToAccessList(addr common.Address) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddAddressToAccessList", addr) +} + +// AddAddressToAccessList indicates an expected call of AddAddressToAccessList. +func (mr *MockStateDBMockRecorder) AddAddressToAccessList(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAddressToAccessList", reflect.TypeOf((*MockStateDB)(nil).AddAddressToAccessList), addr) +} + +// AddBalance mocks base method. +func (m *MockStateDB) AddBalance(arg0 common.Address, arg1 *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddBalance", arg0, arg1) +} + +// AddBalance indicates an expected call of AddBalance. +func (mr *MockStateDBMockRecorder) AddBalance(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBalance", reflect.TypeOf((*MockStateDB)(nil).AddBalance), arg0, arg1) +} + +// AddLog mocks base method. +func (m *MockStateDB) AddLog(arg0 *types.Log) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddLog", arg0) +} + +// AddLog indicates an expected call of AddLog. +func (mr *MockStateDBMockRecorder) AddLog(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLog", reflect.TypeOf((*MockStateDB)(nil).AddLog), arg0) +} + +// AddPreimage mocks base method. +func (m *MockStateDB) AddPreimage(arg0 common.Hash, arg1 []byte) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddPreimage", arg0, arg1) +} + +// AddPreimage indicates an expected call of AddPreimage. +func (mr *MockStateDBMockRecorder) AddPreimage(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPreimage", reflect.TypeOf((*MockStateDB)(nil).AddPreimage), arg0, arg1) +} + +// AddRefund mocks base method. +func (m *MockStateDB) AddRefund(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddRefund", arg0) +} + +// AddRefund indicates an expected call of AddRefund. +func (mr *MockStateDBMockRecorder) AddRefund(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRefund", reflect.TypeOf((*MockStateDB)(nil).AddRefund), arg0) +} + +// AddSlotToAccessList mocks base method. +func (m *MockStateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddSlotToAccessList", addr, slot) +} + +// AddSlotToAccessList indicates an expected call of AddSlotToAccessList. +func (mr *MockStateDBMockRecorder) AddSlotToAccessList(addr, slot interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSlotToAccessList", reflect.TypeOf((*MockStateDB)(nil).AddSlotToAccessList), addr, slot) +} + +// AddressInAccessList mocks base method. +func (m *MockStateDB) AddressInAccessList(addr common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddressInAccessList", addr) + ret0, _ := ret[0].(bool) + return ret0 +} + +// AddressInAccessList indicates an expected call of AddressInAccessList. +func (mr *MockStateDBMockRecorder) AddressInAccessList(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddressInAccessList", reflect.TypeOf((*MockStateDB)(nil).AddressInAccessList), addr) +} + +// CreateAccount mocks base method. +func (m *MockStateDB) CreateAccount(arg0 common.Address) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "CreateAccount", arg0) +} + +// CreateAccount indicates an expected call of CreateAccount. +func (mr *MockStateDBMockRecorder) CreateAccount(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAccount", reflect.TypeOf((*MockStateDB)(nil).CreateAccount), arg0) +} + +// Empty mocks base method. +func (m *MockStateDB) Empty(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Empty", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Empty indicates an expected call of Empty. +func (mr *MockStateDBMockRecorder) Empty(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Empty", reflect.TypeOf((*MockStateDB)(nil).Empty), arg0) +} + +// Exist mocks base method. +func (m *MockStateDB) Exist(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Exist", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Exist indicates an expected call of Exist. +func (mr *MockStateDBMockRecorder) Exist(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exist", reflect.TypeOf((*MockStateDB)(nil).Exist), arg0) +} + +// ForEachStorage mocks base method. +func (m *MockStateDB) ForEachStorage(arg0 common.Address, arg1 func(common.Hash, common.Hash) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ForEachStorage", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ForEachStorage indicates an expected call of ForEachStorage. +func (mr *MockStateDBMockRecorder) ForEachStorage(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForEachStorage", reflect.TypeOf((*MockStateDB)(nil).ForEachStorage), arg0, arg1) +} + +// GetBalance mocks base method. +func (m *MockStateDB) GetBalance(arg0 common.Address) *big.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBalance", arg0) + ret0, _ := ret[0].(*big.Int) + return ret0 +} + +// GetBalance indicates an expected call of GetBalance. +func (mr *MockStateDBMockRecorder) GetBalance(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalance", reflect.TypeOf((*MockStateDB)(nil).GetBalance), arg0) +} + +// GetCode mocks base method. +func (m *MockStateDB) GetCode(arg0 common.Address) []byte { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCode", arg0) + ret0, _ := ret[0].([]byte) + return ret0 +} + +// GetCode indicates an expected call of GetCode. +func (mr *MockStateDBMockRecorder) GetCode(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCode", reflect.TypeOf((*MockStateDB)(nil).GetCode), arg0) +} + +// GetCodeHash mocks base method. +func (m *MockStateDB) GetCodeHash(arg0 common.Address) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCodeHash", arg0) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetCodeHash indicates an expected call of GetCodeHash. +func (mr *MockStateDBMockRecorder) GetCodeHash(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCodeHash", reflect.TypeOf((*MockStateDB)(nil).GetCodeHash), arg0) +} + +// GetCodeSize mocks base method. +func (m *MockStateDB) GetCodeSize(arg0 common.Address) int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCodeSize", arg0) + ret0, _ := ret[0].(int) + return ret0 +} + +// GetCodeSize indicates an expected call of GetCodeSize. +func (mr *MockStateDBMockRecorder) GetCodeSize(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCodeSize", reflect.TypeOf((*MockStateDB)(nil).GetCodeSize), arg0) +} + +// GetCommittedState mocks base method. +func (m *MockStateDB) GetCommittedState(arg0 common.Address, arg1 common.Hash) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCommittedState", arg0, arg1) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetCommittedState indicates an expected call of GetCommittedState. +func (mr *MockStateDBMockRecorder) GetCommittedState(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommittedState", reflect.TypeOf((*MockStateDB)(nil).GetCommittedState), arg0, arg1) +} + +// GetNonce mocks base method. +func (m *MockStateDB) GetNonce(arg0 common.Address) uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNonce", arg0) + ret0, _ := ret[0].(uint64) + return ret0 +} + +// GetNonce indicates an expected call of GetNonce. +func (mr *MockStateDBMockRecorder) GetNonce(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNonce", reflect.TypeOf((*MockStateDB)(nil).GetNonce), arg0) +} + +// GetRefund mocks base method. +func (m *MockStateDB) GetRefund() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRefund") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// GetRefund indicates an expected call of GetRefund. +func (mr *MockStateDBMockRecorder) GetRefund() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRefund", reflect.TypeOf((*MockStateDB)(nil).GetRefund)) +} + +// GetState mocks base method. +func (m *MockStateDB) GetState(arg0 common.Address, arg1 common.Hash) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetState", arg0, arg1) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetState indicates an expected call of GetState. +func (mr *MockStateDBMockRecorder) GetState(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockStateDB)(nil).GetState), arg0, arg1) +} + +// HasSuicided mocks base method. +func (m *MockStateDB) HasSuicided(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasSuicided", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// HasSuicided indicates an expected call of HasSuicided. +func (mr *MockStateDBMockRecorder) HasSuicided(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasSuicided", reflect.TypeOf((*MockStateDB)(nil).HasSuicided), arg0) +} + +// PrepareAccessList mocks base method. +func (m *MockStateDB) PrepareAccessList(sender common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PrepareAccessList", sender, dest, precompiles, txAccesses) +} + +// PrepareAccessList indicates an expected call of PrepareAccessList. +func (mr *MockStateDBMockRecorder) PrepareAccessList(sender, dest, precompiles, txAccesses interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareAccessList", reflect.TypeOf((*MockStateDB)(nil).PrepareAccessList), sender, dest, precompiles, txAccesses) +} + +// RevertToSnapshot mocks base method. +func (m *MockStateDB) RevertToSnapshot(arg0 int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RevertToSnapshot", arg0) +} + +// RevertToSnapshot indicates an expected call of RevertToSnapshot. +func (mr *MockStateDBMockRecorder) RevertToSnapshot(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertToSnapshot", reflect.TypeOf((*MockStateDB)(nil).RevertToSnapshot), arg0) +} + +// SetCode mocks base method. +func (m *MockStateDB) SetCode(arg0 common.Address, arg1 []byte) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCode", arg0, arg1) +} + +// SetCode indicates an expected call of SetCode. +func (mr *MockStateDBMockRecorder) SetCode(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCode", reflect.TypeOf((*MockStateDB)(nil).SetCode), arg0, arg1) +} + +// SetNonce mocks base method. +func (m *MockStateDB) SetNonce(arg0 common.Address, arg1 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetNonce", arg0, arg1) +} + +// SetNonce indicates an expected call of SetNonce. +func (mr *MockStateDBMockRecorder) SetNonce(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNonce", reflect.TypeOf((*MockStateDB)(nil).SetNonce), arg0, arg1) +} + +// SetState mocks base method. +func (m *MockStateDB) SetState(arg0 common.Address, arg1, arg2 common.Hash) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetState", arg0, arg1, arg2) +} + +// SetState indicates an expected call of SetState. +func (mr *MockStateDBMockRecorder) SetState(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*MockStateDB)(nil).SetState), arg0, arg1, arg2) +} + +// SlotInAccessList mocks base method. +func (m *MockStateDB) SlotInAccessList(addr common.Address, slot common.Hash) (bool, bool) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SlotInAccessList", addr, slot) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(bool) + return ret0, ret1 +} + +// SlotInAccessList indicates an expected call of SlotInAccessList. +func (mr *MockStateDBMockRecorder) SlotInAccessList(addr, slot interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlotInAccessList", reflect.TypeOf((*MockStateDB)(nil).SlotInAccessList), addr, slot) +} + +// Snapshot mocks base method. +func (m *MockStateDB) Snapshot() int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Snapshot") + ret0, _ := ret[0].(int) + return ret0 +} + +// Snapshot indicates an expected call of Snapshot. +func (mr *MockStateDBMockRecorder) Snapshot() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Snapshot", reflect.TypeOf((*MockStateDB)(nil).Snapshot)) +} + +// SubBalance mocks base method. +func (m *MockStateDB) SubBalance(arg0 common.Address, arg1 *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SubBalance", arg0, arg1) +} + +// SubBalance indicates an expected call of SubBalance. +func (mr *MockStateDBMockRecorder) SubBalance(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubBalance", reflect.TypeOf((*MockStateDB)(nil).SubBalance), arg0, arg1) +} + +// SubRefund mocks base method. +func (m *MockStateDB) SubRefund(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SubRefund", arg0) +} + +// SubRefund indicates an expected call of SubRefund. +func (mr *MockStateDBMockRecorder) SubRefund(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubRefund", reflect.TypeOf((*MockStateDB)(nil).SubRefund), arg0) +} + +// Suicide mocks base method. +func (m *MockStateDB) Suicide(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Suicide", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Suicide indicates an expected call of Suicide. +func (mr *MockStateDBMockRecorder) Suicide(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Suicide", reflect.TypeOf((*MockStateDB)(nil).Suicide), arg0) +} + +// MockCallContext is a mock of CallContext interface. +type MockCallContext struct { + ctrl *gomock.Controller + recorder *MockCallContextMockRecorder +} + +// MockCallContextMockRecorder is the mock recorder for MockCallContext. +type MockCallContextMockRecorder struct { + mock *MockCallContext +} + +// NewMockCallContext creates a new mock instance. +func NewMockCallContext(ctrl *gomock.Controller) *MockCallContext { + mock := &MockCallContext{ctrl: ctrl} + mock.recorder = &MockCallContextMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCallContext) EXPECT() *MockCallContextMockRecorder { + return m.recorder +} + +// Call mocks base method. +func (m *MockCallContext) Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas uint64, value *big.Int) ([]byte, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Call", env, me, addr, data, gas, value) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(uint64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// Call indicates an expected call of Call. +func (mr *MockCallContextMockRecorder) Call(env, me, addr, data, gas, value interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Call", reflect.TypeOf((*MockCallContext)(nil).Call), env, me, addr, data, gas, value) +} + +// CallCode mocks base method. +func (m *MockCallContext) CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas uint64, value *big.Int) ([]byte, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CallCode", env, me, addr, data, gas, value) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(uint64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// CallCode indicates an expected call of CallCode. +func (mr *MockCallContextMockRecorder) CallCode(env, me, addr, data, gas, value interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallCode", reflect.TypeOf((*MockCallContext)(nil).CallCode), env, me, addr, data, gas, value) +} + +// Create mocks base method. +func (m *MockCallContext) Create(env *EVM, me ContractRef, code []byte, gas uint64, value *big.Int) ([]byte, common.Address, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", env, me, code, gas, value) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(common.Address) + ret2, _ := ret[2].(uint64) + ret3, _ := ret[3].(error) + return ret0, ret1, ret2, ret3 +} + +// Create indicates an expected call of Create. +func (mr *MockCallContextMockRecorder) Create(env, me, code, gas, value interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockCallContext)(nil).Create), env, me, code, gas, value) +} + +// Create2 mocks base method. +func (m *MockCallContext) Create2(env *EVM, me ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) ([]byte, common.Address, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create2", env, me, code, gas, endowment, salt) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(common.Address) + ret2, _ := ret[2].(uint64) + ret3, _ := ret[3].(error) + return ret0, ret1, ret2, ret3 +} + +// Create2 indicates an expected call of Create2. +func (mr *MockCallContextMockRecorder) Create2(env, me, code, gas, endowment, salt interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create2", reflect.TypeOf((*MockCallContext)(nil).Create2), env, me, code, gas, endowment, salt) +} + +// DelegateCall mocks base method. +func (m *MockCallContext) DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas uint64) ([]byte, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DelegateCall", env, me, addr, data, gas) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(uint64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// DelegateCall indicates an expected call of DelegateCall. +func (mr *MockCallContextMockRecorder) DelegateCall(env, me, addr, data, gas interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelegateCall", reflect.TypeOf((*MockCallContext)(nil).DelegateCall), env, me, addr, data, gas) +} + +// StaticCall mocks base method. +func (m *MockCallContext) StaticCall(env *EVM, me ContractRef, addr common.Address, input []byte, gas uint64) ([]byte, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StaticCall", env, me, addr, input, gas) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(uint64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// StaticCall indicates an expected call of StaticCall. +func (mr *MockCallContextMockRecorder) StaticCall(env, me, addr, input, gas interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StaticCall", reflect.TypeOf((*MockCallContext)(nil).StaticCall), env, me, addr, input, gas) +} diff --git a/go.mod b/go.mod index ec65e1322c2e..1bb678377d46 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/go-stack/stack v1.8.0 + github.com/golang/mock v1.3.1 github.com/golang/protobuf v1.4.3 github.com/golang/snappy v0.0.3 github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa diff --git a/go.sum b/go.sum index 64dd2e6428b9..a3869221c291 100644 --- a/go.sum +++ b/go.sum @@ -177,6 +177,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=