github.com/ethereum/go-ethereum@v1.16.1/core/state/access_events_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 state 18 19 import ( 20 "math" 21 "testing" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/params" 25 "github.com/ethereum/go-ethereum/trie/utils" 26 ) 27 28 var ( 29 testAddr [20]byte 30 testAddr2 [20]byte 31 ) 32 33 func init() { 34 for i := byte(0); i < 20; i++ { 35 testAddr[i] = i 36 testAddr[2] = 2 * i 37 } 38 } 39 40 func TestAccountHeaderGas(t *testing.T) { 41 ae := NewAccessEvents(utils.NewPointCache(1024)) 42 43 // Check cold read cost 44 gas := ae.BasicDataGas(testAddr, false, math.MaxUint64, false) 45 if want := params.WitnessBranchReadCost + params.WitnessChunkReadCost; gas != want { 46 t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) 47 } 48 49 // Check warm read cost 50 gas = ae.BasicDataGas(testAddr, false, math.MaxUint64, false) 51 if gas != 0 { 52 t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) 53 } 54 55 // Check cold read costs in the same group no longer incur the branch read cost 56 gas = ae.CodeHashGas(testAddr, false, math.MaxUint64, false) 57 if gas != params.WitnessChunkReadCost { 58 t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WitnessChunkReadCost) 59 } 60 61 // Check cold write cost 62 gas = ae.BasicDataGas(testAddr, true, math.MaxUint64, false) 63 if want := params.WitnessBranchWriteCost + params.WitnessChunkWriteCost; gas != want { 64 t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) 65 } 66 67 // Check warm write cost 68 gas = ae.BasicDataGas(testAddr, true, math.MaxUint64, false) 69 if gas != 0 { 70 t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) 71 } 72 73 // Check a write without a read charges both read and write costs 74 gas = ae.BasicDataGas(testAddr2, true, math.MaxUint64, false) 75 if want := params.WitnessBranchReadCost + params.WitnessBranchWriteCost + params.WitnessChunkWriteCost + params.WitnessChunkReadCost; gas != want { 76 t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) 77 } 78 79 // Check that a write followed by a read charges nothing 80 gas = ae.BasicDataGas(testAddr2, false, math.MaxUint64, false) 81 if gas != 0 { 82 t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) 83 } 84 85 // Check that reading a slot from the account header only charges the 86 // chunk read cost. 87 gas = ae.SlotGas(testAddr, common.Hash{}, false, math.MaxUint64, false) 88 if gas != params.WitnessChunkReadCost { 89 t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WitnessChunkReadCost) 90 } 91 } 92 93 // TestContractCreateInitGas checks that the gas cost of contract creation is correctly 94 // calculated. 95 func TestContractCreateInitGas(t *testing.T) { 96 ae := NewAccessEvents(utils.NewPointCache(1024)) 97 98 var testAddr [20]byte 99 for i := byte(0); i < 20; i++ { 100 testAddr[i] = i 101 } 102 103 // Check cold read cost, without a value 104 gas, _ := ae.ContractCreateInitGas(testAddr, math.MaxUint64) 105 if want := params.WitnessBranchWriteCost + params.WitnessBranchReadCost + 2*params.WitnessChunkWriteCost + 2*params.WitnessChunkReadCost; gas != want { 106 t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) 107 } 108 109 // Check warm read cost 110 gas, _ = ae.ContractCreateInitGas(testAddr, math.MaxUint64) 111 if gas != 0 { 112 t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) 113 } 114 } 115 116 // TestMessageCallGas checks that the gas cost of message calls is correctly 117 // calculated. 118 func TestMessageCallGas(t *testing.T) { 119 ae := NewAccessEvents(utils.NewPointCache(1024)) 120 121 // Check cold read cost, without a value 122 gas := ae.MessageCallGas(testAddr, math.MaxUint64) 123 if want := params.WitnessBranchReadCost + params.WitnessChunkReadCost; gas != want { 124 t.Fatalf("incorrect gas computed, got %d, want %d", gas, want) 125 } 126 127 // Check that reading the basic data and code hash of the same account does not incur the branch read cost 128 gas = ae.BasicDataGas(testAddr, false, math.MaxUint64, false) 129 if gas != 0 { 130 t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) 131 } 132 gas = ae.CodeHashGas(testAddr, false, math.MaxUint64, false) 133 if gas != params.WitnessChunkReadCost { 134 t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) 135 } 136 137 // Check warm read cost 138 gas = ae.MessageCallGas(testAddr, math.MaxUint64) 139 if gas != params.WarmStorageReadCostEIP2929 { 140 t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WarmStorageReadCostEIP2929) 141 } 142 }