Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

save overlay conversion iterator pointers at each block #298

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@

// Declare the end of the verkle transition if need be
if bc.chainConfig.Rules(head.Number, false /* XXX */, head.Time).IsPrague {
bc.stateCache.EndVerkleTransition()
bc.stateCache.EndVerkleTransition(head.Root)
}

if !bc.HasState(head.Root) {
Expand Down Expand Up @@ -1746,7 +1746,7 @@
}

if parent.Number.Uint64() == conversionBlock {
bc.StartVerkleTransition(parent.Root, emptyVerkleRoot, bc.Config(), &parent.Time)
bc.StartVerkleTransition(parent.Root, bc.Config(), &parent.Time, parent.Root)
bc.stateCache.SetLastMerkleRoot(parent.Root)
}
statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
Expand Down Expand Up @@ -2378,7 +2378,7 @@
return false
}

var emptyVerkleRoot common.Hash

Check failure on line 2381 in core/blockchain.go

View workflow job for this annotation

GitHub Actions / lint

var `emptyVerkleRoot` is unused (unused)

// indexBlocks reindexes or unindexes transactions depending on user configuration
func (bc *BlockChain) indexBlocks(tail *uint64, head uint64, done chan struct{}) {
Expand Down Expand Up @@ -2532,17 +2532,13 @@
return time.Duration(bc.flushInterval.Load())
}

func (bc *BlockChain) StartVerkleTransition(originalRoot, translatedRoot common.Hash, chainConfig *params.ChainConfig, pragueTime *uint64) {
bc.stateCache.StartVerkleTransition(originalRoot, translatedRoot, chainConfig, pragueTime)
func (bc *BlockChain) StartVerkleTransition(originalRoot common.Hash, chainConfig *params.ChainConfig, pragueTime *uint64, root common.Hash) {
bc.stateCache.StartVerkleTransition(originalRoot, chainConfig, pragueTime, root)
}
func (bc *BlockChain) ReorgThroughVerkleTransition() {
bc.stateCache.ReorgThroughVerkleTransition()
}

func (bc *BlockChain) EndVerkleTransition() {
bc.stateCache.EndVerkleTransition()
}

func (bc *BlockChain) AddRootTranslation(originalRoot, translatedRoot common.Hash) {
bc.stateCache.AddRootTranslation(originalRoot, translatedRoot)
}
6 changes: 4 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,11 @@
return nil, nil
}
var snaps *snapshot.Tree
triedb := state.NewDatabaseWithConfig(db, &trie.Config{Verkle: true})
for i := 0; i < n; i++ {
triedb := state.NewDatabaseWithConfig(db, nil)
triedb.EndVerkleTransition()
// This needs to be activated because now InTransiton/Transitionned

Check failure on line 430 in core/chain_makers.go

View workflow job for this annotation

GitHub Actions / lint

`Transitionned` is a misspelling of `Transitioned` (misspell)
// depend on the root hash, so you have to mark it as such.
triedb.EndVerkleTransition(parent.Root())
statedb, err := state.New(parent.Root(), triedb, snaps)
if err != nil {
panic(fmt.Sprintf("could not find state for block %d: err=%v, parent root=%x", i, err, parent.Root()))
Expand Down
4 changes: 2 additions & 2 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (ga *GenesisAlloc) deriveHash(cfg *params.ChainConfig, timestamp uint64) (c
// all the derived states will be discarded to not pollute disk.
db := state.NewDatabase(rawdb.NewMemoryDatabase())
if cfg.IsPrague(big.NewInt(int64(0)), timestamp) {
db.EndVerkleTransition()
db.EndVerkleTransition(types.EmptyRootHash)
}
statedb, err := state.New(types.EmptyRootHash, db, nil)
if err != nil {
Expand Down Expand Up @@ -154,7 +154,7 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas

// End the verkle conversion at genesis if the fork block is 0
if triedb.IsVerkle() {
statedb.Database().EndVerkleTransition()
statedb.Database().EndVerkleTransition(common.Hash{})
}

for addr, account := range *ga {
Expand Down
46 changes: 23 additions & 23 deletions core/overlay_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ import (
)

// OverlayVerkleTransition contains the overlay conversion logic
func OverlayVerkleTransition(statedb *state.StateDB) error {
func OverlayVerkleTransition(statedb *state.StateDB, root common.Hash) error {
migrdb := statedb.Database()

// verkle transition: if the conversion process is in progress, move
// N values from the MPT into the verkle tree.
if migrdb.InTransition() {
if migrdb.InTransition(root) {
var (
now = time.Now()
tt = statedb.GetTrie().(*trie.TransitionTrie)
mpt = tt.Base()
vkt = tt.Overlay()
hasPreimagesBin = false
preimageSeek = migrdb.GetCurrentPreimageOffset()
preimageSeek = migrdb.GetCurrentPreimageOffset(root)
fpreimages *bufio.Reader
)

Expand All @@ -65,15 +65,15 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
hasPreimagesBin = true
}

accIt, err := statedb.Snaps().AccountIterator(mpt.Hash(), migrdb.GetCurrentAccountHash())
accIt, err := statedb.Snaps().AccountIterator(mpt.Hash(), migrdb.GetCurrentAccountHash(root))
if err != nil {
return err
}
defer accIt.Release()
accIt.Next()

// If we're about to start with the migration process, we have to read the first account hash preimage.
if migrdb.GetCurrentAccountAddress() == nil {
if migrdb.GetCurrentAccountAddress(root) == nil {
var addr common.Address
if hasPreimagesBin {
if _, err := io.ReadFull(fpreimages, addr[:]); err != nil {
Expand All @@ -85,8 +85,8 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
return fmt.Errorf("addr len is zero is not 32: %d", len(addr))
}
}
migrdb.SetCurrentAccountAddress(addr)
if migrdb.GetCurrentAccountHash() != accIt.Hash() {
migrdb.SetCurrentAccountAddress(addr, root)
if migrdb.GetCurrentAccountHash(root) != accIt.Hash() {
return fmt.Errorf("preimage file does not match account hash: %s != %s", crypto.Keccak256Hash(addr[:]), accIt.Hash())
}
preimageSeek += int64(len(addr))
Expand All @@ -108,7 +108,7 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
log.Error("Invalid account encountered during traversal", "error", err)
return err
}
vkt.SetStorageRootConversion(*migrdb.GetCurrentAccountAddress(), acc.Root)
vkt.SetStorageRootConversion(*migrdb.GetCurrentAccountAddress(root), acc.Root)

// Start with processing the storage, because once the account is
// converted, the `stateRoot` field loses its meaning. Which means
Expand All @@ -120,7 +120,7 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
// to during normal block execution. A mitigation strategy has been
// introduced with the `*StorageRootConversion` fields in VerkleDB.
if acc.HasStorage() {
stIt, err := statedb.Snaps().StorageIterator(mpt.Hash(), accIt.Hash(), migrdb.GetCurrentSlotHash())
stIt, err := statedb.Snaps().StorageIterator(mpt.Hash(), accIt.Hash(), migrdb.GetCurrentSlotHash(root))
if err != nil {
return err
}
Expand All @@ -132,7 +132,7 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
// processing the storage for that account where we left off.
// If the entire storage was processed, then the iterator was
// created in vain, but it's ok as this will not happen often.
for ; !migrdb.GetStorageProcessed() && count < maxMovedCount; count++ {
for ; !migrdb.GetStorageProcessed(root) && count < maxMovedCount; count++ {
var (
value []byte // slot value after RLP decoding
safeValue [32]byte // 32-byte aligned value
Expand Down Expand Up @@ -160,12 +160,12 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
}
preimageSeek += int64(len(slotnr))

mkv.addStorageSlot(migrdb.GetCurrentAccountAddress().Bytes(), slotnr, safeValue[:])
mkv.addStorageSlot(migrdb.GetCurrentAccountAddress(root).Bytes(), slotnr, safeValue[:])

// advance the storage iterator
migrdb.SetStorageProcessed(!stIt.Next())
if !migrdb.GetStorageProcessed() {
migrdb.SetCurrentSlotHash(stIt.Hash())
migrdb.SetStorageProcessed(!stIt.Next(), root)
if !migrdb.GetStorageProcessed(root) {
migrdb.SetCurrentSlotHash(stIt.Hash(), root)
}
}
stIt.Release()
Expand All @@ -178,20 +178,20 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
if count < maxMovedCount {
count++ // count increase for the account itself

mkv.addAccount(migrdb.GetCurrentAccountAddress().Bytes(), acc)
vkt.ClearStrorageRootConversion(*migrdb.GetCurrentAccountAddress())
mkv.addAccount(migrdb.GetCurrentAccountAddress(root).Bytes(), acc)
vkt.ClearStrorageRootConversion(*migrdb.GetCurrentAccountAddress(root))

// Store the account code if present
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
code := rawdb.ReadCode(statedb.Database().DiskDB(), common.BytesToHash(acc.CodeHash))
chunks := trie.ChunkifyCode(code)

mkv.addAccountCode(migrdb.GetCurrentAccountAddress().Bytes(), uint64(len(code)), chunks)
mkv.addAccountCode(migrdb.GetCurrentAccountAddress(root).Bytes(), uint64(len(code)), chunks)
}

// reset storage iterator marker for next account
migrdb.SetStorageProcessed(false)
migrdb.SetCurrentSlotHash(common.Hash{})
migrdb.SetStorageProcessed(false, root)
migrdb.SetCurrentSlotHash(common.Hash{}, root)

// Move to the next account, if available - or end
// the transition otherwise.
Expand All @@ -212,18 +212,18 @@ func OverlayVerkleTransition(statedb *state.StateDB) error {
return fmt.Errorf("preimage file does not match account hash: %s != %s", crypto.Keccak256Hash(addr[:]), accIt.Hash())
}
preimageSeek += int64(len(addr))
migrdb.SetCurrentAccountAddress(addr)
migrdb.SetCurrentAccountAddress(addr, root)
} else {
// case when the account iterator has
// reached the end but count < maxCount
migrdb.EndVerkleTransition()
migrdb.EndVerkleTransition(root)
break
}
}
}
migrdb.SetCurrentPreimageOffset(preimageSeek)
migrdb.SetCurrentPreimageOffset(preimageSeek, root)

log.Info("Collected key values from base tree", "count", count, "duration", time.Since(now), "last account", statedb.Database().GetCurrentAccountHash())
log.Info("Collected key values from base tree", "count", count, "duration", time.Since(now), "last account", statedb.Database().GetCurrentAccountHash(root))

// Take all the collected key-values and prepare the new leaf values.
// This fires a background routine that will start doing the work that
Expand Down
Loading
Loading