aboutsummaryrefslogtreecommitdiffstats
path: root/core/test
diff options
context:
space:
mode:
authorhaoping-ku <haoping.ku@dexon.org>2018-11-29 14:30:02 +0800
committerGitHub <noreply@github.com>2018-11-29 14:30:02 +0800
commitdaf3bab93c323b173345811adc9a334dad4a7094 (patch)
tree8a3957ec1f77262ce92c56f0384b0dedc307628c /core/test
parent8470ac070f097b261fddc42991a4d2e9ec998db6 (diff)
downloaddexon-consensus-daf3bab93c323b173345811adc9a334dad4a7094.tar
dexon-consensus-daf3bab93c323b173345811adc9a334dad4a7094.tar.gz
dexon-consensus-daf3bab93c323b173345811adc9a334dad4a7094.tar.bz2
dexon-consensus-daf3bab93c323b173345811adc9a334dad4a7094.tar.lz
dexon-consensus-daf3bab93c323b173345811adc9a334dad4a7094.tar.xz
dexon-consensus-daf3bab93c323b173345811adc9a334dad4a7094.tar.zst
dexon-consensus-daf3bab93c323b173345811adc9a334dad4a7094.zip
core: syncer: add syncer (#346)
Diffstat (limited to 'core/test')
-rw-r--r--core/test/app.go6
-rw-r--r--core/test/fake-transport.go17
-rw-r--r--core/test/interface.go17
-rw-r--r--core/test/network.go5
-rw-r--r--core/test/revealer.go83
-rw-r--r--core/test/revealer_test.go60
-rw-r--r--core/test/stopper.go4
7 files changed, 136 insertions, 56 deletions
diff --git a/core/test/app.go b/core/test/app.go
index 327555b..9f030e9 100644
--- a/core/test/app.go
+++ b/core/test/app.go
@@ -280,8 +280,8 @@ Loop:
return nil
}
-// Check provides a backdoor to check status of App with reader lock.
-func (app *App) Check(checker func(*App)) {
+// WithLock provides a backdoor to check status of App with reader lock.
+func (app *App) WithLock(function func(*App)) {
app.confirmedLock.RLock()
defer app.confirmedLock.RUnlock()
app.totalOrderedLock.RLock()
@@ -289,5 +289,5 @@ func (app *App) Check(checker func(*App)) {
app.deliveredLock.RLock()
defer app.deliveredLock.RUnlock()
- checker(app)
+ function(app)
}
diff --git a/core/test/fake-transport.go b/core/test/fake-transport.go
index a783ac9..388d0aa 100644
--- a/core/test/fake-transport.go
+++ b/core/test/fake-transport.go
@@ -15,23 +15,6 @@
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.
-// Copyright 2018 The dexon-consensus Authors
-// This file is part of the dexon-consensus library.
-//
-// The dexon-consensus 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 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 library. If not, see
-// <http://www.gnu.org/licenses/>.
-
package test
import (
diff --git a/core/test/interface.go b/core/test/interface.go
index e7a8f70..dcecee8 100644
--- a/core/test/interface.go
+++ b/core/test/interface.go
@@ -15,23 +15,6 @@
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.
-// Copyright 2018 The dexon-consensus Authors
-// This file is part of the dexon-consensus library.
-//
-// The dexon-consensus 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 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 library. If not, see
-// <http://www.gnu.org/licenses/>.
-
package test
import (
diff --git a/core/test/network.go b/core/test/network.go
index 8bcb050..207d8a4 100644
--- a/core/test/network.go
+++ b/core/test/network.go
@@ -437,6 +437,11 @@ func (n *Network) Broadcast(msg interface{}) {
}
}
+// Send exports 'Send' method of Transport.
+func (n *Network) Send(nodeID types.NodeID, msg interface{}) error {
+ return n.trans.Send(nodeID, msg)
+}
+
// ReceiveChanForNode returns a channel for messages not handled by
// core.Consensus.
func (n *Network) ReceiveChanForNode() <-chan interface{} {
diff --git a/core/test/revealer.go b/core/test/revealer.go
index b39a898..dcd75a5 100644
--- a/core/test/revealer.go
+++ b/core/test/revealer.go
@@ -15,26 +15,10 @@
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.
-// Copyright 2018 The dexon-consensus Authors
-// This file is part of the dexon-consensus library.
-//
-// The dexon-consensus 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 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 library. If not, see
-// <http://www.gnu.org/licenses/>.
-
package test
import (
+ "errors"
"math/rand"
"sort"
"time"
@@ -44,6 +28,11 @@ import (
"github.com/dexon-foundation/dexon-consensus/core/types"
)
+// Errors returns from revealer.
+var (
+ ErrNotValidCompactionChain = errors.New("not valid compaction chain")
+)
+
// isAllAckingBlockRevealed is a helper to check if all acking blocks of
// one block are revealed.
func isAllAckingBlockRevealed(
@@ -280,3 +269,63 @@ func (r *RandomTipRevealer) Reset() {
r.chainTip[i] = 0
}
}
+
+// CompactionChainRevealer implements Revealer interface, which would load
+// all blocks from blockdb, reveal them in the order of compaction chain, from
+// the genesis block to the latest one.
+type CompactionChainRevealer struct {
+ blocks types.ByFinalizationHeight
+ nextRevealIndex int
+}
+
+// NewCompactionChainRevealer constructs a revealer in the order of compaction
+// chain.
+func NewCompactionChainRevealer(iter blockdb.BlockIterator,
+ startHeight uint64) (r *CompactionChainRevealer, err error) {
+ blocksByHash, err := loadAllBlocks(iter)
+ if err != nil {
+ return
+ }
+ if startHeight == 0 {
+ startHeight = 1
+ }
+ blocks := types.ByFinalizationHeight{}
+ for _, b := range blocksByHash {
+ if b.Finalization.Height < startHeight {
+ continue
+ }
+ blocks = append(blocks, b)
+ }
+ sort.Sort(types.ByFinalizationHeight(blocks))
+ // Make sure the finalization height of blocks are incremental with step 1.
+ for idx, b := range blocks {
+ if idx == 0 {
+ continue
+ }
+ if b.Finalization.Height != blocks[idx-1].Finalization.Height+1 {
+ err = ErrNotValidCompactionChain
+ return
+ }
+ }
+ r = &CompactionChainRevealer{
+ blocks: blocks,
+ }
+ r.Reset()
+ return
+}
+
+// Next implements Revealer.Next method, which would reveal blocks in the order
+// of compaction chain.
+func (r *CompactionChainRevealer) Next() (types.Block, error) {
+ if r.nextRevealIndex == len(r.blocks) {
+ return types.Block{}, blockdb.ErrIterationFinished
+ }
+ b := r.blocks[r.nextRevealIndex]
+ r.nextRevealIndex++
+ return *b, nil
+}
+
+// Reset implement Revealer.Reset method, which would reset revealing.
+func (r *CompactionChainRevealer) Reset() {
+ r.nextRevealIndex = 0
+}
diff --git a/core/test/revealer_test.go b/core/test/revealer_test.go
index d9920c7..5a1bc07 100644
--- a/core/test/revealer_test.go
+++ b/core/test/revealer_test.go
@@ -157,6 +157,66 @@ func (s *RevealerTestSuite) TestRandomTipReveal() {
s.baseTest(revealer, 10, checkFunc)
}
+func (s *RevealerTestSuite) TestCompactionChainReveal() {
+ db, err := blockdb.NewMemBackedBlockDB()
+ s.Require().NoError(err)
+ // Put several blocks with finalization field ready.
+ b1 := &types.Block{
+ Hash: common.NewRandomHash(),
+ Finalization: types.FinalizationResult{
+ Height: 1,
+ }}
+ b2 := &types.Block{
+ Hash: common.NewRandomHash(),
+ Finalization: types.FinalizationResult{
+ ParentHash: b1.Hash,
+ Height: 2,
+ }}
+ b3 := &types.Block{
+ Hash: common.NewRandomHash(),
+ Finalization: types.FinalizationResult{
+ ParentHash: b2.Hash,
+ Height: 3,
+ }}
+ s.Require().NoError(db.Put(*b1))
+ s.Require().NoError(db.Put(*b3))
+ iter, err := db.GetAll()
+ s.Require().NoError(err)
+ // The compaction chain is not complete, we can't construct a revealer
+ // instance successfully.
+ r, err := NewCompactionChainRevealer(iter, 0)
+ s.Require().Nil(r)
+ s.Require().IsType(ErrNotValidCompactionChain, err)
+ // Put a block to make the compaction chain complete.
+ s.Require().NoError(db.Put(*b2))
+ // We can construct that revealer now.
+ iter, err = db.GetAll()
+ s.Require().NoError(err)
+ r, err = NewCompactionChainRevealer(iter, 0)
+ s.Require().NotNil(r)
+ s.Require().NoError(err)
+ // The revealing order should be ok.
+ chk := func(h uint64) {
+ b, err := r.Next()
+ s.Require().NoError(err)
+ s.Require().Equal(b.Finalization.Height, h)
+ }
+ chk(1)
+ chk(2)
+ chk(3)
+ // Iteration should be finished
+ _, err = r.Next()
+ s.Require().IsType(blockdb.ErrIterationFinished, err)
+ // Test 'startHeight' parameter.
+ iter, err = db.GetAll()
+ s.Require().NoError(err)
+ r, err = NewCompactionChainRevealer(iter, 2)
+ s.Require().NotNil(r)
+ s.Require().NoError(err)
+ chk(2)
+ chk(3)
+}
+
func TestRevealer(t *testing.T) {
suite.Run(t, new(RevealerTestSuite))
}
diff --git a/core/test/stopper.go b/core/test/stopper.go
index abc93c3..40868d8 100644
--- a/core/test/stopper.go
+++ b/core/test/stopper.go
@@ -61,7 +61,7 @@ func (s *StopByConfirmedBlocks) ShouldStop(nID types.NodeID) bool {
lastChecked := s.lastCheckDelivered[nID]
currentConfirmedBlocks := s.confirmedBlocks[nID]
db := s.dbs[nID]
- s.apps[nID].Check(func(app *App) {
+ s.apps[nID].WithLock(func(app *App) {
for _, h := range app.DeliverSequence[lastChecked:] {
b, err := db.Get(h)
if err != nil {
@@ -116,7 +116,7 @@ func (s *StopByRound) ShouldStop(nID types.NodeID) bool {
if curRound := s.currentRounds[nID]; curRound < s.untilRound {
lastChecked := s.lastCheckDelivered[nID]
db := s.dbs[nID]
- s.apps[nID].Check(func(app *App) {
+ s.apps[nID].WithLock(func(app *App) {
for _, h := range app.DeliverSequence[lastChecked:] {
b, err := db.Get(h)
if err != nil {