diff options
author | Mission Liao <mission.liao@dexon.org> | 2018-08-03 13:57:41 +0800 |
---|---|---|
committer | Wei-Ning Huang <aitjcize@gmail.com> | 2018-08-03 13:57:41 +0800 |
commit | 101ce1072667a1a8cfeaa58dc862eb4d0dbec6f7 (patch) | |
tree | 5e4a57f708d64450d1049c791d7786570a3aa24e /core/acking_test.go | |
parent | 6c4617f42f31014727bdc6f5731c32fc21004101 (diff) | |
download | dexon-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.go | 74 |
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)) } |