Skip to content

Commit

Permalink
[ibft] Fix validator build block when syncing (#313)
Browse files Browse the repository at this point in the history
# Description

Validator nodes build blocks during sync, which makes it slow to sync
and full of error logs.
This PR fixes it to only start building blocks when syncing is done.

# Changes include

- [x] Bugfix (non-breaking change that solves an issue)

## Testing

- [x] I have tested this code with the official test suite
- [x] I have tested this code manually

### Manual tests

1. start up a 4-validators network.
2. stop a validator for about 2-3 minutes.
3. restart the stopped validator and check its logs.

On current branch, validator will print out "sequence started" only when
it catch up to the latest height.
On the target branch, validator will print out "sequence started" every
time a new block arrives, and try to build an outdated block every turn.
  • Loading branch information
DarianShawn authored Mar 1, 2023
1 parent 4befcc7 commit 3b1d596
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 14 deletions.
4 changes: 2 additions & 2 deletions consensus/ibft/ibft.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,8 +544,8 @@ func (i *Ibft) startConsensus() {

isValidator = i.isValidSnapshot()

if isValidator {
// i.startNewSequence()
// validator must not be in syncing mode to start a new block
if isValidator && !i.syncer.IsSyncing() {
sequenceCh = i.runSequence(pending)
}

Expand Down
2 changes: 2 additions & 0 deletions protocol/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type Syncer interface {
GetSyncProgression() *progress.Progression
// HasSyncPeer returns whether syncer has the peer syncer can sync with
HasSyncPeer() bool
// IsSyncing returns whether syncer is syncing
IsSyncing() bool
// Sync starts routine to sync blocks
Sync(func(*types.Block) bool) error
}
Expand Down
25 changes: 14 additions & 11 deletions protocol/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,16 @@ func NewSyncer(
return s
}

func (s *noForkSyncer) isSyncing() bool {
func (s *noForkSyncer) IsSyncing() bool {
return s.syncing.Load()
}

func (s *noForkSyncer) setSyncing(syncing bool) (oldStatus bool) {
return s.syncing.Swap(syncing)
func (s *noForkSyncer) startSyncingStatus() (success bool) {
return s.syncing.CompareAndSwap(false, true)
}

func (s *noForkSyncer) stopSyncingStatus() (success bool) {
return s.syncing.CompareAndSwap(true, false)
}

// GetSyncProgression returns the latest sync progression, if any
Expand Down Expand Up @@ -300,15 +304,13 @@ func (s *noForkSyncer) Sync(callback func(*types.Block) bool) error {
}

// The channel should not be blocked, otherwise it will hang when an error occurs
if s.isSyncing() {
if !s.startSyncingStatus() {
s.logger.Debug("skip new status event due to not done syncing")

continue
}
}

s.logger.Debug("got new status event")

if shouldTerminate := s.syncWithSkipList(skipList, callback); shouldTerminate {
s.logger.Error("terminate syncing")

Expand All @@ -323,12 +325,13 @@ func (s *noForkSyncer) syncWithSkipList(
skipList *sync.Map,
callback func(*types.Block) bool,
) (shouldTerminate bool) {
// switch syncing status
s.setSyncing(true)
defer s.setSyncing(false)
s.logger.Debug("got new status event and start syncing")

s.logger.Debug("start syncing")
defer s.logger.Debug("done syncing")
// switch syncing status
defer func() {
s.logger.Debug("done syncing")
s.stopSyncingStatus()
}()

var localLatest uint64

Expand Down
2 changes: 1 addition & 1 deletion protocol/syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func Test_startPeerStatusUpdateProcess(t *testing.T) {
&mockProgression{},
)

syncer.setSyncing(true) // to skip channel blocking
syncer.startSyncingStatus() // to skip channel blocking

go syncer.Sync(nil)

Expand Down

0 comments on commit 3b1d596

Please sign in to comment.