Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: validators form islands on genesis #850

Merged
merged 1 commit into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dash/quorum/validator_conn_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/dashpay/tenderdash/internal/eventbus"
"github.com/dashpay/tenderdash/internal/p2p"
tmpubsub "github.com/dashpay/tenderdash/internal/pubsub"
"github.com/dashpay/tenderdash/internal/state"
tmbytes "github.com/dashpay/tenderdash/libs/bytes"
"github.com/dashpay/tenderdash/libs/log"
"github.com/dashpay/tenderdash/libs/service"
Expand Down Expand Up @@ -62,6 +63,9 @@ type ValidatorConnExecutor struct {
// mux is a mutex to ensure only one goroutine is processing connections
mux sync.Mutex

// state store used on start to setup initial validators
stateStore state.Store

// *** configuration *** //

// EventBusCapacity sets event bus buffer capacity, defaults to 10
Expand Down Expand Up @@ -120,6 +124,15 @@ func WithValidatorsSet(valSet *types.ValidatorSet) func(vc *ValidatorConnExecuto
}
}

// WithStateStore sets state store to be used when setting up initial validators
// Can be nil, in which case no initial validators will be set up.
func WithStateStore(store state.Store) func(vc *ValidatorConnExecutor) error {
return func(vc *ValidatorConnExecutor) error {
vc.stateStore = store
return nil
}
}

// WithLogger sets a logger
func WithLogger(logger log.Logger) func(vc *ValidatorConnExecutor) error {
return func(vc *ValidatorConnExecutor) error {
Expand All @@ -130,6 +143,22 @@ func WithLogger(logger log.Logger) func(vc *ValidatorConnExecutor) error {

// OnStart implements Service to subscribe to Validator Update events
func (vc *ValidatorConnExecutor) OnStart(ctx context.Context) error {
// initial setup of validators, if state store is provided
if vc.stateStore != nil {
valset, err := vc.stateStore.Load()
if err != nil {
return fmt.Errorf("cannot load initial state from state store: %w", err)
}
if err = vc.handleValidatorUpdateEvent(types.EventDataValidatorSetUpdate{
ValidatorSetUpdates: valset.Validators.Validators,
ThresholdPublicKey: valset.Validators.ThresholdPublicKey,
QuorumHash: valset.Validators.QuorumHash,
}); err != nil {
// not fatal, but we should log it
vc.logger.Warn("cannot handle initial validator set, skipping", "err", err)
}
}

if err := vc.subscribe(); err != nil {
return err
}
Expand Down
45 changes: 23 additions & 22 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,28 +271,6 @@ func makeNode(
},
}

// Start Dash connection executor
if len(proTxHash) > 0 {
var validatorConnExecutor *dashquorum.ValidatorConnExecutor

vcLogger := logger.With("node_proTxHash", proTxHash.ShortString(), "module", "ValidatorConnExecutor")
dcm := p2p.NewRouterDashDialer(peerManager, vcLogger)
validatorConnExecutor, err = dashquorum.NewValidatorConnExecutor(
proTxHash,
eventBus,
dcm,
dashquorum.WithLogger(vcLogger),
dashquorum.WithValidatorsSet(state.Validators),
)
if err != nil {
return nil, combineCloseError(err, makeCloser(closers))
}

node.services = append(node.services, validatorConnExecutor)
} else {
logger.Debug("ProTxHash not set, so we are not a validator; skipping ValidatorConnExecutor initialization")
}

node.router, err = createRouter(logger, nodeMetrics.p2p, node.NodeInfo, nodeKey, peerManager, cfg, proxyApp)
if err != nil {
return nil, combineCloseError(
Expand Down Expand Up @@ -453,6 +431,29 @@ func makeNode(
node.rpcEnv.ProTxHash = proTxHash
}

// Start Dash connection executor
// We do it at the end, as we require the state to be loaded and network routing to be set up
if len(proTxHash) > 0 {
var validatorConnExecutor *dashquorum.ValidatorConnExecutor

vcLogger := logger.With("node_proTxHash", proTxHash.ShortString(), "module", "ValidatorConnExecutor")
dcm := p2p.NewRouterDashDialer(peerManager, vcLogger)
validatorConnExecutor, err = dashquorum.NewValidatorConnExecutor(
proTxHash,
eventBus,
dcm,
dashquorum.WithLogger(vcLogger),
dashquorum.WithValidatorsSet(state.Validators),
dashquorum.WithStateStore(stateStore))
if err != nil {
return nil, combineCloseError(err, makeCloser(closers))
}

node.services = append(node.services, validatorConnExecutor)
} else {
logger.Debug("ProTxHash not set, so we are not a validator; skipping ValidatorConnExecutor initialization")
}

node.BaseService = *service.NewBaseService(logger, "Node", node)

return node, nil
Expand Down
Loading