diff --git a/core/types/bal/bal_encoding.go b/core/types/bal/bal_encoding.go index e61cd60d7a..2e146b0686 100644 --- a/core/types/bal/bal_encoding.go +++ b/core/types/bal/bal_encoding.go @@ -125,6 +125,12 @@ func (e *BlockAccessList) Hash() common.Hash { // under reasonable conditions. panic(err) } + /* + bal, err := json.MarshalIndent(e.StringableRepresentation(), "", " ") + if err != nil { + panic(err) + } + */ return crypto.Keccak256Hash(enc.Bytes()) } @@ -142,29 +148,32 @@ type encodingAccountNonce struct { // encodingStorageWrite is the encoding format of StorageWrites. type encodingStorageWrite struct { - TxIdx uint16 `json:"txIndex"` - ValueAfter encodedStorage `json:"valueAfter"` + TxIdx uint16 `json:"txIndex"` + ValueAfter *EncodedStorage `json:"valueAfter"` } -// encodedStorage can represent either a storage key or value -type encodedStorage []byte +// EncodedStorage can represent either a storage key or value +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 { return common.Hash{} } - return common.BytesToHash(*e) + return e.inner.Bytes32() } -func newEncodedStorageFromHash(hash common.Hash) encodedStorage { - return bytes.TrimLeft(hash[:], "\x00") +func newEncodedStorageFromHash(hash common.Hash) *EncodedStorage { + return &EncodedStorage{ + new(uint256.Int).SetBytes(hash[:]), + } } -func (e *encodedStorage) FromHash(hash common.Hash) { - *e = hash[:] -} - -func (s *encodedStorage) UnmarshalJSON(b []byte) error { +func (s *EncodedStorage) UnmarshalJSON(b []byte) error { var str string if err := json.Unmarshal(b, &str); err != nil { return err @@ -190,34 +199,31 @@ func (s *encodedStorage) UnmarshalJSON(b []byte) error { // TODO: check is s == nil ?? should be programmer error - *s = make([]byte, len(val)-1) - copy((*s)[:len(val)-1], val[:]) + *s = EncodedStorage{ + inner: new(uint256.Int).SetBytes(val), + } return nil } -func (s encodedStorage) MarshalJSON() ([]byte, error) { - trimmed := bytes.TrimLeft(s[:], "\x00") - return json.Marshal("0x" + common.Bytes2Hex(trimmed)) +func (s EncodedStorage) MarshalJSON() ([]byte, error) { + return json.Marshal(s.inner.Hex()) } -func (s *encodedStorage) EncodeRLP(_w io.Writer) error { - var obj encodedStorage - if s != nil { - obj = *s +func (s *EncodedStorage) EncodeRLP(_w io.Writer) error { + return s.inner.EncodeRLP(_w) +} + +func (s *EncodedStorage) DecodeRLP(dec *rlp.Stream) error { + if s == nil { + *s = EncodedStorage{} } - trimmed := bytes.TrimLeft(obj[:], "\x00") - fmt.Println("here") - return rlp.Encode(_w, trimmed) -} - -func (s *encodedStorage) DecodeRLP(dec *rlp.Stream) error { - err := dec.ReadBytes((*s)[:]) - return err + s.inner = uint256.NewInt(0) + return dec.ReadUint256(s.inner) } // encodingStorageWrite is the encoding format of SlotWrites. type encodingSlotWrites struct { - Slot encodedStorage `json:"slot"` + Slot *EncodedStorage `json:"slot"` Accesses []encodingStorageWrite `json:"accesses"` } @@ -237,8 +243,8 @@ func (e *encodingSlotWrites) validate() error { // AccountAccess is the encoding format of ConstructionAccountAccesses. type AccountAccess struct { Address common.Address `json:"address,omitempty"` // 20-byte Ethereum address - StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // encodedStorage changes (slot -> [tx_index -> new_value]) - StorageReads []encodedStorage `json:"storageReads,omitempty"` // Read-only storage keys + StorageChanges []encodingSlotWrites `json:"storageChanges,omitempty"` // EncodedStorage changes (slot -> [tx_index -> new_value]) + StorageReads []*EncodedStorage `json:"storageReads,omitempty"` // Read-only storage keys BalanceChanges []encodingBalanceChange `json:"balanceChanges,omitempty"` // Balance changes ([tx_index -> post_balance]) NonceChanges []encodingAccountNonce `json:"nonceChanges,omitempty"` // Nonce changes ([tx_index -> new_nonce]) 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 - 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() return bytes.Compare(aHash[:], bHash[:]) }) { @@ -351,7 +357,7 @@ func (a *ConstructionAccountAccesses) toEncodingObj(addr common.Address) Account res := AccountAccess{ Address: addr, StorageChanges: make([]encodingSlotWrites, 0), - StorageReads: make([]encodedStorage, 0), + StorageReads: make([]*EncodedStorage, 0), BalanceChanges: make([]encodingBalanceChange, 0), NonceChanges: make([]encodingAccountNonce, 0), CodeChanges: make([]CodeChange, 0), diff --git a/core/types/bal/bal_encoding_rlp_generated.go b/core/types/bal/bal_encoding_rlp_generated.go index 442e5661ef..832996b4f0 100644 --- a/core/types/bal/bal_encoding_rlp_generated.go +++ b/core/types/bal/bal_encoding_rlp_generated.go @@ -14,12 +14,16 @@ func (obj *AccountAccess) EncodeRLP(_w io.Writer) error { _tmp1 := w.List() for _, _tmp2 := range obj.StorageChanges { _tmp3 := w.List() - w.WriteBytes(_tmp2.Slot) + if err := _tmp2.Slot.EncodeRLP(w); err != nil { + return err + } _tmp4 := w.List() for _, _tmp5 := range _tmp2.Accesses { _tmp6 := w.List() w.WriteUint64(uint64(_tmp5.TxIdx)) - w.WriteBytes(_tmp5.ValueAfter) + if err := _tmp5.ValueAfter.EncodeRLP(w); err != nil { + return err + } w.ListEnd(_tmp6) } w.ListEnd(_tmp4) @@ -28,7 +32,9 @@ func (obj *AccountAccess) EncodeRLP(_w io.Writer) error { w.ListEnd(_tmp1) _tmp7 := w.List() for _, _tmp8 := range obj.StorageReads { - w.WriteBytes(_tmp8) + if err := _tmp8.EncodeRLP(w); err != nil { + return err + } } w.ListEnd(_tmp7) _tmp9 := w.List() @@ -87,8 +93,8 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error { return err } // Slot: - _tmp4, err := dec.Bytes() - if err != nil { + _tmp4 := new(EncodedStorage) + if err := _tmp4.DecodeRLP(dec); err != nil { return err } _tmp3.Slot = _tmp4 @@ -110,8 +116,8 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error { } _tmp6.TxIdx = _tmp7 // ValueAfter: - _tmp8, err := dec.Bytes() - if err != nil { + _tmp8 := new(EncodedStorage) + if err := _tmp8.DecodeRLP(dec); err != nil { return err } _tmp6.ValueAfter = _tmp8 @@ -136,13 +142,13 @@ func (obj *AccountAccess) DecodeRLP(dec *rlp.Stream) error { } _tmp0.StorageChanges = _tmp2 // StorageReads: - var _tmp9 []encodedStorage + var _tmp9 []*EncodedStorage if _, err := dec.List(); err != nil { return err } for dec.MoreDataInList() { - _tmp10, err := dec.Bytes() - if err != nil { + _tmp10 := new(EncodedStorage) + if err := _tmp10.DecodeRLP(dec); err != nil { return err } _tmp9 = append(_tmp9, _tmp10) diff --git a/core/types/bal/bal_test.go b/core/types/bal/bal_test.go index 641087b04d..b359300c84 100644 --- a/core/types/bal/bal_test.go +++ b/core/types/bal/bal_test.go @@ -119,12 +119,12 @@ func makeTestAccountAccess(sort bool) AccountAccess { ) for i := 0; i < 5; i++ { slot := encodingSlotWrites{ - Slot: testrand.Hash(), + Slot: newEncodedStorageFromHash(testrand.Hash()), } for j := 0; j < 3; j++ { slot.Accesses = append(slot.Accesses, encodingStorageWrite{ TxIdx: uint16(2 * j), - ValueAfter: testrand.Hash(), + ValueAfter: newEncodedStorageFromHash(testrand.Hash()), }) } 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{ Address: [20]byte(testrand.Bytes(20)), StorageChanges: storageWrites, - StorageReads: storageReads, + StorageReads: encodedStorageReads, BalanceChanges: balances, NonceChanges: nonces, CodeChanges: []CodeChange{ @@ -216,7 +220,7 @@ func TestBlockAccessListCopy(t *testing.T) { // Make sure the mutations on copy won't affect the origin for _, aa := range cpyCpy { 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) { diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index ffea35a69f..df01467821 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -515,6 +515,7 @@ func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*eng if data == nil { return nil, engine.UnknownPayload } + return data, nil } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index eb912a5f21..0698e02677 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -22,12 +22,6 @@ import ( "encoding/hex" "encoding/json" "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/hexutil" "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/tracing" "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/log" "github.com/ethereum/go-ethereum/params" @@ -45,6 +40,11 @@ import ( "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/hashdb" "github.com/ethereum/go-ethereum/triedb/pathdb" + stdmath "math" + "math/big" + "os" + "reflect" + "strings" ) // 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) } } + + // 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: blocks := types.Blocks{cb} i, err := blockchain.InsertChain(blocks)