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

overlay transition #198

Closed
wants to merge 1 commit into from
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
13 changes: 6 additions & 7 deletions cmd/geth/verkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,13 @@ func convertToVerkle(ctx *cli.Context) error {
vRoot = verkle.New().(*verkle.InternalNode)
)

saveverkle := func(node verkle.VerkleNode) {
comm := node.Commit()
saveverkle := func(path []byte, node verkle.VerkleNode) {
node.Commit()
s, err := node.Serialize()
if err != nil {
panic(err)
}
commB := comm.Bytes()
if err := chaindb.Put(commB[:], s); err != nil {
if err := chaindb.Put(path, s); err != nil {
panic(err)
}
}
Expand Down Expand Up @@ -330,7 +329,7 @@ func checkChildren(root verkle.VerkleNode, resolver verkle.NodeResolverFn) error
return fmt.Errorf("could not find child %x in db: %w", childC, err)
}
// depth is set to 0, the tree isn't rebuilt so it's not a problem
childN, err := verkle.ParseNode(childS, 0, childC[:])
childN, err := verkle.ParseNode(childS, 0)
if err != nil {
return fmt.Errorf("decode error child %x in db: %w", child.Commitment().Bytes(), err)
}
Expand Down Expand Up @@ -390,7 +389,7 @@ func verifyVerkle(ctx *cli.Context) error {
if err != nil {
return err
}
root, err := verkle.ParseNode(serializedRoot, 0, rootC[:])
root, err := verkle.ParseNode(serializedRoot, 0)
if err != nil {
return err
}
Expand Down Expand Up @@ -439,7 +438,7 @@ func expandVerkle(ctx *cli.Context) error {
if err != nil {
return err
}
root, err := verkle.ParseNode(serializedRoot, 0, rootC[:])
root, err := verkle.ParseNode(serializedRoot, 0)
if err != nil {
return err
}
Expand Down
12 changes: 12 additions & 0 deletions cmd/utils/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"os"
"os/signal"
"runtime"
"runtime/pprof"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -173,6 +174,17 @@ func ImportChain(chain *core.BlockChain, fn string) error {
return err
}
}
cpuProfile, err := os.Create("cpu.out")
if err != nil {
return fmt.Errorf("Error creating CPU profile: %v", err)
}
defer cpuProfile.Close()
err = pprof.StartCPUProfile(cpuProfile)
if err != nil {
return fmt.Errorf("Error starting CPU profile: %v", err)
}
defer pprof.StopCPUProfile()

stream := rlp.NewStream(reader, 0)

// Run actual the import.
Expand Down
31 changes: 18 additions & 13 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,17 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
if hash := types.DeriveSha(block.Transactions(), trie.NewStackTrie(nil)); hash != header.TxHash {
return fmt.Errorf("transaction root hash mismatch: have %x, want %x", hash, header.TxHash)
}
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {
return consensus.ErrUnknownAncestor
}
return consensus.ErrPrunedAncestor
}
// XXX I had to deactivate this check for replay to work: the block state root
// hash is the one of the overlay tree, but in replay mode, it's the hash of
// the base tree that takes precedence, as the chain would not otherwise be
// recognized.
// if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
// if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {
// return consensus.ErrUnknownAncestor
// }
// fmt.Println("failure here")
// return consensus.ErrPrunedAncestor
// }
return nil
}

Expand All @@ -90,15 +95,15 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom)
}
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, Rn]]))
receiptSha := types.DeriveSha(receipts, trie.NewStackTrie(nil))
if receiptSha != header.ReceiptHash {
return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
}
// receiptSha := types.DeriveSha(receipts, trie.NewStackTrie(nil))
// if receiptSha != header.ReceiptHash {
// return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
// }
// Validate the state root against the received state root and throw
// an error if they don't match.
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root)
}
// if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
// return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root)
// }
return nil
}

Expand Down
37 changes: 37 additions & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
package core

import (
"bufio"
"errors"
"fmt"
"io"
"math/big"
"os"
"runtime"
"sort"
"strconv"
"strings"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -1484,6 +1487,21 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
return 0, nil
}

f, err := os.Open("conversion.txt")
if err != nil {
log.Error("Failed to open conversion.txt", "err", err)
return 0, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Scan()
conversionBlock, err := strconv.ParseUint(scanner.Text(), 10, 64)
if err != nil {
log.Error("Failed to parse conversionBlock", "err", err)
return 0, err
}
log.Info("Found conversion block info", "conversionBlock", conversionBlock)

// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)

Expand Down Expand Up @@ -1668,6 +1686,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
if parent == nil {
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
}

if parent.Number.Uint64() == conversionBlock {
bc.StartVerkleTransition(parent.Root, emptyVerkleRoot, bc.Config(), parent.Number)
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the blockchain realizes that the transition should start, and signal a ForkedDB/TransitionTrie adapter should be used.

statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
if err != nil {
return it.index, err
Expand Down Expand Up @@ -1703,6 +1725,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
atomic.StoreUint32(&followupInterrupt, 1)
return it.index, err
}
if fdb, ok := statedb.Database().(*state.ForkingDB); ok {
if fdb.InTransition() || fdb.Transitionned() {
bc.AddRootTranslation(block.Root(), statedb.IntermediateRoot(false))
}
}

// Update the metrics touched during block processing
accountReadTimer.Update(statedb.AccountReads) // Account reads are complete, we can mark them
Expand Down Expand Up @@ -2285,6 +2312,8 @@ func (bc *BlockChain) skipBlock(err error, it *insertIterator) bool {
return false
}

var emptyVerkleRoot common.Hash

// indexBlocks reindexes or unindexes transactions depending on user configuration
func (bc *BlockChain) indexBlocks(tail *uint64, head uint64, done chan struct{}) {
defer func() { close(done) }()
Expand Down Expand Up @@ -2429,3 +2458,11 @@ func (bc *BlockChain) SetBlockValidatorAndProcessorForTesting(v Validator, p Pro
bc.validator = v
bc.processor = p
}

func (bc *BlockChain) StartVerkleTransition(originalRoot, translatedRoot common.Hash, chainConfig *params.ChainConfig, cancunBlock *big.Int) {
bc.stateCache.(*state.ForkingDB).StartTransition(originalRoot, translatedRoot, chainConfig, cancunBlock)
}

func (bc *BlockChain) AddRootTranslation(originalRoot, translatedRoot common.Hash) {
bc.stateCache.(*state.ForkingDB).AddTranslation(originalRoot, translatedRoot)
}
18 changes: 17 additions & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
keyvals := make([]verkle.StateDiff, 0, n)
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
chainreader := &fakeChainReader{config: config}
var preStateTrie *trie.VerkleTrie
genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) {
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
b.header = makeHeader(chainreader, parent, statedb, b.engine)
Expand Down Expand Up @@ -372,13 +373,28 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
kvs[string(key)] = v
}

// Initialize the preStateTrie if it is nil, this should
// correspond to the genesis block. This is a workaround
// needed until the main verkle PR is rebased on top of
// PBSS.
if preStateTrie == nil {
preStateTrie = vtr
}

vtr.Hash()
p, k, err := vtr.ProveAndSerialize(statedb.Witness().Keys(), kvs)
p, k, err := preStateTrie.ProveAndSerialize(statedb.Witness().Keys(), kvs)
if err != nil {
panic(err)
}
proofs = append(proofs, p)
keyvals = append(keyvals, k)

// save the current state of the trie for producing the proof for the next block,
// since reading it from disk is broken with the intermediate PBSS-like system we
// have: it will read the post-state as this is the only state present on disk.
// This is a workaround needed until the main verkle PR is rebased on top of PBSS.
preStateTrie = statedb.GetTrie().(*trie.VerkleTrie)

return block, b.receipts
}
return nil, nil
Expand Down
2 changes: 1 addition & 1 deletion core/state/access_witness.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ func (aw *AccessWitness) Copy() *AccessWitness {
}

func (aw *AccessWitness) GetTreeKeyVersionCached(addr []byte) []byte {
return aw.statedb.db.(*VerkleDB).addrToPoint.GetTreeKeyVersionCached(addr)
return aw.statedb.db.(*ForkingDB).addrToPoint.GetTreeKeyVersionCached(addr)
}

func (aw *AccessWitness) TouchAndChargeProofOfAbsence(addr []byte) uint64 {
Expand Down
Loading