diff options
-rw-r--r-- | core/consensus.go | 22 | ||||
-rw-r--r-- | core/consensus_test.go | 16 | ||||
-rw-r--r-- | core/reliable-broadcast_test.go | 98 | ||||
-rw-r--r-- | core/test/blocks-generator.go | 30 | ||||
-rw-r--r-- | core/test/blocks-generator_test.go | 19 | ||||
-rw-r--r-- | core/test/revealer_test.go | 14 | ||||
-rw-r--r-- | core/test/utils.go | 31 | ||||
-rw-r--r-- | core/total-ordering_test.go | 2 |
8 files changed, 162 insertions, 70 deletions
diff --git a/core/consensus.go b/core/consensus.go index bc6a2d7..b1b1973 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -18,6 +18,7 @@ package core import ( + "fmt" "sync" "time" @@ -36,6 +37,11 @@ func (e *ErrMissingBlockInfo) Error() string { return "missing " + e.MissingField + " in block" } +// Errors for sanity check error. +var ( + ErrIncorrectHash = fmt.Errorf("hash of block is incorrect") +) + // Consensus implements DEXON Consensus algorithm. type Consensus struct { app Application @@ -76,8 +82,23 @@ func NewConsensus( } } +// sanityCheck checks if the block is a valid block +func (con *Consensus) sanityCheck(blockConv types.BlockConverter) (err error) { + b := blockConv.Block() + // Check the hash of block. + hash, err := hashBlock(blockConv) + if err != nil || hash != b.Hash { + return ErrIncorrectHash + } + + return nil +} + // ProcessBlock is the entry point to submit one block to a Consensus instance. func (con *Consensus) ProcessBlock(blockConv types.BlockConverter) (err error) { + if err := con.sanityCheck(blockConv); err != nil { + return err + } b := blockConv.Block() var ( deliveredBlocks []*types.Block @@ -144,6 +165,7 @@ func (con *Consensus) PrepareBlock(blockConv types.BlockConverter, con.rbModule.prepareBlock(b) b.Timestamps[b.ProposerID] = proposeTime + b.Hash, err = hashBlock(b) blockConv.SetBlock(b) return } diff --git a/core/consensus_test.go b/core/consensus_test.go index 84542fd..c26e7e8 100644 --- a/core/consensus_test.go +++ b/core/consensus_test.go @@ -37,11 +37,9 @@ func (s *ConsensusTestSuite) prepareGenesisBlock( proposerID types.ValidatorID, gov Governance) *types.Block { - hash := common.NewRandomHash() block := &types.Block{ ProposerID: proposerID, ParentHash: common.Hash{}, - Hash: hash, Height: 0, Acks: make(map[common.Hash]struct{}), Timestamps: make(map[types.ValidatorID]time.Time), @@ -50,6 +48,9 @@ func (s *ConsensusTestSuite) prepareGenesisBlock( block.Timestamps[vID] = time.Time{} } block.Timestamps[proposerID] = time.Now().UTC() + var err error + block.Hash, err = hashBlock(block) + s.Require().Nil(err) return block } @@ -121,8 +122,10 @@ func (s *ConsensusTestSuite) TestSimpleDeliverBlock() { time.Sleep(minInterval) b11 := &types.Block{ ProposerID: validators[1], - Hash: common.NewRandomHash(), } + var err error + b11.Hash, err = hashBlock(b11) + s.Require().Nil(err) req.Nil(objs[validators[1]].con.PrepareBlock(b11, time.Now().UTC())) req.Len(b11.Acks, 4) req.Contains(b11.Acks, b00.Hash) @@ -280,8 +283,10 @@ func (s *ConsensusTestSuite) TestPrepareBlock() { req.Nil(con.ProcessBlock(b30)) b11 := &types.Block{ ProposerID: validators[1], - Hash: common.NewRandomHash(), } + var err error + b11.Hash, err = hashBlock(b11) + s.Require().Nil(err) // Sleep to make sure 'now' is slower than b10's timestamp. time.Sleep(100 * time.Millisecond) req.Nil(con.PrepareBlock(b11, time.Now().UTC())) @@ -293,8 +298,9 @@ func (s *ConsensusTestSuite) TestPrepareBlock() { req.Nil(con.ProcessBlock(b11)) b12 := &types.Block{ ProposerID: validators[1], - Hash: common.NewRandomHash(), } + b12.Hash, err = hashBlock(b12) + s.Require().Nil(err) req.Nil(con.PrepareBlock(b12, time.Now().UTC())) req.Len(b12.Acks, 1) req.Contains(b12.Acks, b11.Hash) diff --git a/core/reliable-broadcast_test.go b/core/reliable-broadcast_test.go index 220a997..fc90133 100644 --- a/core/reliable-broadcast_test.go +++ b/core/reliable-broadcast_test.go @@ -52,7 +52,6 @@ func (s *ReliableBroadcastTest) prepareGenesisBlock( b = &types.Block{ ProposerID: proposerID, ParentHash: common.Hash{}, - Hash: common.NewRandomHash(), Height: 0, Acks: make(map[common.Hash]struct{}), Timestamps: make(map[types.ValidatorID]time.Time), @@ -61,6 +60,9 @@ func (s *ReliableBroadcastTest) prepareGenesisBlock( b.Timestamps[vID] = time.Time{} } b.Timestamps[proposerID] = time.Now().UTC() + var err error + b.Hash, err = hashBlock(b) + s.Require().Nil(err) return } @@ -86,7 +88,7 @@ func genTestCase1(s *ReliableBroadcastTest, r *reliableBroadcast) []types.Valida // Add genesis blocks. for _, vid := range vids { b = s.prepareGenesisBlock(vid, vids) - r.processBlock(b) + s.Require().Nil(r.processBlock(b)) } // Add block 0-1 which acks 0-0. @@ -94,13 +96,15 @@ func genTestCase1(s *ReliableBroadcastTest, r *reliableBroadcast) []types.Valida b = &types.Block{ ProposerID: vids[0], ParentHash: h, - Hash: common.NewRandomHash(), Height: 1, Acks: map[common.Hash]struct{}{ h: struct{}{}, }, } - r.processBlock(b) + var err error + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) s.NotNil(r.lattice[vids[0]].blocks[1]) // Add block 0-2 which acks 0-1 and 1-0. @@ -108,14 +112,15 @@ func genTestCase1(s *ReliableBroadcastTest, r *reliableBroadcast) []types.Valida b = &types.Block{ ProposerID: vids[0], ParentHash: h, - Hash: common.NewRandomHash(), Height: 2, Acks: map[common.Hash]struct{}{ h: struct{}{}, r.lattice[vids[1]].blocks[0].Hash: struct{}{}, }, } - r.processBlock(b) + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) s.NotNil(r.lattice[vids[0]].blocks[2]) // Add block 0-3 which acks 0-2. @@ -123,13 +128,14 @@ func genTestCase1(s *ReliableBroadcastTest, r *reliableBroadcast) []types.Valida b = &types.Block{ ProposerID: vids[0], ParentHash: h, - Hash: common.NewRandomHash(), Height: 3, Acks: map[common.Hash]struct{}{ h: struct{}{}, }, } - r.processBlock(b) + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) s.NotNil(r.lattice[vids[0]].blocks[3]) // Add block 3-1 which acks 3-0. @@ -137,13 +143,14 @@ func genTestCase1(s *ReliableBroadcastTest, r *reliableBroadcast) []types.Valida b = &types.Block{ ProposerID: vids[3], ParentHash: h, - Hash: common.NewRandomHash(), Height: 1, Acks: map[common.Hash]struct{}{ h: struct{}{}, }, } - r.processBlock(b) + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) s.NotNil(r.lattice[vids[3]].blocks[0]) return vids @@ -171,6 +178,8 @@ func (s *ReliableBroadcastTest) TestSanityCheck() { Height: 10, Acks: make(map[common.Hash]struct{}), } + b.Hash, err = hashBlock(b) + s.Require().Nil(err) err = r.sanityCheck(b) s.NotNil(err) s.Equal(ErrNotAckParent.Error(), err.Error()) @@ -184,6 +193,8 @@ func (s *ReliableBroadcastTest) TestSanityCheck() { r.lattice[vids[2]].blocks[0].Hash: struct{}{}, }, } + b.Hash, err = hashBlock(b) + s.Require().Nil(err) err = r.sanityCheck(b) s.NotNil(err) s.Equal(ErrNotAckParent.Error(), err.Error()) @@ -198,6 +209,8 @@ func (s *ReliableBroadcastTest) TestSanityCheck() { h: struct{}{}, }, } + b.Hash, err = hashBlock(b) + s.Require().Nil(err) err = r.sanityCheck(b) s.NotNil(err) s.Equal(ErrInvalidBlockHeight.Error(), err.Error()) @@ -212,6 +225,8 @@ func (s *ReliableBroadcastTest) TestSanityCheck() { h: struct{}{}, }, } + b.Hash, err = hashBlock(b) + s.Require().Nil(err) err = r.sanityCheck(b) s.NotNil(err) s.Equal(ErrInvalidProposerID.Error(), err.Error()) @@ -225,7 +240,12 @@ func (s *ReliableBroadcastTest) TestSanityCheck() { Acks: map[common.Hash]struct{}{ h: struct{}{}, }, + Timestamps: map[types.ValidatorID]time.Time{ + vids[0]: time.Now().UTC(), + }, } + b.Hash, err = hashBlock(b) + s.Require().Nil(err) err = r.sanityCheck(b) s.NotNil(err) s.Equal(ErrForkBlock.Error(), err.Error()) @@ -241,6 +261,8 @@ func (s *ReliableBroadcastTest) TestSanityCheck() { r.lattice[vids[1]].blocks[0].Hash: struct{}{}, }, } + b.Hash, err = hashBlock(b) + s.Require().Nil(err) err = r.sanityCheck(b) s.NotNil(err) s.Equal(ErrDoubleAck.Error(), err.Error()) @@ -256,6 +278,8 @@ func (s *ReliableBroadcastTest) TestSanityCheck() { common.NewRandomHash(): struct{}{}, }, } + b.Hash, err = hashBlock(b) + s.Require().Nil(err) err = r.sanityCheck(b) s.Nil(err) } @@ -306,14 +330,16 @@ func (s *ReliableBroadcastTest) TestStrongAck() { b = &types.Block{ ProposerID: vids[1], ParentHash: r.lattice[vids[1]].blocks[0].Hash, - Hash: common.NewRandomHash(), Height: 1, Acks: map[common.Hash]struct{}{ r.lattice[vids[0]].blocks[2].Hash: struct{}{}, r.lattice[vids[1]].blocks[0].Hash: struct{}{}, }, } - r.processBlock(b) + var err error + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) s.NotNil(r.lattice[vids[1]].blocks[1]) for i := uint64(0); i < 4; i++ { s.Equal(types.BlockStatusInit, r.lattice[vids[0]].blocks[i].Status) @@ -324,14 +350,15 @@ func (s *ReliableBroadcastTest) TestStrongAck() { b = &types.Block{ ProposerID: vids[2], ParentHash: r.lattice[vids[2]].blocks[0].Hash, - Hash: common.NewRandomHash(), Height: 1, Acks: map[common.Hash]struct{}{ r.lattice[vids[0]].blocks[2].Hash: struct{}{}, r.lattice[vids[2]].blocks[0].Hash: struct{}{}, }, } - r.processBlock(b) + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) s.Equal(types.BlockStatusAcked, r.lattice[vids[0]].blocks[0].Status) s.Equal(types.BlockStatusAcked, r.lattice[vids[0]].blocks[1].Status) s.Equal(types.BlockStatusAcked, r.lattice[vids[0]].blocks[2].Status) @@ -347,7 +374,6 @@ func (s *ReliableBroadcastTest) TestExtractBlocks() { b = &types.Block{ ProposerID: vids[1], ParentHash: r.lattice[vids[1]].blocks[0].Hash, - Hash: common.NewRandomHash(), Height: 1, Acks: map[common.Hash]struct{}{ r.lattice[vids[0]].blocks[2].Hash: struct{}{}, @@ -355,13 +381,15 @@ func (s *ReliableBroadcastTest) TestExtractBlocks() { r.lattice[vids[3]].blocks[0].Hash: struct{}{}, }, } - r.processBlock(b) + var err error + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) // Add block 2-1 which acks 0-2, 2-0, 3-0. b = &types.Block{ ProposerID: vids[2], ParentHash: r.lattice[vids[2]].blocks[0].Hash, - Hash: common.NewRandomHash(), Height: 1, Acks: map[common.Hash]struct{}{ r.lattice[vids[0]].blocks[2].Hash: struct{}{}, @@ -369,7 +397,9 @@ func (s *ReliableBroadcastTest) TestExtractBlocks() { r.lattice[vids[3]].blocks[0].Hash: struct{}{}, }, } - r.processBlock(b) + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) hashs := []common.Hash{ r.lattice[vids[0]].blocks[0].Hash, @@ -402,7 +432,7 @@ func (s *ReliableBroadcastTest) TestRandomIntensiveAcking() { // Generate genesis blocks. for _, vid := range vids { b := s.prepareGenesisBlock(vid, vids) - r.processBlock(b) + s.Require().Nil(r.processBlock(b)) heights[vid] = 1 } @@ -419,12 +449,14 @@ func (s *ReliableBroadcastTest) TestRandomIntensiveAcking() { } b := &types.Block{ ProposerID: vid, - Hash: common.NewRandomHash(), ParentHash: parentHash, Height: height, Acks: acks, } - r.processBlock(b) + var err error + b.Hash, err = hashBlock(b) + s.Require().Nil(err) + s.Require().Nil(r.processBlock(b)) extractedBlocks = append(extractedBlocks, r.extractBlocks()...) } @@ -451,7 +483,7 @@ func (s *ReliableBroadcastTest) TestRandomlyGeneratedBlocks() { s.Nil(db.Close()) } }() - gen := test.NewBlocksGenerator(nil) + gen := test.NewBlocksGenerator(nil, hashBlock) s.Require().Nil(gen.Generate(validatorCount, blockCount, nil, db)) iter, err := db.GetAll() s.Require().Nil(err) @@ -483,7 +515,7 @@ func (s *ReliableBroadcastTest) TestRandomlyGeneratedBlocks() { validators[b.ProposerID] = struct{}{} } // Perform reliable broadcast process. - rb.processBlock(&b) + s.Require().Nil(rb.processBlock(&b)) for _, b := range rb.extractBlocks() { stronglyAckedHashes = append(stronglyAckedHashes, b.Hash) } @@ -528,17 +560,19 @@ func (s *ReliableBroadcastTest) TestPrepareBlock() { time.Sleep(minInterval) b30 := s.prepareGenesisBlock(validators[3], validators) // Submit these blocks to reliableBroadcast instance. - rb.processBlock(b00) - rb.processBlock(b10) - rb.processBlock(b20) - rb.processBlock(b30) + s.Require().Nil(rb.processBlock(b00)) + s.Require().Nil(rb.processBlock(b10)) + s.Require().Nil(rb.processBlock(b20)) + s.Require().Nil(rb.processBlock(b30)) // We should be able to collect all 4 genesis blocks by calling // prepareBlock. b11 := &types.Block{ ProposerID: validators[1], - Hash: common.NewRandomHash(), } rb.prepareBlock(b11) + var err error + b11.Hash, err = hashBlock(b11) + s.Require().Nil(err) req.Contains(b11.Acks, b00.Hash) req.Contains(b11.Acks, b10.Hash) req.Contains(b11.Acks, b20.Hash) @@ -553,13 +587,14 @@ func (s *ReliableBroadcastTest) TestPrepareBlock() { b30.Timestamps[b30.ProposerID].Add(time.Millisecond)) req.Equal(b11.ParentHash, b10.Hash) req.Equal(b11.Height, uint64(1)) - rb.processBlock(b11) + s.Require().Nil(rb.processBlock(b11)) // Propose/Process a block based on collected info. b12 := &types.Block{ ProposerID: validators[1], - Hash: common.NewRandomHash(), } rb.prepareBlock(b12) + b12.Hash, err = hashBlock(b12) + s.Require().Nil(err) // This time we only need to ack b11. req.Len(b12.Acks, 1) req.Contains(b12.Acks, b11.Hash) @@ -569,9 +604,10 @@ func (s *ReliableBroadcastTest) TestPrepareBlock() { // get 4 blocks to ack. b01 := &types.Block{ ProposerID: validators[0], - Hash: common.NewRandomHash(), } rb.prepareBlock(b01) + b01.Hash, err = hashBlock(b01) + s.Require().Nil(err) req.Len(b01.Acks, 4) req.Contains(b01.Acks, b00.Hash) req.Contains(b01.Acks, b11.Hash) diff --git a/core/test/blocks-generator.go b/core/test/blocks-generator.go index 976b661..926ef5b 100644 --- a/core/test/blocks-generator.go +++ b/core/test/blocks-generator.go @@ -39,6 +39,8 @@ type validatorStatus struct { lastAckingHeight map[types.ValidatorID]uint64 } +type hashBlockFn func(types.BlockConverter) (common.Hash, error) + // getAckedBlockHash would randomly pick one block between // last acked one to current head. func (vs *validatorStatus) getAckedBlockHash( @@ -71,9 +73,10 @@ type validatorSetStatus struct { status map[types.ValidatorID]*validatorStatus validatorIDs []types.ValidatorID randGen *rand.Rand + hashBlock hashBlockFn } -func newValidatorSetStatus(vIDs []types.ValidatorID) *validatorSetStatus { +func newValidatorSetStatus(vIDs []types.ValidatorID, hashBlock hashBlockFn) *validatorSetStatus { status := make(map[types.ValidatorID]*validatorStatus) for _, vID := range vIDs { status[vID] = &validatorStatus{ @@ -85,6 +88,7 @@ func newValidatorSetStatus(vIDs []types.ValidatorID) *validatorSetStatus { status: status, validatorIDs: vIDs, randGen: rand.New(rand.NewSource(time.Now().UnixNano())), + hashBlock: hashBlock, } } @@ -139,10 +143,9 @@ func (vs *validatorSetStatus) prepareAcksForNewBlock( // proposeBlock propose new block and update validator status. func (vs *validatorSetStatus) proposeBlock( proposerID types.ValidatorID, - acks map[common.Hash]struct{}) *types.Block { + acks map[common.Hash]struct{}) (*types.Block, error) { status := vs.status[proposerID] - hash := common.NewRandomHash() parentHash := common.Hash{} if len(status.blocks) > 0 { parentHash = status.blocks[len(status.blocks)-1].Hash @@ -151,13 +154,17 @@ func (vs *validatorSetStatus) proposeBlock( newBlock := &types.Block{ ProposerID: proposerID, ParentHash: parentHash, - Hash: hash, Height: uint64(len(status.blocks)), Acks: acks, // TODO(mission.liao): Generate timestamp randomly. } + var err error + newBlock.Hash, err = vs.hashBlock(newBlock) + if err != nil { + return nil, err + } status.blocks = append(status.blocks, newBlock) - return newBlock + return newBlock, nil } // normalAckingCountGenerator would randomly pick acking count @@ -189,17 +196,20 @@ func generateValidatorPicker() func([]types.ValidatorID) types.ValidatorID { // BlocksGenerator could generate blocks forming valid DAGs. type BlocksGenerator struct { validatorPicker func([]types.ValidatorID) types.ValidatorID + hashBlock hashBlockFn } // NewBlocksGenerator constructs BlockGenerator. func NewBlocksGenerator(validatorPicker func( - []types.ValidatorID) types.ValidatorID) *BlocksGenerator { + []types.ValidatorID) types.ValidatorID, + hashBlock hashBlockFn) *BlocksGenerator { if validatorPicker == nil { validatorPicker = generateValidatorPicker() } return &BlocksGenerator{ validatorPicker: validatorPicker, + hashBlock: hashBlock, } } @@ -228,7 +238,7 @@ func (gen *BlocksGenerator) Generate( validators = append( validators, types.ValidatorID{Hash: common.NewRandomHash()}) } - status := newValidatorSetStatus(validators) + status := newValidatorSetStatus(validators, gen.hashBlock) // We would record the smallest height of block that could be acked // from each validator's point-of-view. @@ -255,7 +265,11 @@ func (gen *BlocksGenerator) Generate( if err != nil { return } - newBlock := status.proposeBlock(proposerID, acks) + var newBlock *types.Block + newBlock, err = status.proposeBlock(proposerID, acks) + if err != nil { + return + } // Persist block to db. err = writer.Put(*newBlock) diff --git a/core/test/blocks-generator_test.go b/core/test/blocks-generator_test.go index 84bee4c..0624da2 100644 --- a/core/test/blocks-generator_test.go +++ b/core/test/blocks-generator_test.go @@ -15,23 +15,6 @@ // along with the dexon-consensus-core library. If not, see // <http://www.gnu.org/licenses/>. -// Copyright 2018 The dexon-consensus-core Authors -// This file is part of the dexon-consensus-core library. -// -// The dexon-consensus-core library is free software: you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// The dexon-consensus-core library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the dexon-consensus-core library. If not, see -// <http://www.gnu.org/licenses/>. - package test import ( @@ -52,7 +35,7 @@ func (s *BlocksGeneratorTestCase) TestGenerate() { // This test case is to make sure the generated blocks are legimate. validatorCount := 19 blockCount := 50 - gen := NewBlocksGenerator(nil) + gen := NewBlocksGenerator(nil, stableRandomHash) db, err := blockdb.NewMemBackedBlockDB() s.Require().Nil(err) diff --git a/core/test/revealer_test.go b/core/test/revealer_test.go index 0ef19a1..8087136 100644 --- a/core/test/revealer_test.go +++ b/core/test/revealer_test.go @@ -1,15 +1,15 @@ // Copyright 2018 The dexon-consensus-core Authors // This file is part of the dexon-consensus-core library. // -// The dexon-consensus-core library is free software: you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as +// The dexon-consensus-core library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // -// The dexon-consensus-core library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. +// The dexon-consensus-core library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the dexon-consensus-core library. If not, see @@ -44,7 +44,7 @@ func (s *RevealerTestSuite) SetupSuite() { s.Require().Nil(err) // Randomly generate blocks. - gen := NewBlocksGenerator(nil) + gen := NewBlocksGenerator(nil, stableRandomHash) err = gen.Generate( validatorCount, blockCount, nil, s.db) s.Require().Nil(err) diff --git a/core/test/utils.go b/core/test/utils.go new file mode 100644 index 0000000..eae12a0 --- /dev/null +++ b/core/test/utils.go @@ -0,0 +1,31 @@ +// Copyright 2018 The dexon-consensus-core Authors +// This file is part of the dexon-consensus-core library. +// +// The dexon-consensus-core library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// The dexon-consensus-core library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the dexon-consensus-core library. If not, see +// <http://www.gnu.org/licenses/>. + +package test + +import ( + "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core/types" +) + +func stableRandomHash(blockConv types.BlockConverter) (common.Hash, error) { + block := blockConv.Block() + if (block.Hash != common.Hash{}) { + return block.Hash, nil + } + return common.NewRandomHash(), nil +} diff --git a/core/total-ordering_test.go b/core/total-ordering_test.go index 49b28fa..69297d3 100644 --- a/core/total-ordering_test.go +++ b/core/total-ordering_test.go @@ -929,7 +929,7 @@ func (s *TotalOrderingTestSuite) TestRandomlyGeneratedBlocks() { } }() - gen := test.NewBlocksGenerator(nil) + gen := test.NewBlocksGenerator(nil, hashBlock) s.Require().Nil(gen.Generate(validatorCount, blockCount, nil, db)) iter, err := db.GetAll() s.Require().Nil(err) |