github.com/carter-ya/go-ethereum@v0.0.0-20230628080049-d2309be3983b/core/vm/interpreter_test.go (about) 1 // Copyright 2021 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "math/big" 21 "testing" 22 "time" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/common/math" 26 "github.com/ethereum/go-ethereum/core/rawdb" 27 "github.com/ethereum/go-ethereum/core/state" 28 "github.com/ethereum/go-ethereum/params" 29 ) 30 31 var loopInterruptTests = []string{ 32 // infinite loop using JUMP: push(2) jumpdest dup1 jump 33 "60025b8056", 34 // infinite loop using JUMPI: push(1) push(4) jumpdest dup2 dup2 jumpi 35 "600160045b818157", 36 } 37 38 func TestLoopInterrupt(t *testing.T) { 39 address := common.BytesToAddress([]byte("contract")) 40 vmctx := BlockContext{ 41 Transfer: func(StateDB, common.Address, common.Address, *big.Int) {}, 42 } 43 44 for i, tt := range loopInterruptTests { 45 statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) 46 statedb.CreateAccount(address) 47 statedb.SetCode(address, common.Hex2Bytes(tt)) 48 statedb.Finalise(true) 49 50 evm := NewEVM(vmctx, TxContext{}, statedb, params.AllEthashProtocolChanges, Config{}) 51 52 errChannel := make(chan error) 53 timeout := make(chan bool) 54 55 go func(evm *EVM) { 56 _, _, err := evm.Call(AccountRef(common.Address{}), address, nil, math.MaxUint64, new(big.Int)) 57 errChannel <- err 58 }(evm) 59 60 go func() { 61 <-time.After(time.Second) 62 timeout <- true 63 }() 64 65 evm.Cancel() 66 67 select { 68 case <-timeout: 69 t.Errorf("test %d timed out", i) 70 case err := <-errChannel: 71 if err != nil { 72 t.Errorf("test %d failure: %v", i, err) 73 } 74 } 75 } 76 }