Skip to content

Commit

Permalink
feat(dash): connect to all other quorum members
Browse files Browse the repository at this point in the history
  • Loading branch information
lklimek committed Aug 8, 2024
1 parent cc55430 commit 205f419
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 11 deletions.
35 changes: 26 additions & 9 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ const (
ModeFull = "full"
ModeValidator = "validator"
ModeSeed = "seed"

// ValidatorConnectionAlgorithmAll is a name of the peer selection algorithm that selects all validators
ValidatorConnectionAlgorithmAll = "all"
// ValidatorConnectionAlgorithmDIP6 is a name of the peer selection algorithm that selects validators based on DIP-6
ValidatorConnectionAlgorithmDIP6 = "dip6"
)

// NOTE: Most of the structs & relevant comments + the
Expand Down Expand Up @@ -1111,7 +1116,15 @@ type ConsensusConfig struct {
PeerGossipSleepDuration time.Duration `mapstructure:"peer-gossip-sleep-duration"`
PeerQueryMaj23SleepDuration time.Duration `mapstructure:"peer-query-maj23-sleep-duration"`

DoubleSignCheckHeight int64 `mapstructure:"double-sign-check-height"`
// ValidatorConnectionAlgorithm defines the algorithm used to select the
// validators to which direct connection should be established.
// Possible values are:
// - "all" - validators establish direct connections to all other validators in the current quorum
// - "dip6" - validators establish direct connections to a subset of other validators, determined according to DIP-6
//
// Defaults to "dip6".
ValidatorConnectionAlgorithm string `mapstructure:"validator-connection-algorithm"`
DoubleSignCheckHeight int64 `mapstructure:"double-sign-check-height"`

DeprecatedQuorumType btcjson.LLMQType `mapstructure:"quorum-type"`

Expand Down Expand Up @@ -1152,14 +1165,15 @@ type ConsensusConfig struct {
// DefaultConsensusConfig returns a default configuration for the consensus service
func DefaultConsensusConfig() *ConsensusConfig {
return &ConsensusConfig{
WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"),
WalSkipRoundsToLast: false,
CreateEmptyBlocks: true,
CreateEmptyBlocksInterval: 0 * time.Second,
PeerGossipSleepDuration: 100 * time.Millisecond,
PeerQueryMaj23SleepDuration: 2000 * time.Millisecond,
DoubleSignCheckHeight: int64(0),
DontAutoPropose: false,
WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"),
WalSkipRoundsToLast: false,
CreateEmptyBlocks: true,
CreateEmptyBlocksInterval: 0 * time.Second,
PeerGossipSleepDuration: 100 * time.Millisecond,
PeerQueryMaj23SleepDuration: 2000 * time.Millisecond,
DoubleSignCheckHeight: int64(0),
DontAutoPropose: false,
ValidatorConnectionAlgorithm: ValidatorConnectionAlgorithmDIP6,
}
}

Expand Down Expand Up @@ -1220,6 +1234,9 @@ func (cfg *ConsensusConfig) ValidateBasic() error {
if cfg.DoubleSignCheckHeight < 0 {
return errors.New("double-sign-check-height can't be negative")
}
if cfg.ValidatorConnectionAlgorithm != ValidatorConnectionAlgorithmAll && cfg.ValidatorConnectionAlgorithm != ValidatorConnectionAlgorithmDIP6 {
return fmt.Errorf("validator-connection-algorithm must be either 'all' or 'dip6'")
}
return nil
}

Expand Down
9 changes: 9 additions & 0 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,15 @@ create-empty-blocks-interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
peer-gossip-sleep-duration = "{{ .Consensus.PeerGossipSleepDuration }}"
peer-query-maj23-sleep-duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
# ValidatorConnectionAlgorithm defines the algorithm used to select the
# validators to which direct connection should be established.
# Possible values are:
# - "all" - validators establish direct connections to all other validators in the current quorum
# - "dip6" - validators establish direct connections to a subset of other validators, determined according to DIP-6
#
# Defaults to "dip6".
validator-connection-algorithm = "{{ .Consensus.ValidatorConnectionAlgorithm }}"
### Unsafe Timeout Overrides ###
# These fields provide temporary overrides for the Timeout consensus parameters.
Expand Down
31 changes: 31 additions & 0 deletions dash/quorum/selectpeers/allvalidators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package selectpeers

import (
"github.com/dashpay/tenderdash/types"
)

type allValidatorsSelector struct {
}

var _ ValidatorSelector = (*allValidatorsSelector)(nil)

// NewAllValidatorsSelector creates new implementation of validator selector algorithm
// that selects all validators except local node
func NewAllValidatorsSelector() ValidatorSelector {
return &allValidatorsSelector{}
}

// SelectValidators implements ValidtorSelector.
// SelectValidators selects all validators from `validatorSetMembers`, except local node
func (s *allValidatorsSelector) SelectValidators(
validatorSetMembers []*types.Validator,
me *types.Validator,
) ([]*types.Validator, error) {
ret := make([]*types.Validator, 0, len(validatorSetMembers)-1)
for _, val := range validatorSetMembers {
if !val.ProTxHash.Equal(me.ProTxHash) {
ret = append(ret, val)
}
}
return ret, nil
}
34 changes: 33 additions & 1 deletion dash/quorum/validator_conn_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"

sync "github.com/sasha-s/go-deadlock"

"github.com/hashicorp/go-multierror"

"github.com/dashpay/tenderdash/config"
"github.com/dashpay/tenderdash/crypto"
"github.com/dashpay/tenderdash/dash/quorum/selectpeers"
"github.com/dashpay/tenderdash/internal/eventbus"
Expand Down Expand Up @@ -70,6 +72,10 @@ type ValidatorConnExecutor struct {

// EventBusCapacity sets event bus buffer capacity, defaults to 10
EventBusCapacity int

// selectionAlgorithm determines how to select validators to connect to
// Supported values: "all", "dip6"
selectionAlgorithm string
}

var (
Expand All @@ -93,6 +99,7 @@ func NewValidatorConnExecutor(
validatorSetMembers: validatorMap{},
connectedValidators: validatorMap{},
quorumHash: make(tmbytes.HexBytes, crypto.QuorumHashSize),
selectionAlgorithm: config.ValidatorConnectionAlgorithmDIP6,
}
vc.nodeIDResolvers = map[string]p2p.NodeIDResolver{
resolverAddressBook: vc.dialer,
Expand All @@ -106,6 +113,7 @@ func NewValidatorConnExecutor(
return nil, err
}
}

return vc, nil
}

Expand Down Expand Up @@ -141,8 +149,23 @@ func WithLogger(logger log.Logger) func(vc *ValidatorConnExecutor) error {
}
}

// WithSelectionAlgorithm sets the algorithm used to select validators to connect to
func WithSelectionAlgorithm(algorithm string) func(vc *ValidatorConnExecutor) error {
return func(vc *ValidatorConnExecutor) error {
algorithm := strings.ToLower(algorithm)

if algorithm != config.ValidatorConnectionAlgorithmAll && algorithm != config.ValidatorConnectionAlgorithmDIP6 {
return fmt.Errorf("invalid selection algorithm: %s", algorithm)
}

vc.selectionAlgorithm = algorithm
return nil
}
}

// OnStart implements Service to subscribe to Validator Update events
func (vc *ValidatorConnExecutor) OnStart(ctx context.Context) error {
vc.logger.Debug("ValidatorConnExecutor starting with selection algorithm " + vc.selectionAlgorithm)
// initial setup of validators, if state store is provided
if vc.stateStore != nil {
valset, err := vc.stateStore.Load()
Expand Down Expand Up @@ -314,7 +337,16 @@ func (vc *ValidatorConnExecutor) selectValidators() (validatorMap, error) {
return validatorMap{}, fmt.Errorf("current node is not member of active validator set")
}

selector := selectpeers.NewDIP6ValidatorSelector(vc.quorumHash)
var selector selectpeers.ValidatorSelector
switch vc.selectionAlgorithm {
case config.ValidatorConnectionAlgorithmAll:
selector = selectpeers.NewAllValidatorsSelector()
case config.ValidatorConnectionAlgorithmDIP6:
selector = selectpeers.NewDIP6ValidatorSelector(vc.quorumHash)
default:
return validatorMap{}, fmt.Errorf("invalid selection algorithm: %s", vc.selectionAlgorithm)
}

selectedValidators, err := selector.SelectValidators(activeValidators.values(), me)
if err != nil {
return validatorMap{}, err
Expand Down
4 changes: 3 additions & 1 deletion node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,9 @@ func makeNode(
dcm,
dashquorum.WithLogger(vcLogger),
dashquorum.WithValidatorsSet(state.Validators),
dashquorum.WithStateStore(stateStore))
dashquorum.WithStateStore(stateStore),
dashquorum.WithSelectionAlgorithm(cfg.Consensus.ValidatorConnectionAlgorithm),
)
if err != nil {
return nil, combineCloseError(err, makeCloser(closers))
}
Expand Down

0 comments on commit 205f419

Please sign in to comment.