Skip to content

Commit e559437

Browse files
Merge pull request #4799 from ElrondNetwork/EN-13432-shuffler-refactoring
EN-13432: Nodes shuffler refactoring
2 parents 38d96a4 + 7efe443 commit e559437

22 files changed

+439
-528
lines changed

common/constants.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,8 @@ const (
596596
const (
597597
// StorerOrder defines the order of storers to be notified of a start of epoch event
598598
StorerOrder = iota
599+
// ChainParametersOrder defines the order in which ChainParameters is notified of a start of epoch event
600+
ChainParametersOrder
599601
// NodesCoordinatorOrder defines the order in which NodesCoordinator is notified of a start of epoch event
600602
NodesCoordinatorOrder
601603
// ConsensusOrder defines the order in which Consensus is notified of a start of epoch event

factory/core/coreComponents.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,11 @@ func (ccf *coreComponentsFactory) Create() (*coreComponents, error) {
179179
log.Debug("NTP average clock offset", "value", syncer.ClockOffset())
180180

181181
epochNotifier := forking.NewGenericEpochNotifier()
182+
epochStartHandlerWithConfirm := notifier.NewEpochStartSubscriptionHandler()
182183

183184
argsChainParametersHandler := sharding.ArgsChainParametersHolder{
184-
EpochNotifier: epochNotifier,
185-
ChainParameters: ccf.config.GeneralSettings.ChainParametersByEpoch,
185+
EpochStartEventNotifier: epochStartHandlerWithConfirm,
186+
ChainParameters: ccf.config.GeneralSettings.ChainParametersByEpoch,
186187
}
187188
chainParametersHandler, err := sharding.NewChainParametersHolder(argsChainParametersHandler)
188189
if err != nil {
@@ -305,13 +306,10 @@ func (ccf *coreComponentsFactory) Create() (*coreComponents, error) {
305306
}
306307

307308
argsNodesShuffler := &nodesCoordinator.NodesShufflerArgs{
308-
NodesShard: genesisNodesConfig.MinNumberOfShardNodes(),
309-
NodesMeta: genesisNodesConfig.MinNumberOfMetaNodes(),
310-
Hysteresis: genesisNodesConfig.GetHysteresis(),
311-
Adaptivity: genesisNodesConfig.GetAdaptivity(),
312-
ShuffleBetweenShards: true,
313-
MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch,
314-
EnableEpochsHandler: enableEpochsHandler,
309+
ChainParametersHandler: chainParametersHandler,
310+
ShuffleBetweenShards: true,
311+
MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch,
312+
EnableEpochsHandler: enableEpochsHandler,
315313
}
316314

317315
nodesShuffler, err := nodesCoordinator.NewHashValidatorsShuffler(argsNodesShuffler)

integrationTests/nodesCoordinatorFactory.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import (
55

66
"github.com/ElrondNetwork/elrond-go-core/data/endProcess"
77
"github.com/ElrondNetwork/elrond-go-core/hashing"
8+
"github.com/ElrondNetwork/elrond-go/config"
89
"github.com/ElrondNetwork/elrond-go/integrationTests/mock"
910
"github.com/ElrondNetwork/elrond-go/sharding"
1011
"github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator"
1112
"github.com/ElrondNetwork/elrond-go/storage"
1213
"github.com/ElrondNetwork/elrond-go/testscommon"
1314
"github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock"
15+
"github.com/ElrondNetwork/elrond-go/testscommon/shardingmock"
1416
vic "github.com/ElrondNetwork/elrond-go/testscommon/validatorInfoCacher"
1517
)
1618

@@ -43,10 +45,16 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd
4345
pubKeyBytes, _ := keys.Pk.ToByteArray()
4446

4547
nodeShufflerArgs := &nodesCoordinator.NodesShufflerArgs{
46-
NodesShard: uint32(arg.nodesPerShard),
47-
NodesMeta: uint32(arg.nbMetaNodes),
48-
Hysteresis: hysteresis,
49-
Adaptivity: adaptivity,
48+
ChainParametersHandler: &shardingmock.ChainParametersHandlerStub{
49+
CurrentChainParametersCalled: func() config.ChainParametersByEpochConfig {
50+
return config.ChainParametersByEpochConfig{
51+
ShardMinNumNodes: uint32(arg.nodesPerShard),
52+
MetachainMinNumNodes: uint32(arg.nbMetaNodes),
53+
Hysteresis: hysteresis,
54+
Adaptivity: adaptivity,
55+
}
56+
},
57+
},
5058
ShuffleBetweenShards: shuffleBetweenShards,
5159
MaxNodesEnableConfig: nil,
5260
EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{},
@@ -97,10 +105,16 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato
97105
pubKeyBytes, _ := keys.Pk.ToByteArray()
98106

99107
shufflerArgs := &nodesCoordinator.NodesShufflerArgs{
100-
NodesShard: uint32(arg.nodesPerShard),
101-
NodesMeta: uint32(arg.nbMetaNodes),
102-
Hysteresis: hysteresis,
103-
Adaptivity: adaptivity,
108+
ChainParametersHandler: &shardingmock.ChainParametersHandlerStub{
109+
CurrentChainParametersCalled: func() config.ChainParametersByEpochConfig {
110+
return config.ChainParametersByEpochConfig{
111+
ShardMinNumNodes: uint32(arg.nodesPerShard),
112+
MetachainMinNumNodes: uint32(arg.nbMetaNodes),
113+
Hysteresis: hysteresis,
114+
Adaptivity: adaptivity,
115+
}
116+
},
117+
},
104118
ShuffleBetweenShards: shuffleBetweenShards,
105119
MaxNodesEnableConfig: nil,
106120
EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{

integrationTests/testProcessorNodeWithMultisigner.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks"
3333
"github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock"
3434
"github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks"
35+
"github.com/ElrondNetwork/elrond-go/testscommon/shardingmock"
3536
vic "github.com/ElrondNetwork/elrond-go/testscommon/validatorInfoCacher"
3637
)
3738

@@ -392,10 +393,16 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier(
392393
nodesMap := make(map[uint32][]*TestProcessorNode)
393394

394395
shufflerArgs := &nodesCoordinator.NodesShufflerArgs{
395-
NodesShard: uint32(nodesPerShard),
396-
NodesMeta: uint32(nbMetaNodes),
397-
Hysteresis: hysteresis,
398-
Adaptivity: adaptivity,
396+
ChainParametersHandler: &shardingmock.ChainParametersHandlerStub{
397+
CurrentChainParametersCalled: func() config.ChainParametersByEpochConfig {
398+
return config.ChainParametersByEpochConfig{
399+
ShardMinNumNodes: uint32(nodesPerShard),
400+
MetachainMinNumNodes: uint32(nbMetaNodes),
401+
Hysteresis: hysteresis,
402+
Adaptivity: adaptivity,
403+
}
404+
},
405+
},
399406
ShuffleBetweenShards: shuffleBetweenShards,
400407
MaxNodesEnableConfig: nil,
401408
EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{},

sharding/chainParametersHolder.go

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"sync"
77

88
"github.com/ElrondNetwork/elrond-go-core/core/check"
9+
"github.com/ElrondNetwork/elrond-go-core/data"
10+
"github.com/ElrondNetwork/elrond-go/common"
911
"github.com/ElrondNetwork/elrond-go/config"
1012
)
1113

@@ -17,8 +19,8 @@ type chainParametersHolder struct {
1719

1820
// ArgsChainParametersHolder holds the arguments needed for creating a new chainParametersHolder
1921
type ArgsChainParametersHolder struct {
20-
EpochNotifier EpochNotifier
21-
ChainParameters []config.ChainParametersByEpochConfig
22+
EpochStartEventNotifier EpochStartEventNotifier
23+
ChainParameters []config.ChainParametersByEpochConfig
2224
}
2325

2426
// NewChainParametersHolder returns a new instance of chainParametersHolder
@@ -39,24 +41,19 @@ func NewChainParametersHolder(args ArgsChainParametersHolder) (*chainParametersH
3941
return nil, ErrMissingConfigurationForEpochZero
4042
}
4143

42-
currentParams, err := getMatchingChainParametersUnprotected(args.EpochNotifier.CurrentEpoch(), args.ChainParameters)
43-
if err != nil {
44-
return nil, err
45-
}
46-
4744
paramsHolder := &chainParametersHolder{
48-
currentChainParameters: currentParams,
45+
currentChainParameters: earliestChainParams, // will be updated on the epoch notifier handlers
4946
chainParameters: args.ChainParameters,
5047
}
5148

52-
args.EpochNotifier.RegisterNotifyHandler(paramsHolder)
49+
args.EpochStartEventNotifier.RegisterHandler(paramsHolder)
5350

5451
return paramsHolder, nil
5552
}
5653

5754
func validateArgs(args ArgsChainParametersHolder) error {
58-
if check.IfNil(args.EpochNotifier) {
59-
return ErrNilEpochNotifier
55+
if check.IfNil(args.EpochStartEventNotifier) {
56+
return ErrNilEpochStartEventNotifier
6057
}
6158
if len(args.ChainParameters) == 0 {
6259
return ErrMissingChainParameters
@@ -83,8 +80,21 @@ func validateChainParameters(chainParametersConfig []config.ChainParametersByEpo
8380
return nil
8481
}
8582

86-
// EpochConfirmed is called at each epoch change event
87-
func (c *chainParametersHolder) EpochConfirmed(epoch uint32, _ uint64) {
83+
// EpochStartAction is called when a new epoch is confirmed
84+
func (c *chainParametersHolder) EpochStartAction(header data.HeaderHandler) {
85+
c.handleEpochChange(header.GetEpoch())
86+
}
87+
88+
// EpochStartPrepare is called when a new epoch is observed, but not yet confirmed. No action is required on this component
89+
func (c *chainParametersHolder) EpochStartPrepare(_ data.HeaderHandler, _ data.BodyHandler) {
90+
}
91+
92+
// NotifyOrder returns the notification order for a start of epoch event
93+
func (c *chainParametersHolder) NotifyOrder() uint32 {
94+
return common.ChainParametersOrder
95+
}
96+
97+
func (c *chainParametersHolder) handleEpochChange(epoch uint32) {
8898
c.mutOperations.Lock()
8999
defer c.mutOperations.Unlock()
90100

sharding/chainParametersHolder_test.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import (
66
"testing"
77

88
"github.com/ElrondNetwork/elrond-go-core/core/check"
9+
"github.com/ElrondNetwork/elrond-go-core/data/block"
910
"github.com/ElrondNetwork/elrond-go/config"
10-
"github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier"
11+
"github.com/ElrondNetwork/elrond-go/testscommon/epochstartmock"
1112
"github.com/stretchr/testify/require"
1213
)
1314

@@ -16,7 +17,7 @@ func TestNewChainParametersHolder(t *testing.T) {
1617

1718
getDummyArgs := func() ArgsChainParametersHolder {
1819
return ArgsChainParametersHolder{
19-
EpochNotifier: &epochNotifier.EpochNotifierStub{},
20+
EpochStartEventNotifier: &epochstartmock.EpochStartNotifierStub{},
2021
ChainParameters: []config.ChainParametersByEpochConfig{
2122
{
2223
EnableEpoch: 0,
@@ -32,15 +33,15 @@ func TestNewChainParametersHolder(t *testing.T) {
3233
}
3334
}
3435

35-
t.Run("nil epoch notifier", func(t *testing.T) {
36+
t.Run("nil epoch start event notifier", func(t *testing.T) {
3637
t.Parallel()
3738

3839
args := getDummyArgs()
39-
args.EpochNotifier = nil
40+
args.EpochStartEventNotifier = nil
4041

4142
paramsHolder, err := NewChainParametersHolder(args)
4243
require.True(t, check.IfNil(paramsHolder))
43-
require.Equal(t, ErrNilEpochNotifier, err)
44+
require.Equal(t, ErrNilEpochStartEventNotifier, err)
4445
})
4546

4647
t.Run("empty chain parameters", func(t *testing.T) {
@@ -165,8 +166,8 @@ func TestChainParametersHolder_ChainParametersForEpoch(t *testing.T) {
165166
}
166167

167168
paramsHolder, _ := NewChainParametersHolder(ArgsChainParametersHolder{
168-
ChainParameters: params,
169-
EpochNotifier: &epochNotifier.EpochNotifierStub{},
169+
ChainParameters: params,
170+
EpochStartEventNotifier: &epochstartmock.EpochStartNotifierStub{},
170171
})
171172

172173
res, _ := paramsHolder.ChainParametersForEpoch(0)
@@ -210,8 +211,8 @@ func TestChainParametersHolder_ChainParametersForEpoch(t *testing.T) {
210211
}
211212

212213
paramsHolder, _ := NewChainParametersHolder(ArgsChainParametersHolder{
213-
ChainParameters: params,
214-
EpochNotifier: &epochNotifier.EpochNotifierStub{},
214+
ChainParameters: params,
215+
EpochStartEventNotifier: &epochstartmock.EpochStartNotifierStub{},
215216
})
216217

217218
for i := 0; i < 200; i++ {
@@ -251,20 +252,20 @@ func TestChainParametersHolder_CurrentChainParameters(t *testing.T) {
251252
}
252253

253254
paramsHolder, _ := NewChainParametersHolder(ArgsChainParametersHolder{
254-
ChainParameters: params,
255-
EpochNotifier: &epochNotifier.EpochNotifierStub{},
255+
ChainParameters: params,
256+
EpochStartEventNotifier: &epochstartmock.EpochStartNotifierStub{},
256257
})
257258

258-
paramsHolder.EpochConfirmed(0, 0)
259+
paramsHolder.EpochStartAction(&block.MetaBlock{Epoch: 0})
259260
require.Equal(t, uint32(5), paramsHolder.CurrentChainParameters().ShardConsensusGroupSize)
260261

261-
paramsHolder.EpochConfirmed(3, 0)
262+
paramsHolder.EpochStartAction(&block.MetaBlock{Epoch: 3})
262263
require.Equal(t, uint32(5), paramsHolder.CurrentChainParameters().ShardConsensusGroupSize)
263264

264-
paramsHolder.EpochConfirmed(10, 0)
265+
paramsHolder.EpochStartAction(&block.MetaBlock{Epoch: 10})
265266
require.Equal(t, uint32(50), paramsHolder.CurrentChainParameters().ShardConsensusGroupSize)
266267

267-
paramsHolder.EpochConfirmed(999, 0)
268+
paramsHolder.EpochStartAction(&block.MetaBlock{Epoch: 999})
268269
require.Equal(t, uint32(50), paramsHolder.CurrentChainParameters().ShardConsensusGroupSize)
269270
}
270271

@@ -289,8 +290,8 @@ func TestChainParametersHolder_AllChainParameters(t *testing.T) {
289290
}
290291

291292
paramsHolder, _ := NewChainParametersHolder(ArgsChainParametersHolder{
292-
ChainParameters: params,
293-
EpochNotifier: &epochNotifier.EpochNotifierStub{},
293+
ChainParameters: params,
294+
EpochStartEventNotifier: &epochstartmock.EpochStartNotifierStub{},
294295
})
295296

296297
returnedAllChainsParameters := paramsHolder.AllChainParameters()
@@ -314,8 +315,8 @@ func TestChainParametersHolder_ConcurrentOperations(t *testing.T) {
314315
}
315316

316317
paramsHolder, _ := NewChainParametersHolder(ArgsChainParametersHolder{
317-
ChainParameters: chainParams,
318-
EpochNotifier: &epochNotifier.EpochNotifierStub{},
318+
ChainParameters: chainParams,
319+
EpochStartEventNotifier: &epochstartmock.EpochStartNotifierStub{},
319320
})
320321

321322
numOperations := 500
@@ -325,7 +326,7 @@ func TestChainParametersHolder_ConcurrentOperations(t *testing.T) {
325326
go func(idx int) {
326327
switch idx {
327328
case 0:
328-
paramsHolder.EpochConfirmed(uint32(idx), 0)
329+
paramsHolder.EpochStartAction(&block.MetaBlock{Epoch: uint32(idx)})
329330
case 1:
330331
_ = paramsHolder.CurrentChainParameters()
331332
case 2:

sharding/errors.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ var ErrNilEndOfProcessingHandler = errors.New("nil end of processing handler")
4343
// ErrNilChainParametersProvider signals that a nil chain parameters provider has been given
4444
var ErrNilChainParametersProvider = errors.New("nil chain parameters provider")
4545

46-
// ErrNilEpochNotifier signals that a nil epoch notifier has been provided
47-
var ErrNilEpochNotifier = errors.New("nil epoch notifier")
46+
// ErrNilEpochStartEventNotifier signals that a nil epoch start event notifier has been provided
47+
var ErrNilEpochStartEventNotifier = errors.New("nil epoch start event notifier")
4848

4949
// ErrMissingChainParameters signals that a nil chain parameters array has been provided
5050
var ErrMissingChainParameters = errors.New("empty chain parameters array")

sharding/interface.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package sharding
22

33
import (
4-
"github.com/ElrondNetwork/elrond-go-core/data"
54
"github.com/ElrondNetwork/elrond-go/config"
5+
"github.com/ElrondNetwork/elrond-go/epochStart"
66
"github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator"
7-
vmcommon "github.com/ElrondNetwork/elrond-vm-common"
87
)
98

109
// Coordinator defines what a shard state coordinator should hold
@@ -68,11 +67,10 @@ type GenesisNodesSetupHandler interface {
6867
IsInterfaceNil() bool
6968
}
7069

71-
// EpochNotifier can notify upon an epoch change and provide the current epoch
72-
type EpochNotifier interface {
73-
RegisterNotifyHandler(handler vmcommon.EpochSubscriberHandler)
74-
CurrentEpoch() uint32
75-
CheckEpoch(header data.HeaderHandler)
70+
// EpochStartEventNotifier provides Register and Unregister functionality for the end of epoch events
71+
type EpochStartEventNotifier interface {
72+
RegisterHandler(handler epochStart.ActionHandler)
73+
UnregisterHandler(handler epochStart.ActionHandler)
7674
IsInterfaceNil() bool
7775
}
7876

sharding/mock/epochHandlerMock.go

Lines changed: 0 additions & 16 deletions
This file was deleted.

sharding/mock/epochHandlerStub.go

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)