diff --git a/core/stateless/database.go b/core/stateless/database.go index f54c123dda..7b035527fc 100644 --- a/core/stateless/database.go +++ b/core/stateless/database.go @@ -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) diff --git a/core/stateless/encoding.go b/core/stateless/encoding.go index 5c43159e66..8aa98a0682 100644 --- a/core/stateless/encoding.go +++ b/core/stateless/encoding.go @@ -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"` } diff --git a/core/stateless/witness.go b/core/stateless/witness.go index 588c895a2f..d85cd6f346 100644 --- a/core/stateless/witness.go +++ b/core/stateless/witness.go @@ -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 {