aboutsummaryrefslogtreecommitdiffstats
path: root/core/consensus_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/consensus_test.go')
-rw-r--r--core/consensus_test.go322
1 files changed, 1 insertions, 321 deletions
diff --git a/core/consensus_test.go b/core/consensus_test.go
index ddaf731..67070d2 100644
--- a/core/consensus_test.go
+++ b/core/consensus_test.go
@@ -19,7 +19,6 @@ package core
import (
"encoding/json"
- "sort"
"testing"
"time"
@@ -186,20 +185,6 @@ func (s *ConsensusTestSuite) newNetworkConnection() *networkConnection {
}
}
-func (s *ConsensusTestSuite) prepareGenesisBlock(
- chainID uint32,
- con *Consensus) *types.Block {
-
- block := &types.Block{
- Position: types.Position{
- ChainID: chainID,
- },
- }
- err := con.PrepareGenesisBlock(block, time.Now().UTC())
- s.Require().NoError(err)
- return block
-}
-
func (s *ConsensusTestSuite) prepareConsensus(
dMoment time.Time,
gov *test.Governance,
@@ -214,7 +199,6 @@ func (s *ConsensusTestSuite) prepareConsensus(
network := conn.newNetwork(nID)
con := NewConsensus(
dMoment, app, gov, dbInst, network, prvKey, &common.NullLogger{})
- con.ccModule.init(&types.Block{})
conn.setCon(nID, con)
return app, con
}
@@ -229,310 +213,6 @@ func (s *ConsensusTestSuite) prepareAgreementMgrWithoutRunning(
}, common.NewRandomHash())
}
-func (s *ConsensusTestSuite) TestSimpleDeliverBlock() {
- // This test scenario:
- // o o o o <- this layer makes older blocks strongly acked.
- // |x|x|x| <- lots of acks.
- // o | o o <- this layer would be sent to total ordering.
- // |\|/|-|
- // | o | | <- the only block which is acked by all other blocks
- // |/|\|\| at the same height.
- // o o o o <- genesis blocks
- // 0 1 2 3 <- index of node ID
- //
- // - This test case only works for Total Ordering with K=0.
- // - Byzantine Agreement layer is not taken into consideration, every
- // block is passed to lattice module directly.
- var (
- req = s.Require()
- nodes []types.NodeID
- conn = s.newNetworkConnection()
- )
- prvKeys, pubKeys, err := test.NewKeys(4)
- s.Require().NoError(err)
- gov, err := test.NewGovernance(test.NewState(
- pubKeys, time.Second, &common.NullLogger{}, true), ConfigRoundShift)
- s.Require().NoError(err)
- minInterval := gov.Configuration(0).MinBlockInterval
- // Setup core.Consensus and test.App.
- objs := map[types.NodeID]*struct {
- app *test.App
- con *Consensus
- }{}
- dMoment := time.Now().UTC()
- for _, key := range prvKeys {
- nID := types.NewNodeID(key.PublicKey())
- app, con := s.prepareConsensus(dMoment, gov, key, conn)
- objs[nID] = &struct {
- app *test.App
- con *Consensus
- }{app, con}
- nodes = append(nodes, nID)
- }
- // It's a helper function to emit one block
- // to all core.Consensus objects.
- broadcast := func(b *types.Block) {
- h := common.NewRandomHash()
- b.Finalization.Randomness = h[:]
- for _, obj := range objs {
- copied := b.Clone()
- obj.con.ccModule.registerBlock(copied)
- req.Nil(obj.con.processBlock(copied))
- }
- }
- // Genesis blocks
- b00 := s.prepareGenesisBlock(0, objs[nodes[0]].con)
- b10 := s.prepareGenesisBlock(1, objs[nodes[1]].con)
- b20 := s.prepareGenesisBlock(2, objs[nodes[2]].con)
- b30 := s.prepareGenesisBlock(3, objs[nodes[3]].con)
- broadcast(b00)
- broadcast(b10)
- broadcast(b20)
- broadcast(b30)
- // Setup b11.
- b11 := &types.Block{
- Position: types.Position{
- ChainID: 1,
- },
- }
- req.NoError(
- objs[nodes[1]].con.prepareBlock(b11, b10.Timestamp.Add(minInterval)))
- req.Len(b11.Acks, 4)
- req.Contains(b11.Acks, b00.Hash)
- req.Contains(b11.Acks, b10.Hash)
- req.Contains(b11.Acks, b20.Hash)
- req.Contains(b11.Acks, b30.Hash)
- broadcast(b11)
- // Setup b01.
- b01 := &types.Block{
- Position: types.Position{
- ChainID: 0,
- },
- }
- req.NoError(
- objs[nodes[0]].con.prepareBlock(b01, b00.Timestamp.Add(minInterval)))
- req.Len(b01.Acks, 4)
- req.Contains(b01.Acks, b00.Hash)
- req.Contains(b01.Acks, b11.Hash)
- req.Contains(b01.Acks, b20.Hash)
- req.Contains(b01.Acks, b30.Hash)
- // Setup b21.
- b21 := &types.Block{
- Position: types.Position{
- ChainID: 2,
- },
- }
- req.NoError(
- objs[nodes[2]].con.prepareBlock(b21, b20.Timestamp.Add(minInterval)))
- req.Len(b21.Acks, 4)
- req.Contains(b21.Acks, b00.Hash)
- req.Contains(b21.Acks, b11.Hash)
- req.Contains(b21.Acks, b20.Hash)
- req.Contains(b21.Acks, b30.Hash)
- // Setup b31.
- b31 := &types.Block{
- Position: types.Position{
- ChainID: 3,
- },
- }
- req.NoError(
- objs[nodes[3]].con.prepareBlock(b31, b30.Timestamp.Add(minInterval)))
- req.Len(b31.Acks, 4)
- req.Contains(b31.Acks, b00.Hash)
- req.Contains(b31.Acks, b11.Hash)
- req.Contains(b31.Acks, b20.Hash)
- req.Contains(b31.Acks, b30.Hash)
- // Broadcast other height=1 blocks.
- broadcast(b01)
- broadcast(b21)
- broadcast(b31)
- // Setup height=2 blocks.
- // Setup b02.
- b02 := &types.Block{
- Position: types.Position{
- ChainID: 0,
- },
- }
- req.NoError(
- objs[nodes[0]].con.prepareBlock(b02, b01.Timestamp.Add(minInterval)))
- req.Len(b02.Acks, 3)
- req.Contains(b02.Acks, b01.Hash)
- req.Contains(b02.Acks, b21.Hash)
- req.Contains(b02.Acks, b31.Hash)
- // Setup b12.
- b12 := &types.Block{
- Position: types.Position{
- ChainID: 1,
- },
- }
- req.NoError(
- objs[nodes[1]].con.prepareBlock(b12, b11.Timestamp.Add(minInterval)))
- req.Len(b12.Acks, 4)
- req.Contains(b12.Acks, b01.Hash)
- req.Contains(b12.Acks, b11.Hash)
- req.Contains(b12.Acks, b21.Hash)
- req.Contains(b12.Acks, b31.Hash)
- // Setup b22.
- b22 := &types.Block{
- Position: types.Position{
- ChainID: 2,
- },
- }
- req.NoError(
- objs[nodes[2]].con.prepareBlock(b22, b21.Timestamp.Add(minInterval)))
- req.Len(b22.Acks, 3)
- req.Contains(b22.Acks, b01.Hash)
- req.Contains(b22.Acks, b21.Hash)
- req.Contains(b22.Acks, b31.Hash)
- // Setup b32.
- b32 := &types.Block{
- Position: types.Position{
- ChainID: 3,
- },
- }
- req.NoError(
- objs[nodes[3]].con.prepareBlock(b32, b31.Timestamp.Add(minInterval)))
- req.Len(b32.Acks, 3)
- req.Contains(b32.Acks, b01.Hash)
- req.Contains(b32.Acks, b21.Hash)
- req.Contains(b32.Acks, b31.Hash)
- // Broadcast blocks at height=2.
- broadcast(b02)
- broadcast(b12)
- broadcast(b22)
- broadcast(b32)
-
- // Verify the cached status of each app.
- verify := func(app *test.App) {
- req.Contains(app.Confirmed, b00.Hash)
- req.Contains(app.Confirmed, b10.Hash)
- req.Contains(app.Confirmed, b20.Hash)
- req.Contains(app.Confirmed, b30.Hash)
- req.Contains(app.Confirmed, b01.Hash)
- req.Contains(app.Confirmed, b11.Hash)
- req.Contains(app.Confirmed, b21.Hash)
- req.Contains(app.Confirmed, b31.Hash)
- // Genesis blocks are delivered by total ordering as a set.
- delivered0 := common.Hashes{b00.Hash, b10.Hash, b20.Hash, b30.Hash}
- sort.Sort(delivered0)
- req.Len(app.TotalOrdered, 4)
- req.Equal(app.TotalOrdered[0].BlockHashes, delivered0)
- req.Equal(app.TotalOrdered[0].Mode, TotalOrderingModeNormal)
- // b11 is the sencond set delivered by total ordering.
- delivered1 := common.Hashes{b11.Hash}
- sort.Sort(delivered1)
- req.Equal(app.TotalOrdered[1].BlockHashes, delivered1)
- req.Equal(app.TotalOrdered[1].Mode, TotalOrderingModeNormal)
- // b01, b21, b31 are the third set delivered by total ordering.
- delivered2 := common.Hashes{b01.Hash, b21.Hash, b31.Hash}
- sort.Sort(delivered2)
- req.Equal(app.TotalOrdered[2].BlockHashes, delivered2)
- req.Equal(app.TotalOrdered[2].Mode, TotalOrderingModeNormal)
- // b02, b12, b22, b32 are the fourth set delivered by total ordering.
- delivered3 := common.Hashes{b02.Hash, b12.Hash, b22.Hash, b32.Hash}
- sort.Sort(delivered3)
- req.Equal(app.TotalOrdered[3].BlockHashes, delivered3)
- req.Equal(app.TotalOrdered[3].Mode, TotalOrderingModeNormal)
- // Check generated timestamps.
- req.Contains(app.Delivered, b00.Hash)
- req.Contains(app.Delivered, b10.Hash)
- req.Contains(app.Delivered, b20.Hash)
- req.Contains(app.Delivered, b30.Hash)
- req.Contains(app.Delivered, b11.Hash)
- // Check timestamps, there is no direct way to know which block is
- // selected as main chain, we can only detect it by making sure
- // its ConsensusTimestamp is not interpolated.
- timestamps := make([]time.Time, 4)
- timestamps[0] = b00.Timestamp
- timestamps[1] = b10.Timestamp
- timestamps[2] = b20.Timestamp
- timestamps[3] = b30.Timestamp
- t, err := getMedianTime(timestamps)
- req.NoError(err)
- req.Equal(t, app.Delivered[b11.Hash].Result.Timestamp)
- }
- for _, obj := range objs {
- if nb, ok := obj.con.app.(*nonBlocking); ok {
- nb.wait()
- }
- verify(obj.app)
- req.NoError(test.VerifyDB(obj.con.db))
- }
-}
-
-func (s *ConsensusTestSuite) TestPrepareBlock() {
- // This test case would test these steps:
- // - Add all genesis blocks into lattice.
- // - Make sure Consensus.prepareBlock would attempt to ack
- // all genesis blocks.
- // - Add the prepared block into lattice.
- // - Make sure Consensus.prepareBlock would only attempt to
- // ack the prepared block.
- var (
- req = s.Require()
- nodes []types.NodeID
- conn = s.newNetworkConnection()
- )
- prvKeys, pubKeys, err := test.NewKeys(4)
- s.Require().NoError(err)
- gov, err := test.NewGovernance(test.NewState(
- pubKeys, time.Second, &common.NullLogger{}, true), ConfigRoundShift)
- s.Require().NoError(err)
- dMoment := time.Now().UTC()
- // Setup core.Consensus and test.App.
- cons := map[types.NodeID]*Consensus{}
- for _, key := range prvKeys {
- _, con := s.prepareConsensus(dMoment, gov, key, conn)
- s.prepareAgreementMgrWithoutRunning(con, 4)
- nID := types.NewNodeID(key.PublicKey())
- cons[nID] = con
- nodes = append(nodes, nID)
- }
- b00 := s.prepareGenesisBlock(0, cons[nodes[0]])
- b10 := s.prepareGenesisBlock(1, cons[nodes[1]])
- b20 := s.prepareGenesisBlock(2, cons[nodes[2]])
- b30 := s.prepareGenesisBlock(3, cons[nodes[3]])
- for _, con := range cons {
- req.Nil(con.processBlock(b00))
- req.Nil(con.processBlock(b10))
- req.Nil(con.processBlock(b20))
- req.Nil(con.processBlock(b30))
- }
- b11 := &types.Block{
- Position: types.Position{ChainID: b10.Position.ChainID},
- }
- interval := gov.Configuration(0).MinBlockInterval
- req.Nil(cons[nodes[1]].prepareBlock(b11, b10.Timestamp.Add(interval)))
- for _, con := range cons {
- req.Nil(con.preProcessBlock(b11))
- req.Nil(con.processBlock(b11))
- }
- b12 := &types.Block{
- Position: types.Position{ChainID: b11.Position.ChainID},
- }
- req.Nil(cons[nodes[1]].prepareBlock(b12, b11.Timestamp.Add(interval)))
- req.Len(b12.Acks, 1)
- req.Contains(b12.Acks, b11.Hash)
-}
-
-func (s *ConsensusTestSuite) TestPrepareGenesisBlock() {
- conn := s.newNetworkConnection()
- prvKeys, pubKeys, err := test.NewKeys(4)
- s.Require().NoError(err)
- gov, err := test.NewGovernance(test.NewState(
- pubKeys, time.Second, &common.NullLogger{}, true), ConfigRoundShift)
- s.Require().NoError(err)
- prvKey := prvKeys[0]
- _, con := s.prepareConsensus(time.Now().UTC(), gov, prvKey, conn)
- s.prepareAgreementMgrWithoutRunning(con, 4)
- block := &types.Block{
- Position: types.Position{ChainID: 0},
- }
- s.Require().NoError(con.PrepareGenesisBlock(block, time.Now().UTC()))
- s.True(block.IsGenesis())
- s.NoError(con.preProcessBlock(block))
-}
-
func (s *ConsensusTestSuite) TestDKGCRS() {
n := 21
lambda := 200 * time.Millisecond
@@ -620,7 +300,7 @@ func (s *ConsensusTestSuite) TestSyncBA() {
// - the ticker is 1 lambdaa.
time.Sleep(5 * lambdaBA)
s.Require().NoError(con.ProcessAgreementResult(baResult))
- aID := con.baMgr.baModules[0].agreementID()
+ aID := con.baMgr.baModule.agreementID()
s.Equal(pos, aID)
// Negative cases are moved to TestVerifyAgreementResult in utils_test.go.