diff --git a/dash/quorum/validator_conn_executor.go b/dash/quorum/validator_conn_executor.go index a2a8a9f8cc..e4a91ad171 100644 --- a/dash/quorum/validator_conn_executor.go +++ b/dash/quorum/validator_conn_executor.go @@ -40,6 +40,8 @@ type Switch interface { AddrBook() p2p.AddrBook } +type optionFunc func(vc *ValidatorConnExecutor) error + // ValidatorConnExecutor retrieves validator update events and establishes new validator connections // within the ValidatorSet. // If it's already connected to a member of current validator set, it will keep that connection. @@ -80,7 +82,8 @@ func NewValidatorConnExecutor( proTxHash types.ProTxHash, eventBus *types.EventBus, sw Switch, - logger log.Logger) *ValidatorConnExecutor { + opts ...optionFunc, +) (*ValidatorConnExecutor, error) { vc := &ValidatorConnExecutor{ proTxHash: proTxHash, eventBus: eventBus, @@ -94,11 +97,39 @@ func NewValidatorConnExecutor( dashtypes.NewTCPNodeIDResolver(), }, } - - baseService := service.NewBaseService(logger, validatorConnExecutorName, vc) + baseService := service.NewBaseService(log.NewNopLogger(), validatorConnExecutorName, vc) vc.BaseService = *baseService - return vc + for _, opt := range opts { + err := opt(vc) + if err != nil { + return nil, err + } + } + return vc, nil +} + +// WithValidatorsSet sets the validators and quorum-hash as default values +func WithValidatorsSet(valSet *types.ValidatorSet) func(vc *ValidatorConnExecutor) error { + return func(vc *ValidatorConnExecutor) error { + if len(valSet.Validators) == 0 { + return nil + } + err := vc.setQuorumHash(valSet.QuorumHash) + if err != nil { + return err + } + vc.validatorSetMembers = newValidatorMap(valSet.Validators) + return nil + } +} + +// WithLogger sets a logger +func WithLogger(logger log.Logger) func(vc *ValidatorConnExecutor) error { + return func(vc *ValidatorConnExecutor) error { + vc.Logger = logger.With("module", "ValidatorConnExecutor") + return nil + } } // OnStart implements Service to subscribe to Validator Update events @@ -106,7 +137,11 @@ func (vc *ValidatorConnExecutor) OnStart() error { if err := vc.subscribe(); err != nil { return err } - + // establish connection with validators retrieves from genesis or init-chain + err := vc.updateConnections() + if err != nil { + return err + } go func() { var err error for err == nil { diff --git a/dash/quorum/validator_conn_executor_test.go b/dash/quorum/validator_conn_executor_test.go index c5d661a5d6..2724e827be 100644 --- a/dash/quorum/validator_conn_executor_test.go +++ b/dash/quorum/validator_conn_executor_test.go @@ -352,7 +352,8 @@ func TestEndBlock(t *testing.T) { // setup ValidatorConnExecutor sw := mock.NewMockSwitch() proTxHash := newVals.Validators[0].ProTxHash - vc := NewValidatorConnExecutor(proTxHash, eventBus, sw, log.TestingLogger()) + vc, err := NewValidatorConnExecutor(proTxHash, eventBus, sw) + require.NoError(t, err) err = vc.Start() require.NoError(t, err) defer func() { err := vc.Stop(); require.NoError(t, err) }() @@ -506,7 +507,8 @@ func setup( sw = mock.NewMockSwitch() proTxHash := me.ProTxHash - vc = NewValidatorConnExecutor(proTxHash, eventBus, sw, log.TestingLogger()) + vc, err = NewValidatorConnExecutor(proTxHash, eventBus, sw) + require.NoError(t, err) err = vc.Start() require.NoError(t, err) diff --git a/node/node.go b/node/node.go index 183e0973c9..9830024869 100644 --- a/node/node.go +++ b/node/node.go @@ -1049,12 +1049,16 @@ func NewNode(config *cfg.Config, // Initialize ValidatorConnExecutor (only on Validators) var validatorConnExecutor *dashquorum.ValidatorConnExecutor if proTxHashP != nil { - validatorConnExecutor = dashquorum.NewValidatorConnExecutor( + validatorConnExecutor, err = dashquorum.NewValidatorConnExecutor( *proTxHashP, eventBus, sw, - logger.With("module", "ValidatorConnExecutor"), + dashquorum.WithLogger(logger), + dashquorum.WithValidatorsSet(state.Validators), ) + if err != nil { + return nil, err + } } node := &Node{ diff --git a/p2p/switch.go b/p2p/switch.go index d55af6e103..901cbd8125 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -589,6 +589,9 @@ func (sw *Switch) AddPersistentPeers(addrs []string) error { // It ignores ErrNetAddressLookup. However, if there are other errors, first encounter is // returned. func (sw *Switch) RemovePersistentPeer(addr string) error { + if len(sw.persistentPeersAddrs) == 0 { + return nil + } sw.Logger.Info("Removing persistent peer", "addr", addr) toDelete, err := NewNetAddressString(addr) if err != nil { diff --git a/test/e2e/Makefile b/test/e2e/Makefile index d2b22fd686..7b9184d7c7 100644 --- a/test/e2e/Makefile +++ b/test/e2e/Makefile @@ -20,6 +20,9 @@ runner/dashcore: runner e2e/app/compile runner/rotate: runner e2e/app/compile ./build/runner -f networks/rotate.toml +runner/island: runner e2e/app/compile + ./build/runner -f networks/island.toml + # We need to build support for database backends into the app in # order to build a binary with a Tenderdash node in it (for built-in # ABCI testing). diff --git a/test/e2e/networks/island.toml b/test/e2e/networks/island.toml new file mode 100644 index 0000000000..68312a7909 --- /dev/null +++ b/test/e2e/networks/island.toml @@ -0,0 +1,81 @@ +initial_height = 1000 +initial_state = { initial01 = "a", initial02 = "b", initial03 = "c" } +initial_core_chain_locked_height = 3400 + +[chainlock_updates] +1000 = 3450 +1004 = 3451 +1009 = 3452 +1020 = 3454 +1040 = 3500 + +[validator_update.0] +validator01 = 100 +validator02 = 100 +validator03 = 100 +validator04 = 100 + +[validator_update.1010] +validator02 = 100 +validator04 = 100 +validator06 = 100 +validator07 = 100 + +[validator_update.1020] +validator01 = 100 +validator03 = 100 +validator05 = 100 +validator07 = 100 + +[validator_update.1030] +validator01 = 100 +validator02 = 100 +validator03 = 100 +validator04 = 100 +validator05 = 100 +validator06 = 100 +validator07 = 100 + +[node.validator01] +snapshot_interval = 5 +perturb = ["disconnect"] +privval_protocol = "dashcore" + +[node.validator02] +database = "boltdb" +abci_protocol = "tcp" +privval_protocol = "dashcore" +persist_interval = 0 +perturb = ["restart"] + +[node.validator03] +database = "badgerdb" +privval_protocol = "dashcore" +persist_interval = 3 +retain_blocks = 3 +perturb = ["kill"] + +[node.validator04] +database = "rocksdb" +abci_protocol = "builtin" +privval_protocol = "dashcore" +perturb = ["pause"] + +[node.validator05] +start_at = 1005 +database = "cleveldb" +fast_sync = "v0" +privval_protocol = "dashcore" +perturb = ["kill", "pause", "disconnect", "restart"] + +[node.validator06] +database = "rocksdb" +fast_sync = "v0" +privval_protocol = "dashcore" + +[node.validator07] +start_at = 1005 +database = "cleveldb" +fast_sync = "v0" +privval_protocol = "dashcore" +perturb = ["pause"]