aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/consensus.go22
-rw-r--r--core/consensus_test.go16
-rw-r--r--core/reliable-broadcast_test.go98
-rw-r--r--core/test/blocks-generator.go30
-rw-r--r--core/test/blocks-generator_test.go19
-rw-r--r--core/test/revealer_test.go14
-rw-r--r--core/test/utils.go31
-rw-r--r--core/total-ordering_test.go2
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)