github.com/ontio/ontology@v1.14.4/vm/evm/gas_table_test.go (about) 1 // Copyright (C) 2021 The Ontology Authors 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package evm 19 20 import ( 21 "math" 22 "math/big" 23 "testing" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/common/hexutil" 27 "github.com/ontio/ontology/core/store/leveldbstore" 28 "github.com/ontio/ontology/core/store/overlaydb" 29 "github.com/ontio/ontology/smartcontract/service/native/ong" 30 "github.com/ontio/ontology/smartcontract/storage" 31 "github.com/ontio/ontology/vm/evm/errors" 32 "github.com/ontio/ontology/vm/evm/params" 33 ) 34 35 func TestMemoryGasCost(t *testing.T) { 36 tests := []struct { 37 size uint64 38 cost uint64 39 overflow bool 40 }{ 41 {0x1fffffffe0, 36028809887088637, false}, 42 {0x1fffffffe1, 0, true}, 43 } 44 for i, tt := range tests { 45 v, err := memoryGasCost(&Memory{}, tt.size) 46 if (err == errors.ErrGasUintOverflow) != tt.overflow { 47 t.Errorf("test %d: overflow mismatch: have %v, want %v", i, err == errors.ErrGasUintOverflow, tt.overflow) 48 } 49 if v != tt.cost { 50 t.Errorf("test %d: gas cost mismatch: have %v, want %v", i, v, tt.cost) 51 } 52 } 53 } 54 55 var eip2200Tests = []struct { 56 original byte 57 gaspool uint64 58 input string 59 used uint64 60 refund uint64 61 failure error 62 }{ 63 {0, math.MaxUint64, "0x60006000556000600055", 1612, 0, nil}, // 0 -> 0 -> 0 64 {0, math.MaxUint64, "0x60006000556001600055", 20812, 0, nil}, // 0 -> 0 -> 1 65 {0, math.MaxUint64, "0x60016000556000600055", 20812, 19200, nil}, // 0 -> 1 -> 0 66 {0, math.MaxUint64, "0x60016000556002600055", 20812, 0, nil}, // 0 -> 1 -> 2 67 {0, math.MaxUint64, "0x60016000556001600055", 20812, 0, nil}, // 0 -> 1 -> 1 68 {1, math.MaxUint64, "0x60006000556000600055", 5812, 15000, nil}, // 1 -> 0 -> 0 69 {1, math.MaxUint64, "0x60006000556001600055", 5812, 4200, nil}, // 1 -> 0 -> 1 70 {1, math.MaxUint64, "0x60006000556002600055", 5812, 0, nil}, // 1 -> 0 -> 2 71 {1, math.MaxUint64, "0x60026000556000600055", 5812, 15000, nil}, // 1 -> 2 -> 0 72 {1, math.MaxUint64, "0x60026000556003600055", 5812, 0, nil}, // 1 -> 2 -> 3 73 {1, math.MaxUint64, "0x60026000556001600055", 5812, 4200, nil}, // 1 -> 2 -> 1 74 {1, math.MaxUint64, "0x60026000556002600055", 5812, 0, nil}, // 1 -> 2 -> 2 75 {1, math.MaxUint64, "0x60016000556000600055", 5812, 15000, nil}, // 1 -> 1 -> 0 76 {1, math.MaxUint64, "0x60016000556002600055", 5812, 0, nil}, // 1 -> 1 -> 2 77 {1, math.MaxUint64, "0x60016000556001600055", 1612, 0, nil}, // 1 -> 1 -> 1 78 {0, math.MaxUint64, "0x600160005560006000556001600055", 40818, 19200, nil}, // 0 -> 1 -> 0 -> 1 79 {1, math.MaxUint64, "0x600060005560016000556000600055", 10818, 19200, nil}, // 1 -> 0 -> 1 -> 0 80 {1, 2306, "0x6001600055", 2306, 0, errors.ErrOutOfGas}, // 1 -> 1 (2300 sentry + 2xPUSH) 81 {1, 2307, "0x6001600055", 806, 0, nil}, // 1 -> 1 (2301 sentry + 2xPUSH) 82 } 83 84 func TestEIP2200(t *testing.T) { 85 for i, tt := range eip2200Tests { 86 address := common.BytesToAddress([]byte("contract")) 87 88 db := storage.NewCacheDB(overlaydb.NewOverlayDB(leveldbstore.NewMemLevelDBStore())) 89 statedb := storage.NewStateDB(db, common.Hash{}, common.Hash{}, ong.OngBalanceHandle{}) 90 statedb.CreateAccount(address) 91 statedb.SetCode(address, hexutil.MustDecode(tt.input)) 92 statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original})) 93 _ = statedb.Commit() // Push the state into the "original" slot 94 95 vmctx := BlockContext{ 96 CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true }, 97 Transfer: func(StateDB, common.Address, common.Address, *big.Int) {}, 98 } 99 vmenv := NewEVM(vmctx, TxContext{}, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) 100 101 _, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(big.Int)) 102 if err != tt.failure { 103 t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure) 104 } 105 if used := tt.gaspool - gas; used != tt.used { 106 t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used) 107 } 108 if refund := vmenv.StateDB.GetRefund(); refund != tt.refund { 109 t.Errorf("test %d: gas refund mismatch: have %v, want %v", i, refund, tt.refund) 110 } 111 } 112 }