@@ -972,14 +972,14 @@ impl ConsensusObserver {
972972 ) {
973973 // Get the epoch and round for the synced commit decision
974974 let ledger_info = latest_synced_ledger_info. ledger_info ( ) ;
975- let epoch = ledger_info. epoch ( ) ;
976- let round = ledger_info. round ( ) ;
975+ let synced_epoch = ledger_info. epoch ( ) ;
976+ let synced_round = ledger_info. round ( ) ;
977977
978978 // Log the state sync notification
979979 info ! (
980980 LogSchema :: new( LogEntry :: ConsensusObserver ) . message( & format!(
981- "Received state sync notification for commit completion! Epoch {}, round: {}!" ,
982- epoch , round
981+ "Received state sync notification for commit completion! Synced epoch {}, round: {}!" ,
982+ synced_epoch , synced_round
983983 ) )
984984 ) ;
985985
@@ -992,26 +992,41 @@ impl ConsensusObserver {
992992 return ;
993993 }
994994
995- // Verify that the state sync notification is for the current epoch and round
996- if !self
997- . observer_block_data
998- . lock ( )
999- . check_root_epoch_and_round ( epoch, round)
1000- {
995+ // Get the block data root epoch and round
996+ let block_data_root = self . observer_block_data . lock ( ) . root ( ) ;
997+ let block_data_epoch = block_data_root. ledger_info ( ) . epoch ( ) ;
998+ let block_data_round = block_data_root. ledger_info ( ) . round ( ) ;
999+
1000+ // If the commit sync notification is behind the block data root, ignore it. This
1001+ // is possible due to a race condition where we started syncing to a newer commit
1002+ // at the same time that state sync sent the notification for a previous commit.
1003+ if ( synced_epoch, synced_round) < ( block_data_epoch, block_data_round) {
1004+ info ! (
1005+ LogSchema :: new( LogEntry :: ConsensusObserver ) . message( & format!(
1006+ "Ignoring old commit sync notification for epoch: {}, round: {}! Current root: {:?}" ,
1007+ synced_epoch, synced_round, block_data_root
1008+ ) )
1009+ ) ;
1010+ return ;
1011+ }
1012+
1013+ // If the commit sync notification is ahead the block data root, something has gone wrong!
1014+ if ( synced_epoch, synced_round) > ( block_data_epoch, block_data_round) {
10011015 // Log the error, reset the state sync manager and return early
10021016 error ! (
10031017 LogSchema :: new( LogEntry :: ConsensusObserver ) . message( & format!(
10041018 "Received invalid commit sync notification for epoch: {}, round: {}! Current root: {:?}" ,
1005- epoch , round , self . observer_block_data . lock ( ) . root ( )
1019+ synced_epoch , synced_round , block_data_root
10061020 ) )
10071021 ) ;
10081022 self . state_sync_manager . clear_active_commit_sync ( ) ;
10091023 return ;
10101024 }
10111025
1012- // If the epoch has changed, end the current epoch and start the latest one
1026+ // Otherwise, the commit sync notification matches the block data root.
1027+ // If the epoch has changed, end the current epoch and start the latest one.
10131028 let current_epoch_state = self . get_epoch_state ( ) ;
1014- if epoch > current_epoch_state. epoch {
1029+ if synced_epoch > current_epoch_state. epoch {
10151030 // Wait for the latest epoch to start
10161031 self . execution_client . end_epoch ( ) . await ;
10171032 self . wait_for_epoch_start ( ) . await ;
0 commit comments