@@ -26,6 +26,7 @@ import (
2626 "github.com/ethereum/go-ethereum/common"
2727 "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
2828 "github.com/ethereum/go-ethereum/core/types"
29+ "github.com/ethereum/go-ethereum/core/types/bal"
2930 "github.com/ethereum/go-ethereum/crypto"
3031 "github.com/ethereum/go-ethereum/ethdb"
3132 "github.com/ethereum/go-ethereum/log"
@@ -605,6 +606,55 @@ func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
605606 }
606607}
607608
609+ // HasAccessList verifies the existence of a block access list for a block.
610+ func HasAccessList (db ethdb.Reader , hash common.Hash , number uint64 ) bool {
611+ has , _ := db .Has (accessListKey (number , hash ))
612+ return has
613+ }
614+
615+ // ReadAccessListRLP retrieves the RLP-encoded block access list for a block from KV.
616+ func ReadAccessListRLP (db ethdb.Reader , hash common.Hash , number uint64 ) rlp.RawValue {
617+ data , _ := db .Get (accessListKey (number , hash ))
618+ return data
619+ }
620+
621+ // ReadAccessList retrieves and decodes the block access list for a block.
622+ func ReadAccessList (db ethdb.Reader , hash common.Hash , number uint64 ) * bal.BlockAccessList {
623+ data := ReadAccessListRLP (db , hash , number )
624+ if len (data ) == 0 {
625+ return nil
626+ }
627+ b := new (bal.BlockAccessList )
628+ if err := rlp .DecodeBytes (data , b ); err != nil {
629+ log .Error ("Invalid BAL RLP" , "hash" , hash , "err" , err )
630+ return nil
631+ }
632+ return b
633+ }
634+
635+ // WriteAccessList RLP-encodes and stores a block access list in the active KV store.
636+ func WriteAccessList (db ethdb.KeyValueWriter , hash common.Hash , number uint64 , b * bal.BlockAccessList ) {
637+ bytes , err := rlp .EncodeToBytes (b )
638+ if err != nil {
639+ log .Crit ("Failed to encode BAL" , "err" , err )
640+ }
641+ WriteAccessListRLP (db , hash , number , bytes )
642+ }
643+
644+ // WriteAccessListRLP stores a pre-encoded block access list in the active KV store.
645+ func WriteAccessListRLP (db ethdb.KeyValueWriter , hash common.Hash , number uint64 , encoded rlp.RawValue ) {
646+ if err := db .Put (accessListKey (number , hash ), encoded ); err != nil {
647+ log .Crit ("Failed to store BAL" , "err" , err )
648+ }
649+ }
650+
651+ // DeleteAccessList removes a block access list from the active KV store.
652+ func DeleteAccessList (db ethdb.KeyValueWriter , hash common.Hash , number uint64 ) {
653+ if err := db .Delete (accessListKey (number , hash )); err != nil {
654+ log .Crit ("Failed to delete BAL" , "err" , err )
655+ }
656+ }
657+
608658// ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
609659// the list of logs. When decoding a stored receipt into this object we
610660// avoid creating the bloom filter.
@@ -659,13 +709,25 @@ func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
659709 if body == nil {
660710 return nil
661711 }
662- return types .NewBlockWithHeader (header ).WithBody (* body )
712+ block := types .NewBlockWithHeader (header ).WithBody (* body )
713+
714+ // Best-effort assembly of the block access list from the database.
715+ if header .BlockAccessListHash != nil {
716+ al := ReadAccessList (db , hash , number )
717+ block = block .WithAccessListUnsafe (al )
718+ }
719+ return block
663720}
664721
665722// WriteBlock serializes a block into the database, header and body separately.
666723func WriteBlock (db ethdb.KeyValueWriter , block * types.Block ) {
667- WriteBody (db , block .Hash (), block .NumberU64 (), block .Body ())
724+ hash , number := block .Hash (), block .NumberU64 ()
725+ WriteBody (db , hash , number , block .Body ())
668726 WriteHeader (db , block .Header ())
727+
728+ if accessList := block .AccessList (); accessList != nil {
729+ WriteAccessList (db , hash , number , accessList )
730+ }
669731}
670732
671733// WriteAncientBlocks writes entire block data into ancient store and returns the total written size.
0 commit comments