@@ -431,9 +431,40 @@ func (pm *ProtocolManager) startRaft() {
431431 maybeRaftSnapshot = pm .loadSnapshot () // re-establishes peer connections
432432 }
433433
434- pm .wal = pm .replayWAL (maybeRaftSnapshot )
434+ loadedWal , entries := pm .replayWAL (maybeRaftSnapshot )
435+ pm .wal = loadedWal
435436
436437 if walExisted {
438+
439+ // If we shutdown but didn't manage to flush the state to disk, then it will be the case that we will only sync
440+ // up to the snapshot. In this case, we can replay the raft entries that we have in saved to replay the blocks
441+ // back into our chain. We output errors but cannot do much if one occurs, since we can't fork to a different
442+ // chain and all other nodes in the network have confirmed these blocks
443+ if maybeRaftSnapshot != nil {
444+ currentChainHead := pm .blockchain .CurrentBlock ().Number ()
445+ for _ , entry := range entries {
446+ if entry .Type == raftpb .EntryNormal {
447+ var block types.Block
448+ if err := rlp .DecodeBytes (entry .Data , & block ); err != nil {
449+ log .Error ("error decoding block: " , "err" , err )
450+ continue
451+ }
452+
453+ if thisBlockHead := pm .blockchain .GetBlockByHash (block .Hash ()); thisBlockHead != nil {
454+ // check if the block is already existing in the local chain
455+ // and the block number is greater than current chain head
456+ if thisBlockHeadNum := thisBlockHead .Number (); thisBlockHeadNum .Cmp (currentChainHead ) > 0 {
457+ // insert the block only if its already seen
458+ blocks := []* types.Block {& block }
459+ if _ , err := pm .blockchain .InsertChain (blocks ); err != nil {
460+ log .Error ("error inserting the block into the chain" , "number" , block .NumberU64 (), "hash" , block .Hash (), "err" , err )
461+ }
462+ }
463+ }
464+ }
465+ }
466+ }
467+
437468 if hardState , _ , err := pm .raftStorage .InitialState (); err != nil {
438469 panic (fmt .Sprintf ("failed to read initial state from raft while restarting: %v" , err ))
439470 } else {
0 commit comments