aboutsummaryrefslogtreecommitdiffstats
path: root/core/acking_test.go
diff options
context:
space:
mode:
authorMission Liao <mission.liao@dexon.org>2018-08-03 13:57:41 +0800
committerWei-Ning Huang <aitjcize@gmail.com>2018-08-03 13:57:41 +0800
commit101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7 (patch)
tree5e4a57f708d64450d1049c791d7786570a3aa24e /core/acking_test.go
parent6c4617f42f31014727bdc6f5731c32fc21004101 (diff)
downloaddexon-consensus-101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7.tar
dexon-consensus-101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7.tar.gz
dexon-consensus-101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7.tar.bz2
dexon-consensus-101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7.tar.lz
dexon-consensus-101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7.tar.xz
dexon-consensus-101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7.tar.zst
dexon-consensus-101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7.zip
test: random blocks generator (#26)
* Add blocks generator. This helper would randomly generate blocks that forms valid DAGs. * Add revealer Revealer is an extension of blockdb.BlockIterator. The block sequence from 'Next' method would be either randomly (see RandomRevealer) or meeting some specific condition (ex. forming a DAG, see RandomDAGRevealer). * Add test for sequencer based on random blocks. * core: refine Application interface and add Governance interface (#24) Add a new Governance interface for interaction with the governance contract. Also remove the ValidateBlock call in application interface as the application should validate it before putting it into the consensus module. A new BlockConverter interface is also added. The consensus module should accept the BlockConverter interface in future implementation, and use the Block() function to get the underlying block info.
Diffstat (limited to 'core/acking_test.go')
-rw-r--r--core/acking_test.go74
1 files changed, 74 insertions, 0 deletions
diff --git a/core/acking_test.go b/core/acking_test.go
index c0b6402..b1f26b2 100644
--- a/core/acking_test.go
+++ b/core/acking_test.go
@@ -19,11 +19,14 @@ package core
import (
"math/rand"
+ "sort"
"testing"
"github.com/stretchr/testify/suite"
+ "github.com/dexon-foundation/dexon-consensus-core/blockdb"
"github.com/dexon-foundation/dexon-consensus-core/common"
+ "github.com/dexon-foundation/dexon-consensus-core/core/test"
"github.com/dexon-foundation/dexon-consensus-core/core/types"
)
@@ -421,6 +424,77 @@ func (s *AckingTest) TestRandomIntensiveAcking() {
s.True(len(a.blocks) < 500)
}
+func (s *AckingTest) TestRandomlyGeneratedBlocks() {
+ var (
+ validatorCount = 19
+ blockCount = 50
+ repeat = 20
+ )
+
+ // Prepare a randomly generated blocks.
+ db, err := blockdb.NewMemBackedBlockDB("test-acking-random.blockdb")
+ s.Require().Nil(err)
+ defer func() {
+ // If the test fails, keep the block database for troubleshooting.
+ if s.T().Failed() {
+ s.Nil(db.Close())
+ }
+ }()
+ gen := test.NewBlocksGenerator(nil)
+ s.Require().Nil(gen.Generate(validatorCount, blockCount, nil, db))
+ iter, err := db.GetAll()
+ s.Require().Nil(err)
+ // Setup a revealer that would reveal blocks randomly.
+ revealer, err := test.NewRandomRevealer(iter)
+ s.Require().Nil(err)
+
+ stronglyAckedHashesAsString := map[string]struct{}{}
+ for i := 0; i < repeat; i++ {
+ validators := map[types.ValidatorID]struct{}{}
+ acking := newAcking()
+ stronglyAckedHashes := common.Hashes{}
+ revealer.Reset()
+
+ for {
+ // Reveal next block.
+ b, err := revealer.Next()
+ if err != nil {
+ if err == blockdb.ErrIterationFinished {
+ err = nil
+ break
+ }
+ }
+ s.Require().Nil(err)
+
+ // It's a hack to add validator to Acking module.
+ if _, added := validators[b.ProposerID]; !added {
+ acking.addValidator(b.ProposerID)
+ validators[b.ProposerID] = struct{}{}
+ }
+ // Perform reliable broadcast process.
+ acking.processBlock(&b)
+ for _, b := range acking.extractBlocks() {
+ stronglyAckedHashes = append(stronglyAckedHashes, b.Hash)
+ }
+ }
+ // To make it easier to check, sort hashes of
+ // strongly acked blocks, and concatenate them into
+ // a string.
+ sort.Sort(stronglyAckedHashes)
+ asString := ""
+ for _, h := range stronglyAckedHashes {
+ asString += h.String() + ","
+ }
+ stronglyAckedHashesAsString[asString] = struct{}{}
+ }
+ // Make sure concatenated hashes of strongly acked blocks are identical.
+ s.Require().Len(stronglyAckedHashesAsString, 1)
+ for h := range stronglyAckedHashesAsString {
+ // Make sure at least some blocks are strongly acked.
+ s.True(len(h) > 0)
+ }
+}
+
func TestAcking(t *testing.T) {
suite.Run(t, new(AckingTest))
}