Skip to content

Commit

Permalink
test: fix random test failures (#1381)
Browse files Browse the repository at this point in the history
  • Loading branch information
b00f authored Jun 29, 2024
1 parent e9a21b3 commit 23613ac
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 79 deletions.
2 changes: 1 addition & 1 deletion cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ func makeLocalGenesis(w wallet.Wallet) *genesis.Genesis {
crypto.TreasuryAddress: acc,
}

genValNum := 6
genValNum := 4
vals := make([]*validator.Validator, genValNum)
for i := 0; i < genValNum; i++ {
info := w.AddressInfo(w.AddressInfos()[i].Address)
Expand Down
4 changes: 2 additions & 2 deletions committee/committee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ func TestContains(t *testing.T) {
func TestProposer(t *testing.T) {
ts := testsuite.NewTestSuite(t)

cmt, _ := ts.GenerateTestCommittee(6)
cmt, _ := ts.GenerateTestCommittee(4)

assert.Equal(t, cmt.Proposer(0).Number(), int32(0))
assert.Equal(t, cmt.Proposer(3).Number(), int32(3))
assert.Equal(t, cmt.Proposer(6).Number(), int32(0))
assert.Equal(t, cmt.Proposer(4).Number(), int32(0))

cmt.Update(0, nil)
assert.Equal(t, cmt.Proposer(0).Number(), int32(1))
Expand Down
32 changes: 17 additions & 15 deletions network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,12 @@ func TestStoppingNetwork(t *testing.T) {
// - M, N, and X are Private Nodes behind a Network Address Translation (NAT)
// - M and N have relay enabled, while X does not.
//
// The test will evaluate the following scenarios:
// The test evaluates the following scenarios:
// - Get supporting protocols
// - Connection establishment to the bootstrap node
// - bLOCK and consensus topics and gossip message
// - Direct and relayed stream communication between nodes
// - Receiving gossip message
// - Receiving direct message
// - Receiving relayed message (Not covered yet!)
func TestNetwork(t *testing.T) {
ts := testsuite.NewTestSuite(t)

Expand Down Expand Up @@ -207,10 +209,10 @@ func TestNetwork(t *testing.T) {
assert.NoError(t, networkN.JoinTopic(TopicIDConsensus, alwaysPropagate))
// Network X doesn't join the consensus topic

time.Sleep(2 * time.Second)
time.Sleep(4 * time.Second)

t.Run("Supported Protocols", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

require.EventuallyWithT(t, func(_ *assert.CollectT) {
protos := networkM.Protocols()
Expand All @@ -232,7 +234,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("all nodes have at least one connection to the bootstrap node B", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

assert.EventuallyWithT(t, func(c *assert.CollectT) {
assert.GreaterOrEqual(c, networkP.NumConnectedPeers(), 1) // Connected to B, M, N, X
Expand All @@ -256,7 +258,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("Gossip: all nodes receive gossip messages", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

msg := ts.RandBytes(64)

Expand All @@ -274,7 +276,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("only nodes subscribed to the consensus topic receive consensus gossip messages", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

msg := ts.RandBytes(64)

Expand All @@ -291,7 +293,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("node P (public) is directly accessible by nodes M and N (private behind NAT)", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

require.NoError(t, networkM.host.Connect(networkM.ctx, *publicAddrInfo))

Expand All @@ -303,7 +305,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("node P (public) is directly accessible by node X (private behind NAT, without relay)", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

require.NoError(t, networkX.host.Connect(networkX.ctx, *publicAddrInfo))

Expand All @@ -315,7 +317,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("node P (public) is directly accessible by node B (bootstrap)", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

msgB := ts.RandBytes(64)

Expand All @@ -326,7 +328,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("Ignore broadcasting identical messages", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

msg := ts.RandBytes(64)

Expand All @@ -343,7 +345,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("node X (private, not connected via relay) is not accessible by node M", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

msgM := ts.RandBytes(64)
networkM.SendTo(msgM, networkX.SelfID())
Expand All @@ -358,7 +360,7 @@ func TestNetwork(t *testing.T) {
// })

t.Run("closing connection", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

msgB := ts.RandBytes(64)

Expand All @@ -370,7 +372,7 @@ func TestNetwork(t *testing.T) {
})

t.Run("Reachability Status", func(t *testing.T) {
t.Log(t.Name())
fmt.Printf("Running %s\n", t.Name())

assert.Equal(t, networkP.ReachabilityStatus(), "Public")
assert.Equal(t, networkB.ReachabilityStatus(), "Public")
Expand Down
1 change: 1 addition & 0 deletions node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func TestRunningNode(t *testing.T) {
conf.Store.Path = util.TempDirPath()
conf.Network.EnableRelay = false
conf.Network.NetworkKey = util.TempFilePath()
conf.Network.PeerStorePath = util.TempFilePath()

valKeys := []*bls.ValidatorKey{ts.RandValKey(), ts.RandValKey()}
rewardAddrs := []crypto.Address{ts.RandAccAddress(), ts.RandAccAddress()}
Expand Down
6 changes: 3 additions & 3 deletions state/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func TestProposeBlock(t *testing.T) {
assert.True(t, blk.Transactions()[0].IsSubsidyTx())
assert.NoError(t, td.state.CommitBlock(blk, cert))

assert.Equal(t, td.state.TotalPower(), int64(1000000006))
assert.Equal(t, td.state.committee.TotalPower(), int64(6))
assert.Equal(t, td.state.TotalPower(), int64(1000000004))
assert.Equal(t, td.state.committee.TotalPower(), int64(4))
}

func TestExecuteBlock(t *testing.T) {
Expand Down Expand Up @@ -139,6 +139,6 @@ func TestExecuteBlock(t *testing.T) {
// Check if fee is claimed
treasury := sb.Account(crypto.TreasuryAddress)
subsidy := td.state.params.BlockReward
assert.Equal(t, treasury.Balance(), 21*1e15-(12*subsidy)) // Two blocks has committed yet
assert.Equal(t, treasury.Balance(), 21*1e15-(10*subsidy)) // Two extra blocks has committed yet
})
}
92 changes: 42 additions & 50 deletions state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func setup(t *testing.T) *testData {

ts := testsuite.NewTestSuite(t)

genValNum := 6
genValNum := 4
genValKeys := make([]*bls.ValidatorKey, 0, genValNum)
genVals := make([]*validator.Validator, 0, genValNum)
for i := 0; i < genValNum; i++ {
Expand Down Expand Up @@ -72,7 +72,8 @@ func setup(t *testing.T) *testData {

gnDoc := genesis.MakeGenesis(genTime, genAccs, genVals, params)

valKeys := []*bls.ValidatorKey{ts.RandValKey(), ts.RandValKey()}
// First validator is in the committee
valKeys := []*bls.ValidatorKey{genValKeys[0], ts.RandValKey()}
st1, err := LoadOrNewState(gnDoc, valKeys, mockStore, mockTxPool, nil)
require.NoError(t, err)

Expand All @@ -86,7 +87,7 @@ func setup(t *testing.T) *testData {
commonTxPool: mockTxPool,
}

td.commitBlocks(t, 10)
td.commitBlocks(t, 8)

return td
}
Expand Down Expand Up @@ -116,8 +117,8 @@ func (td *testData) makeCertificateAndSign(t *testing.T, blockHash hash.Hash,
height := td.state.LastBlockHeight()
cert := certificate.NewBlockCertificate(height+1, round, true)
signBytes := cert.SignBytes(blockHash)
committers := []int32{0, 1, 2, 3, 4, 5}
absentees := []int32{5}
committers := []int32{0, 1, 2, 3}
absentees := []int32{3}

for _, key := range td.genValKeys[:len(td.genValKeys)-1] {
sig := key.Sign(signBytes)
Expand Down Expand Up @@ -191,7 +192,7 @@ func TestTryCommitValidBlocks(t *testing.T) {
assert.Equal(t, td.state.LastBlockHash(), blk.Hash())
assert.Equal(t, td.state.LastBlockTime(), blk.Header().Time())
assert.Equal(t, td.state.LastCertificate().Hash(), crt.Hash())
assert.Equal(t, td.state.LastBlockHeight(), uint32(11))
assert.Equal(t, td.state.LastBlockHeight(), uint32(9))
}

func TestCommitSandbox(t *testing.T) {
Expand Down Expand Up @@ -333,34 +334,25 @@ func TestUpdateLastCertificate(t *testing.T) {
}
}

// func TestBlockProposal(t *testing.T) {
// td := setup(t)

// t.Run("validity of proposed block", func(t *testing.T) {
// b, err := td.state.ProposeBlock(td.state.valKeys[0], td.RandAccAddress())
// assert.NoError(t, err)
// assert.NoError(t, td.state.ValidateBlock(b, 0))
// })

// t.Run("Tx pool has two subsidy transactions", func(t *testing.T) {
// trx := td.state.createSubsidyTx(td.RandAccAddress(), 0)
// assert.NoError(t, td.state.AddPendingTx(trx))
func TestBlockProposal(t *testing.T) {
td := setup(t)

// // Moving to the next round
// b, err := td.state.ProposeBlock(td.state.valKeys[0], td.RandAccAddress())
// assert.NoError(t, err)
// assert.NoError(t, td.state.ValidateBlock(b, 0))
// assert.Equal(t, b.Transactions().Len(), 1)
// })
// }
t.Run("validity of the proposed block", func(t *testing.T) {
b, err := td.state.ProposeBlock(td.state.valKeys[0], td.RandAccAddress())
assert.NoError(t, err)
assert.NoError(t, td.state.ValidateBlock(b, 0))
})

// func TestInvalidBlock(t *testing.T) {
// td := setup(t)
t.Run("Tx pool has two subsidy transactions", func(t *testing.T) {
trx := td.state.createSubsidyTx(td.RandAccAddress(), 0)
assert.NoError(t, td.state.AddPendingTx(trx))

// panic("test coverage")
// invBlk, _ := td.GenerateTestBlock(td.RandHeight())
// assert.Error(t, td.state.ValidateBlock(invBlk))
// }
b, err := td.state.ProposeBlock(td.state.valKeys[0], td.RandAccAddress())
assert.NoError(t, err)
assert.NoError(t, td.state.ValidateBlock(b, 0))
assert.Equal(t, b.Transactions().Len(), 1)
})
}

func TestForkDetection(t *testing.T) {
td := setup(t)
Expand Down Expand Up @@ -399,34 +391,34 @@ func TestForkDetection(t *testing.T) {
func TestSortition(t *testing.T) {
td := setup(t)

myValKey := td.state.valKeys[0]
secValKey := td.state.valKeys[1]
assert.False(t, td.state.evaluateSortition()) // not a validator
assert.False(t, td.state.IsValidator(myValKey.Address()))
assert.Equal(t, td.state.CommitteePower(), int64(6))
assert.False(t, td.state.IsValidator(secValKey.Address()))
assert.Equal(t, td.state.CommitteePower(), int64(4))

trx := tx.NewBondTx(1, td.genAccKey.PublicKeyNative().AccountAddress(),
myValKey.Address(), myValKey.PublicKey(), 1000000000, 100000, "")
secValKey.Address(), secValKey.PublicKey(), 1000000000, 100000, "")
td.HelperSignTransaction(td.genAccKey, trx)
assert.NoError(t, td.state.AddPendingTx(trx))

td.commitBlocks(t, 1)

assert.False(t, td.state.evaluateSortition()) // bonding period
assert.True(t, td.state.IsValidator(myValKey.Address()))
assert.Equal(t, td.state.CommitteePower(), int64(6))
assert.False(t, td.state.committee.Contains(myValKey.Address())) // Not in the committee
assert.True(t, td.state.IsValidator(secValKey.Address()))
assert.Equal(t, td.state.CommitteePower(), int64(4))
assert.False(t, td.state.committee.Contains(secValKey.Address())) // Not in the committee

// Committing another 10 blocks
td.commitBlocks(t, 10)

assert.True(t, td.state.evaluateSortition()) // OK
assert.False(t, td.state.committee.Contains(myValKey.Address())) // Still not in the committee
assert.True(t, td.state.evaluateSortition()) // OK
assert.False(t, td.state.committee.Contains(secValKey.Address())) // Still not in the committee

td.commitBlocks(t, 1)

assert.True(t, td.state.IsValidator(myValKey.Address()))
assert.Equal(t, td.state.CommitteePower(), int64(1000000006))
assert.True(t, td.state.committee.Contains(myValKey.Address())) // In the committee
assert.True(t, td.state.IsValidator(secValKey.Address()))
assert.Equal(t, td.state.CommitteePower(), int64(1000000004))
assert.True(t, td.state.committee.Contains(secValKey.Address())) // In the committee
}

func TestValidateBlockTime(t *testing.T) {
Expand Down Expand Up @@ -475,9 +467,9 @@ func TestValidateBlockTime(t *testing.T) {
assert.NoError(t, td.state.validateBlockTime(roundedNow.Add(10*time.Second)))

// More than the threshold
assert.Error(t, td.state.validateBlockTime(roundedNow.Add(20*time.Second)))
assert.Error(t, td.state.validateBlockTime(roundedNow.Add(30*time.Second)))

expectedProposeTime := roundedNow
expectedProposeTime := util.RoundNow(10)
assert.Equal(t, expectedProposeTime, td.state.proposeNextBlockTime())
})

Expand Down Expand Up @@ -562,8 +554,8 @@ func TestLoadState(t *testing.T) {
assert.Equal(t, td.state.Params(), newState.Params())
assert.ElementsMatch(t, td.state.ValidatorAddresses(), newState.ValidatorAddresses())

assert.Equal(t, int32(13), td.state.TotalAccounts()) // 11 subsidy addrs + 2 genesis addrs
assert.Equal(t, int32(7), td.state.TotalValidators())
assert.Equal(t, int32(11), td.state.TotalAccounts()) // 9 subsidy addrs + 2 genesis addrs
assert.Equal(t, int32(5), td.state.TotalValidators())

// Try committing the next block
require.NoError(t, newState.CommitBlock(blk6, cert6))
Expand All @@ -577,7 +569,7 @@ func TestLoadStateAfterChangingGenesis(t *testing.T) {
require.NoError(t, err)

pub, _ := td.RandBLSKeyPair()
val := validator.NewValidator(pub, 6)
val := validator.NewValidator(pub, 4)
newVals := append(td.state.genDoc.Validators(), val)

genDoc := genesis.MakeGenesis(
Expand All @@ -596,8 +588,8 @@ func TestIsValidator(t *testing.T) {
td := setup(t)

assert.True(t, td.state.IsInCommittee(td.genValKeys[0].Address()))
assert.True(t, td.state.IsProposer(td.genValKeys[4].Address(), 0))
assert.True(t, td.state.IsProposer(td.genValKeys[5].Address(), 1))
assert.True(t, td.state.IsProposer(td.genValKeys[0].Address(), 0))
assert.True(t, td.state.IsProposer(td.genValKeys[1].Address(), 1))
assert.True(t, td.state.IsInCommittee(td.genValKeys[1].Address()))
assert.True(t, td.state.IsValidator(td.genValKeys[1].Address()))

Expand Down
Loading

0 comments on commit 23613ac

Please sign in to comment.