Skip to content

Commit

Permalink
(fix) Remove t.Skip: TestSimulateValidatorsChange
Browse files Browse the repository at this point in the history
  • Loading branch information
tnasu committed Aug 27, 2021
1 parent 68521b8 commit 566220f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 80 deletions.
2 changes: 1 addition & 1 deletion consensus/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func ResetConfig(name string) *cfg.Config {
// validator stub (a kvstore consensus peer we control)

type validatorStub struct {
Index int32 // Validator index. NOTE: we don't assume validator set changes.
Index int32 // Voter index. NOTE: we don't assume validator set changes.
Height int64
Round int32
types.PrivValidator
Expand Down
135 changes: 56 additions & 79 deletions consensus/replay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,32 +331,20 @@ func getProposerIdx(state *State, height int64, round int32) (int32, *types.Vali
return state.Voters.GetByAddress(proposer.PubKey.Address())
}

func createProposalBlock(cs *State, proposerState *State, round int32) (*types.Block, *types.PartSet) {
var commit *types.Commit
if cs.Height == 1 {
commit = types.NewCommit(0, 0, types.BlockID{}, nil)
} else {
commit = cs.LastCommit.MakeCommit()
}
pubKey, _ := proposerState.privValidator.GetPubKey()
proposerAddr := pubKey.Address()
message := cs.state.MakeHashMessage(round)
proof, err := proposerState.privValidator.GenerateVRFProof(message)
if err != nil {
cs.Logger.Error("enterPropose: Cannot generate vrf proof: %s", err.Error())
return nil, nil
}
return cs.blockExec.CreateProposalBlock(cs.Height, cs.state, commit, proposerAddr, round, proof)
}
func consensusNewBlock(t *testing.T, height int64, vss []*validatorStub, css []*State,
newRoundCh, proposalCH <-chan tmpubsub.Message, addTxFn func()) {

func consensusNewBlock(t *testing.T, height int64, vss []*validatorStub, css []*State, selfIndex int,
newRoundCh, proposalCH <-chan tmpubsub.Message, voterList []int, addTxFn func()) {
// perform added tx
if addTxFn != nil {
addTxFn()
}

proposerIdx, prop := getProposerIdx(css[0], height, 0)
// state0 is main started machine (css[0])
cs := css[0]
csPubKey, err := cs.privValidator.GetPubKey()
require.NoError(t, err)
proposerIdx, prop := getProposerIdx(cs, height, 0)

// search idx of proposer in the css
proposerIdxOfCSS := 0
for i, cs := range css {
Expand All @@ -368,48 +356,49 @@ func consensusNewBlock(t *testing.T, height int64, vss []*validatorStub, css []*
}
}

// state0 is main started machine (css[0])
if proposerIdxOfCSS == 0 {
ensureNewProposal(proposalCH, height, 0)
rs := css[0].GetRoundState()
for i, voterIdx := range voterList {
if i == selfIndex {
continue
}
signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[voterIdx])
// make idx of voter in the vss
proposerIdxOfVSS := 0
voterSet := cs.Voters
vssIndexOfVoterList := make([]int, len(voterSet.Voters)-1)
var idx = 0
for i, vs := range vss {
vsPubKey, err := vs.GetPubKey()
require.NoError(t, err)
if vsPubKey.Equals(csPubKey) {
continue
}
} else {
propBlock, _ := createProposalBlock(css[0], css[proposerIdxOfCSS], 0)
propBlockParts := propBlock.MakePartSet(types.BlockPartSizeBytes)
blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
proposal := types.NewProposal(vss[proposerIdx].Height, 0, -1, blockID)
p := proposal.ToProto()
if err := vss[proposerIdx].SignProposal(config.ChainID(), p); err != nil {
t.Fatal("failed to sign bad proposal", err)
index, voter := voterSet.GetByAddress(vsPubKey.Address())
if index == -1 && voter == nil {
continue
}
if index == proposerIdx {
proposerIdxOfVSS = i
}
proposal.Signature = p.Signature
vs.Index = index // Update validatorStub.Index for signAndVote since VoterSet's order is changed
vssIndexOfVoterList[idx] = i
idx++
}

if proposerIdxOfCSS != 0 {
proposal, propBlock := decideProposal(cs, vss[proposerIdxOfVSS], height, 0)
propBlockParts := propBlock.MakePartSet(types.BlockPartSizeBytes)
// set the proposal block
if err := css[0].SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil {
if err := cs.SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err)
}
ensureNewProposal(proposalCH, height, 0)
rs := css[0].GetRoundState()
for i, voterIdx := range voterList {
if i == selfIndex {
continue
}
signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[voterIdx])
}
}

ensureNewProposal(proposalCH, height, 0)
rs := cs.GetRoundState()
for _, voterIdx := range vssIndexOfVoterList {
signAddVotes(cs, tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[voterIdx])
}

ensureNewRound(newRoundCh, height+1, 0)
}

// This is actually not a test, it's for storing validator change tx data for testHandshakeReplay
func TestSimulateValidatorsChange(t *testing.T) {
t.Skipf("We will skip this test case and prepare another one later" +
" because it's difficult to apply to random sampling with VRF.")
const nPeers = 7
const nVals = 4
css, genDoc, config, cleanup := randConsensusNetWithPeers(
Expand Down Expand Up @@ -437,15 +426,15 @@ func TestSimulateValidatorsChange(t *testing.T) {
ensureNewRound(newRoundCh, height, 0)

// height 1
consensusNewBlock(t, height, vss, css, -1, newRoundCh, proposalCh, []int{1, 2, 3}, nil)
consensusNewBlock(t, height, vss, css, newRoundCh, proposalCh, nil)

// height 2
height++
incrementHeight(vss...)

// proposal.Signature = p.Signature

consensusNewBlock(t, height, vss, css, -1, newRoundCh, proposalCh, []int{1, 2, 3}, func() {
consensusNewBlock(t, height, vss, css, newRoundCh, proposalCh, func() {
newValidatorPubKey1, err := css[nVals].privValidator.GetPubKey()
assert.Nil(t, err)
valPubKey1ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey1)
Expand All @@ -459,7 +448,7 @@ func TestSimulateValidatorsChange(t *testing.T) {
height++
incrementHeight(vss...)

consensusNewBlock(t, height, vss, css, -1, newRoundCh, proposalCh, []int{1, 2, 3}, func() {
consensusNewBlock(t, height, vss, css, newRoundCh, proposalCh, func() {
updateValidatorPubKey1, err := css[nVals].privValidator.GetPubKey()
require.NoError(t, err)
updatePubKey1ABCI, err := cryptoenc.PubKeyToProto(updateValidatorPubKey1)
Expand All @@ -475,27 +464,8 @@ func TestSimulateValidatorsChange(t *testing.T) {
newVss := make([]*validatorStub, nVals+1)
copy(newVss, vss[:nVals+1])
sort.Sort(ValidatorStubsByPower(newVss))
voterList := make([]int, nVals)

// re-calculate voterList
valIndexFn := func(cssIdx int) int {
for i, vs := range newVss {
vsPubKey, err := vs.GetPubKey()
require.NoError(t, err)

cssPubKey, err := css[cssIdx].privValidator.GetPubKey()
require.NoError(t, err)

if vsPubKey.Equals(cssPubKey) {
return i
}
}
panic(fmt.Sprintf("validator css[%d] not found in newVss", cssIdx))
}

selfIndex := valIndexFn(0)

consensusNewBlock(t, height, newVss, css, selfIndex, newRoundCh, proposalCh, voterList, func() {
consensusNewBlock(t, height, newVss, css, newRoundCh, proposalCh, func() {
newValidatorPubKey2, err := css[nVals+1].privValidator.GetPubKey()
require.NoError(t, err)
newVal2ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey2)
Expand All @@ -515,10 +485,21 @@ func TestSimulateValidatorsChange(t *testing.T) {
// height 5
height++
incrementHeight(vss...)
consensusNewBlock(t, height, newVss, css, selfIndex, newRoundCh, proposalCh, voterList, nil)
consensusNewBlock(t, height, newVss, css, newRoundCh, proposalCh, nil)

// Reflect the changes to vss[nVals] at height 3 and resort newVss.
newVssIdx := valIndexFn(nVals)
newVssIdx := func(cssIdx int) int {
for i, vs := range newVss {
vsPubKey, err := vs.GetPubKey()
require.NoError(t, err)
cssPubKey, err := css[cssIdx].privValidator.GetPubKey()
require.NoError(t, err)
if vsPubKey.Equals(cssPubKey) {
return i
}
}
panic(fmt.Sprintf("validator css[%d] not found in newVss", cssIdx))
}(nVals)
newVss[newVssIdx].VotingPower = 25
sort.Sort(ValidatorStubsByPower(newVss))

Expand All @@ -531,11 +512,7 @@ func TestSimulateValidatorsChange(t *testing.T) {
copy(newVss, vss[:nVals+3])
sort.Sort(ValidatorStubsByPower(newVss))

// re-calculate voterList
voterList = make([]int, nVals+2)
selfIndex = valIndexFn(0)

consensusNewBlock(t, height, newVss, css, selfIndex, newRoundCh, proposalCh, voterList, func() {
consensusNewBlock(t, height, newVss, css, newRoundCh, proposalCh, func() {
newValidatorPubKey3, err := css[nVals+2].privValidator.GetPubKey()
require.NoError(t, err)
newVal3ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey3)
Expand Down

0 comments on commit 566220f

Please sign in to comment.