diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 25f4f9d2b2..d01aa75ee4 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -282,6 +282,12 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa if !amsterdam && header.SlotNumber != nil { return fmt.Errorf("invalid slotNumber: have %d, expected nil", *header.SlotNumber) } + if amsterdam && header.BlockAccessListHash == nil { + return errors.New("header is missing block access list hash") + } + if !amsterdam && header.BlockAccessListHash != nil { + return fmt.Errorf("invalid block access list hash: have %x, expected nil", header.BlockAccessListHash) + } return nil } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index bf6b8aaf80..f101bb150b 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -606,15 +606,15 @@ func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { } } -// HasBAL verifies the existence of a block access list for a block. -func HasBAL(db ethdb.Reader, hash common.Hash, number uint64) bool { - return len(ReadBALRLP(db, hash, number)) > 0 +// HasAccessList verifies the existence of a block access list for a block. +func HasAccessList(db ethdb.Reader, hash common.Hash, number uint64) bool { + return len(ReadAccessListRLP(db, hash, number)) > 0 } -// ReadBALRLP retrieves the RLP-encoded block access list for a block. -func ReadBALRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { +// ReadAccessListRLP retrieves the RLP-encoded block access list for a block. +func ReadAccessListRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { var data []byte - db.ReadAncients(func(reader ethdb.AncientReaderOp) error { + err := db.ReadAncients(func(reader ethdb.AncientReaderOp) error { if isCanon(reader, number, hash) { data, _ = reader.Ancient(ChainFreezerBALTable, number) return nil @@ -622,12 +622,15 @@ func ReadBALRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { data, _ = db.Get(balKey(number, hash)) return nil }) + if err != nil { + log.Crit("error reading from ancient store", "err", err) + } return data } -// ReadCanonicalBALRLP retrieves the BAL RLP for the canonical block at number. +// ReadCanonicalAccessListRLP retrieves the BAL RLP for the canonical block at number. // Optionally takes the block hash to avoid looking it up. -func ReadCanonicalBALRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp.RawValue { +func ReadCanonicalAccessListRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp.RawValue { var data []byte db.ReadAncients(func(reader ethdb.AncientReaderOp) error { data, _ = reader.Ancient(ChainFreezerBALTable, number) @@ -646,9 +649,9 @@ func ReadCanonicalBALRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp. return data } -// ReadBAL retrieves and decodes the block access list for a block. -func ReadBAL(db ethdb.Reader, hash common.Hash, number uint64) *bal.BlockAccessList { - data := ReadBALRLP(db, hash, number) +// ReadAccessList retrieves and decodes the block access list for a block. +func ReadAccessList(db ethdb.Reader, hash common.Hash, number uint64) *bal.BlockAccessList { + data := ReadAccessListRLP(db, hash, number) if len(data) == 0 { return nil } @@ -660,26 +663,24 @@ func ReadBAL(db ethdb.Reader, hash common.Hash, number uint64) *bal.BlockAccessL return b } -// WriteBAL RLP-encodes and stores a block access list in the active KV store. -func WriteBAL(db ethdb.KeyValueWriter, hash common.Hash, number uint64, b *bal.BlockAccessList) { +// WriteAccessList RLP-encodes and stores a block access list in the active KV store. +func WriteAccessList(db ethdb.KeyValueWriter, hash common.Hash, number uint64, b *bal.BlockAccessList) { bytes, err := rlp.EncodeToBytes(b) if err != nil { log.Crit("Failed to encode BAL", "err", err) } - if err := db.Put(balKey(number, hash), bytes); err != nil { - log.Crit("Failed to store BAL", "err", err) - } + WriteAccessListRLP(db, hash, number, bytes) } -// WriteBALRLP stores a pre-encoded block access list in the active KV store. -func WriteBALRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, encoded rlp.RawValue) { +// WriteAccessListRLP stores a pre-encoded block access list in the active KV store. +func WriteAccessListRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, encoded rlp.RawValue) { if err := db.Put(balKey(number, hash), encoded); err != nil { log.Crit("Failed to store BAL", "err", err) } } -// DeleteBAL removes a block access list from the active KV store. -func DeleteBAL(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { +// DeleteAccessList removes a block access list from the active KV store. +func DeleteAccessList(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { if err := db.Delete(balKey(number, hash)); err != nil { log.Crit("Failed to delete BAL", "err", err) } @@ -739,13 +740,23 @@ func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { if body == nil { return nil } - return types.NewBlockWithHeader(header).WithBody(*body) + block := types.NewBlockWithHeader(header).WithBody(*body) + if header.BlockAccessListHash != nil { + accessList := ReadAccessList(db, hash, number) + if accessList != nil { + block = block.WithAccessList(accessList) + } + } + return block } // WriteBlock serializes a block into the database, header and body separately. func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) WriteHeader(db, block.Header()) + if block.AccessList() != nil { + WriteAccessList(db, block.Hash(), block.NumberU64(), block.AccessList()) + } } // WriteAncientBlocks writes entire block data into ancient store and returns the total written size. @@ -815,7 +826,7 @@ func WriteAncientHeaderChain(db ethdb.AncientWriter, headers []*types.Header) (i // DeleteBlock removes all block data associated with a hash. func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { DeleteReceipts(db, hash, number) - DeleteBAL(db, hash, number) + DeleteAccessList(db, hash, number) DeleteHeader(db, hash, number) DeleteBody(db, hash, number) } @@ -824,7 +835,7 @@ func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { // the hash to number mapping. func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { DeleteReceipts(db, hash, number) - DeleteBAL(db, hash, number) + DeleteAccessList(db, hash, number) deleteHeaderWithoutNumber(db, hash, number) DeleteBody(db, hash, number) } diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 37253dceb7..27413bb40a 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -934,45 +934,45 @@ func TestBALStorage(t *testing.T) { number := uint64(42) // Check that no BAL exists in a new database. - if HasBAL(db, hash, number) { + if HasAccessList(db, hash, number) { t.Fatal("BAL found in new database") } - if b := ReadBAL(db, hash, number); b != nil { + if b := ReadAccessList(db, hash, number); b != nil { t.Fatalf("non existent BAL returned: %v", b) } // Write a BAL and verify it can be read back. encoded, testBAL := makeTestBAL(t) - WriteBAL(db, hash, number, testBAL) + WriteAccessList(db, hash, number, testBAL) - if !HasBAL(db, hash, number) { - t.Fatal("HasBAL returned false after write") + if !HasAccessList(db, hash, number) { + t.Fatal("HasAccessList returned false after write") } - if blob := ReadBALRLP(db, hash, number); len(blob) == 0 { - t.Fatal("ReadBALRLP returned empty after write") + if blob := ReadAccessListRLP(db, hash, number); len(blob) == 0 { + t.Fatal("ReadAccessListRLP returned empty after write") } - if b := ReadBAL(db, hash, number); b == nil { - t.Fatal("ReadBAL returned nil after write") + if b := ReadAccessList(db, hash, number); b == nil { + t.Fatal("ReadAccessList returned nil after write") } else if b.Hash() != testBAL.Hash() { t.Fatalf("BAL hash mismatch: got %x, want %x", b.Hash(), testBAL.Hash()) } - // Also test WriteBALRLP with pre-encoded data. + // Also test WriteAccessListRLP with pre-encoded data. hash2 := common.BytesToHash([]byte{0x03, 0x15}) - WriteBALRLP(db, hash2, number, encoded) - if b := ReadBAL(db, hash2, number); b == nil { - t.Fatal("ReadBAL returned nil after WriteBALRLP") + WriteAccessListRLP(db, hash2, number, encoded) + if b := ReadAccessList(db, hash2, number); b == nil { + t.Fatal("ReadAccessList returned nil after WriteAccessListRLP") } else if b.Hash() != testBAL.Hash() { - t.Fatalf("BAL hash mismatch after WriteBALRLP: got %x, want %x", b.Hash(), testBAL.Hash()) + t.Fatalf("BAL hash mismatch after WriteAccessListRLP: got %x, want %x", b.Hash(), testBAL.Hash()) } // Delete the BAL and verify it's gone. - DeleteBAL(db, hash, number) + DeleteAccessList(db, hash, number) - if HasBAL(db, hash, number) { - t.Fatal("HasBAL returned true after delete") + if HasAccessList(db, hash, number) { + t.Fatal("HasAccessList returned true after delete") } - if b := ReadBAL(db, hash, number); b != nil { + if b := ReadAccessList(db, hash, number); b != nil { t.Fatalf("deleted BAL returned: %v", b) } } @@ -998,7 +998,7 @@ func TestBALFreezer(t *testing.T) { hash, number := block.Hash(), block.NumberU64() // Verify no BAL exists before writing. - if blob := ReadBALRLP(db, hash, number); len(blob) > 0 { + if blob := ReadAccessListRLP(db, hash, number); len(blob) > 0 { t.Fatalf("non existent BAL returned") } @@ -1009,18 +1009,18 @@ func TestBALFreezer(t *testing.T) { WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil}), []rlp.RawValue{balRLP}) // Verify the BAL can be read from the freezer. - if blob := ReadBALRLP(db, hash, number); len(blob) == 0 { + if blob := ReadAccessListRLP(db, hash, number); len(blob) == 0 { t.Fatal("no BAL returned from freezer") } - if b := ReadBAL(db, hash, number); b == nil { - t.Fatal("ReadBAL returned nil from freezer") + if b := ReadAccessList(db, hash, number); b == nil { + t.Fatal("ReadAccessList returned nil from freezer") } else if b.Hash() != testBAL.Hash() { t.Fatalf("frozen BAL hash mismatch: got %x, want %x", b.Hash(), testBAL.Hash()) } - // Verify ReadCanonicalBALRLP works. - if blob := ReadCanonicalBALRLP(db, number, &hash); len(blob) == 0 { - t.Fatal("ReadCanonicalBALRLP returned empty for frozen block") + // Verify ReadCanonicalAccessListRLP works. + if blob := ReadCanonicalAccessListRLP(db, number, &hash); len(blob) == 0 { + t.Fatal("ReadCanonicalAccessListRLP returned empty for frozen block") } } @@ -1046,11 +1046,11 @@ func TestBALEmptyFreezer(t *testing.T) { WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil}), nil) - // HasBAL should return false for a block with an empty freezer entry. - if HasBAL(db, hash, number) { - t.Fatal("HasBAL returned true for block with no BAL") + // HasAccessList should return false for a block with an empty freezer entry. + if HasAccessList(db, hash, number) { + t.Fatal("HasAccessList returned true for block with no BAL") } - if b := ReadBAL(db, hash, number); b != nil { - t.Fatalf("ReadBAL returned non-nil for block with no BAL: %v", b) + if b := ReadAccessList(db, hash, number); b != nil { + t.Fatalf("ReadAccessList returned non-nil for block with no BAL: %v", b) } } diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index f7d3c75343..917014ec5d 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -327,7 +327,7 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash if len(receipts) == 0 { return fmt.Errorf("block receipts missing, can't freeze block %d", number) } - bal := ReadBALRLP(nfdb, hash, number) + bal := ReadAccessListRLP(nfdb, hash, number) // Write to the batch. if err := op.AppendRaw(ChainFreezerHashTable, number, hash[:]); err != nil { return fmt.Errorf("can't write hash to Freezer: %v", err) diff --git a/core/types/block.go b/core/types/block.go index d092351b58..aee7f8752a 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -21,6 +21,7 @@ import ( "crypto/sha256" "encoding/binary" "fmt" + "github.com/ethereum/go-ethereum/core/types/bal" "io" "math/big" "reflect" @@ -99,23 +100,27 @@ type Header struct { // RequestsHash was added by EIP-7685 and is ignored in legacy headers. RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` + // BlockAccessListHash was added by EIP-7928 and is ignored in legacy headers. + BlockAccessListHash *common.Hash `json:"balHash" rlp:"optional"` + // SlotNumber was added by EIP-7843 and is ignored in legacy headers. SlotNumber *uint64 `json:"slotNumber" rlp:"optional"` } // field type overrides for gencodec type headerMarshaling struct { - Difficulty *hexutil.Big - Number *hexutil.Big - GasLimit hexutil.Uint64 - GasUsed hexutil.Uint64 - Time hexutil.Uint64 - Extra hexutil.Bytes - BaseFee *hexutil.Big - Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON - BlobGasUsed *hexutil.Uint64 - ExcessBlobGas *hexutil.Uint64 - SlotNumber *hexutil.Uint64 + Difficulty *hexutil.Big + Number *hexutil.Big + GasLimit hexutil.Uint64 + GasUsed hexutil.Uint64 + Time hexutil.Uint64 + Extra hexutil.Bytes + BaseFee *hexutil.Big + Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON + BlobGasUsed *hexutil.Uint64 + ExcessBlobGas *hexutil.Uint64 + BlockAccessListHash *common.Hash + SlotNumber *hexutil.Uint64 } // Hash returns the block hash of the header, which is simply the keccak256 hash of its @@ -204,6 +209,7 @@ type Block struct { uncles []*Header transactions Transactions withdrawals Withdrawals + accessList *bal.BlockAccessList // caches hash atomic.Pointer[common.Hash] @@ -358,9 +364,10 @@ func (b *Block) Body() *Body { // Accessors for body data. These do not return a copy because the content // of the body slices does not affect the cached hash/size in block. -func (b *Block) Uncles() []*Header { return b.uncles } -func (b *Block) Transactions() Transactions { return b.transactions } -func (b *Block) Withdrawals() Withdrawals { return b.withdrawals } +func (b *Block) Uncles() []*Header { return b.uncles } +func (b *Block) Transactions() Transactions { return b.transactions } +func (b *Block) Withdrawals() Withdrawals { return b.withdrawals } +func (b *Block) AccessList() *bal.BlockAccessList { return b.accessList } func (b *Block) Transaction(hash common.Hash) *Transaction { for _, transaction := range b.transactions { @@ -513,6 +520,24 @@ func (b *Block) WithBody(body Body) *Block { return block } +// WithAccessList returns a copy of the block with the given access list embedded. +func (b *Block) WithAccessList(accessList *bal.BlockAccessList) *Block { + alCopy := accessList.Copy() + alHash := accessList.Hash() + b.header.BlockAccessListHash = &alHash + block := &Block{ + header: b.header, + transactions: slices.Clone(b.transactions), + uncles: make([]*Header, len(b.uncles)), + withdrawals: slices.Clone(b.withdrawals), + accessList: &alCopy, + } + for i := range b.uncles { + block.uncles[i] = CopyHeader(b.uncles[i]) + } + return block +} + // Hash returns the keccak256 hash of b's header. // The hash is computed on the first call and cached thereafter. func (b *Block) Hash() common.Hash { diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index 16fb03f612..2e2f1cdca5 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -16,29 +16,30 @@ var _ = (*headerMarshaling)(nil) // MarshalJSON marshals as JSON. func (h Header) MarshalJSON() ([]byte, error) { type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` - ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` - RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` - SlotNumber *hexutil.Uint64 `json:"slotNumber" rlp:"optional"` - Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce BlockNonce `json:"nonce"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` + ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` + RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` + BlockAccessListHash *common.Hash `json:"balHash" rlp:"optional"` + SlotNumber *hexutil.Uint64 `json:"slotNumber" rlp:"optional"` + Hash common.Hash `json:"hash"` } var enc Header enc.ParentHash = h.ParentHash @@ -62,6 +63,7 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.ExcessBlobGas = (*hexutil.Uint64)(h.ExcessBlobGas) enc.ParentBeaconRoot = h.ParentBeaconRoot enc.RequestsHash = h.RequestsHash + enc.BlockAccessListHash = h.BlockAccessListHash enc.SlotNumber = (*hexutil.Uint64)(h.SlotNumber) enc.Hash = h.Hash() return json.Marshal(&enc) @@ -70,28 +72,29 @@ func (h Header) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (h *Header) UnmarshalJSON(input []byte) error { type Header struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner"` - Root *common.Hash `json:"stateRoot" gencodec:"required"` - TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest *common.Hash `json:"mixHash"` - Nonce *BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` - ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` - RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` - SlotNumber *hexutil.Uint64 `json:"slotNumber" rlp:"optional"` + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase *common.Address `json:"miner"` + Root *common.Hash `json:"stateRoot" gencodec:"required"` + TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom *Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest *common.Hash `json:"mixHash"` + Nonce *BlockNonce `json:"nonce"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` + ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` + RequestsHash *common.Hash `json:"requestsHash" rlp:"optional"` + BlockAccessListHash *common.Hash `json:"balHash" rlp:"optional"` + SlotNumber *hexutil.Uint64 `json:"slotNumber" rlp:"optional"` } var dec Header if err := json.Unmarshal(input, &dec); err != nil { @@ -172,6 +175,9 @@ func (h *Header) UnmarshalJSON(input []byte) error { if dec.RequestsHash != nil { h.RequestsHash = dec.RequestsHash } + if dec.BlockAccessListHash != nil { + h.BlockAccessListHash = dec.BlockAccessListHash + } if dec.SlotNumber != nil { h.SlotNumber = (*uint64)(dec.SlotNumber) } diff --git a/core/types/gen_header_rlp.go b/core/types/gen_header_rlp.go index cfbd57ab8a..3b7eb2c926 100644 --- a/core/types/gen_header_rlp.go +++ b/core/types/gen_header_rlp.go @@ -43,8 +43,9 @@ func (obj *Header) EncodeRLP(_w io.Writer) error { _tmp4 := obj.ExcessBlobGas != nil _tmp5 := obj.ParentBeaconRoot != nil _tmp6 := obj.RequestsHash != nil - _tmp7 := obj.SlotNumber != nil - if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 { + _tmp7 := obj.BlockAccessListHash != nil + _tmp8 := obj.SlotNumber != nil + if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { if obj.BaseFee == nil { w.Write(rlp.EmptyString) } else { @@ -54,42 +55,49 @@ func (obj *Header) EncodeRLP(_w io.Writer) error { w.WriteBigInt(obj.BaseFee) } } - if _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 { + if _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { if obj.WithdrawalsHash == nil { w.Write([]byte{0x80}) } else { w.WriteBytes(obj.WithdrawalsHash[:]) } } - if _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 { + if _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { if obj.BlobGasUsed == nil { w.Write([]byte{0x80}) } else { w.WriteUint64((*obj.BlobGasUsed)) } } - if _tmp4 || _tmp5 || _tmp6 || _tmp7 { + if _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { if obj.ExcessBlobGas == nil { w.Write([]byte{0x80}) } else { w.WriteUint64((*obj.ExcessBlobGas)) } } - if _tmp5 || _tmp6 || _tmp7 { + if _tmp5 || _tmp6 || _tmp7 || _tmp8 { if obj.ParentBeaconRoot == nil { w.Write([]byte{0x80}) } else { w.WriteBytes(obj.ParentBeaconRoot[:]) } } - if _tmp6 || _tmp7 { + if _tmp6 || _tmp7 || _tmp8 { if obj.RequestsHash == nil { w.Write([]byte{0x80}) } else { w.WriteBytes(obj.RequestsHash[:]) } } - if _tmp7 { + if _tmp7 || _tmp8 { + if obj.BlockAccessListHash == nil { + w.Write([]byte{0x80}) + } else { + w.WriteBytes(obj.BlockAccessListHash[:]) + } + } + if _tmp8 { if obj.SlotNumber == nil { w.Write([]byte{0x80}) } else {