This commit is contained in:
Jared Wasinger 2024-02-19 20:45:42 -08:00
parent d7ba47e08a
commit 100d2e34e1
2 changed files with 9 additions and 77 deletions

View file

@ -3,21 +3,16 @@ package state
import ( import (
"bytes" "bytes"
"crypto/sha256" "crypto/sha256"
"encoding/json"
"fmt" "fmt"
"math/big"
"os"
"path/filepath"
"sort" "sort"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
// A Witness contains a block and all pre-state needed to execute the block
// and compute the post-state root.
type Witness struct { type Witness struct {
Block *types.Block Block *types.Block
blockHashes map[uint64]common.Hash blockHashes map[uint64]common.Hash
@ -26,14 +21,6 @@ type Witness struct {
lists map[common.Hash]map[string][]byte lists map[common.Hash]map[string][]byte
} }
func (w *Witness) GetBlockHash(num uint64) common.Hash {
return w.blockHashes[num]
}
func (w *Witness) Root() common.Hash {
return w.root
}
type rlpWitness struct { type rlpWitness struct {
EncBlock []byte EncBlock []byte
Root common.Hash Root common.Hash
@ -46,7 +33,7 @@ type rlpWitness struct {
CodeHashes []common.Hash CodeHashes []common.Hash
} }
func (e *rlpWitness) ToWitness() (*Witness, error) { func (e *rlpWitness) toWitness() (*Witness, error) {
res := NewWitness(e.Root) res := NewWitness(e.Root)
if err := rlp.DecodeBytes(e.EncBlock, &res.Block); err != nil { if err := rlp.DecodeBytes(e.EncBlock, &res.Block); err != nil {
return nil, err return nil, err
@ -72,7 +59,7 @@ func DecodeWitnessRLP(b []byte) (*Witness, error) {
if err := rlp.DecodeBytes(b, &res); err != nil { if err := rlp.DecodeBytes(b, &res); err != nil {
return nil, err return nil, err
} }
if wit, err := res.ToWitness(); err != nil { if wit, err := res.toWitness(); err != nil {
return nil, err return nil, err
} else { } else {
return wit, nil return wit, nil
@ -152,8 +139,6 @@ func (w *Witness) AddCode(hash common.Hash, code Code) {
} }
// AddCodeHash adds a code hash to the witness // AddCodeHash adds a code hash to the witness
// TODO bug: adding a code hash before executing the same account later would result in the account's code
// not being added to the witness. this should be covered in state tests?
func (w *Witness) AddCodeHash(hash common.Hash) { func (w *Witness) AddCodeHash(hash common.Hash) {
if _, ok := w.codes[hash]; ok { if _, ok := w.codes[hash]; ok {
return return
@ -352,60 +337,3 @@ func NewWitness(root common.Hash) *Witness {
lists: make(map[common.Hash]map[string][]byte), lists: make(map[common.Hash]map[string][]byte),
} }
} }
// DumpBlockWitnessToFile serializes a witness object and writes it and the provided chain config to files on
// a given path.
func DumpBlockWitnessToFile(cfg *params.ChainConfig, w *Witness, path string) error {
enc, _ := w.EncodeRLP()
blockHash := w.Block.Hash()
witnessOutputFName := fmt.Sprintf("%d-%x.rlp", w.Block.NumberU64(), blockHash[0:8])
witnessPath := filepath.Join(path, witnessOutputFName)
err := os.WriteFile(witnessPath, enc, 0644)
if err != nil {
return err
}
cfgOutputFName := fmt.Sprintf("%d-%x-chaincfg.json", w.Block.NumberU64(), blockHash[0:8])
cfgPath := filepath.Join(path, cfgOutputFName)
f, err := os.OpenFile(cfgPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
if err != nil {
return err
}
defer f.Close()
cfgWriter := json.NewEncoder(f)
cfgWriter.Encode(cfg)
return nil
}
// PopulateDB imports trie nodes from the witness
// into the specified backing database.
func (w *Witness) PopulateDB(db ethdb.Database) error {
batch := db.NewBatch()
for owner, nodes := range w.lists {
for path, node := range nodes {
if owner == (common.Hash{}) {
rawdb.WriteAccountTrieNode(batch, []byte(path), node)
} else {
rawdb.WriteStorageTrieNode(batch, owner, []byte(path), node)
}
}
}
for blockNum, blockHash := range w.blockHashes {
fakeHeader := types.Header{}
fakeHeader.ParentHash = blockHash
fakeHeader.Number = new(big.Int).SetUint64(blockNum)
rawdb.WriteHeader(batch, &fakeHeader)
}
for codeHash, code := range w.codes {
rawdb.WriteCode(batch, codeHash, code)
}
if err := batch.Write(); err != nil {
return err
}
return nil
}

View file

@ -197,10 +197,14 @@ func (t *BlockTest) run(stateless bool, snapshotter bool, scheme string, tracer
if stateless { if stateless {
for _, blk := range validBlocks { for _, blk := range validBlocks {
_, err := eth.BuildProof(blk.BlockHeader.Number.Uint64(), chain) proof, err := eth.BuildProof(blk.BlockHeader.Number.Uint64(), chain)
if err != nil { if err != nil {
return fmt.Errorf("failed to build proof: %v", err) return fmt.Errorf("failed to build proof: %v", err)
} }
_, err = state.DecodeWitnessRLP(proof)
if err != nil {
return fmt.Errorf("failed to decode witness RLP: %v", err)
}
// TODO: decode and execute the stateless proof, verify the produced root // TODO: decode and execute the stateless proof, verify the produced root
// matches the block root. // matches the block root.
} }