Skip to content

Commit

Permalink
simplified gas accounting layer (ethereum#405)
Browse files Browse the repository at this point in the history
* simplified gas accounting layer

* integrate some review feedback

* Apply suggestions from code review

Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>

* more suggestions from code review

* don't charge creation gas + charge code chunks in create

* A couple more fixes

* make linter happy

* fix create init gas consumption issue

* fix: in gas funcs, use tx witness instead of global witness

* fix linter issue

* Apply suggestions from code review

Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>

* fix: EXTCODECOPY gas consumption

* fix warm gas costs

* fix the order gas is charged in during contract creation epilogue

* fix selfdestruct

* fix ethereum#365 in eip rewrite (ethereum#407)

* fix: OOG type in code creation OOG (ethereum#408)

* core/vm: charge BLOCKHASH witness cost (ethereum#409)

* core/vm: charge BLOCKHASH witness cost

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* remove gas optimization for now

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

---------

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* remove redundant logic for contract creation (ethereum#413)

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* fix precompile address check for charging witness costs & fix missing value-bearing rule (ethereum#412)

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* core/vm: fix wrong check (ethereum#416)

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* charge for account creation if selfdestruct creates a new account (ethereum#417)

* add key comparison test (ethereum#418)

* core/vm: charge contract init before execution logic (ethereum#419)

* core/vm: charge contract init before execution logic

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* fix CREATE2 as well

---------

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>

* quell linter

---------

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>
  • Loading branch information
gballet and jsign authored Apr 15, 2024
1 parent c23058e commit e73619a
Show file tree
Hide file tree
Showing 20 changed files with 424 additions and 283 deletions.
7 changes: 1 addition & 6 deletions consensus/beacon/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/utils"
"github.com/ethereum/go-verkle"
"github.com/holiman/uint256"
)

// Proof-of-stake protocol constants.
Expand Down Expand Up @@ -357,11 +356,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
state.AddBalance(w.Address, amount)

// The returned gas is not charged
state.Witness().TouchAddressOnWriteAndComputeGas(w.Address[:], uint256.Int{}, utils.VersionLeafKey)
state.Witness().TouchAddressOnWriteAndComputeGas(w.Address[:], uint256.Int{}, utils.BalanceLeafKey)
state.Witness().TouchAddressOnWriteAndComputeGas(w.Address[:], uint256.Int{}, utils.NonceLeafKey)
state.Witness().TouchAddressOnWriteAndComputeGas(w.Address[:], uint256.Int{}, utils.CodeKeccakLeafKey)
state.Witness().TouchAddressOnWriteAndComputeGas(w.Address[:], uint256.Int{}, utils.CodeSizeLeafKey)
state.Witness().TouchFullAccount(w.Address[:], true)
}
}

Expand Down
11 changes: 0 additions & 11 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/utils"
"github.com/holiman/uint256"
"golang.org/x/crypto/sha3"
)

Expand Down Expand Up @@ -568,19 +566,10 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header
r.Div(r, big8)

// This should not happen, but it's useful for replay tests
if config.IsPrague(header.Number, header.Time) {
state.Witness().TouchAddressOnReadAndComputeGas(uncle.Coinbase.Bytes(), uint256.Int{}, utils.BalanceLeafKey)
}
state.AddBalance(uncle.Coinbase, r)

r.Div(blockReward, big32)
reward.Add(reward, r)
}
if config.IsPrague(header.Number, header.Time) {
state.Witness().TouchAddressOnReadAndComputeGas(header.Coinbase.Bytes(), uint256.Int{}, utils.BalanceLeafKey)
state.Witness().TouchAddressOnReadAndComputeGas(header.Coinbase.Bytes(), uint256.Int{}, utils.VersionLeafKey)
state.Witness().TouchAddressOnReadAndComputeGas(header.Coinbase.Bytes(), uint256.Int{}, utils.NonceLeafKey)
state.Witness().TouchAddressOnReadAndComputeGas(header.Coinbase.Bytes(), uint256.Int{}, utils.CodeKeccakLeafKey)
}
state.AddBalance(header.Coinbase, reward)
}
122 changes: 79 additions & 43 deletions core/state/access_witness.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package state

import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie/utils"
"github.com/holiman/uint256"
Expand Down Expand Up @@ -88,61 +89,44 @@ func (aw *AccessWitness) Copy() *AccessWitness {
return naw
}

func (aw *AccessWitness) TouchAndChargeProofOfAbsence(addr []byte) uint64 {
func (aw *AccessWitness) TouchFullAccount(addr []byte, isWrite bool) uint64 {
var gas uint64
gas += aw.TouchAddressOnReadAndComputeGas(addr, zeroTreeIndex, utils.VersionLeafKey)
gas += aw.TouchAddressOnReadAndComputeGas(addr, zeroTreeIndex, utils.BalanceLeafKey)
gas += aw.TouchAddressOnReadAndComputeGas(addr, zeroTreeIndex, utils.CodeSizeLeafKey)
gas += aw.TouchAddressOnReadAndComputeGas(addr, zeroTreeIndex, utils.CodeKeccakLeafKey)
gas += aw.TouchAddressOnReadAndComputeGas(addr, zeroTreeIndex, utils.NonceLeafKey)
for i := utils.VersionLeafKey; i <= utils.CodeSizeLeafKey; i++ {
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, byte(i), isWrite)
}
return gas
}

func (aw *AccessWitness) TouchAndChargeMessageCall(addr []byte) uint64 {
var gas uint64
gas += aw.TouchAddressOnReadAndComputeGas(addr, zeroTreeIndex, utils.VersionLeafKey)
gas += aw.TouchAddressOnReadAndComputeGas(addr, zeroTreeIndex, utils.CodeSizeLeafKey)
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.VersionLeafKey, false)
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeSizeLeafKey, false)
return gas
}

func (aw *AccessWitness) TouchAndChargeValueTransfer(callerAddr, targetAddr []byte) uint64 {
var gas uint64
gas += aw.TouchAddressOnWriteAndComputeGas(callerAddr, zeroTreeIndex, utils.BalanceLeafKey)
gas += aw.TouchAddressOnWriteAndComputeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey)
gas += aw.touchAddressAndChargeGas(callerAddr, zeroTreeIndex, utils.BalanceLeafKey, true)
gas += aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey, true)
return gas
}

// TouchAndChargeContractCreateInit charges access costs to initiate
// a contract creation
func (aw *AccessWitness) TouchAndChargeContractCreateInit(addr []byte, createSendsValue bool) uint64 {
var gas uint64
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.VersionLeafKey)
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.NonceLeafKey)
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.VersionLeafKey, true)
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.NonceLeafKey, true)
if createSendsValue {
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.BalanceLeafKey)
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BalanceLeafKey, true)
}
return gas
}

// TouchAndChargeContractCreateCompleted charges access access costs after
// the completion of a contract creation to populate the created account in
// the tree
func (aw *AccessWitness) TouchAndChargeContractCreateCompleted(addr []byte) uint64 {
var gas uint64
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.VersionLeafKey)
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.BalanceLeafKey)
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.CodeSizeLeafKey)
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.CodeKeccakLeafKey)
gas += aw.TouchAddressOnWriteAndComputeGas(addr, zeroTreeIndex, utils.NonceLeafKey)
return gas
}

func (aw *AccessWitness) TouchTxOriginAndComputeGas(originAddr []byte) uint64 {
aw.TouchAddressOnReadAndComputeGas(originAddr, zeroTreeIndex, utils.VersionLeafKey)
aw.TouchAddressOnReadAndComputeGas(originAddr, zeroTreeIndex, utils.CodeSizeLeafKey)
aw.TouchAddressOnReadAndComputeGas(originAddr, zeroTreeIndex, utils.CodeKeccakLeafKey)
aw.TouchAddressOnWriteAndComputeGas(originAddr, zeroTreeIndex, utils.NonceLeafKey)
aw.TouchAddressOnWriteAndComputeGas(originAddr, zeroTreeIndex, utils.BalanceLeafKey)
for i := utils.VersionLeafKey; i <= utils.CodeSizeLeafKey; i++ {
aw.touchAddressAndChargeGas(originAddr, zeroTreeIndex, byte(i), i == utils.BalanceLeafKey || i == utils.NonceLeafKey)
}

// Kaustinen note: we're currently experimenting with stop chargin gas for the origin address
// so simple transfer still take 21000 gas. This is to potentially avoid breaking existing tooling.
Expand All @@ -152,14 +136,14 @@ func (aw *AccessWitness) TouchTxOriginAndComputeGas(originAddr []byte) uint64 {
}

func (aw *AccessWitness) TouchTxExistingAndComputeGas(targetAddr []byte, sendsValue bool) uint64 {
aw.TouchAddressOnReadAndComputeGas(targetAddr, zeroTreeIndex, utils.VersionLeafKey)
aw.TouchAddressOnReadAndComputeGas(targetAddr, zeroTreeIndex, utils.CodeSizeLeafKey)
aw.TouchAddressOnReadAndComputeGas(targetAddr, zeroTreeIndex, utils.CodeKeccakLeafKey)
aw.TouchAddressOnReadAndComputeGas(targetAddr, zeroTreeIndex, utils.NonceLeafKey)
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.VersionLeafKey, false)
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.CodeSizeLeafKey, false)
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.CodeHashLeafKey, false)
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.NonceLeafKey, false)
if sendsValue {
aw.TouchAddressOnWriteAndComputeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey)
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey, true)
} else {
aw.TouchAddressOnReadAndComputeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey)
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey, false)
}

// Kaustinen note: we're currently experimenting with stop chargin gas for the origin address
Expand All @@ -169,12 +153,9 @@ func (aw *AccessWitness) TouchTxExistingAndComputeGas(targetAddr []byte, sendsVa
return 0
}

func (aw *AccessWitness) TouchAddressOnWriteAndComputeGas(addr []byte, treeIndex uint256.Int, subIndex byte) uint64 {
return aw.touchAddressAndChargeGas(addr, treeIndex, subIndex, true)
}

func (aw *AccessWitness) TouchAddressOnReadAndComputeGas(addr []byte, treeIndex uint256.Int, subIndex byte) uint64 {
return aw.touchAddressAndChargeGas(addr, treeIndex, subIndex, false)
func (aw *AccessWitness) TouchSlotAndChargeGas(addr []byte, slot common.Hash, isWrite bool) uint64 {
treeIndex, subIndex := utils.GetTreeKeyStorageSlotTreeIndexes(slot.Bytes())
return aw.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite)
}

func (aw *AccessWitness) touchAddressAndChargeGas(addr []byte, treeIndex uint256.Int, subIndex byte, isWrite bool) uint64 {
Expand Down Expand Up @@ -259,3 +240,58 @@ func newChunkAccessKey(branchKey branchAccessKey, leafKey byte) chunkAccessKey {
lk.leafKey = leafKey
return lk
}

// touchCodeChunksRangeOnReadAndChargeGas is a helper function to touch every chunk in a code range and charge witness gas costs
func (aw *AccessWitness) TouchCodeChunksRangeAndChargeGas(contractAddr []byte, startPC, size uint64, codeLen uint64, isWrite bool) uint64 {
// note that in the case where the copied code is outside the range of the
// contract code but touches the last leaf with contract code in it,
// we don't include the last leaf of code in the AccessWitness. The
// reason that we do not need the last leaf is the account's code size
// is already in the AccessWitness so a stateless verifier can see that
// the code from the last leaf is not needed.
if (codeLen == 0 && size == 0) || startPC > codeLen {
return 0
}

endPC := startPC + size
if endPC > codeLen {
endPC = codeLen
}
if endPC > 0 {
endPC -= 1 // endPC is the last bytecode that will be touched.
}

var statelessGasCharged uint64
for chunkNumber := startPC / 31; chunkNumber <= endPC/31; chunkNumber++ {
treeIndex := *uint256.NewInt((chunkNumber + 128) / 256)
subIndex := byte((chunkNumber + 128) % 256)
gas := aw.touchAddressAndChargeGas(contractAddr, treeIndex, subIndex, isWrite)
var overflow bool
statelessGasCharged, overflow = math.SafeAdd(statelessGasCharged, gas)
if overflow {
panic("overflow when adding gas")
}
}

return statelessGasCharged
}

func (aw *AccessWitness) TouchVersion(addr []byte, isWrite bool) uint64 {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.VersionLeafKey, isWrite)
}

func (aw *AccessWitness) TouchBalance(addr []byte, isWrite bool) uint64 {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BalanceLeafKey, isWrite)
}

func (aw *AccessWitness) TouchNonce(addr []byte, isWrite bool) uint64 {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.NonceLeafKey, isWrite)
}

func (aw *AccessWitness) TouchCodeSize(addr []byte, isWrite bool) uint64 {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeSizeLeafKey, isWrite)
}

func (aw *AccessWitness) TouchCodeHash(addr []byte, isWrite bool) uint64 {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite)
}
2 changes: 1 addition & 1 deletion core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
// - Add coinbase to access list (EIP-3651)
// - Reset transient storage (EIP-1153)
func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) {
if rules.IsBerlin {
if rules.IsEIP2929 {
// Clear out any leftover from previous executions
al := newAccessList()
s.accessList = al
Expand Down
12 changes: 8 additions & 4 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/utils"
tutils "github.com/ethereum/go-ethereum/trie/utils"
"github.com/ethereum/go-verkle"
"github.com/holiman/uint256"
Expand Down Expand Up @@ -261,7 +260,7 @@ func (kvm *keyValueMigrator) addAccount(addr []byte, acc *types.StateAccount) {
binary.LittleEndian.PutUint64(nonce[:8], acc.Nonce)
leafNodeData.Values[tutils.NonceLeafKey] = nonce[:]

leafNodeData.Values[tutils.CodeKeccakLeafKey] = acc.CodeHash[:]
leafNodeData.Values[tutils.CodeHashLeafKey] = acc.CodeHash[:]
}

func (kvm *keyValueMigrator) addAccountCode(addr []byte, codeSize uint64, chunks []byte) {
Expand Down Expand Up @@ -369,7 +368,13 @@ func (kvm *keyValueMigrator) migrateCollectedKeyValues(tree *trie.VerkleTrie) er
return nil
}

// InsertBlockHashHistoryAtEip2935Fork handles the insertion of all previous 256
// blocks on the eip2935 activation block. It also adds the account header of the
// history contract to the witness.
func InsertBlockHashHistoryAtEip2935Fork(statedb *state.StateDB, prevNumber uint64, prevHash common.Hash, chain consensus.ChainHeaderReader) {
// Make sure that the historical contract is added to the witness
statedb.Witness().TouchFullAccount(params.HistoryStorageAddress[:], true)

ancestor := chain.GetHeader(prevHash, prevNumber)
for i := prevNumber; i > 0 && i >= prevNumber-params.Eip2935BlockHashHistorySize; i-- {
ProcessParentBlockHash(statedb, i, ancestor.Hash())
Expand All @@ -382,6 +387,5 @@ func ProcessParentBlockHash(statedb *state.StateDB, prevNumber uint64, prevHash
var key common.Hash
binary.BigEndian.PutUint64(key[24:], ringIndex)
statedb.SetState(params.HistoryStorageAddress, key, prevHash)
index, suffix := utils.GetTreeKeyStorageSlotTreeIndexes(key[:])
statedb.Witness().TouchAddressOnWriteAndComputeGas(params.HistoryStorageAddress[:], *index, suffix)
statedb.Witness().TouchSlotAndChargeGas(params.HistoryStorageAddress[:], key, true)
}
50 changes: 45 additions & 5 deletions core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"bytes"
"crypto/ecdsa"
"encoding/binary"
"encoding/json"
"fmt"
"os"

//"fmt"
"math/big"
Expand All @@ -37,7 +40,9 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie/utils"

//"github.com/ethereum/go-ethereum/rlp"
Expand Down Expand Up @@ -472,11 +477,19 @@ func TestProcessVerkle(t *testing.T) {
},
},
}
loggerCfg = &logger.Config{}
)

os.MkdirAll("output", 0755)
traceFile, err := os.Create("./output/traces.jsonl")
if err != nil {
t.Fatal(err)
}

// Verkle trees use the snapshot, which must be enabled before the
// data is saved into the tree+database.
genesis := gspec.MustCommit(bcdb)
blockchain, _ := NewBlockChain(bcdb, nil, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil, nil)
blockchain, _ := NewBlockChain(bcdb, nil, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{Tracer: logger.NewJSONLogger(loggerCfg, traceFile)}, nil, nil)
defer blockchain.Stop()

// Commit the genesis block to the block-generation database as it
Expand All @@ -485,8 +498,8 @@ func TestProcessVerkle(t *testing.T) {

txCost1 := params.TxGas
txCost2 := params.TxGas
contractCreationCost := intrinsicContractCreationGas + uint64(5600+700+700+700 /* creation with value */ +2739 /* execution costs */)
codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas + uint64(5600+700 /* creation */ +302044 /* execution costs */)
contractCreationCost := intrinsicContractCreationGas + uint64(5600+700+700+700 /* creation with value */ +1439 /* execution costs */)
codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas + uint64(5600+700 /* creation */ +44044 /* execution costs */)
blockGasUsagesExpected := []uint64{
txCost1*2 + txCost2,
txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas,
Expand All @@ -513,6 +526,33 @@ func TestProcessVerkle(t *testing.T) {
}
})

kvjson, err := json.Marshal(keyvals)
if err != nil {
t.Fatal(err)
}
err = os.WriteFile("./output/statediffs.json", kvjson, 0644)
if err != nil {
t.Fatal(err)
}
blockrlp, err := rlp.EncodeToBytes(genesis)
if err != nil {
t.Fatal(err)
}
err = os.WriteFile(fmt.Sprintf("./output/block%d.rlp.hex", 0), []byte(fmt.Sprintf("%x", blockrlp)), 0644)
if err != nil {
t.Fatal(err)
}
for _, block := range chain {
blockrlp, err := rlp.EncodeToBytes(block)
if err != nil {
t.Fatal(err)
}
err = os.WriteFile(fmt.Sprintf("./output/block%d.rlp.hex", block.NumberU64()), []byte(fmt.Sprintf("%x", blockrlp)), 0644)
if err != nil {
t.Fatal(err)
}
}

// Uncomment to extract block #2
//f, _ := os.Create("block2.rlp")
//defer f.Close()
Expand All @@ -521,7 +561,7 @@ func TestProcessVerkle(t *testing.T) {
//f.Write(buf.Bytes())
//fmt.Printf("root= %x\n", chain[0].Root())
// check the proof for the last block
err := trie.DeserializeAndVerifyVerkleProof(proofs[1], chain[0].Root().Bytes(), chain[1].Root().Bytes(), keyvals[1])
err = trie.DeserializeAndVerifyVerkleProof(proofs[1], chain[0].Root().Bytes(), chain[1].Root().Bytes(), keyvals[1])
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -913,7 +953,7 @@ func TestProcessVerklExtCodeHashOpcode(t *testing.T) {
}

codeHashStateDiff := statediff[1][stateDiffIdx].SuffixDiffs[0]
if codeHashStateDiff.Suffix != utils.CodeKeccakLeafKey {
if codeHashStateDiff.Suffix != utils.CodeHashLeafKey {
t.Fatalf("code hash invalid suffix")
}
if codeHashStateDiff.CurrentValue == nil {
Expand Down
Loading

0 comments on commit e73619a

Please sign in to comment.