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

feat: allow defining validator power threshold in consensus params #1052

Draft
wants to merge 5 commits into
base: v1.5-dev
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions internal/consensus/replay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,7 @@ func TestHandshakeUpdatesValidators(t *testing.T) {
btcjson.LLMQType_5_60,
randQuorumHash,
true,
nil,
)
abciValidatorSetUpdates := types.TM2PB.ValidatorUpdates(vals)
app := &initChainApp{vals: &abciValidatorSetUpdates}
Expand Down
18 changes: 17 additions & 1 deletion internal/consensus/replayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,18 @@ func (r *BlockReplayer) execInitChain(ctx context.Context, rs *replayState, stat
quorumType = r.genDoc.QuorumType
}

var valParams *types.ValidatorParams
if res.ConsensusParams != nil && res.ConsensusParams.Validator != nil {
params := types.ValidatorParamsFromProto(res.ConsensusParams.Validator)
valParams = &params
}

if len(res.ValidatorSetUpdate.ValidatorUpdates) != 0 {
// we replace existing validator with the one from InitChain instead of applying it as a diff
state.Validators = types.NewValidatorSet(nil, nil, quorumType, nil, false)
state.Validators = types.NewValidatorSet(nil, nil, quorumType, nil, false, valParams)
// } else if valParams != nil && valParams.VotingPowerThreshold != nil {
// // we update the existing validator set with the new voting threshold
// state.Validators.VotingPowerThreshold = *valParams.VotingPowerThreshold
}

// we only update state when we are in initial state
Expand Down Expand Up @@ -401,11 +410,18 @@ func validatorSetUpdateFromGenesis(genDoc *types.GenesisDoc) (*abci.ValidatorSet
return nil, fmt.Errorf("blockReplayer blocks error when validating validator: %s", err)
}
}

var validatorParams types.ValidatorParams
if genDoc.ConsensusParams != nil {
validatorParams = genDoc.ConsensusParams.Validator
}

validatorSet := types.NewValidatorSetCheckPublicKeys(
validators,
genDoc.ThresholdPublicKey,
genDoc.QuorumType,
genDoc.QuorumHash,
&validatorParams,
)
err := validatorSet.ValidateBasic()
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions internal/consensus/replayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ func TestInitChainGenesisTime(t *testing.T) {
QuorumHash: make([]byte, 32),
GenesisTime: time.Date(1999, 1, 1, 0, 0, 0, 0, time.UTC),
}
// We must synchronize genesis validator set voting threshold with the one from the validator set.
// In normal cicrumstances, the threshold is set in genesis or in ResponseInitChain.
genDoc.ConsensusParams.Validator.VotingPowerThreshold = &vset.VotingPowerThreshold

err = genDoc.ValidateAndComplete()
require.NoError(t, err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestProposerSelection1(t *testing.T) {
types.NewTestValidatorGeneratedFromProTxHash(fooProTxHash),
types.NewTestValidatorGeneratedFromProTxHash(barProTxHash),
types.NewTestValidatorGeneratedFromProTxHash(bazProTxHash),
}, bls12381.GenPrivKey().PubKey(), btcjson.LLMQType_5_60, crypto.RandQuorumHash(), true)
}, bls12381.GenPrivKey().PubKey(), btcjson.LLMQType_5_60, crypto.RandQuorumHash(), true, nil)
var proposers []string

vs, err := selectproposer.NewProposerSelector(types.ConsensusParams{}, vset, 0, 0, nil, log.NewTestingLogger(t))
Expand Down
4 changes: 2 additions & 2 deletions internal/evidence/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func TestAddExpiredEvidence(t *testing.T) {
quorumHash = crypto.RandQuorumHash()
privval = types.NewMockPVForQuorum(quorumHash)
val = privval.ExtractIntoValidator(ctx, quorumHash)
valSet = types.NewValidatorSet([]*types.Validator{val}, val.PubKey, btcjson.LLMQType_5_60, quorumHash, true)
valSet = types.NewValidatorSet([]*types.Validator{val}, val.PubKey, btcjson.LLMQType_5_60, quorumHash, true, nil)
height = int64(30)
stateStore = initializeValidatorState(ctx, t, privval, height, btcjson.LLMQType_5_60, quorumHash)
evidenceDB = dbm.NewMemDB()
Expand Down Expand Up @@ -221,7 +221,7 @@ func TestReportConflictingVotes(t *testing.T) {
state.LastBlockHeight++
state.LastBlockTime = ev.Time()
state.LastValidators = types.NewValidatorSet([]*types.Validator{val}, val.PubKey, btcjson.LLMQType_5_60,
quorumHash, true)
quorumHash, true, nil)
pool.Update(ctx, state, []types.Evidence{})

// should be able to retrieve evidence from pool
Expand Down
5 changes: 3 additions & 2 deletions internal/evidence/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,14 @@
rts.network.Nodes[nodeID].PeerManager.Register(ctx, pu)
rts.nodes = append(rts.nodes, rts.network.Nodes[nodeID])

chCreator := func(ctx context.Context, chdesc *p2p.ChannelDescriptor) (p2p.Channel, error) {
chCreator := func(_ctx context.Context, chdesc *p2p.ChannelDescriptor) (p2p.Channel, error) {

Check failure on line 102 in internal/evidence/reactor_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unused-parameter: parameter 'chdesc' seems to be unused, consider removing or renaming it to match ^_ (revive)
return rts.evidenceChannels[nodeID], nil
}

rts.reactors[nodeID] = evidence.NewReactor(
logger,
chCreator,
func(ctx context.Context, _ string) *p2p.PeerUpdates { return pu },
func(_ctx context.Context, _ string) *p2p.PeerUpdates { return pu },
rts.pools[nodeID])

require.NoError(t, rts.reactors[nodeID].Start(ctx))
Expand Down Expand Up @@ -550,6 +550,7 @@
btcjson.LLMQType_5_60,
crypto.RandQuorumHash(),
true,
nil,
)

dupl, err := types.NewDuplicateVoteEvidence(
Expand Down
2 changes: 1 addition & 1 deletion internal/evidence/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) {
val := types.NewMockPVForQuorum(quorumHash)
val2 := types.NewMockPVForQuorum(quorumHash)
validator1 := val.ExtractIntoValidator(context.Background(), quorumHash)
valSet := types.NewValidatorSet([]*types.Validator{validator1}, validator1.PubKey, quorumType, quorumHash, true)
valSet := types.NewValidatorSet([]*types.Validator{validator1}, validator1.PubKey, quorumType, quorumHash, true, nil)
stateID := types.RandStateID()
blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"), stateID)
blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"), stateID)
Expand Down
8 changes: 6 additions & 2 deletions internal/state/current_round_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ func valsetUpdate(
} else {
// if we don't have proTxHash, NewValidatorSetWithLocalNodeProTxHash behaves like NewValidatorSet
nValSet = types.NewValidatorSetCheckPublicKeys(validatorUpdates, thresholdPubKey,
currentVals.QuorumType, quorumHash)
currentVals.QuorumType, quorumHash, &params)
}
} else {
// validators not changed, but we might have a new quorum hash or threshold public key
Expand All @@ -340,7 +340,11 @@ func valsetUpdate(
if thresholdPubKey != nil {
nValSet.ThresholdPublicKey = thresholdPubKey
}

if params.VotingPowerThreshold != nil {
nValSet.VotingPowerThreshold = *params.VotingPowerThreshold
}
}

return nValSet, nil
return nValSet, nValSet.ValidateBasic()
}
9 changes: 7 additions & 2 deletions internal/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,13 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
}

var validatorSet *types.ValidatorSet
var valParams *types.ValidatorParams
if genDoc.ConsensusParams != nil {
valParams = &genDoc.ConsensusParams.Validator
}

if len(genDoc.Validators) == 0 {
validatorSet = types.NewValidatorSet(nil, nil, genDoc.QuorumType, nil, false)
validatorSet = types.NewValidatorSet(nil, nil, genDoc.QuorumType, nil, false, valParams)
} else {
validators := make([]*types.Validator, len(genDoc.Validators))
hasAllPublicKeys := true
Expand All @@ -394,7 +399,7 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
}
}
validatorSet = types.NewValidatorSet(
validators, genDoc.ThresholdPublicKey, genDoc.QuorumType, genDoc.QuorumHash, hasAllPublicKeys,
validators, genDoc.ThresholdPublicKey, genDoc.QuorumType, genDoc.QuorumHash, hasAllPublicKeys, valParams,
)
}

Expand Down
6 changes: 4 additions & 2 deletions internal/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,14 @@ func TestEmptyValidatorUpdates(t *testing.T) {
tearDown, _, state := setupTestCase(t)
defer tearDown(t)

originalValidatorSet, _ := types.RandValidatorSet(2)
state.Validators = originalValidatorSet

firstNode := state.Validators.GetByIndex(0)
require.NotZero(t, firstNode.ProTxHash)
ctx := dash.ContextWithProTxHash(context.Background(), firstNode.ProTxHash)

newPrivKey := bls12381.GenPrivKeyFromSecret([]byte("test"))
newPubKey := newPrivKey.PubKey()
newPubKey := originalValidatorSet.ThresholdPublicKey
newQuorumHash := crypto.RandQuorumHash()

expectValidators := types.ValidatorListString(state.Validators.Validators)
Expand Down
9 changes: 8 additions & 1 deletion internal/test/factory/validator_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,12 @@ func MockValidatorSet() (*types.ValidatorSet, []types.PrivValidator) {
false,
)
}
return types.NewValidatorSet(valz, thPubKey, btcjson.LLMQType_5_60, quorumHash, true), privVals
votingPowerThreshold := uint64(len(valz)) * uint64(types.DefaultDashVotingPower)
return types.NewValidatorSet(valz,
thPubKey,
btcjson.LLMQType_5_60,
quorumHash,
true,
&types.ValidatorParams{VotingPowerThreshold: &votingPowerThreshold},
), privVals
}
1 change: 1 addition & 0 deletions light/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (pkz privKeys) ToValidators(thresholdPublicKey crypto.PubKey) *types.Valida
btcjson.LLMQType_5_60,
crypto.Checksum(thresholdPublicKey.Bytes()),
true,
nil,
)
}

Expand Down
2 changes: 1 addition & 1 deletion light/provider/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func (p *http) validatorSet(ctx context.Context, height *int64, proposer types.P
break
}
}
valSet := types.NewValidatorSet(vals, thresholdPubKey, quorumType, quorumHash, false)
valSet := types.NewValidatorSet(vals, thresholdPubKey, quorumType, quorumHash, false, nil)

if valSet == nil || valSet.IsNilOrEmpty() {
return nil, provider.ErrBadLightBlock{Reason: fmt.Errorf("retrieved nil or empty validator set")}
Expand Down
Loading
Loading