@@ -47,9 +47,10 @@ import (
47
47
)
48
48
49
49
var (
50
- headBlockGauge = metrics .NewRegisteredGauge ("chain/head/block" , nil )
51
- headHeaderGauge = metrics .NewRegisteredGauge ("chain/head/header" , nil )
52
- headFastBlockGauge = metrics .NewRegisteredGauge ("chain/head/receipt" , nil )
50
+ headBlockGauge = metrics .NewRegisteredGauge ("chain/head/block" , nil )
51
+ headHeaderGauge = metrics .NewRegisteredGauge ("chain/head/header" , nil )
52
+ headFastBlockGauge = metrics .NewRegisteredGauge ("chain/head/receipt" , nil )
53
+ headFinalizedBlockGauge = metrics .NewRegisteredGauge ("chain/head/finalized" , nil )
53
54
54
55
accountReadTimer = metrics .NewRegisteredTimer ("chain/account/reads" , nil )
55
56
accountHashTimer = metrics .NewRegisteredTimer ("chain/account/hashes" , nil )
@@ -187,8 +188,9 @@ type BlockChain struct {
187
188
// Readers don't need to take it, they can just read the database.
188
189
chainmu * syncx.ClosableMutex
189
190
190
- currentBlock atomic.Value // Current head of the block chain
191
- currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
191
+ currentBlock atomic.Value // Current head of the block chain
192
+ currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
193
+ currentFinalizedBlock atomic.Value // Current finalized head
192
194
193
195
stateCache state.Database // State database to reuse between imports (contains state cache)
194
196
bodyCache * lru.Cache // Cache for the most recent block bodies
@@ -264,6 +266,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
264
266
var nilBlock * types.Block
265
267
bc .currentBlock .Store (nilBlock )
266
268
bc .currentFastBlock .Store (nilBlock )
269
+ bc .currentFinalizedBlock .Store (nilBlock )
267
270
268
271
// Initialize the chain with ancient data if it isn't empty.
269
272
var txIndexBlock uint64
@@ -460,8 +463,17 @@ func (bc *BlockChain) loadLastState() error {
460
463
headFastBlockGauge .Update (int64 (block .NumberU64 ()))
461
464
}
462
465
}
466
+
467
+ // Restore the last known finalized block
468
+ if head := rawdb .ReadFinalizedBlockHash (bc .db ); head != (common.Hash {}) {
469
+ if block := bc .GetBlockByHash (head ); block != nil {
470
+ bc .currentFinalizedBlock .Store (block )
471
+ headFinalizedBlockGauge .Update (int64 (block .NumberU64 ()))
472
+ }
473
+ }
463
474
// Issue a status log for the user
464
475
currentFastBlock := bc .CurrentFastBlock ()
476
+ currentFinalizedBlock := bc .CurrentFinalizedBlock ()
465
477
466
478
headerTd := bc .GetTd (currentHeader .Hash (), currentHeader .Number .Uint64 ())
467
479
blockTd := bc .GetTd (currentBlock .Hash (), currentBlock .NumberU64 ())
@@ -470,6 +482,11 @@ func (bc *BlockChain) loadLastState() error {
470
482
log .Info ("Loaded most recent local header" , "number" , currentHeader .Number , "hash" , currentHeader .Hash (), "td" , headerTd , "age" , common .PrettyAge (time .Unix (int64 (currentHeader .Time ), 0 )))
471
483
log .Info ("Loaded most recent local full block" , "number" , currentBlock .Number (), "hash" , currentBlock .Hash (), "td" , blockTd , "age" , common .PrettyAge (time .Unix (int64 (currentBlock .Time ()), 0 )))
472
484
log .Info ("Loaded most recent local fast block" , "number" , currentFastBlock .Number (), "hash" , currentFastBlock .Hash (), "td" , fastTd , "age" , common .PrettyAge (time .Unix (int64 (currentFastBlock .Time ()), 0 )))
485
+
486
+ if currentFinalizedBlock != nil {
487
+ finalTd := bc .GetTd (currentFinalizedBlock .Hash (), currentFinalizedBlock .NumberU64 ())
488
+ log .Info ("Loaded most recent local finalized block" , "number" , currentFinalizedBlock .Number (), "hash" , currentFinalizedBlock .Hash (), "td" , finalTd , "age" , common .PrettyAge (time .Unix (int64 (currentFinalizedBlock .Time ()), 0 )))
489
+ }
473
490
if pivot := rawdb .ReadLastPivotNumber (bc .db ); pivot != nil {
474
491
log .Info ("Loaded last fast-sync pivot marker" , "number" , * pivot )
475
492
}
@@ -484,6 +501,13 @@ func (bc *BlockChain) SetHead(head uint64) error {
484
501
return err
485
502
}
486
503
504
+ // SetFinalized sets the finalized block.
505
+ func (bc * BlockChain ) SetFinalized (block * types.Block ) {
506
+ bc .currentFinalizedBlock .Store (block )
507
+ rawdb .WriteFinalizedBlockHash (bc .db , block .Hash ())
508
+ headFinalizedBlockGauge .Update (int64 (block .NumberU64 ()))
509
+ }
510
+
487
511
// setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
488
512
// that the rewind must pass the specified state root. This method is meant to be
489
513
// used when rewinding with snapshots enabled to ensure that we go back further than
0 commit comments