blockchain: Support voting multiple agendas in test.

This allows creating tests that require multiple agendas to be activated
simultaneously.
This commit is contained in:
Matheus Degiovani 2021-06-24 10:02:07 -03:00 committed by Dave Collins
parent 52c6bd033b
commit cf4ecd90be
2 changed files with 80 additions and 32 deletions

View File

@ -482,6 +482,49 @@ func findDeploymentChoice(deployment *chaincfg.ConsensusDeployment, choiceID str
return nil, fmt.Errorf("unable to find vote choice for id %q", choiceID)
}
// findDeploymentAllYesChoices returns the deployment version and the OR'ed sum
// of the 'yes' choices for all the passed agendas.
//
// Note that all agendas must be in the same deployment version or this
// function errors.
func findDeploymentAllYesChoices(params *chaincfg.Params, voteIDs []string) (uint32, uint16, error) {
var yesBits uint16
var deploymentVer uint32
var foundIDs int
for version, deployments := range params.Deployments {
for _, deployment := range deployments {
for _, wantID := range voteIDs {
if deployment.Vote.Id == wantID {
yesChoice, err := findDeploymentChoice(&deployment, "yes")
if err != nil {
return 0, 0, err
}
deploymentVer = version
foundIDs++
yesBits |= yesChoice.Bits
}
}
}
if foundIDs == 0 {
continue
}
// Agendas can only be voted simultaneously if they belong to
// the same deployment version, so return an error if we found
// some, but not all vote IDs in a specific version.
if foundIDs != len(voteIDs) {
return 0, 0, fmt.Errorf("not all voteIDs were found " +
"in the same deployment version")
}
return deploymentVer, yesBits, nil
}
return 0, 0, fmt.Errorf("unable to find deployment for any of the " +
"provided vote IDs")
}
// removeDeployment modifies the passed parameters to remove all deployments for
// the provided vote ID. An error is returned when not found.
func removeDeployment(params *chaincfg.Params, voteID string) error {
@ -1281,27 +1324,27 @@ func (g *chaingenHarness) AdvanceToStakeValidationHeight() {
g.generateToStakeValidationHeight(accept)
}
// AdvanceFromSVHToActiveAgenda generates and accepts enough blocks with the
// appropriate vote bits set to reach one block prior to the specified agenda
// AdvanceFromSVHToActiveAgendas generates and accepts enough blocks with the
// appropriate vote bits set to reach one block prior to the specified agendas
// becoming active.
//
// The function will fail with a fatal test error if it is called when the
// harness is not at stake validation height.
// harness is not at stake validation height or if the agendas are not all from
// the same deployment.
//
// WARNING: This function currently assumes the chain parameters were created
// via the quickVoteActivationParams. It should be updated in the future to
// work with arbitrary params.
func (g *chaingenHarness) AdvanceFromSVHToActiveAgenda(voteID string) {
func (g *chaingenHarness) AdvanceFromSVHToActiveAgendas(voteIDs ...string) {
g.t.Helper()
// Find the correct deployment for the provided ID along with the yes
// vote choice within it.
params := g.Params()
deploymentVer, deployment, err := findDeployment(params, voteID)
if err != nil {
g.t.Fatal(err)
if len(voteIDs) < 1 {
g.t.Fatal("no vote IDs specified")
}
yesChoice, err := findDeploymentChoice(deployment, "yes")
// Sum all yes bits from all the agendas.
params := g.Params()
deploymentVer, yesBits, err := findDeploymentAllYesChoices(params, voteIDs)
if err != nil {
g.t.Fatal(err)
}
@ -1310,6 +1353,11 @@ func (g *chaingenHarness) AdvanceFromSVHToActiveAgenda(voteID string) {
stakeValidationHeight := params.StakeValidationHeight
stakeVerInterval := params.StakeVersionInterval
ruleChangeInterval := int64(params.RuleChangeActivationInterval)
testThresholdState := func(state ThresholdState) {
for _, voteID := range voteIDs {
g.TestThresholdState(voteID, state)
}
}
// Only allow this to be called on a harness at SVH.
if g.Tip().Header.Height != uint32(stakeValidationHeight) {
@ -1342,7 +1390,7 @@ func (g *chaingenHarness) AdvanceFromSVHToActiveAgenda(voteID string) {
g.SaveTipCoinbaseOuts()
g.AcceptTipBlock()
}
g.TestThresholdState(voteID, ThresholdStarted)
testThresholdState(ThresholdStarted)
// ---------------------------------------------------------------------
// Generate enough blocks to reach the next rule change interval with
@ -1363,14 +1411,14 @@ func (g *chaingenHarness) AdvanceFromSVHToActiveAgenda(voteID string) {
g.NextBlock(blockName, nil, outs[1:],
chaingen.ReplaceBlockVersion(int32(deploymentVer)),
chaingen.ReplaceStakeVersion(deploymentVer),
chaingen.ReplaceVotes(vbPrevBlockValid|yesChoice.Bits, deploymentVer))
chaingen.ReplaceVotes(vbPrevBlockValid|yesBits, deploymentVer))
g.SaveTipCoinbaseOuts()
g.AcceptTipBlock()
}
g.AssertTipHeight(uint32(stakeValidationHeight + ruleChangeInterval*2 - 1))
g.AssertBlockVersion(int32(deploymentVer))
g.AssertStakeVersion(deploymentVer)
g.TestThresholdState(voteID, ThresholdLockedIn)
testThresholdState(ThresholdLockedIn)
// ---------------------------------------------------------------------
// Generate enough blocks to reach the next rule change interval with
@ -1398,5 +1446,5 @@ func (g *chaingenHarness) AdvanceFromSVHToActiveAgenda(voteID string) {
g.AssertTipHeight(uint32(stakeValidationHeight + ruleChangeInterval*3 - 1))
g.AssertBlockVersion(int32(deploymentVer))
g.AssertStakeVersion(deploymentVer)
g.TestThresholdState(voteID, ThresholdActive)
testThresholdState(ThresholdActive)
}

View File

@ -503,7 +503,7 @@ func TestTSpendVoteCount(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -919,7 +919,7 @@ func TestTSpendEmptyTreasury(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -1096,7 +1096,7 @@ func TestTSpendExpendituresPolicy(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -1595,7 +1595,7 @@ func TestExpendituresReorg(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -1833,7 +1833,7 @@ func TestSpendableTreasuryTxs(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -2131,7 +2131,7 @@ func TestTSpendDupVote(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -2278,7 +2278,7 @@ func TestTSpendTooManyTSpend(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -2392,7 +2392,7 @@ func TestTSpendWindow(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -2515,7 +2515,7 @@ func TestTSpendSignature(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -2733,7 +2733,7 @@ func TestTSpendSignatureInvalid(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -2881,7 +2881,7 @@ func TestTSpendExists(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -3146,7 +3146,7 @@ func TestTreasuryBalance(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -3445,7 +3445,7 @@ func TestTAddCorners(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -3700,7 +3700,7 @@ func TestTreasuryBaseCorners(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -3838,7 +3838,7 @@ func TestTSpendCorners(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -4178,7 +4178,7 @@ func TestTreasuryInRegularTree(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash
@ -4742,7 +4742,7 @@ func TestTSpendTooManyTAdds(t *testing.T) {
// ---------------------------------------------------------------------
g.AdvanceToStakeValidationHeight()
g.AdvanceFromSVHToActiveAgenda(tVoteID)
g.AdvanceFromSVHToActiveAgendas(tVoteID)
// Ensure treasury agenda is active.
tipHash := &g.chain.BestSnapshot().Hash