@@ -197,6 +197,9 @@ type BlockChainConfig struct {
197197 // If the value is -1, indexing is disabled.
198198 TxLookupLimit int64
199199
200+ // EnableBAL enables block access list creation and verification for post-Cancun blocks which contain access lists.
201+ EnableBAL bool
202+
200203 // StateSizeTracking indicates whether the state size tracking is enabled.
201204 StateSizeTracking bool
202205}
@@ -1905,9 +1908,17 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
19051908 if parent == nil {
19061909 parent = bc .GetHeader (block .ParentHash (), block .NumberU64 ()- 1 )
19071910 }
1911+
1912+ // construct or verify block access lists if BALs are enabled and
1913+ // we are post-selfdestruct removal fork.
1914+ enableBAL := (bc .cfg .EnableBAL && bc .chainConfig .IsCancun (block .Number (), block .Time ())) || bc .chainConfig .IsAmsterdam (block .Number (), block .Time ())
1915+ blockHasAccessList := block .Body ().AccessList != nil
1916+ makeBAL := enableBAL && ! blockHasAccessList
1917+ validateBAL := enableBAL && blockHasAccessList
1918+
19081919 // The traced section of block import.
19091920 start := time .Now ()
1910- res , err := bc .processBlock (parent .Root , block , setHead , makeWitness && len (chain ) == 1 )
1921+ res , err := bc .processBlock (parent .Root , block , setHead , makeWitness && len (chain ) == 1 , makeBAL , validateBAL )
19111922 if err != nil {
19121923 return nil , it .index , err
19131924 }
@@ -1975,7 +1986,7 @@ type blockProcessingResult struct {
19751986
19761987// processBlock executes and validates the given block. If there was no error
19771988// it writes the block and associated state to database.
1978- func (bc * BlockChain ) processBlock (parentRoot common.Hash , block * types.Block , setHead bool , makeWitness bool ) (_ * blockProcessingResult , blockEndErr error ) {
1989+ func (bc * BlockChain ) processBlock (parentRoot common.Hash , block * types.Block , setHead bool , makeWitness bool , constructBALForTesting bool , validateBAL bool ) (bpr * blockProcessingResult , blockEndErr error ) {
19791990 var (
19801991 err error
19811992 startTime = time .Now ()
@@ -2034,6 +2045,9 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
20342045 }(time .Now (), throwaway , block )
20352046 }
20362047
2048+ if constructBALForTesting {
2049+ statedb .EnableStateDiffRecording ()
2050+ }
20372051 // If we are past Byzantium, enable prefetching to pull in trie node paths
20382052 // while processing transactions. Before Byzantium the prefetcher is mostly
20392053 // useless due to the intermediate root hashing after each transaction.
@@ -2071,22 +2085,37 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s
20712085 }()
20722086 }
20732087
2088+ // Process block using the parent state as reference point
2089+ var sdb state.BlockProcessingDB = statedb
2090+ if constructBALForTesting {
2091+ sdb = state .NewBlockAccessListBuilder (statedb )
2092+ }
20742093 // Process block using the parent state as reference point
20752094 pstart := time .Now ()
2076- res , err := bc .processor .Process (block , statedb , bc .cfg .VmConfig )
2095+ res , err := bc .processor .Process (block , sdb , bc .cfg .VmConfig )
20772096 if err != nil {
20782097 bc .reportBlock (block , res , err )
20792098 return nil , err
20802099 }
20812100 ptime := time .Since (pstart )
20822101
20832102 vstart := time .Now ()
2084- if err := bc .validator .ValidateState (block , statedb , res , false ); err != nil {
2103+ if err := bc .validator .ValidateState (block , sdb , res , false ); err != nil {
20852104 bc .reportBlock (block , res , err )
20862105 return nil , err
20872106 }
20882107 vtime := time .Since (vstart )
20892108
2109+ if constructBALForTesting {
2110+ // very ugly... deep-copy the block body before setting the block access
2111+ // list on it to prevent mutating the block instance passed by the caller.
2112+ existingBody := block .Body ()
2113+ block = block .WithBody (* existingBody )
2114+ existingBody = block .Body ()
2115+ existingBody .AccessList = sdb .(* state.AccessListCreationDB ).ConstructedBlockAccessList ().ToEncodingObj ()
2116+ block = block .WithBody (* existingBody )
2117+ }
2118+
20902119 // If witnesses was generated and stateless self-validation requested, do
20912120 // that now. Self validation should *never* run in production, it's more of
20922121 // a tight integration to enable running *all* consensus tests through the
0 commit comments