github.com/klaytn/klaytn@v1.10.2/blockchain/vm/gas_table_test.go (about)

     1  // Modifications Copyright 2018 The klaytn 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  // This file is derived from core/vm/gas_table_test.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package vm
    22  
    23  import (
    24  	"math"
    25  	"math/big"
    26  	"testing"
    27  
    28  	"github.com/klaytn/klaytn/blockchain/state"
    29  	"github.com/klaytn/klaytn/common"
    30  	"github.com/klaytn/klaytn/common/hexutil"
    31  	"github.com/klaytn/klaytn/kerrors"
    32  	"github.com/klaytn/klaytn/params"
    33  	"github.com/klaytn/klaytn/storage/database"
    34  )
    35  
    36  func TestMemoryGasCost(t *testing.T) {
    37  	tests := []struct {
    38  		size     uint64
    39  		cost     uint64
    40  		overflow bool
    41  	}{
    42  		{0x1fffffffe0, 36028809887088637, false},
    43  		{0x1fffffffe1, 0, true},
    44  	}
    45  	for i, tt := range tests {
    46  		v, err := memoryGasCost(&Memory{}, tt.size)
    47  		if (err == errGasUintOverflow) != tt.overflow {
    48  			t.Errorf("test %d: overflow mismatch: have %v, want %v", i, err == errGasUintOverflow, tt.overflow)
    49  		}
    50  		if v != tt.cost {
    51  			t.Errorf("test %d: gas cost mismatch: have %v, want %v", i, v, tt.cost)
    52  		}
    53  	}
    54  }
    55  
    56  var eip2200Tests = []struct {
    57  	original byte
    58  	gaspool  uint64
    59  	input    string
    60  	used     uint64
    61  	refund   uint64
    62  	failure  error
    63  }{
    64  	// before istanbul compatible hard fork
    65  	{0, math.MaxUint64, "0x60006000556000600055", 10012, 0, nil},               // 0 -> 0 -> 0
    66  	{0, math.MaxUint64, "0x60006000556001600055", 25012, 0, nil},               // 0 -> 0 -> 1
    67  	{0, math.MaxUint64, "0x60016000556000600055", 25012, 15000, nil},           // 0 -> 1 -> 0
    68  	{0, math.MaxUint64, "0x60016000556002600055", 25012, 0, nil},               // 0 -> 1 -> 2
    69  	{0, math.MaxUint64, "0x60016000556001600055", 25012, 0, nil},               // 0 -> 1 -> 1
    70  	{1, math.MaxUint64, "0x60006000556000600055", 10012, 15000, nil},           // 1 -> 0 -> 0
    71  	{1, math.MaxUint64, "0x60006000556001600055", 25012, 15000, nil},           // 1 -> 0 -> 1
    72  	{1, math.MaxUint64, "0x60006000556002600055", 25012, 15000, nil},           // 1 -> 0 -> 2
    73  	{1, math.MaxUint64, "0x60026000556000600055", 10012, 15000, nil},           // 1 -> 2 -> 0
    74  	{1, math.MaxUint64, "0x60026000556003600055", 10012, 0, nil},               // 1 -> 2 -> 3
    75  	{1, math.MaxUint64, "0x60026000556001600055", 10012, 0, nil},               // 1 -> 2 -> 1
    76  	{1, math.MaxUint64, "0x60026000556002600055", 10012, 0, nil},               // 1 -> 2 -> 2
    77  	{1, math.MaxUint64, "0x60016000556000600055", 10012, 15000, nil},           // 1 -> 1 -> 0
    78  	{1, math.MaxUint64, "0x60016000556002600055", 10012, 0, nil},               // 1 -> 1 -> 2
    79  	{1, math.MaxUint64, "0x60016000556001600055", 10012, 0, nil},               // 1 -> 1 -> 1
    80  	{0, math.MaxUint64, "0x600160005560006000556001600055", 45018, 15000, nil}, // 0 -> 1 -> 0 -> 1
    81  	{1, math.MaxUint64, "0x600060005560016000556000600055", 30018, 30000, nil}, // 1 -> 0 -> 1 -> 0
    82  	{1, 2306, "0x6001600055", 2306, 0, kerrors.ErrOutOfGas},                    // 1 -> 1 (2300 sentry + 2xPUSH)
    83  	{1, 2307, "0x6001600055", 2307, 0, kerrors.ErrOutOfGas},                    // 1 -> 1 (2301 sentry + 2xPUSH)
    84  	// after istanbul compatible hard fork
    85  	{0, math.MaxUint64, "0x60006000556000600055", 1612, 0, nil},                // 0 -> 0 -> 0
    86  	{0, math.MaxUint64, "0x60006000556001600055", 20812, 0, nil},               // 0 -> 0 -> 1
    87  	{0, math.MaxUint64, "0x60016000556000600055", 20812, 19200, nil},           // 0 -> 1 -> 0
    88  	{0, math.MaxUint64, "0x60016000556002600055", 20812, 0, nil},               // 0 -> 1 -> 2
    89  	{0, math.MaxUint64, "0x60016000556001600055", 20812, 0, nil},               // 0 -> 1 -> 1
    90  	{1, math.MaxUint64, "0x60006000556000600055", 5812, 15000, nil},            // 1 -> 0 -> 0
    91  	{1, math.MaxUint64, "0x60006000556001600055", 5812, 4200, nil},             // 1 -> 0 -> 1
    92  	{1, math.MaxUint64, "0x60006000556002600055", 5812, 0, nil},                // 1 -> 0 -> 2
    93  	{1, math.MaxUint64, "0x60026000556000600055", 5812, 15000, nil},            // 1 -> 2 -> 0
    94  	{1, math.MaxUint64, "0x60026000556003600055", 5812, 0, nil},                // 1 -> 2 -> 3
    95  	{1, math.MaxUint64, "0x60026000556001600055", 5812, 4200, nil},             // 1 -> 2 -> 1
    96  	{1, math.MaxUint64, "0x60026000556002600055", 5812, 0, nil},                // 1 -> 2 -> 2
    97  	{1, math.MaxUint64, "0x60016000556000600055", 5812, 15000, nil},            // 1 -> 1 -> 0
    98  	{1, math.MaxUint64, "0x60016000556002600055", 5812, 0, nil},                // 1 -> 1 -> 2
    99  	{1, math.MaxUint64, "0x60016000556001600055", 1612, 0, nil},                // 1 -> 1 -> 1
   100  	{0, math.MaxUint64, "0x600160005560006000556001600055", 40818, 19200, nil}, // 0 -> 1 -> 0 -> 1
   101  	{1, math.MaxUint64, "0x600060005560016000556000600055", 10818, 19200, nil}, // 1 -> 0 -> 1 -> 0
   102  	{1, 2306, "0x6001600055", 2306, 0, kerrors.ErrOutOfGas},                    // 1 -> 1 (2300 sentry + 2xPUSH)
   103  	{1, 2307, "0x6001600055", 806, 0, nil},                                     // 1 -> 1 (2301 sentry + 2xPUSH)
   104  }
   105  
   106  func TestEIP2200(t *testing.T) {
   107  	for i, tt := range eip2200Tests {
   108  		address := common.BytesToAddress([]byte("contract"))
   109  
   110  		statedb, _ := state.New(common.Hash{}, state.NewDatabase(database.NewMemoryDBManager()), nil)
   111  		statedb.CreateSmartContractAccount(address, params.CodeFormatEVM, params.Rules{IsIstanbul: true})
   112  		statedb.SetCode(address, hexutil.MustDecode(tt.input))
   113  		statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
   114  		statedb.Finalise(true, false) // Push the state into the "original" slot
   115  
   116  		vmctx := Context{
   117  			CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true },
   118  			Transfer:    func(StateDB, common.Address, common.Address, *big.Int) {},
   119  		}
   120  		var vmenv *EVM
   121  		if i <= 18 {
   122  			vmenv = NewEVM(vmctx, statedb, params.AllGxhashProtocolChanges, &Config{})
   123  		} else {
   124  			vmenv = NewEVM(vmctx, statedb, params.AllGxhashProtocolChanges, &Config{ExtraEips: []int{2200}})
   125  		}
   126  
   127  		_, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(big.Int))
   128  		if err != tt.failure {
   129  			t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
   130  		}
   131  		if used := tt.gaspool - gas; used != tt.used {
   132  			t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used)
   133  		}
   134  		if refund := vmenv.StateDB.GetRefund(); refund != tt.refund {
   135  			t.Errorf("test %d: gas refund mismatch: have %v, want %v", i, refund, tt.refund)
   136  		}
   137  	}
   138  }