diff --git a/common/configs/processConfigs.go b/common/configs/processConfigs.go index cdc20eaae85..957bdcb0d5e 100644 --- a/common/configs/processConfigs.go +++ b/common/configs/processConfigs.go @@ -137,6 +137,12 @@ func checkRoundConfigValues(cfg config.ProcessConfigByRound) error { return fmt.Errorf("%w for MaxBlockProcessingTimeMs, received %d, min expected %d", process.ErrInvalidValue, cfg.MaxBlockProcessingTimeMs, minBlockProcessingTimeMs) } + if cfg.RoundModulusTriggerWhenSyncIsStuck == 0 { + return fmt.Errorf("%w for RoundModulusTriggerWhenSyncIsStuck, %d received", + process.ErrInvalidValue, + cfg.RoundModulusTriggerWhenSyncIsStuck, + ) + } return nil } diff --git a/common/configs/processConfigs_test.go b/common/configs/processConfigs_test.go index e9d2b005051..96d6c6f2f54 100644 --- a/common/configs/processConfigs_test.go +++ b/common/configs/processConfigs_test.go @@ -24,6 +24,7 @@ func getConfigsByRound() []config.ProcessConfigByRound { NumFloodingRoundsOutOfSpecs: 4, MaxConsecutiveRoundsOfRatingDecrease: 600, MaxBlockProcessingTimeMs: 1000, + RoundModulusTriggerWhenSyncIsStuck: 10, }, { EnableRound: 1, @@ -35,6 +36,7 @@ func getConfigsByRound() []config.ProcessConfigByRound { NumFloodingRoundsOutOfSpecs: 40, MaxConsecutiveRoundsOfRatingDecrease: 6000, MaxBlockProcessingTimeMs: 1000, + RoundModulusTriggerWhenSyncIsStuck: 10, }, } } @@ -112,6 +114,21 @@ func TestNewProcessConfigsByEpoch(t *testing.T) { require.True(t, strings.Contains(err.Error(), "MaxRoundsToKeepUnprocessedMiniBlocks")) }) + t.Run("should return error for zero RoundModulusTriggerWhenSyncIsStuck value", func(t *testing.T) { + t.Parallel() + + confByEpoch := []config.ProcessConfigByEpoch{ + {EnableEpoch: 0, MaxMetaNoncesBehind: 15}, + } + confByRound := getConfigsByRound() + confByRound[0].RoundModulusTriggerWhenSyncIsStuck = 0 + + pce, err := configs.NewProcessConfigsHandler(confByEpoch, confByRound, &epochNotifier.RoundNotifierStub{}) + require.Nil(t, pce) + require.ErrorIs(t, err, process.ErrInvalidValue) + require.True(t, strings.Contains(err.Error(), "RoundModulusTriggerWhenSyncIsStuck")) + }) + t.Run("should return error for invalid max consecutive rounds of rating decrease value", func(t *testing.T) { t.Parallel() @@ -175,6 +192,7 @@ func TestProcessConfigsByEpoch_Getters(t *testing.T) { NumFloodingRoundsOutOfSpecs: 4, MaxConsecutiveRoundsOfRatingDecrease: 600, MaxBlockProcessingTimeMs: 1000, + RoundModulusTriggerWhenSyncIsStuck: 10, }, {EnableRound: 1, MaxRoundsWithoutNewBlockReceived: 11, @@ -187,6 +205,7 @@ func TestProcessConfigsByEpoch_Getters(t *testing.T) { NumFloodingRoundsOutOfSpecs: 40, MaxConsecutiveRoundsOfRatingDecrease: 6000, MaxBlockProcessingTimeMs: 2000, + RoundModulusTriggerWhenSyncIsStuck: 10, }, } diff --git a/consensus/spos/bls/ntpsync/roundSyncController.go b/consensus/spos/bls/ntpsync/roundSyncController.go index 64b5094f4f6..df418923428 100644 --- a/consensus/spos/bls/ntpsync/roundSyncController.go +++ b/consensus/spos/bls/ntpsync/roundSyncController.go @@ -1,6 +1,8 @@ package ntpsync import ( + "sort" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-go/consensus" @@ -95,8 +97,12 @@ func areNoncesInAscendingOrder(nonces []uint64) bool { return false } - for i := 1; i < len(nonces); i++ { - if nonces[i] != nonces[i-1]+1 { + dst := make([]uint64, len(nonces)) + copy(dst, nonces) + sort.Slice(dst, func(i, j int) bool { return dst[i] < dst[j] }) + + for i := 1; i < len(dst); i++ { + if dst[i] != dst[i-1]+1 { return false } } diff --git a/consensus/spos/bls/v2/subroundEndRound.go b/consensus/spos/bls/v2/subroundEndRound.go index cab036cc4fb..bab1ca6aa16 100644 --- a/consensus/spos/bls/v2/subroundEndRound.go +++ b/consensus/spos/bls/v2/subroundEndRound.go @@ -1028,6 +1028,11 @@ func (sr *subroundEndRound) receivedSignature(_ context.Context, cnsDta *consens return false } + if sr.HasProofForCompetingBlock() { + log.Debug("receivedSignature: competing block proof detected, dropping signature") + return false + } + remainingTime := sr.remainingTime() if remainingTime <= 0 { return false diff --git a/node/chainSimulator/components/coreComponents_test.go b/node/chainSimulator/components/coreComponents_test.go index e5ba304974e..bdf907cb3d1 100644 --- a/node/chainSimulator/components/coreComponents_test.go +++ b/node/chainSimulator/components/coreComponents_test.go @@ -77,6 +77,7 @@ func createArgsCoreComponentsHolder() ArgsCoreComponentsHolder { MaxConsecutiveRoundsOfRatingDecrease: 600, MaxBlockProcessingTimeMs: 1000, NumHeadersToRequestInAdvance: 10, + RoundModulusTriggerWhenSyncIsStuck: 20, }, }, EpochStartConfigsByEpoch: []config.EpochStartConfigByEpoch{ diff --git a/process/track/baseBlockTrack_test.go b/process/track/baseBlockTrack_test.go index 2f72872b12c..117f51cff36 100644 --- a/process/track/baseBlockTrack_test.go +++ b/process/track/baseBlockTrack_test.go @@ -156,6 +156,7 @@ func CreateShardTrackerMockArguments() track.ArgShardTracker { NumFloodingRoundsOutOfSpecs: 40, MaxConsecutiveRoundsOfRatingDecrease: 600, MaxBlockProcessingTimeMs: 1000, + RoundModulusTriggerWhenSyncIsStuck: 20, }, }, &epochNotifier.RoundNotifierStub{}, diff --git a/testscommon/components/configs.go b/testscommon/components/configs.go index 08e2486ddc5..72f046fe1fb 100644 --- a/testscommon/components/configs.go +++ b/testscommon/components/configs.go @@ -188,6 +188,7 @@ func GetGeneralConfig() config.Config { MaxConsecutiveRoundsOfRatingDecrease: 600, MaxBlockProcessingTimeMs: 1000, NumHeadersToRequestInAdvance: 10, + RoundModulusTriggerWhenSyncIsStuck: 20, }, }, EpochStartConfigsByEpoch: []config.EpochStartConfigByEpoch{