attempt to align behavior with other clients (spec tests currently incorrect)

This commit is contained in:
Jared Wasinger 2025-12-16 18:00:05 -08:00
parent 00136d1735
commit abaef48d54
5 changed files with 82 additions and 55 deletions

View file

@ -125,6 +125,12 @@ func (e *BlockAccessList) Hash() common.Hash {
// under reasonable conditions. // under reasonable conditions.
panic(err) panic(err)
} }
/*
bal, err := json.MarshalIndent(e.StringableRepresentation(), "", " ")
if err != nil {
panic(err)
}
*/
return crypto.Keccak256Hash(enc.Bytes()) return crypto.Keccak256Hash(enc.Bytes())
} }
@ -142,29 +148,32 @@ type encodingAccountNonce struct {
// encodingStorageWrite is the encoding format of StorageWrites. // encodingStorageWrite is the encoding format of StorageWrites.
type encodingStorageWrite struct { type encodingStorageWrite struct {
TxIdx uint16 `json:"txIndex"` TxIdx uint16 `json:"txIndex"`
ValueAfter encodedStorage `json:"valueAfter"` ValueAfter *EncodedStorage `json:"valueAfter"`
} }
// encodedStorage can represent either a storage key or value // EncodedStorage can represent either a storage key or value
type encodedStorage []byte type EncodedStorage struct {
inner *uint256.Int
}
func (e *encodedStorage) ToHash() common.Hash { var _ rlp.Encoder = &EncodedStorage{}
var _ rlp.Decoder = &EncodedStorage{}
func (e *EncodedStorage) ToHash() common.Hash {
if e == nil { if e == nil {
return common.Hash{} return common.Hash{}
} }
return common.BytesToHash(*e) return e.inner.Bytes32()
} }
func newEncodedStorageFromHash(hash common.Hash) encodedStorage { func newEncodedStorageFromHash(hash common.Hash) *EncodedStorage {
return bytes.TrimLeft(hash[:], "\x00") return &EncodedStorage{
new(uint256.Int).SetBytes(hash[:]),
}
} }
func (e *encodedStorage) FromHash(hash common.Hash) { func (s *EncodedStorage) UnmarshalJSON(b []byte) error {
*e = hash[:]
}
func (s *encodedStorage) UnmarshalJSON(b []byte) error {
var str string var str string
if err := json.Unmarshal(b, &str); err != nil { if err := json.Unmarshal(b, &str); err != nil {
return err return err
@ -190,34 +199,31 @@ func (s *encodedStorage) UnmarshalJSON(b []byte) error {
// TODO: check is s == nil ?? should be programmer error // TODO: check is s == nil ?? should be programmer error
*s = make([]byte, len(val)-1) *s = EncodedStorage{
copy((*s)[:len(val)-1], val[:]) inner: new(uint256.Int).SetBytes(val),
}
return nil return nil
} }
func (s encodedStorage) MarshalJSON() ([]byte, error) { func (s EncodedStorage) MarshalJSON() ([]byte, error) {
trimmed := bytes.TrimLeft(s[:], "\x00") return json.Marshal(s.inner.Hex())
return json.Marshal("0x" + common.Bytes2Hex(trimmed))
} }
func (s *encodedStorage) EncodeRLP(_w io.Writer) error { func (s *EncodedStorage) EncodeRLP(_w io.Writer) error {
var obj encodedStorage return s.inner.EncodeRLP(_w)
if s != nil { }
obj = *s
func (s *EncodedStorage) DecodeRLP(dec *rlp.Stream) error {
if s == nil {
*s = EncodedStorage{}
} }
trimmed := bytes.TrimLeft(obj[:], "\x00") s.inner = uint256.NewInt(0)
fmt.Println("here") return dec.ReadUint256(s.inner)
return rlp.Encode(_w, trimmed)
}
func (s *encodedStorage) DecodeRLP(dec *rlp.Stream) error {
err := dec.ReadBytes((*s)[:])
return err
} }
// encodingStorageWrite is the encoding format of SlotWrites. // encodingStorageWrite is the encoding format of SlotWrites.
type encodingSlotWrites struct { type encodingSlotWrites struct {
Slot encodedStorage `json:"slot"` Slot *EncodedStorage `json:"slot"`
Accesses []encodingStorageWrite `json:"accesses"` Accesses []encodingStorageWrite `json:"accesses"`
} }
@ -237,8 +243,8 @@ func (e *encodingSlotWrites) validate() error {
// AccountAccess is the encoding format of ConstructionAccountAccesses. // AccountAccess is the encoding format of ConstructionAccountAccesses.
type AccountAccess struct { type AccountAccess struct {
Address common.Address `json:"address,omitempty"` // 20-byte Ethereum address Address common.Address `json:"address,omitempty"` // 20-byte Ethereum address
StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // encodedStorage changes (slot -> [tx_index -> new_value]) StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // EncodedStorage changes (slot -> [tx_index -> new_value])
StorageReads []encodedStorage `json:"storageReads,omitempty"` // Read-only storage keys StorageReads []*EncodedStorage `json:"storageReads,omitempty"` // Read-only storage keys
BalanceChanges []encodingBalanceChange `json:"balanceChanges,omitempty"` // Balance changes ([tx_index -> post_balance]) BalanceChanges []encodingBalanceChange `json:"balanceChanges,omitempty"` // Balance changes ([tx_index -> post_balance])
NonceChanges []encodingAccountNonce `json:"nonceChanges,omitempty"` // Nonce changes ([tx_index -> new_nonce]) NonceChanges []encodingAccountNonce `json:"nonceChanges,omitempty"` // Nonce changes ([tx_index -> new_nonce])
CodeChanges []CodeChange `json:"code,omitempty"` // CodeChanges changes ([tx_index -> new_code]) CodeChanges []CodeChange `json:"code,omitempty"` // CodeChanges changes ([tx_index -> new_code])
@ -283,7 +289,7 @@ func (e *AccountAccess) validate() error {
} }
// Check the storage read slots are sorted in order // Check the storage read slots are sorted in order
if !slices.IsSortedFunc(e.StorageReads, func(a, b encodedStorage) int { if !slices.IsSortedFunc(e.StorageReads, func(a, b *EncodedStorage) int {
aHash, bHash := a.ToHash(), b.ToHash() aHash, bHash := a.ToHash(), b.ToHash()
return bytes.Compare(aHash[:], bHash[:]) return bytes.Compare(aHash[:], bHash[:])
}) { }) {
@ -351,7 +357,7 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account
res := AccountAccess{ res := AccountAccess{
Address: addr, Address: addr,
StorageChanges: make([]encodingSlotWrites, 0), StorageChanges: make([]encodingSlotWrites, 0),
StorageReads: make([]encodedStorage, 0), StorageReads: make([]*EncodedStorage, 0),
BalanceChanges: make([]encodingBalanceChange, 0), BalanceChanges: make([]encodingBalanceChange, 0),
NonceChanges: make([]encodingAccountNonce, 0), NonceChanges: make([]encodingAccountNonce, 0),
CodeChanges: make([]CodeChange, 0), CodeChanges: make([]CodeChange, 0),

View file

@ -14,12 +14,16 @@ func (obj *AccountAccess) EncodeRLP(_w io.Writer) error {
_tmp1 := w.List() _tmp1 := w.List()
for _, _tmp2 := range obj.StorageChanges { for _, _tmp2 := range obj.StorageChanges {
_tmp3 := w.List() _tmp3 := w.List()
w.WriteBytes(_tmp2.Slot) if err := _tmp2.Slot.EncodeRLP(w); err != nil {
return err
}
_tmp4 := w.List() _tmp4 := w.List()
for _, _tmp5 := range _tmp2.Accesses { for _, _tmp5 := range _tmp2.Accesses {
_tmp6 := w.List() _tmp6 := w.List()
w.WriteUint64(uint64(_tmp5.TxIdx)) w.WriteUint64(uint64(_tmp5.TxIdx))
w.WriteBytes(_tmp5.ValueAfter) if err := _tmp5.ValueAfter.EncodeRLP(w); err != nil {
return err
}
w.ListEnd(_tmp6) w.ListEnd(_tmp6)
} }
w.ListEnd(_tmp4) w.ListEnd(_tmp4)
@ -28,7 +32,9 @@ func (obj *AccountAccess) EncodeRLP(_w io.Writer) error {
w.ListEnd(_tmp1) w.ListEnd(_tmp1)
_tmp7 := w.List() _tmp7 := w.List()
for _, _tmp8 := range obj.StorageReads { for _, _tmp8 := range obj.StorageReads {
w.WriteBytes(_tmp8) if err := _tmp8.EncodeRLP(w); err != nil {
return err
}
} }
w.ListEnd(_tmp7) w.ListEnd(_tmp7)
_tmp9 := w.List() _tmp9 := w.List()
@ -87,8 +93,8 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error {
return err return err
} }
// Slot: // Slot:
_tmp4, err := dec.Bytes() _tmp4 := new(EncodedStorage)
if err != nil { if err := _tmp4.DecodeRLP(dec); err != nil {
return err return err
} }
_tmp3.Slot = _tmp4 _tmp3.Slot = _tmp4
@ -110,8 +116,8 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error {
} }
_tmp6.TxIdx = _tmp7 _tmp6.TxIdx = _tmp7
// ValueAfter: // ValueAfter:
_tmp8, err := dec.Bytes() _tmp8 := new(EncodedStorage)
if err != nil { if err := _tmp8.DecodeRLP(dec); err != nil {
return err return err
} }
_tmp6.ValueAfter = _tmp8 _tmp6.ValueAfter = _tmp8
@ -136,13 +142,13 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error {
} }
_tmp0.StorageChanges = _tmp2 _tmp0.StorageChanges = _tmp2
// StorageReads: // StorageReads:
var _tmp9 []encodedStorage var _tmp9 []*EncodedStorage
if _, err := dec.List(); err != nil { if _, err := dec.List(); err != nil {
return err return err
} }
for dec.MoreDataInList() { for dec.MoreDataInList() {
_tmp10, err := dec.Bytes() _tmp10 := new(EncodedStorage)
if err != nil { if err := _tmp10.DecodeRLP(dec); err != nil {
return err return err
} }
_tmp9 = append(_tmp9, _tmp10) _tmp9 = append(_tmp9, _tmp10)

View file

@ -119,12 +119,12 @@ func makeTestAccountAccess(sort bool) AccountAccess {
) )
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
slot := encodingSlotWrites{ slot := encodingSlotWrites{
Slot: testrand.Hash(), Slot: newEncodedStorageFromHash(testrand.Hash()),
} }
for j := 0; j < 3; j++ { for j := 0; j < 3; j++ {
slot.Accesses = append(slot.Accesses, encodingStorageWrite{ slot.Accesses = append(slot.Accesses, encodingStorageWrite{
TxIdx: uint16(2 * j), TxIdx: uint16(2 * j),
ValueAfter: testrand.Hash(), ValueAfter: newEncodedStorageFromHash(testrand.Hash()),
}) })
} }
if sort { if sort {
@ -173,10 +173,14 @@ func makeTestAccountAccess(sort bool) AccountAccess {
}) })
} }
var encodedStorageReads []EncodedStorage
for _, slot := range storageReads {
encodedStorageReads = append(encodedStorageReads, newEncodedStorageFromHash(slot))
}
return AccountAccess{ return AccountAccess{
Address: [20]byte(testrand.Bytes(20)), Address: [20]byte(testrand.Bytes(20)),
StorageChanges: storageWrites, StorageChanges: storageWrites,
StorageReads: storageReads, StorageReads: encodedStorageReads,
BalanceChanges: balances, BalanceChanges: balances,
NonceChanges: nonces, NonceChanges: nonces,
CodeChanges: []CodeChange{ CodeChanges: []CodeChange{
@ -216,7 +220,7 @@ func TestBlockAccessListCopy(t *testing.T) {
// Make sure the mutations on copy won't affect the origin // Make sure the mutations on copy won't affect the origin
for _, aa := range cpyCpy { for _, aa := range cpyCpy {
for i := 0; i < len(aa.StorageReads); i++ { for i := 0; i < len(aa.StorageReads); i++ {
aa.StorageReads[i] = [32]byte(testrand.Bytes(32)) aa.StorageReads[i] = testrand.Bytes(32)
} }
} }
if !reflect.DeepEqual(list, cpy) { if !reflect.DeepEqual(list, cpy) {

View file

@ -515,6 +515,7 @@ func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*eng
if data == nil { if data == nil {
return nil, engine.UnknownPayload return nil, engine.UnknownPayload
} }
return data, nil return data, nil
} }

View file

@ -22,12 +22,6 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/core/types/bal"
stdmath "math"
"math/big"
"os"
"reflect"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
@ -38,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types/bal"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -45,6 +40,11 @@ import (
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
"github.com/ethereum/go-ethereum/triedb/hashdb" "github.com/ethereum/go-ethereum/triedb/hashdb"
"github.com/ethereum/go-ethereum/triedb/pathdb" "github.com/ethereum/go-ethereum/triedb/pathdb"
stdmath "math"
"math/big"
"os"
"reflect"
"strings"
) )
// A BlockTest checks handling of entire blocks. // A BlockTest checks handling of entire blocks.
@ -305,6 +305,16 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error)
return nil, fmt.Errorf("block RLP decoding failed when expected to succeed: %v", err) return nil, fmt.Errorf("block RLP decoding failed when expected to succeed: %v", err)
} }
} }
// check that if we encode the same block, it will result in the same RLP
var enc bytes.Buffer
if err := rlp.Encode(&enc, cb); err != nil {
return nil, err
}
expected := common.Hex2Bytes(strings.TrimLeft(b.Rlp, "0x"))
if !bytes.Equal(enc.Bytes(), expected) {
return nil, fmt.Errorf("mismatch. expected\n%s\ngot\n%x\n", expected, enc.Bytes())
}
// RLP decoding worked, try to insert into chain: // RLP decoding worked, try to insert into chain:
blocks := types.Blocks{cb} blocks := types.Blocks{cb}
i, err := blockchain.InsertChain(blocks) i, err := blockchain.InsertChain(blocks)