mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 22:56:43 +00:00
core/state, trie: implement stateless transition
Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
This commit is contained in:
parent
f50b2541a4
commit
8e8d10ac6c
6 changed files with 77 additions and 39 deletions
|
|
@ -146,7 +146,7 @@ func (kvm *keyValueMigrator) getOrInitLeafNodeData(bk branchKey) *verkle.BatchNe
|
||||||
return &kvm.leafData[bk].leafNodeData
|
return &kvm.leafData[bk].leafNodeData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kvm *keyValueMigrator) prepare() {
|
func (kvm *keyValueMigrator) prepare(pointCache *utils.PointCache) {
|
||||||
// We fire a background routine to process the leafData and save the result in newLeaves.
|
// We fire a background routine to process the leafData and save the result in newLeaves.
|
||||||
// The background routine signals that it is done by closing processingReady.
|
// The background routine signals that it is done by closing processingReady.
|
||||||
go func() {
|
go func() {
|
||||||
|
|
@ -175,7 +175,7 @@ func (kvm *keyValueMigrator) prepare() {
|
||||||
for i := range batch {
|
for i := range batch {
|
||||||
if batch[i].branchKey.addr != currAddr || currAddr == (common.Address{}) {
|
if batch[i].branchKey.addr != currAddr || currAddr == (common.Address{}) {
|
||||||
currAddr = batch[i].branchKey.addr
|
currAddr = batch[i].branchKey.addr
|
||||||
currPoint = utils.EvaluateAddressPoint(currAddr[:])
|
currPoint = pointCache.Get(currAddr[:])
|
||||||
}
|
}
|
||||||
stem := utils.GetTreeKeyWithEvaluatedAddress(currPoint, &batch[i].branchKey.treeIndex, 0)
|
stem := utils.GetTreeKeyWithEvaluatedAddress(currPoint, &batch[i].branchKey.treeIndex, 0)
|
||||||
stem = stem[:verkle.StemSize]
|
stem = stem[:verkle.StemSize]
|
||||||
|
|
@ -227,7 +227,6 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
now = time.Now()
|
now = time.Now()
|
||||||
tt = statedb.GetTrie().(*trie.TransitionTrie)
|
tt = statedb.GetTrie().(*trie.TransitionTrie)
|
||||||
mpt = tt.Base()
|
mpt = tt.Base()
|
||||||
vkt = tt.Overlay()
|
|
||||||
hasPreimagesBin = false
|
hasPreimagesBin = false
|
||||||
preimageSeek = migrdb.GetCurrentPreimageOffset()
|
preimageSeek = migrdb.GetCurrentPreimageOffset()
|
||||||
fpreimages *bufio.Reader
|
fpreimages *bufio.Reader
|
||||||
|
|
@ -247,7 +246,7 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
hasPreimagesBin = true
|
hasPreimagesBin = true
|
||||||
}
|
}
|
||||||
|
|
||||||
accIt, err := statedb.Snaps().AccountIterator(mpt.Hash(), migrdb.GetCurrentAccountHash())
|
accIt, err := statedb.Database().Snapshot().AccountIterator(mpt.Hash(), migrdb.GetCurrentAccountHash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -262,7 +261,7 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
return fmt.Errorf("reading preimage file: %s", err)
|
return fmt.Errorf("reading preimage file: %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addr = common.BytesToAddress(rawdb.ReadPreimage(migrdb.DiskDB(), accIt.Hash()))
|
addr = common.BytesToAddress(rawdb.ReadPreimage(migrdb.TrieDB().Disk(), accIt.Hash()))
|
||||||
if len(addr) != 20 {
|
if len(addr) != 20 {
|
||||||
return fmt.Errorf("addr len is zero is not 32: %d", len(addr))
|
return fmt.Errorf("addr len is zero is not 32: %d", len(addr))
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +288,6 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
log.Error("Invalid account encountered during traversal", "error", err)
|
log.Error("Invalid account encountered during traversal", "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
vkt.SetStorageRootConversion(*migrdb.GetCurrentAccountAddress(), acc.Root)
|
|
||||||
|
|
||||||
// Start with processing the storage, because once the account is
|
// Start with processing the storage, because once the account is
|
||||||
// converted, the `stateRoot` field loses its meaning. Which means
|
// converted, the `stateRoot` field loses its meaning. Which means
|
||||||
|
|
@ -301,7 +299,7 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
// to during normal block execution. A mitigation strategy has been
|
// to during normal block execution. A mitigation strategy has been
|
||||||
// introduced with the `*StorageRootConversion` fields in VerkleDB.
|
// introduced with the `*StorageRootConversion` fields in VerkleDB.
|
||||||
if len(acc.Root) == 32 && acc.Root != types.EmptyRootHash {
|
if len(acc.Root) == 32 && acc.Root != types.EmptyRootHash {
|
||||||
stIt, err := statedb.Snaps().StorageIterator(mpt.Hash(), accIt.Hash(), migrdb.GetCurrentSlotHash())
|
stIt, err := statedb.Database().Snapshot().StorageIterator(mpt.Hash(), accIt.Hash(), migrdb.GetCurrentSlotHash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +335,7 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
return fmt.Errorf("reading preimage file: %s", err)
|
return fmt.Errorf("reading preimage file: %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
slotnr = rawdb.ReadPreimage(migrdb.DiskDB(), stIt.Hash())
|
slotnr = rawdb.ReadPreimage(migrdb.TrieDB().Disk(), stIt.Hash())
|
||||||
if len(slotnr) != 32 {
|
if len(slotnr) != 32 {
|
||||||
return fmt.Errorf("slotnr len is zero is not 32: %d", len(slotnr))
|
return fmt.Errorf("slotnr len is zero is not 32: %d", len(slotnr))
|
||||||
}
|
}
|
||||||
|
|
@ -367,11 +365,10 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
count++ // count increase for the account itself
|
count++ // count increase for the account itself
|
||||||
|
|
||||||
mkv.addAccount(migrdb.GetCurrentAccountAddress().Bytes(), acc)
|
mkv.addAccount(migrdb.GetCurrentAccountAddress().Bytes(), acc)
|
||||||
vkt.ClearStrorageRootConversion(*migrdb.GetCurrentAccountAddress())
|
|
||||||
|
|
||||||
// Store the account code if present
|
// Store the account code if present
|
||||||
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
|
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
|
||||||
code := rawdb.ReadCode(statedb.Database().DiskDB(), common.BytesToHash(acc.CodeHash))
|
code := rawdb.ReadCode(statedb.Database().TrieDB().Disk(), common.BytesToHash(acc.CodeHash))
|
||||||
chunks := trie.ChunkifyCode(code)
|
chunks := trie.ChunkifyCode(code)
|
||||||
|
|
||||||
mkv.addAccountCode(migrdb.GetCurrentAccountAddress().Bytes(), uint64(len(code)), chunks)
|
mkv.addAccountCode(migrdb.GetCurrentAccountAddress().Bytes(), uint64(len(code)), chunks)
|
||||||
|
|
@ -391,7 +388,7 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
return fmt.Errorf("reading preimage file: %s", err)
|
return fmt.Errorf("reading preimage file: %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addr = common.BytesToAddress(rawdb.ReadPreimage(migrdb.DiskDB(), accIt.Hash()))
|
addr = common.BytesToAddress(rawdb.ReadPreimage(migrdb.TrieDB().Disk(), accIt.Hash()))
|
||||||
if len(addr) != 20 {
|
if len(addr) != 20 {
|
||||||
return fmt.Errorf("account address len is zero is not 20: %d", len(addr))
|
return fmt.Errorf("account address len is zero is not 20: %d", len(addr))
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +419,7 @@ func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash, maxMovedC
|
||||||
// after we fix an existing bug, we can call prepare() before the block execution and
|
// after we fix an existing bug, we can call prepare() before the block execution and
|
||||||
// let it do the work in the background. After the block execution and finalization
|
// let it do the work in the background. After the block execution and finalization
|
||||||
// finish, we can call migrateCollectedKeyValues() which should already find everything ready.
|
// finish, we can call migrateCollectedKeyValues() which should already find everything ready.
|
||||||
mkv.prepare()
|
mkv.prepare(statedb.PointCache())
|
||||||
now = time.Now()
|
now = time.Now()
|
||||||
if err := mkv.migrateCollectedKeyValues(tt.Overlay()); err != nil {
|
if err := mkv.migrateCollectedKeyValues(tt.Overlay()); err != nil {
|
||||||
return fmt.Errorf("could not migrate key values: %w", err)
|
return fmt.Errorf("could not migrate key values: %w", err)
|
||||||
|
|
|
||||||
30
core/rawdb/accessors_overlay.go
Normal file
30
core/rawdb/accessors_overlay.go
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2024 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package rawdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ReadVerkleTransitionState(db ethdb.KeyValueReader, hash common.Hash) ([]byte, error) {
|
||||||
|
return db.Get(transitionStateKey(hash))
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteVerkleTransitionState(db ethdb.KeyValueWriter, hash common.Hash, state []byte) error {
|
||||||
|
return db.Put(transitionStateKey(hash), state)
|
||||||
|
}
|
||||||
|
|
@ -147,6 +147,9 @@ var (
|
||||||
preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil)
|
preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil)
|
||||||
preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil)
|
preimageHitsCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil)
|
||||||
preimageMissCounter = metrics.NewRegisteredCounter("db/preimage/miss", nil)
|
preimageMissCounter = metrics.NewRegisteredCounter("db/preimage/miss", nil)
|
||||||
|
|
||||||
|
// Verkle transition information
|
||||||
|
VerkleTransitionStatePrefix = []byte("verkle-transition-state-")
|
||||||
)
|
)
|
||||||
|
|
||||||
// LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary
|
// LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary
|
||||||
|
|
@ -362,3 +365,8 @@ func filterMapBlockLVKey(number uint64) []byte {
|
||||||
binary.BigEndian.PutUint64(key[l:], number)
|
binary.BigEndian.PutUint64(key[l:], number)
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// transitionStateKey = transitionStatusKey + hash
|
||||||
|
func transitionStateKey(hash common.Hash) []byte {
|
||||||
|
return append(VerkleTransitionStatePrefix, hash.Bytes()...)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,18 +69,24 @@ type Database interface {
|
||||||
// Snapshot returns the underlying state snapshot.
|
// Snapshot returns the underlying state snapshot.
|
||||||
Snapshot() *snapshot.Tree
|
Snapshot() *snapshot.Tree
|
||||||
|
|
||||||
|
// StartVerkleTransition marks the start of the verkle transition
|
||||||
StartVerkleTransition(originalRoot, translatedRoot common.Hash, chainConfig *params.ChainConfig, verkleTime *uint64, root common.Hash)
|
StartVerkleTransition(originalRoot, translatedRoot common.Hash, chainConfig *params.ChainConfig, verkleTime *uint64, root common.Hash)
|
||||||
|
|
||||||
|
// EndVerkleTransition marks the end of the verkle transition
|
||||||
EndVerkleTransition()
|
EndVerkleTransition()
|
||||||
|
|
||||||
|
// InTransition returns true if the verkle transition is currently ongoing
|
||||||
InTransition() bool
|
InTransition() bool
|
||||||
|
|
||||||
|
// Transitioned returns true if the verkle transition has ended
|
||||||
Transitioned() bool
|
Transitioned() bool
|
||||||
|
|
||||||
InitTransitionStatus(bool, bool, common.Hash)
|
InitTransitionStatus(bool, bool, common.Hash)
|
||||||
|
|
||||||
|
// SetCurrentSlotHash provides the next slot to be translated
|
||||||
SetCurrentSlotHash(common.Hash)
|
SetCurrentSlotHash(common.Hash)
|
||||||
|
|
||||||
|
// GetCurrentAccountAddress returns the address of the account that is currently being translated
|
||||||
GetCurrentAccountAddress() *common.Address
|
GetCurrentAccountAddress() *common.Address
|
||||||
|
|
||||||
SetCurrentAccountAddress(common.Address)
|
SetCurrentAccountAddress(common.Address)
|
||||||
|
|
@ -226,6 +232,7 @@ func (db *CachingDB) Transitioned() bool {
|
||||||
return db.CurrentTransitionState != nil && db.CurrentTransitionState.Ended
|
return db.CurrentTransitionState != nil && db.CurrentTransitionState.Ended
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartVerkleTransition marks the start of the verkle transition
|
||||||
func (db *CachingDB) StartVerkleTransition(originalRoot, translatedRoot common.Hash, chainConfig *params.ChainConfig, verkleTime *uint64, root common.Hash) {
|
func (db *CachingDB) StartVerkleTransition(originalRoot, translatedRoot common.Hash, chainConfig *params.ChainConfig, verkleTime *uint64, root common.Hash) {
|
||||||
db.CurrentTransitionState = &TransitionState{
|
db.CurrentTransitionState = &TransitionState{
|
||||||
Started: true,
|
Started: true,
|
||||||
|
|
@ -317,7 +324,7 @@ func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) {
|
||||||
}
|
}
|
||||||
// Set up the trie reader, which is expected to always be available
|
// Set up the trie reader, which is expected to always be available
|
||||||
// as the gatekeeper unless the state is corrupted.
|
// as the gatekeeper unless the state is corrupted.
|
||||||
tr, err := newTrieReader(stateRoot, db.triedb, db.pointCache)
|
tr, err := newTrieReader(stateRoot, db.triedb, db.pointCache, db.InTransition(), db.Transitioned())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -338,24 +345,11 @@ func (db *CachingDB) openMPTTrie(root common.Hash) (Trie, error) {
|
||||||
return tr, nil
|
return tr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *CachingDB) openVKTrie(_ common.Hash) (Trie, error) {
|
|
||||||
payload, err := db.DiskDB().Get(trie.FlatDBVerkleNodeKeyPrefix)
|
|
||||||
if err != nil {
|
|
||||||
return trie.NewVerkleTrie(verkle.New(), db.triedb, db.addrToPoint, db.CurrentTransitionState.Ended)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := verkle.ParseNode(payload, 0)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return trie.NewVerkleTrie(r, db.triedb, db.addrToPoint, db.CurrentTransitionState.Ended)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenTrie opens the main account trie at a specific root hash.
|
// OpenTrie opens the main account trie at a specific root hash.
|
||||||
func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||||
if db.InTransition() || db.Transitioned() {
|
if db.InTransition() || db.Transitioned() {
|
||||||
// NOTE this is a kaustinen-only change, it will break replay
|
// NOTE this is a kaustinen-only change, it will break replay
|
||||||
vkt, err := db.openVKTrie(root)
|
vkt, err := trie.NewVerkleTrie(root, db.triedb, db.addrToPoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open the vkt", "err", err)
|
log.Error("failed to open the vkt", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -376,7 +370,7 @@ func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return trie.NewTransitionTree(mpt.(*trie.SecureTrie), vkt.(*trie.VerkleTrie), false), nil
|
return trie.NewTransitionTree(mpt.(*trie.SecureTrie), vkt, false), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("not in transition, opening mpt alone", "root", root)
|
log.Info("not in transition, opening mpt alone", "root", root)
|
||||||
|
|
@ -509,7 +503,7 @@ func (db *CachingDB) SaveTransitionState(root common.Hash) {
|
||||||
// it has been saved.
|
// it has been saved.
|
||||||
db.TransitionStatePerRoot.Add(root, db.CurrentTransitionState.Copy())
|
db.TransitionStatePerRoot.Add(root, db.CurrentTransitionState.Copy())
|
||||||
|
|
||||||
rawdb.WriteVerkleTransitionState(db.DiskDB(), root, buf.Bytes())
|
rawdb.WriteVerkleTransitionState(db.TrieDB().Disk(), root, buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("saving transition state", "storage processed", db.CurrentTransitionState.StorageProcessed, "addr", db.CurrentTransitionState.CurrentAccountAddress, "slot hash", db.CurrentTransitionState.CurrentSlotHash, "root", root, "ended", db.CurrentTransitionState.Ended, "started", db.CurrentTransitionState.Started)
|
log.Debug("saving transition state", "storage processed", db.CurrentTransitionState.StorageProcessed, "addr", db.CurrentTransitionState.CurrentAccountAddress, "slot hash", db.CurrentTransitionState.CurrentSlotHash, "root", root, "ended", db.CurrentTransitionState.Ended, "started", db.CurrentTransitionState.Started)
|
||||||
|
|
@ -524,7 +518,7 @@ func (db *CachingDB) LoadTransitionState(root common.Hash) {
|
||||||
ts, ok := db.TransitionStatePerRoot.Get(root)
|
ts, ok := db.TransitionStatePerRoot.Get(root)
|
||||||
if !ok {
|
if !ok {
|
||||||
// Not in the cache, try getting it from the DB
|
// Not in the cache, try getting it from the DB
|
||||||
data, err := rawdb.ReadVerkleTransitionState(db.DiskDB(), root)
|
data, err := rawdb.ReadVerkleTransitionState(db.TrieDB().Disk(), root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to read transition state", "err", err)
|
log.Error("failed to read transition state", "err", err)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -207,15 +207,26 @@ type trieReader struct {
|
||||||
|
|
||||||
// trieReader constructs a trie reader of the specific state. An error will be
|
// trieReader constructs a trie reader of the specific state. An error will be
|
||||||
// returned if the associated trie specified by root is not existent.
|
// returned if the associated trie specified by root is not existent.
|
||||||
func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCache) (*trieReader, error) {
|
func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCache, intransition, transitioned bool) (*trieReader, error) {
|
||||||
var (
|
var (
|
||||||
tr Trie
|
tr Trie
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if !db.IsVerkle() {
|
if !intransition && !transitioned {
|
||||||
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
||||||
} else {
|
} else {
|
||||||
tr, err = trie.NewVerkleTrie(root, db, cache)
|
vktr, err := trie.NewVerkleTrie(root, db, cache)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tr = vktr
|
||||||
|
if intransition {
|
||||||
|
mptr, err := trie.NewStateTrie(trie.StateTrieID(root), db)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tr = trie.NewTransitionTree(mptr, vktr, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,6 @@ func (t *TransitionTrie) GetAccount(address common.Address) (*types.StateAccount
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if data != nil {
|
if data != nil {
|
||||||
if t.overlay.db.HasStorageRootConversion(address) {
|
|
||||||
data.Root = t.overlay.db.StorageRootConversion(address)
|
|
||||||
}
|
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
// TODO also insert value into overlay
|
// TODO also insert value into overlay
|
||||||
|
|
@ -109,9 +106,6 @@ func (t *TransitionTrie) UpdateStorage(address common.Address, key []byte, value
|
||||||
|
|
||||||
// UpdateAccount abstract an account write to the trie.
|
// UpdateAccount abstract an account write to the trie.
|
||||||
func (t *TransitionTrie) UpdateAccount(addr common.Address, account *types.StateAccount, codeLen int) error {
|
func (t *TransitionTrie) UpdateAccount(addr common.Address, account *types.StateAccount, codeLen int) error {
|
||||||
if account.Root != (common.Hash{}) && account.Root != types.EmptyRootHash {
|
|
||||||
t.overlay.db.SetStorageRootConversion(addr, account.Root)
|
|
||||||
}
|
|
||||||
return t.overlay.UpdateAccount(addr, account, codeLen)
|
return t.overlay.UpdateAccount(addr, account, codeLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,3 +186,7 @@ func (t *TransitionTrie) Copy() *TransitionTrie {
|
||||||
func (t *TransitionTrie) UpdateContractCode(addr common.Address, codeHash common.Hash, code []byte) error {
|
func (t *TransitionTrie) UpdateContractCode(addr common.Address, codeHash common.Hash, code []byte) error {
|
||||||
return t.overlay.UpdateContractCode(addr, codeHash, code)
|
return t.overlay.UpdateContractCode(addr, codeHash, code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TransitionTrie) Witness() map[string]struct{} {
|
||||||
|
return t.overlay.Witness()
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue