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