Skip to content

Commit 2178b75

Browse files
committed
fixes for the IPA testnet
upgrade to latest go-verkle update go-verkle to get more fixes simplify code by removing all stateless references (#25) fix verkle proof test by enforcing values alignment to 32 bytes remove unneeded KZG tag fix the stateless test Move AccessWitness into StateDB (#27) * move AccessWitness into StateDB * set Accesses in TxContext constructor * Ensures that a statedb is initialized with a witness * copy AccessWitness in StateDB.Copy. use copied state in miner worker.commit. * remove redundant line Co-authored-by: Guillaume Ballet <[email protected]> Fix contract creation issue
1 parent 66956ea commit 2178b75

File tree

12 files changed

+59
-190
lines changed

12 files changed

+59
-190
lines changed

accounts/abi/bind/bind_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1983,7 +1983,7 @@ func TestGolangBindings(t *testing.T) {
19831983
t.Fatalf("failed to tidy Go module file: %v\n%s", err, out)
19841984
}
19851985
// Test the entire package and report any failures
1986-
cmd := exec.Command(gocmd, "test", "-tags=bignum_kilic", "-v", "-count", "1")
1986+
cmd := exec.Command(gocmd, "test", "-v", "-count", "1")
19871987
cmd.Dir = pkg
19881988
if out, err := cmd.CombinedOutput(); err != nil {
19891989
t.Fatalf("failed to run binding test: %v\n%s", err, out)

consensus/ethash/consensus.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/ethereum/go-ethereum/params"
3535
"github.com/ethereum/go-ethereum/rlp"
3636
"github.com/ethereum/go-ethereum/trie"
37+
"github.com/ethereum/go-ethereum/trie/utils"
3738
"golang.org/x/crypto/sha3"
3839
)
3940

@@ -592,6 +593,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H
592593
// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
593594
// setting the final state on the header
594595
func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
596+
// TODO(gballet) aw should be part of StateDB
595597
// Accumulate any block and uncle rewards and commit the final state root
596598
accumulateRewards(chain.Config(), state, header, uncles)
597599
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
@@ -666,4 +668,6 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header
666668
reward.Add(reward, r)
667669
}
668670
state.AddBalance(header.Coinbase, reward)
671+
coinbase := utils.GetTreeKeyBalance(header.Coinbase.Bytes())
672+
state.Witness().TouchAddress(coinbase, state.GetBalance(header.Coinbase).Bytes())
669673
}

core/blockchain.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,17 +1613,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
16131613
receipts types.Receipts
16141614
logs []*types.Log
16151615
)
1616-
if len(block.Header().VerkleProof) == 0 {
1617-
receipts, logs, _, usedGas, err = bc.processor.Process(block, statedb, bc.vmConfig)
1618-
} else {
1619-
var leaves map[common.Hash]common.Hash
1620-
leaves, err = trie.DeserializeAndVerifyVerkleProof(block.Header().VerkleProof)
1621-
if err != nil {
1622-
return it.index, err
1623-
}
1624-
statedb.SetStateless(leaves)
1625-
receipts, logs, usedGas, err = bc.processor.ProcessStateless(block, statedb, bc.vmConfig, leaves)
1626-
}
1616+
receipts, logs, _, usedGas, err = bc.processor.Process(block, statedb, bc.vmConfig)
16271617
if err != nil {
16281618
bc.reportBlock(block, receipts, err)
16291619
atomic.StoreUint32(&followupInterrupt, 1)

core/chain_makers.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ type BlockGen struct {
4444
txs []*types.Transaction
4545
receipts []*types.Receipt
4646
uncles []*types.Header
47-
witness *types.AccessWitness
4847

4948
config *params.ChainConfig
5049
engine consensus.Engine
@@ -110,10 +109,10 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
110109
panic(err)
111110
}
112111
if accesses != nil {
113-
if b.witness != nil {
114-
b.witness.Merge(accesses)
112+
if b.statedb.Witness() != nil {
113+
b.statedb.Witness().Merge(accesses)
115114
} else {
116-
b.witness = accesses
115+
b.statedb.SetWitness(accesses)
117116
}
118117
}
119118
b.txs = append(b.txs, tx)
@@ -266,7 +265,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
266265
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
267266
chainreader := &fakeChainReader{config: config}
268267
genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) {
269-
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine, witness: types.NewAccessWitness()}
268+
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
270269
b.header = makeHeader(chainreader, parent, statedb, b.engine)
271270

272271
// Mutate the state and block according to any hard-fork specs
@@ -309,7 +308,8 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
309308
// before building the proof. Ultimately, node
310309
// resolution can be done with a prefetcher or
311310
// from GetCommitmentsAlongPath.
312-
keys := b.witness.Keys()
311+
312+
keys := statedb.Witness().Keys()
313313
for _, key := range keys {
314314
out, err := vtr.TryGet(key)
315315
if err != nil {
@@ -320,7 +320,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
320320
}
321321
}
322322
vtr.Hash()
323-
_, err := vtr.ProveAndSerialize(keys, b.witness.KeyVals())
323+
_, err := vtr.ProveAndSerialize(keys, statedb.Witness().KeyVals())
324324
//block.SetVerkleProof(p)
325325
if err != nil {
326326
panic(err)

core/state/statedb.go

Lines changed: 23 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ type StateDB struct {
102102
// Per-transaction access list
103103
accessList *accessList
104104

105-
// Stateless locations for this block
106-
stateless map[common.Hash]common.Hash
105+
witness *types.AccessWitness
107106

108107
// Journal of state modifications. This is the backbone of
109108
// Snapshot and RevertToSnapshot.
@@ -149,6 +148,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
149148
journal: newJournal(),
150149
accessList: newAccessList(),
151150
hasher: crypto.NewKeccakState(),
151+
witness: types.NewAccessWitness(),
152152
}
153153
if sdb.snaps == nil && tr.IsVerkle() {
154154
sdb.snaps, err = snapshot.New(db.TrieDB().DiskDB(), db.TrieDB(), 1, root, false, true, false, true)
@@ -166,6 +166,14 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
166166
return sdb, nil
167167
}
168168

169+
func (s *StateDB) Witness() *types.AccessWitness {
170+
return s.witness
171+
}
172+
173+
func (s *StateDB) SetWitness(aw *types.AccessWitness) {
174+
s.witness = aw
175+
}
176+
169177
// StartPrefetcher initializes a new trie prefetcher to pull in nodes from the
170178
// state trie concurrently while the state is mutated so that when we reach the
171179
// commit phase, most of the needed data is already hot.
@@ -423,12 +431,6 @@ func (s *StateDB) SetCode(addr common.Address, code []byte) {
423431
}
424432
}
425433

426-
// SetStateless sets the vales recovered from the execution of a stateless
427-
// block.
428-
func (s *StateDB) SetStateless(leaves map[common.Hash]common.Hash) {
429-
s.stateless = leaves
430-
}
431-
432434
func (s *StateDB) SetState(addr common.Address, key, value common.Hash) {
433435
stateObject := s.GetOrNewStateObject(addr)
434436
if stateObject != nil {
@@ -470,46 +472,6 @@ func (s *StateDB) Suicide(addr common.Address) bool {
470472
// Setting, updating & deleting state object methods.
471473
//
472474

473-
func (s *StateDB) updateStatelessStateObject(obj *stateObject) {
474-
addr := obj.Address()
475-
476-
var (
477-
ok bool
478-
n common.Hash
479-
v common.Hash
480-
b common.Hash
481-
cs common.Hash
482-
ch common.Hash
483-
)
484-
485-
versionKey := common.BytesToHash(trieUtils.GetTreeKeyVersion(addr[:]))
486-
if v, ok = s.stateless[versionKey]; ok {
487-
nonceKey := common.BytesToHash(trieUtils.GetTreeKeyNonce(addr[:]))
488-
if n, ok = s.stateless[nonceKey]; ok {
489-
balanceKey := common.BytesToHash(trieUtils.GetTreeKeyBalance(addr[:]))
490-
if b, ok = s.stateless[balanceKey]; ok {
491-
codeHashKey := common.BytesToHash(trieUtils.GetTreeKeyCodeKeccak(addr[:]))
492-
if _, ok = s.stateless[codeHashKey]; ok {
493-
v[0] = byte(0)
494-
binary.BigEndian.PutUint64(n[:], obj.data.Nonce)
495-
copy(ch[:], obj.data.CodeHash[:])
496-
copy(b[:], obj.data.Balance.Bytes())
497-
binary.BigEndian.PutUint64(cs[:], uint64(len(obj.code)))
498-
499-
// TODO(@gballet) stateless tree update
500-
// i.e. perform a "delta" update on all
501-
// commitments. go-verkle currently has
502-
// no support for these.
503-
}
504-
}
505-
}
506-
}
507-
508-
if !ok {
509-
s.setError(fmt.Errorf("updateStatelessStateObject (%x) missing", addr[:]))
510-
}
511-
}
512-
513475
// updateStateObject writes the given object to the trie.
514476
func (s *StateDB) updateStateObject(obj *stateObject) {
515477
// Track the amount of time wasted on updating the account from the trie
@@ -519,12 +481,6 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
519481
// Encode the account and update the account trie
520482
addr := obj.Address()
521483

522-
// bypass the snapshot and writing to tree if in stateless mode
523-
if s.stateless != nil {
524-
s.updateStatelessStateObject(obj)
525-
return
526-
}
527-
528484
if err := s.trie.TryUpdateAccount(addr[:], &obj.data); err != nil {
529485
s.setError(fmt.Errorf("updateStateObject (%x) error: %w", addr[:], err))
530486
}
@@ -534,6 +490,16 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
534490
if err := s.trie.TryUpdate(trieUtils.GetTreeKeyCodeSize(addr[:]), cs); err != nil {
535491
s.setError(fmt.Errorf("updateStateObject (%x) error: %w", addr[:], err))
536492
}
493+
494+
if obj.dirtyCode {
495+
if chunks, err := trie.ChunkifyCode(addr, obj.code); err == nil {
496+
for i := range chunks {
497+
s.trie.TryUpdate(trieUtils.GetTreeKeyCodeChunk(addr[:], uint256.NewInt(uint64(i))), chunks[i][:])
498+
}
499+
} else {
500+
s.setError(err)
501+
}
502+
}
537503
}
538504

539505
// If state snapshotting is active, cache the data til commit. Note, this
@@ -545,21 +511,12 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
545511
}
546512
}
547513

548-
func (s *StateDB) deleteStatelessStateObject(obj *stateObject) {
549-
// unsupported
550-
panic("not currently supported")
551-
}
552-
553514
// deleteStateObject removes the given object from the state trie.
554515
func (s *StateDB) deleteStateObject(obj *stateObject) {
555516
// Track the amount of time wasted on deleting the account from the trie
556517
if metrics.EnabledExpensive {
557518
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
558519
}
559-
if s.stateless != nil {
560-
s.deleteStatelessStateObject(obj)
561-
return
562-
}
563520

564521
// Delete the account from the trie
565522
if !s.trie.IsVerkle() {
@@ -586,48 +543,6 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject {
586543
return nil
587544
}
588545

589-
func (s *StateDB) getStatelessDeletedStateObject(addr common.Address) *stateObject {
590-
// Check that it is present in the witness, if running
591-
// in stateless execution mode.
592-
chunk := trieUtils.GetTreeKeyNonce(addr[:])
593-
nb, ok := s.stateless[common.BytesToHash(chunk)]
594-
if !ok {
595-
log.Error("Failed to decode state object", "addr", addr)
596-
s.setError(fmt.Errorf("could not find nonce chunk in proof: %x", chunk))
597-
// TODO(gballet) remove after debug, and check the issue is found
598-
panic("inivalid chunk")
599-
return nil
600-
}
601-
chunk = trieUtils.GetTreeKeyBalance(addr[:])
602-
bb, ok := s.stateless[common.BytesToHash(chunk)]
603-
if !ok {
604-
log.Error("Failed to decode state object", "addr", addr)
605-
s.setError(fmt.Errorf("could not find balance chunk in proof: %x", chunk))
606-
// TODO(gballet) remove after debug, and check the issue is found
607-
panic("inivalid chunk")
608-
return nil
609-
}
610-
chunk = trieUtils.GetTreeKeyCodeKeccak(addr[:])
611-
cb, ok := s.stateless[common.BytesToHash(chunk)]
612-
if !ok {
613-
// Assume that this is an externally-owned account, and that
614-
// the code has not been accessed.
615-
// TODO(gballet) write this down, just like deletions, so
616-
// that an error can be triggered if trying to access the
617-
// account code.
618-
copy(cb[:], emptyCodeHash)
619-
}
620-
data := &types.StateAccount{
621-
Nonce: binary.BigEndian.Uint64(nb[:8]),
622-
Balance: big.NewInt(0).SetBytes(bb[:]),
623-
CodeHash: cb[:],
624-
}
625-
// Insert into the live set
626-
obj := newObject(s, addr, *data)
627-
s.setStateObject(obj)
628-
return obj
629-
}
630-
631546
// getDeletedStateObject is similar to getStateObject, but instead of returning
632547
// nil for a deleted state object, it returns the actual object with the deleted
633548
// flag set. This is needed by the state journal to revert to the correct s-
@@ -642,10 +557,6 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
642557
data *types.StateAccount
643558
err error
644559
)
645-
// if executing statelessly, bypass the snapshot and the db.
646-
if s.stateless != nil {
647-
return s.getStatelessDeletedStateObject(addr)
648-
}
649560
if s.snap != nil {
650561
if metrics.EnabledExpensive {
651562
defer func(start time.Time) { s.SnapshotAccountReads += time.Since(start) }(time.Now())
@@ -802,6 +713,7 @@ func (s *StateDB) Copy() *StateDB {
802713
preimages: make(map[common.Hash][]byte, len(s.preimages)),
803714
journal: newJournal(),
804715
hasher: crypto.NewKeccakState(),
716+
witness: s.witness.Copy(),
805717
}
806718
// Copy the dirty states, logs, and preimages
807719
for addr := range s.journal.dirties {
@@ -852,13 +764,6 @@ func (s *StateDB) Copy() *StateDB {
852764
// to not blow up if we ever decide copy it in the middle of a transaction
853765
state.accessList = s.accessList.Copy()
854766

855-
if s.stateless != nil {
856-
state.stateless = make(map[common.Hash]common.Hash, len(s.stateless))
857-
for addr, value := range s.stateless {
858-
state.stateless[addr] = value
859-
}
860-
}
861-
862767
// If there's a prefetcher running, make an inactive copy of it that can
863768
// only access data but does not actively preload (since the user will not
864769
// know that they need to explicitly terminate an active copy).
@@ -1088,8 +993,8 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
1088993
if obj.code != nil && obj.dirtyCode {
1089994
if s.trie.IsVerkle() {
1090995
if chunks, err := trie.ChunkifyCode(addr, obj.code); err == nil {
1091-
for i, chunk := range chunks {
1092-
s.trie.TryUpdate(trieUtils.GetTreeKeyCodeChunk(addr[:], uint256.NewInt(uint64(i))), chunk[:])
996+
for i := range chunks {
997+
s.trie.TryUpdate(trieUtils.GetTreeKeyCodeChunk(addr[:], uint256.NewInt(uint64(i))), chunks[i][:])
1093998
}
1094999
} else {
10951000
s.setError(err)

core/state_processor.go

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -94,43 +94,6 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
9494
return receipts, allLogs, accesses, *usedGas, nil
9595
}
9696

97-
func (p *StateProcessor) ProcessStateless(block *types.Block, statedb *state.StateDB, cfg vm.Config, leaves map[common.Hash]common.Hash) (types.Receipts, []*types.Log, uint64, error) {
98-
var (
99-
receipts types.Receipts
100-
usedGas = new(uint64)
101-
header = block.Header()
102-
blockHash = block.Hash()
103-
blockNumber = block.Number()
104-
allLogs []*types.Log
105-
gp = new(GasPool).AddGas(block.GasLimit())
106-
)
107-
// Mutate the block and state according to any hard-fork specs
108-
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
109-
misc.ApplyDAOHardFork(statedb)
110-
}
111-
blockContext := NewEVMBlockContext(header, p.bc, nil)
112-
blockContext.StatelessAccesses = leaves
113-
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
114-
// Iterate over and process the individual transactions
115-
for i, tx := range block.Transactions() {
116-
msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee)
117-
if err != nil {
118-
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
119-
}
120-
statedb.Prepare(tx.Hash(), i)
121-
receipt, _, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
122-
if err != nil {
123-
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
124-
}
125-
receipts = append(receipts, receipt)
126-
allLogs = append(allLogs, receipt.Logs...)
127-
}
128-
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
129-
p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles())
130-
131-
return receipts, allLogs, *usedGas, nil
132-
}
133-
13497
func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, *types.AccessWitness, error) {
13598
// Create a new context to be used in the EVM environment.
13699
txContext := NewEVMTxContext(msg)

core/types.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package core
1818

1919
import (
20-
"github.com/ethereum/go-ethereum/common"
2120
"github.com/ethereum/go-ethereum/core/state"
2221
"github.com/ethereum/go-ethereum/core/types"
2322
"github.com/ethereum/go-ethereum/core/vm"
@@ -49,6 +48,4 @@ type Processor interface {
4948
// the transaction messages using the statedb and applying any rewards to both
5049
// the processor (coinbase) and any included uncles.
5150
Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *types.AccessWitness, uint64, error)
52-
53-
ProcessStateless(block *types.Block, statedb *state.StateDB, cfg vm.Config, accesses map[common.Hash]common.Hash) (types.Receipts, []*types.Log, uint64, error)
5451
}

0 commit comments

Comments
 (0)