@@ -56,6 +56,7 @@ import (
56
56
"github.com/ethereum/go-ethereum/triedb"
57
57
"github.com/ethereum/go-ethereum/triedb/hashdb"
58
58
"github.com/ethereum/go-ethereum/triedb/pathdb"
59
+ "golang.org/x/exp/slices"
59
60
)
60
61
61
62
var (
@@ -109,7 +110,6 @@ var (
109
110
)
110
111
111
112
const (
112
- << << << < HEAD
113
113
bodyCacheLimit = 256
114
114
blockCacheLimit = 256
115
115
diffLayerCacheLimit = 1024
@@ -127,13 +127,6 @@ const (
127
127
maxDiffForkDist = 11 // Maximum allowed backward distance from the chain head
128
128
129
129
rewindBadBlockInterval = 1 * time .Second
130
- == == == =
131
- bodyCacheLimit = 256
132
- blockCacheLimit = 256
133
- receiptsCacheLimit = 32
134
- txLookupCacheLimit = 1024
135
- TriesInMemory = 128
136
- >> >> >> > f4d53133f (consensus , cmd , core , eth : remove support for non - merge mode of operation (#29169 ))
137
130
138
131
// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
139
132
//
@@ -299,7 +292,6 @@ type BlockChain struct {
299
292
txLookupCache * lru.Cache [common.Hash , txLookup ]
300
293
sidecarsCache * lru.Cache [common.Hash , types.BlobSidecars ]
301
294
302
- << << << < HEAD
303
295
// future blocks are blocks added for later processing
304
296
futureBlocks * lru.Cache [common.Hash , * types.Block ]
305
297
// Cache for the blocks that failed to pass MPT root verification
@@ -312,8 +304,6 @@ type BlockChain struct {
312
304
diffQueueBuffer chan * types.DiffLayer
313
305
diffLayerFreezerBlockLimit uint64
314
306
315
- == == == =
316
- >> >> >> > f4d53133f (consensus , cmd , core , eth : remove support for non - merge mode of operation (#29169 ))
317
307
wg sync.WaitGroup
318
308
dbWg sync.WaitGroup
319
309
quit chan struct {} // shutdown signal, closed in Stop.
@@ -373,7 +363,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
373
363
*/
374
364
375
365
bc := & BlockChain {
376
- << << << < HEAD
377
366
chainConfig : chainConfig ,
378
367
cacheConfig : cacheConfig ,
379
368
db : db ,
@@ -396,22 +385,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
396
385
vmConfig : vmConfig ,
397
386
diffQueue : prque.New [int64 , * types.DiffLayer ](nil ),
398
387
diffQueueBuffer : make (chan * types.DiffLayer ),
399
- == == == =
400
- chainConfig : chainConfig ,
401
- cacheConfig : cacheConfig ,
402
- db : db ,
403
- triedb : triedb ,
404
- triegc : prque.New [int64 , common.Hash ](nil ),
405
- quit : make (chan struct {}),
406
- chainmu : syncx .NewClosableMutex (),
407
- bodyCache: lru .NewCache [common.Hash , * types.Body ](bodyCacheLimit ),
408
- bodyRLPCache: lru .NewCache [common.Hash , rlp.RawValue ](bodyCacheLimit ),
409
- receiptsCache: lru .NewCache [common.Hash , []* types.Receipt ](receiptsCacheLimit ),
410
- blockCache: lru .NewCache [common.Hash , * types.Block ](blockCacheLimit ),
411
- txLookupCache: lru .NewCache [common.Hash , txLookup ](txLookupCacheLimit ),
412
- engine : engine ,
413
- vmConfig : vmConfig ,
414
- >> >> >> > f4d53133f (consensus , cmd , core , eth : remove support for non - merge mode of operation (#29169 ))
415
388
}
416
389
bc .flushInterval .Store (int64 (cacheConfig .TrieTimeLimit ))
417
390
bc .forker = NewForkChoice (bc , shouldPreserve )
@@ -577,7 +550,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
577
550
return nil , err
578
551
}
579
552
}
580
- << << << < HEAD
581
553
// Start future block processor.
582
554
bc .wg .Add (1 )
583
555
go bc .updateFutureBlocks ()
@@ -598,8 +570,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
598
570
go bc .startDoubleSignMonitor ()
599
571
}
600
572
601
- == == == =
602
- >> >> >> > f4d53133f (consensus , cmd , core , eth : remove support for non - merge mode of operation (#29169 ))
603
573
// Rewind the chain in case of an incompatible config upgrade.
604
574
if compat , ok := genesisErr .(* params.ConfigCompatError ); ok {
605
575
log .Warn ("Rewinding chain to upgrade configuration" , "err" , compat )
@@ -1187,6 +1157,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
1187
1157
bc .sidecarsCache .Purge ()
1188
1158
bc .blockCache .Purge ()
1189
1159
bc .txLookupCache .Purge ()
1160
+ bc .futureBlocks .Purge ()
1190
1161
1191
1162
if finalized := bc .CurrentFinalBlock (); finalized != nil && head < finalized .Number .Uint64 () {
1192
1163
log .Error ("SetHead invalidated finalized block" )
@@ -1474,6 +1445,24 @@ func (bc *BlockChain) insertStopped() bool {
1474
1445
return bc .procInterrupt .Load ()
1475
1446
}
1476
1447
1448
+ func (bc * BlockChain ) procFutureBlocks () {
1449
+ blocks := make ([]* types.Block , 0 , bc .futureBlocks .Len ())
1450
+ for _ , hash := range bc .futureBlocks .Keys () {
1451
+ if block , exist := bc .futureBlocks .Peek (hash ); exist {
1452
+ blocks = append (blocks , block )
1453
+ }
1454
+ }
1455
+ if len (blocks ) > 0 {
1456
+ slices .SortFunc (blocks , func (a , b * types.Block ) int {
1457
+ return a .Number ().Cmp (b .Number ())
1458
+ })
1459
+ // Insert one by one as chain insertion needs contiguous ancestry between blocks
1460
+ for i := range blocks {
1461
+ bc .InsertChain (blocks [i : i + 1 ])
1462
+ }
1463
+ }
1464
+ }
1465
+
1477
1466
// WriteStatus status of write
1478
1467
type WriteStatus byte
1479
1468
@@ -1970,6 +1959,8 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types
1970
1959
if status == CanonStatTy {
1971
1960
bc .writeHeadBlock (block )
1972
1961
}
1962
+ bc .futureBlocks .Remove (block .Hash ())
1963
+
1973
1964
if status == CanonStatTy {
1974
1965
bc .chainFeed .Send (ChainEvent {Block : block , Hash : block .Hash (), Logs : logs })
1975
1966
if len (logs ) > 0 {
@@ -1998,6 +1989,25 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types
1998
1989
return status , nil
1999
1990
}
2000
1991
1992
+ // addFutureBlock checks if the block is within the max allowed window to get
1993
+ // accepted for future processing, and returns an error if the block is too far
1994
+ // ahead and was not added.
1995
+ //
1996
+ // TODO after the transition, the future block shouldn't be kept. Because
1997
+ // it's not checked in the Geth side anymore.
1998
+ func (bc * BlockChain ) addFutureBlock (block * types.Block ) error {
1999
+ max := uint64 (time .Now ().Unix () + maxTimeFutureBlocks )
2000
+ if block .Time () > max {
2001
+ return fmt .Errorf ("future block timestamp %v > allowed %v" , block .Time (), max )
2002
+ }
2003
+ if block .Difficulty ().Cmp (common .Big0 ) == 0 {
2004
+ // Never add PoS blocks into the future queue
2005
+ return nil
2006
+ }
2007
+ bc .futureBlocks .Add (block .Hash (), block )
2008
+ return nil
2009
+ }
2010
+
2001
2011
// InsertChain attempts to insert the given batch of blocks in to the canonical
2002
2012
// chain or, otherwise, create a fork. If an error is returned it will return
2003
2013
// the index number of the failing block as well an error describing what went
@@ -2152,10 +2162,26 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
2152
2162
_ , err := bc .recoverAncestors (block )
2153
2163
return it .index , err
2154
2164
}
2165
+ // First block is future, shove it (and all children) to the future queue (unknown ancestor)
2166
+ case errors .Is (err , consensus .ErrFutureBlock ) || (errors .Is (err , consensus .ErrUnknownAncestor ) && bc .futureBlocks .Contains (it .first ().ParentHash ())):
2167
+ for block != nil && (it .index == 0 || errors .Is (err , consensus .ErrUnknownAncestor )) {
2168
+ log .Debug ("Future block, postponing import" , "number" , block .Number (), "hash" , block .Hash ())
2169
+ if err := bc .addFutureBlock (block ); err != nil {
2170
+ return it .index , err
2171
+ }
2172
+ block , err = it .next ()
2173
+ }
2174
+ stats .queued += it .processed ()
2175
+ stats .ignored += it .remaining ()
2176
+
2177
+ // If there are any still remaining, mark as ignored
2178
+ return it .index , err
2179
+
2155
2180
// Some other error(except ErrKnownBlock) occurred, abort.
2156
2181
// ErrKnownBlock is allowed here since some known blocks
2157
2182
// still need re-execution to generate snapshots that are missing
2158
2183
case err != nil && ! errors .Is (err , ErrKnownBlock ):
2184
+ bc .futureBlocks .Remove (block .Hash ())
2159
2185
stats .ignored += len (it .chain )
2160
2186
bc .reportBlock (block , nil , err )
2161
2187
return it .index , err
@@ -2354,7 +2380,23 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
2354
2380
}
2355
2381
bc .chainBlockFeed .Send (ChainHeadEvent {block })
2356
2382
}
2383
+
2384
+ // Any blocks remaining here? The only ones we care about are the future ones
2385
+ if block != nil && errors .Is (err , consensus .ErrFutureBlock ) {
2386
+ if err := bc .addFutureBlock (block ); err != nil {
2387
+ return it .index , err
2388
+ }
2389
+ block , err = it .next ()
2390
+
2391
+ for ; block != nil && errors .Is (err , consensus .ErrUnknownAncestor ); block , err = it .next () {
2392
+ if err := bc .addFutureBlock (block ); err != nil {
2393
+ return it .index , err
2394
+ }
2395
+ stats .queued ++
2396
+ }
2397
+ }
2357
2398
stats .ignored += it .remaining ()
2399
+
2358
2400
return it .index , err
2359
2401
}
2360
2402
@@ -2833,7 +2875,6 @@ func (bc *BlockChain) SetCanonical(head *types.Block) (common.Hash, error) {
2833
2875
return head .Hash (), nil
2834
2876
}
2835
2877
2836
- << << << < HEAD
2837
2878
func (bc * BlockChain ) updateFutureBlocks () {
2838
2879
futureTimer := time .NewTicker (5 * time .Second )
2839
2880
defer futureTimer .Stop ()
@@ -2960,8 +3001,6 @@ func (bc *BlockChain) startDoubleSignMonitor() {
2960
3001
}
2961
3002
}
2962
3003
2963
- == == == =
2964
- >> >> >> > f4d53133f (consensus , cmd , core , eth : remove support for non - merge mode of operation (#29169 ))
2965
3004
// skipBlock returns 'true', if the block being imported can be skipped over, meaning
2966
3005
// that the block does not need to be processed but can be considered already fully 'done'.
2967
3006
func (bc * BlockChain ) skipBlock (err error , it * insertIterator ) bool {
0 commit comments