@@ -28,15 +28,22 @@ import (
2828 "github.com/ethereum/go-ethereum/common"
2929 "github.com/ethereum/go-ethereum/common/hexutil"
3030 "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
31+ "github.com/ethereum/go-ethereum/core"
32+ "github.com/ethereum/go-ethereum/core/rawdb"
3133 "github.com/ethereum/go-ethereum/core/state"
3234 "github.com/ethereum/go-ethereum/core/tracing"
3335 "github.com/ethereum/go-ethereum/core/types"
3436 "github.com/ethereum/go-ethereum/core/vm"
37+ "github.com/ethereum/go-ethereum/crypto"
3538 "github.com/ethereum/go-ethereum/eth/tracers"
3639 "github.com/ethereum/go-ethereum/eth/tracers/logger"
3740 "github.com/ethereum/go-ethereum/log"
3841 "github.com/ethereum/go-ethereum/params"
3942 "github.com/ethereum/go-ethereum/tests"
43+ "github.com/ethereum/go-ethereum/trie"
44+ "github.com/ethereum/go-ethereum/trie/utils"
45+ "github.com/ethereum/go-ethereum/triedb"
46+ "github.com/holiman/uint256"
4047 "github.com/urfave/cli/v2"
4148)
4249
@@ -194,7 +201,9 @@ func Transition(ctx *cli.Context) error {
194201 s .DumpToCollector (collector , nil )
195202 } else {
196203 vktleaves = make (map [common.Hash ]hexutil.Bytes )
197- s .DumpVKTLeaves (vktleaves )
204+ if err := s .DumpVKTLeaves (vktleaves ); err != nil {
205+ return err
206+ }
198207 }
199208 return dispatchOutput (ctx , baseDir , result , collector , body , vktleaves )
200209}
@@ -368,3 +377,171 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a
368377 }
369378 return nil
370379}
380+
381+ // VerkleKey computes the tree key given an address and an optional
382+ // slot number.
383+ func VerkleKey (ctx * cli.Context ) error {
384+ if ctx .Args ().Len () == 0 || ctx .Args ().Len () > 2 {
385+ return errors .New ("invalid number of arguments: expecting an address and an optional slot number" )
386+ }
387+
388+ addr , err := hexutil .Decode (ctx .Args ().Get (0 ))
389+ if err != nil {
390+ return fmt .Errorf ("error decoding address: %w" , err )
391+ }
392+
393+ ap := utils .EvaluateAddressPoint (addr )
394+ if ctx .Args ().Len () == 2 {
395+ slot , err := hexutil .Decode (ctx .Args ().Get (1 ))
396+ if err != nil {
397+ return fmt .Errorf ("error decoding slot: %w" , err )
398+ }
399+ fmt .Printf ("%#x\n " , utils .GetTreeKeyStorageSlotWithEvaluatedAddress (ap , slot ))
400+ } else {
401+ fmt .Printf ("%#x\n " , utils .GetTreeKeyBasicDataEvaluatedAddress (ap ))
402+ }
403+ return nil
404+ }
405+
406+ // VerkleKeys computes a set of tree keys given a genesis alloc.
407+ func VerkleKeys (ctx * cli.Context ) error {
408+ var allocStr = ctx .String (InputAllocFlag .Name )
409+ var alloc core.GenesisAlloc
410+ // Figure out the prestate alloc
411+ if allocStr == stdinSelector {
412+ decoder := json .NewDecoder (os .Stdin )
413+ if err := decoder .Decode (& alloc ); err != nil {
414+ return NewError (ErrorJson , fmt .Errorf ("failed unmarshaling stdin: %v" , err ))
415+ }
416+ }
417+ if allocStr != stdinSelector {
418+ if err := readFile (allocStr , "alloc" , & alloc ); err != nil {
419+ return err
420+ }
421+ }
422+
423+ vkt , err := genVktFromAlloc (alloc )
424+ if err != nil {
425+ return fmt .Errorf ("error generating vkt: %w" , err )
426+ }
427+
428+ collector := make (map [common.Hash ]hexutil.Bytes )
429+ it , err := vkt .NodeIterator (nil )
430+ if err != nil {
431+ panic (err )
432+ }
433+ for it .Next (true ) {
434+ if it .Leaf () {
435+ collector [common .BytesToHash (it .LeafKey ())] = it .LeafBlob ()
436+ }
437+ }
438+
439+ output , err := json .MarshalIndent (collector , "" , "" )
440+ if err != nil {
441+ return fmt .Errorf ("error outputting tree: %w" , err )
442+ }
443+
444+ fmt .Println (string (output ))
445+
446+ return nil
447+ }
448+
449+ // VerkleRoot computes the root of a VKT from a genesis alloc.
450+ func VerkleRoot (ctx * cli.Context ) error {
451+ var allocStr = ctx .String (InputAllocFlag .Name )
452+ var alloc core.GenesisAlloc
453+ if allocStr == stdinSelector {
454+ decoder := json .NewDecoder (os .Stdin )
455+ if err := decoder .Decode (& alloc ); err != nil {
456+ return NewError (ErrorJson , fmt .Errorf ("failed unmarshaling stdin: %v" , err ))
457+ }
458+ }
459+ if allocStr != stdinSelector {
460+ if err := readFile (allocStr , "alloc" , & alloc ); err != nil {
461+ return err
462+ }
463+ }
464+
465+ vkt , err := genVktFromAlloc (alloc )
466+ if err != nil {
467+ return fmt .Errorf ("error generating vkt: %w" , err )
468+ }
469+ fmt .Println (vkt .Hash ().Hex ())
470+
471+ return nil
472+ }
473+
474+ func genVktFromAlloc (alloc core.GenesisAlloc ) (* trie.VerkleTrie , error ) {
475+ vkt , err := trie .NewVerkleTrie (types .EmptyVerkleHash , triedb .NewDatabase (rawdb .NewMemoryDatabase (),
476+ & triedb.Config {
477+ IsVerkle : true ,
478+ }), utils .NewPointCache (1024 ))
479+ if err != nil {
480+ return nil , err
481+ }
482+
483+ for addr , acc := range alloc {
484+ for slot , value := range acc .Storage {
485+ err := vkt .UpdateStorage (addr , slot .Bytes (), value .Big ().Bytes ())
486+ if err != nil {
487+ return nil , fmt .Errorf ("error inserting storage: %w" , err )
488+ }
489+ }
490+
491+ account := & types.StateAccount {
492+ Balance : uint256 .MustFromBig (acc .Balance ),
493+ Nonce : acc .Nonce ,
494+ CodeHash : crypto .Keccak256Hash (acc .Code ).Bytes (),
495+ Root : common.Hash {},
496+ }
497+ err := vkt .UpdateAccount (addr , account , len (acc .Code ))
498+ if err != nil {
499+ return nil , fmt .Errorf ("error inserting account: %w" , err )
500+ }
501+
502+ err = vkt .UpdateContractCode (addr , common .BytesToHash (account .CodeHash ), acc .Code )
503+ if err != nil {
504+ return nil , fmt .Errorf ("error inserting code: %w" , err )
505+ }
506+ }
507+ return vkt , nil
508+ }
509+
510+ // VerkleCodeChunkKey computes the tree key of a code-chunk for a given address.
511+ func VerkleCodeChunkKey (ctx * cli.Context ) error {
512+ if ctx .Args ().Len () == 0 || ctx .Args ().Len () > 2 {
513+ return errors .New ("invalid number of arguments: expecting an address and an code-chunk number" )
514+ }
515+
516+ addr , err := hexutil .Decode (ctx .Args ().Get (0 ))
517+ if err != nil {
518+ return fmt .Errorf ("error decoding address: %w" , err )
519+ }
520+ chunkNumberBytes , err := hexutil .Decode (ctx .Args ().Get (1 ))
521+ if err != nil {
522+ return fmt .Errorf ("error decoding chunk number: %w" , err )
523+ }
524+ var chunkNumber uint256.Int
525+ chunkNumber .SetBytes (chunkNumberBytes )
526+
527+ fmt .Printf ("%#x\n " , utils .GetTreeKeyCodeChunk (addr , & chunkNumber ))
528+
529+ return nil
530+ }
531+
532+ // VerkleChunkifyCode returns the code chunkification for a given code.
533+ func VerkleChunkifyCode (ctx * cli.Context ) error {
534+ if ctx .Args ().Len () == 0 || ctx .Args ().Len () > 1 {
535+ return errors .New ("invalid number of arguments: expecting a bytecode" )
536+ }
537+
538+ bytecode , err := hexutil .Decode (ctx .Args ().Get (0 ))
539+ if err != nil {
540+ return fmt .Errorf ("error decoding address: %w" , err )
541+ }
542+
543+ chunkedCode := trie .ChunkifyCode (bytecode )
544+ fmt .Printf ("%#x\n " , chunkedCode )
545+
546+ return nil
547+ }
0 commit comments