use Bytes to simplify the Witness's operation logic

This commit is contained in:
maskpp 2025-09-18 18:21:52 +08:00
parent 8a171dce1f
commit a0b180c68a
3 changed files with 19 additions and 49 deletions

View file

@ -44,9 +44,7 @@ func (w *Witness) MakeHashDB() ethdb.Database {
rawdb.WriteHeader(memdb, header)
}
// Inject all the bytecodes into the ephemeral database
for code := range w.Codes {
blob := []byte(code)
for _, blob := range w.Codes {
hasher.Reset()
hasher.Write(blob)
hasher.Read(hash)
@ -54,9 +52,7 @@ func (w *Witness) MakeHashDB() ethdb.Database {
rawdb.WriteCode(memdb, common.BytesToHash(hash), blob)
}
// Inject all the MPT trie nodes into the ephemeral database
for node := range w.State {
blob := []byte(node)
for _, blob := range w.State {
hasher.Reset()
hasher.Write(blob)
hasher.Read(hash)

View file

@ -18,6 +18,7 @@ package stateless
import (
"io"
"slices"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
@ -26,47 +27,21 @@ import (
// ToExtWitness converts our internal witness representation to the consensus one.
func (w *Witness) ToExtWitness() *ExtWitness {
ext := &ExtWitness{
Headers: w.Headers,
return &ExtWitness{
Headers: slices.Clone(w.Headers),
Codes: slices.Clone(w.Codes),
State: slices.Clone(w.State),
}
ext.Codes = make([]hexutil.Bytes, 0, len(w.Codes))
for code := range w.Codes {
ext.Codes = append(ext.Codes, []byte(code))
}
ext.State = make([]hexutil.Bytes, 0, len(w.State))
for node := range w.State {
ext.State = append(ext.State, []byte(node))
}
return ext
}
// fromExtWitness converts the consensus witness format into our internal one.
func (w *Witness) fromExtWitness(ext *ExtWitness) error {
w.Headers = ext.Headers
w.Codes = make(map[string]struct{}, len(ext.Codes))
for _, code := range ext.Codes {
w.Codes[string(code)] = struct{}{}
}
w.State = make(map[string]struct{}, len(ext.State))
for _, node := range ext.State {
w.State[string(node)] = struct{}{}
}
return nil
}
// EncodeRLP serializes a witness as RLP.
func (w *Witness) EncodeRLP(wr io.Writer) error {
return rlp.Encode(wr, w.ToExtWitness())
return rlp.Encode(wr, w)
}
// DecodeRLP decodes a witness from RLP.
func (w *Witness) DecodeRLP(s *rlp.Stream) error {
var ext ExtWitness
if err := s.Decode(&ext); err != nil {
return err
}
return w.fromExtWitness(&ext)
return s.Decode(&w)
}
// ExtWitness is a witness RLP encoding for transferring across clients.
@ -74,5 +49,4 @@ type ExtWitness struct {
Headers []*types.Header `json:"headers"`
Codes []hexutil.Bytes `json:"codes"`
State []hexutil.Bytes `json:"state"`
Keys []hexutil.Bytes `json:"keys"`
}

View file

@ -18,11 +18,11 @@ package stateless
import (
"errors"
"maps"
"slices"
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
)
@ -38,9 +38,9 @@ type HeaderReader interface {
type Witness struct {
context *types.Header // Header to which this witness belongs to, with rootHash and receiptHash zeroed out
Headers []*types.Header // Past headers in reverse order (0=parent, 1=parent's-parent, etc). First *must* be set.
Codes map[string]struct{} // Set of bytecodes ran or accessed
State map[string]struct{} // Set of MPT state trie nodes (account and storage together)
Headers []*types.Header `json:"headers"` // Past headers in reverse order (0=parent, 1=parent's-parent, etc). First *must* be set.
Codes []hexutil.Bytes `json:"codes"` // Set of bytecodes ran or accessed
State []hexutil.Bytes `json:"state"` // Set of MPT state trie nodes (account and storage together)
chain HeaderReader // Chain reader to convert block hash ops to header proofs
lock sync.Mutex // Lock to allow concurrent state insertions
@ -62,8 +62,8 @@ func NewWitness(context *types.Header, chain HeaderReader) (*Witness, error) {
return &Witness{
context: context,
Headers: headers,
Codes: make(map[string]struct{}),
State: make(map[string]struct{}),
Codes: []hexutil.Bytes{},
State: []hexutil.Bytes{},
chain: chain,
}, nil
}
@ -84,7 +84,7 @@ func (w *Witness) AddCode(code []byte) {
if len(code) == 0 {
return
}
w.Codes[string(code)] = struct{}{}
w.Codes = append(w.Codes, code)
}
// AddState inserts a batch of MPT trie nodes into the witness.
@ -96,7 +96,7 @@ func (w *Witness) AddState(nodes map[string][]byte) {
defer w.lock.Unlock()
for _, value := range nodes {
w.State[string(value)] = struct{}{}
w.State = append(w.State, value)
}
}
@ -109,8 +109,8 @@ func (w *Witness) AddKey() {
func (w *Witness) Copy() *Witness {
cpy := &Witness{
Headers: slices.Clone(w.Headers),
Codes: maps.Clone(w.Codes),
State: maps.Clone(w.State),
Codes: slices.Clone(w.Codes),
State: slices.Clone(w.State),
chain: w.chain,
}
if w.context != nil {