aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2018-08-09 14:12:15 +0800
committerGitHub <noreply@github.com>2018-08-09 14:12:15 +0800
commitd28cc2c0cf87061fed9356509a28a307b9f55943 (patch)
tree09ac5ccd9ec721072f2c653e8201c1487e9e265c
parent7326f9722771633f3d137944c814544888a7a87f (diff)
downloaddexon-consensus-d28cc2c0cf87061fed9356509a28a307b9f55943.tar
dexon-consensus-d28cc2c0cf87061fed9356509a28a307b9f55943.tar.gz
dexon-consensus-d28cc2c0cf87061fed9356509a28a307b9f55943.tar.bz2
dexon-consensus-d28cc2c0cf87061fed9356509a28a307b9f55943.tar.lz
dexon-consensus-d28cc2c0cf87061fed9356509a28a307b9f55943.tar.xz
dexon-consensus-d28cc2c0cf87061fed9356509a28a307b9f55943.tar.zst
dexon-consensus-d28cc2c0cf87061fed9356509a28a307b9f55943.zip
core: Add Block.IsGenesis() and set Block.ParentHash to 0 in genesis block. (#37)
-rw-r--r--core/consensus_test.go2
-rw-r--r--core/reliable-broadcast.go13
-rw-r--r--core/reliable-broadcast_test.go42
-rw-r--r--core/test/blocks-generator.go14
-rw-r--r--core/test/blocks-generator_test.go19
-rw-r--r--core/total-ordering_test.go90
-rw-r--r--core/types/block.go5
-rw-r--r--core/types/block_test.go30
-rw-r--r--simulation/validator.go7
9 files changed, 109 insertions, 113 deletions
diff --git a/core/consensus_test.go b/core/consensus_test.go
index 7ce06e9..1544818 100644
--- a/core/consensus_test.go
+++ b/core/consensus_test.go
@@ -40,7 +40,7 @@ func (s *ConsensusTestSuite) prepareGenesisBlock(
hash := common.NewRandomHash()
block := &types.Block{
ProposerID: proposerID,
- ParentHash: hash,
+ ParentHash: common.Hash{},
Hash: hash,
Height: 0,
Acks: make(map[common.Hash]struct{}),
diff --git a/core/reliable-broadcast.go b/core/reliable-broadcast.go
index 7db8212..e7ae9e7 100644
--- a/core/reliable-broadcast.go
+++ b/core/reliable-broadcast.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
@@ -304,7 +304,6 @@ func (rb *reliableBroadcast) extractBlocks() []*types.Block {
func (rb *reliableBroadcast) prepareBlock(block *types.Block) {
// Reset fields to make sure we got these information from parent block.
block.Height = 0
- // TODO(mission): make all genesis block would contain zero ParentHash.
block.ParentHash = common.Hash{}
// The helper function to accumulate timestamps.
accumulateTimestamps := func(
diff --git a/core/reliable-broadcast_test.go b/core/reliable-broadcast_test.go
index bd77ea3..220a997 100644
--- a/core/reliable-broadcast_test.go
+++ b/core/reliable-broadcast_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
@@ -49,11 +49,10 @@ func (s *ReliableBroadcastTest) prepareGenesisBlock(
proposerID types.ValidatorID,
validatorIDs []types.ValidatorID) (b *types.Block) {
- hash := common.NewRandomHash()
b = &types.Block{
ProposerID: proposerID,
- ParentHash: hash,
- Hash: hash,
+ ParentHash: common.Hash{},
+ Hash: common.NewRandomHash(),
Height: 0,
Acks: make(map[common.Hash]struct{}),
Timestamps: make(map[types.ValidatorID]time.Time),
@@ -85,15 +84,8 @@ func genTestCase1(s *ReliableBroadcastTest, r *reliableBroadcast) []types.Valida
vids = append(vids, vid)
}
// Add genesis blocks.
- for i := 0; i < 4; i++ {
- h = common.NewRandomHash()
- b = &types.Block{
- ProposerID: vids[i],
- ParentHash: h,
- Hash: h,
- Height: 0,
- Acks: map[common.Hash]struct{}{},
- }
+ for _, vid := range vids {
+ b = s.prepareGenesisBlock(vid, vids)
r.processBlock(b)
}
@@ -401,19 +393,15 @@ func (s *ReliableBroadcastTest) TestRandomIntensiveAcking() {
heights := map[types.ValidatorID]uint64{}
extractedBlocks := []*types.Block{}
- // Generate validators and genesis blocks.
+ // Generate validators.
for i := 0; i < 4; i++ {
vid := types.ValidatorID{Hash: common.NewRandomHash()}
r.addValidator(vid)
vids = append(vids, vid)
- h := common.NewRandomHash()
- b := &types.Block{
- Hash: h,
- ParentHash: h,
- Acks: map[common.Hash]struct{}{},
- Height: 0,
- ProposerID: vid,
- }
+ }
+ // Generate genesis blocks.
+ for _, vid := range vids {
+ b := s.prepareGenesisBlock(vid, vids)
r.processBlock(b)
heights[vid] = 1
}
diff --git a/core/test/blocks-generator.go b/core/test/blocks-generator.go
index ae41757..976b661 100644
--- a/core/test/blocks-generator.go
+++ b/core/test/blocks-generator.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
@@ -143,7 +143,7 @@ func (vs *validatorSetStatus) proposeBlock(
status := vs.status[proposerID]
hash := common.NewRandomHash()
- parentHash := hash
+ parentHash := common.Hash{}
if len(status.blocks) > 0 {
parentHash = status.blocks[len(status.blocks)-1].Hash
}
diff --git a/core/test/blocks-generator_test.go b/core/test/blocks-generator_test.go
index b9c0b35..84bee4c 100644
--- a/core/test/blocks-generator_test.go
+++ b/core/test/blocks-generator_test.go
@@ -1,6 +1,23 @@
// 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/>.
+
+// 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,
@@ -72,7 +89,7 @@ func (s *BlocksGeneratorTestCase) TestGenerate() {
// Check genesis block.
genesisBlock := blocks[0]
- s.Equal(genesisBlock.Hash, genesisBlock.ParentHash)
+ s.Equal(genesisBlock.ParentHash, common.Hash{})
s.Equal(genesisBlock.Height, uint64(0))
s.Empty(genesisBlock.Acks)
diff --git a/core/total-ordering_test.go b/core/total-ordering_test.go
index b4fe13c..78b4d96 100644
--- a/core/total-ordering_test.go
+++ b/core/total-ordering_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
@@ -45,14 +45,13 @@ func (s *TotalOrderingTestSuite) generateValidatorIDs(
return validatorIDs
}
-func (s *TotalOrderingTestSuite) genRootBlock(
+func (s *TotalOrderingTestSuite) genGenesisBlock(
vID types.ValidatorID, acks map[common.Hash]struct{}) *types.Block {
- hash := common.NewRandomHash()
return &types.Block{
ProposerID: vID,
- ParentHash: hash,
- Hash: hash,
+ ParentHash: common.Hash{},
+ Hash: common.NewRandomHash(),
Height: 0,
Acks: acks,
}
@@ -88,14 +87,7 @@ func (s *TotalOrderingTestSuite) TestBlockRelation() {
vID := types.ValidatorID{Hash: common.NewRandomHash()}
- hash := common.NewRandomHash()
- blockA := &types.Block{
- ProposerID: vID,
- ParentHash: hash,
- Hash: hash,
- Height: 0,
- Acks: map[common.Hash]struct{}{},
- }
+ blockA := s.genGenesisBlock(vID, map[common.Hash]struct{}{})
blockB := &types.Block{
ProposerID: vID,
ParentHash: blockA.Hash,
@@ -243,16 +235,9 @@ func (s *TotalOrderingTestSuite) TestCycleDetection() {
// create blocks with cycles in acking relation.
cycledHash := common.NewRandomHash()
- hash := common.NewRandomHash()
- b00 := &types.Block{
- ProposerID: validators[0],
- ParentHash: hash,
- Hash: hash,
- Height: 0,
- Acks: map[common.Hash]struct{}{
- cycledHash: struct{}{},
- },
- }
+ b00 := s.genGenesisBlock(validators[0], map[common.Hash]struct{}{
+ cycledHash: struct{}{},
+ })
b01 := &types.Block{
ProposerID: validators[0],
ParentHash: b00.Hash,
@@ -282,16 +267,8 @@ func (s *TotalOrderingTestSuite) TestCycleDetection() {
}
// Create a block acks self.
- hash = common.NewRandomHash()
- b10 := &types.Block{
- ProposerID: validators[1],
- ParentHash: hash,
- Hash: hash,
- Height: 0,
- Acks: map[common.Hash]struct{}{
- hash: struct{}{},
- },
- }
+ b10 := s.genGenesisBlock(validators[1], map[common.Hash]struct{}{})
+ b10.Acks[b10.Hash] = struct{}{}
// Make sure we won't hang when cycle exists.
to := newTotalOrdering(1, 3, 5)
@@ -309,14 +286,7 @@ func (s *TotalOrderingTestSuite) TestNotValidDAGDetection() {
validators := s.generateValidatorIDs(4)
to := newTotalOrdering(1, 3, 5)
- hash := common.NewRandomHash()
- b00 := &types.Block{
- ProposerID: validators[0],
- ParentHash: hash,
- Hash: hash,
- Height: 0,
- Acks: map[common.Hash]struct{}{},
- }
+ b00 := s.genGenesisBlock(validators[0], map[common.Hash]struct{}{})
b01 := &types.Block{
ProposerID: validators[0],
ParentHash: b00.Hash,
@@ -356,23 +326,23 @@ func (s *TotalOrderingTestSuite) TestEarlyDeliver() {
}
}
- b00 := s.genRootBlock(validators[0], map[common.Hash]struct{}{})
+ b00 := s.genGenesisBlock(validators[0], map[common.Hash]struct{}{})
b01 := genNextBlock(b00)
b02 := genNextBlock(b01)
- b10 := s.genRootBlock(validators[1], map[common.Hash]struct{}{
+ b10 := s.genGenesisBlock(validators[1], map[common.Hash]struct{}{
b00.Hash: struct{}{},
})
b11 := genNextBlock(b10)
b12 := genNextBlock(b11)
- b20 := s.genRootBlock(validators[2], map[common.Hash]struct{}{
+ b20 := s.genGenesisBlock(validators[2], map[common.Hash]struct{}{
b00.Hash: struct{}{},
})
b21 := genNextBlock(b20)
b22 := genNextBlock(b21)
- b30 := s.genRootBlock(validators[3], map[common.Hash]struct{}{
+ b30 := s.genGenesisBlock(validators[3], map[common.Hash]struct{}{
b00.Hash: struct{}{},
})
b31 := genNextBlock(b30)
@@ -460,13 +430,13 @@ func (s *TotalOrderingTestSuite) TestBasicCaseForK2() {
to := newTotalOrdering(2, 3, 5)
validators := s.generateValidatorIDs(5)
- b00 := s.genRootBlock(validators[0], map[common.Hash]struct{}{})
- b10 := s.genRootBlock(validators[1], map[common.Hash]struct{}{})
- b20 := s.genRootBlock(
+ b00 := s.genGenesisBlock(validators[0], map[common.Hash]struct{}{})
+ b10 := s.genGenesisBlock(validators[1], map[common.Hash]struct{}{})
+ b20 := s.genGenesisBlock(
validators[2], map[common.Hash]struct{}{b10.Hash: struct{}{}})
- b30 := s.genRootBlock(
+ b30 := s.genGenesisBlock(
validators[3], map[common.Hash]struct{}{b20.Hash: struct{}{}})
- b40 := s.genRootBlock(validators[4], map[common.Hash]struct{}{})
+ b40 := s.genGenesisBlock(validators[4], map[common.Hash]struct{}{})
b11 := &types.Block{
ProposerID: validators[1],
ParentHash: b10.Hash,
@@ -791,10 +761,10 @@ func (s *TotalOrderingTestSuite) TestBasicCaseForK0() {
to := newTotalOrdering(0, 3, 5)
validators := s.generateValidatorIDs(5)
- b00 := s.genRootBlock(validators[0], map[common.Hash]struct{}{})
- b10 := s.genRootBlock(validators[1], map[common.Hash]struct{}{})
- b20 := s.genRootBlock(validators[2], map[common.Hash]struct{}{})
- b30 := s.genRootBlock(validators[3], map[common.Hash]struct{}{
+ b00 := s.genGenesisBlock(validators[0], map[common.Hash]struct{}{})
+ b10 := s.genGenesisBlock(validators[1], map[common.Hash]struct{}{})
+ b20 := s.genGenesisBlock(validators[2], map[common.Hash]struct{}{})
+ b30 := s.genGenesisBlock(validators[3], map[common.Hash]struct{}{
b20.Hash: struct{}{},
})
b01 := &types.Block{
@@ -836,7 +806,7 @@ func (s *TotalOrderingTestSuite) TestBasicCaseForK0() {
b30.Hash: struct{}{},
},
}
- b40 := s.genRootBlock(validators[4], map[common.Hash]struct{}{
+ b40 := s.genGenesisBlock(validators[4], map[common.Hash]struct{}{
b31.Hash: struct{}{},
})
diff --git a/core/types/block.go b/core/types/block.go
index 55e82da..e35ab8d 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -111,6 +111,11 @@ func (b *Block) Clone() *Block {
return bcopy
}
+// IsGenesis checks if the block is a genesisBlock
+func (b *Block) IsGenesis() bool {
+ return b.Height == 0 && b.ParentHash == common.Hash{}
+}
+
// ByHash is the helper type for sorting slice of blocks by hash.
type ByHash []*Block
diff --git a/core/types/block_test.go b/core/types/block_test.go
index 8297508..2087373 100644
--- a/core/types/block_test.go
+++ b/core/types/block_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
@@ -62,6 +62,24 @@ func (s *BlockTestSuite) TestSortByHeight() {
s.Equal(blocks[3].Hash, b3.Hash)
}
+func (s *BlockTestSuite) TestGenesisBlock() {
+ b0 := &Block{
+ Height: 0,
+ ParentHash: common.Hash{},
+ }
+ s.True(b0.IsGenesis())
+ b1 := &Block{
+ Height: 1,
+ ParentHash: common.Hash{},
+ }
+ s.False(b1.IsGenesis())
+ b2 := &Block{
+ Height: 0,
+ ParentHash: common.NewRandomHash(),
+ }
+ s.False(b2.IsGenesis())
+}
+
func TestBlock(t *testing.T) {
suite.Run(t, new(BlockTestSuite))
}
diff --git a/simulation/validator.go b/simulation/validator.go
index a30420e..b4e6127 100644
--- a/simulation/validator.go
+++ b/simulation/validator.go
@@ -135,7 +135,7 @@ func (v *Validator) MsgServer(isStopped chan struct{}) {
}
} else {
pendingBlocks = append(pendingBlocks, val)
- if val.ParentHash == val.Hash {
+ if val.IsGenesis() {
v.gov.addValidator(val.ProposerID)
}
validatorSet := v.gov.GetValidatorSet()
@@ -162,11 +162,10 @@ func (v *Validator) BroadcastGenesisBlock() {
for v.network.NumPeers() != v.config.Num {
time.Sleep(time.Second)
}
- hash := common.NewRandomHash()
b := &types.Block{
ProposerID: v.ID,
- ParentHash: hash,
- Hash: hash,
+ ParentHash: common.Hash{},
+ Hash: common.NewRandomHash(),
Height: 0,
Acks: map[common.Hash]struct{}{},
Timestamps: map[types.ValidatorID]time.Time{