diff options
author | Mission Liao <mission.liao@dexon.org> | 2019-02-15 14:18:59 +0800 |
---|---|---|
committer | Jimmy Hu <jimmy.hu@dexon.org> | 2019-02-19 10:48:50 +0800 |
commit | 4dbdc22e355cf1f6f0c39af1b2f3737b7527bc0c (patch) | |
tree | 625b7d34aa700d072ffb8e68dc89ed3936b76d29 /core/consensus_test.go | |
parent | e4825619fb2499f5f534537c1a4d52d3e0bcacfe (diff) | |
download | dexon-consensus-4dbdc22e355cf1f6f0c39af1b2f3737b7527bc0c.tar.gz dexon-consensus-4dbdc22e355cf1f6f0c39af1b2f3737b7527bc0c.tar.zst dexon-consensus-4dbdc22e355cf1f6f0c39af1b2f3737b7527bc0c.zip |
big-bang: single chain (#446)
Diffstat (limited to 'core/consensus_test.go')
-rw-r--r-- | core/consensus_test.go | 322 |
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. |