diff options
Diffstat (limited to 'core/lattice_test.go')
-rw-r--r-- | core/lattice_test.go | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/core/lattice_test.go b/core/lattice_test.go deleted file mode 100644 index b847fad..0000000 --- a/core/lattice_test.go +++ /dev/null @@ -1,262 +0,0 @@ -// 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 core - -import ( - "math/rand" - "testing" - "time" - - "github.com/dexon-foundation/dexon-consensus/common" - "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa" - "github.com/dexon-foundation/dexon-consensus/core/db" - "github.com/dexon-foundation/dexon-consensus/core/test" - "github.com/dexon-foundation/dexon-consensus/core/types" - "github.com/dexon-foundation/dexon-consensus/core/utils" - "github.com/stretchr/testify/suite" -) - -// testLatticeMgr wraps compaction chain and lattice. -type testLatticeMgr struct { - lattice *Lattice - ccModule *compactionChain - app *test.App - db db.Database -} - -func (mgr *testLatticeMgr) prepareBlock( - chainID uint32) (b *types.Block, err error) { - - b = &types.Block{ - Position: types.Position{ - ChainID: chainID, - }} - err = mgr.lattice.PrepareBlock(b, time.Now().UTC()) - return -} - -// Process describes the usage of Lattice.ProcessBlock. -func (mgr *testLatticeMgr) processBlock(b *types.Block) (err error) { - var ( - delivered []*types.Block - ) - if err = mgr.lattice.SanityCheck(b, false); err != nil { - if err == ErrRetrySanityCheckLater { - err = nil - } else { - return - } - } - if err = mgr.db.PutBlock(*b); err != nil { - if err != db.ErrBlockExists { - return - } - err = nil - } - if delivered, err = mgr.lattice.ProcessBlock(b); err != nil { - return - } - // Deliver blocks. - for _, b = range delivered { - if err = mgr.ccModule.processBlock(b); err != nil { - return - } - } - for _, b = range mgr.ccModule.extractBlocks() { - if err = mgr.db.UpdateBlock(*b); err != nil { - return - } - mgr.app.BlockDelivered(b.Hash, b.Position, b.Finalization) - } - if err = mgr.lattice.PurgeBlocks(delivered); err != nil { - return - } - return -} - -type LatticeTestSuite struct { - suite.Suite -} - -func (s *LatticeTestSuite) newTestLatticeMgr( - cfg *types.Config, dMoment time.Time) *testLatticeMgr { - var req = s.Require() - // Setup private key. - prvKey, err := ecdsa.NewPrivateKey() - req.NoError(err) - // Setup db. - dbInst, err := db.NewMemBackedDB() - req.NoError(err) - // Setup governance. - logger := &common.NullLogger{} - _, pubKeys, err := test.NewKeys(int(cfg.NotarySetSize)) - req.NoError(err) - gov, err := test.NewGovernance(test.NewState( - pubKeys, cfg.LambdaBA, logger, true), ConfigRoundShift) - req.NoError(err) - // Setup application. - app := test.NewApp(0, gov) - // Setup compaction chain. - cc := newCompactionChain(gov) - cc.init(&types.Block{}) - mock := newMockTSigVerifier(true) - for i := 0; i < cc.tsigVerifier.cacheSize; i++ { - cc.tsigVerifier.verifier[uint64(i)] = mock - } - // Setup lattice. - return &testLatticeMgr{ - ccModule: cc, - app: app, - db: dbInst, - lattice: NewLattice( - dMoment, - 0, - cfg, - utils.NewSigner(prvKey), - app, - app, - dbInst, - logger)} -} - -func (s *LatticeTestSuite) TestBasicUsage() { - // One Lattice prepare blocks on chains randomly selected each time - // and process it. Those generated blocks and kept into a buffer, and - // process by other Lattice instances with random order. - var ( - blockNum = 100 - chainNum = uint32(19) - otherLatticeNum = 20 - req = s.Require() - err error - cfg = types.Config{ - NumChains: chainNum, - NotarySetSize: chainNum, - PhiRatio: float32(2) / float32(3), - K: 0, - MinBlockInterval: 0, - RoundInterval: time.Hour, - } - dMoment = time.Now().UTC() - master = s.newTestLatticeMgr(&cfg, dMoment) - apps = []*test.App{master.app} - revealSeq = map[string]struct{}{} - ) - // Master-lattice generates blocks. - for i := uint32(0); i < chainNum; i++ { - // Produced genesis blocks should be delivered before all other blocks, - // or the consensus time would be wrong. - b, err := master.prepareBlock(i) - req.NotNil(b) - req.NoError(err) - // Ignore error "acking blocks don't exist". - req.NoError(master.processBlock(b)) - } - for i := 0; i < (blockNum - int(chainNum)); i++ { - b, err := master.prepareBlock(uint32(rand.Intn(int(chainNum)))) - req.NotNil(b) - req.NoError(err) - // Ignore error "acking blocks don't exist". - req.NoError(master.processBlock(b)) - } - // Now we have some blocks, replay them on different lattices. - iter, err := master.db.GetAllBlocks() - req.NoError(err) - revealer, err := test.NewRandomBlockRevealer(iter) - req.NoError(err) - for i := 0; i < otherLatticeNum; i++ { - revealer.Reset() - revealed := "" - other := s.newTestLatticeMgr(&cfg, dMoment) - for { - b, err := revealer.NextBlock() - if err != nil { - if err == db.ErrIterationFinished { - err = nil - break - } - } - req.NoError(err) - req.NoError(other.processBlock(&b)) - revealed += b.Hash.String() + "," - } - revealSeq[revealed] = struct{}{} - apps = append(apps, other.app) - } - // Make sure not only one revealing sequence. - req.True(len(revealSeq) > 1) - // Make sure nothing goes wrong. - for i, app := range apps { - err := app.Verify() - req.NoError(err) - for j, otherApp := range apps { - if i >= j { - continue - } - err := app.Compare(otherApp) - s.NoError(err) - } - } -} - -func (s *LatticeTestSuite) TestSanityCheck() { - // This sanity check focuses on hash/signature part. - var ( - chainNum = uint32(19) - cfg = types.Config{ - NumChains: chainNum, - PhiRatio: float32(2) / float32(3), - K: 0, - MinBlockInterval: 0, - } - lattice = s.newTestLatticeMgr(&cfg, time.Now().UTC()).lattice - signer = lattice.signer // Steal signer module from lattice, :( - req = s.Require() - err error - ) - // A block properly signed should pass sanity check. - b := &types.Block{ - Position: types.Position{ChainID: 0}, - Timestamp: time.Now().UTC(), - } - req.NoError(signer.SignBlock(b)) - req.NoError(lattice.SanityCheck(b, false)) - // A block with incorrect signature should not pass sanity check. - otherPrvKey, err := ecdsa.NewPrivateKey() - req.NoError(err) - b.Signature, err = otherPrvKey.Sign(common.NewRandomHash()) - req.Equal(lattice.SanityCheck(b, false), ErrIncorrectSignature) - // A block with un-sorted acks should not pass sanity check. - b.Acks = common.NewSortedHashes(common.Hashes{ - common.NewRandomHash(), - common.NewRandomHash(), - common.NewRandomHash(), - common.NewRandomHash(), - common.NewRandomHash(), - }) - b.Acks[0], b.Acks[1] = b.Acks[1], b.Acks[0] - req.NoError(signer.SignBlock(b)) - req.Equal(lattice.SanityCheck(b, false), ErrAcksNotSorted) - // A block with incorrect hash should not pass sanity check. - b.Hash = common.NewRandomHash() - req.Equal(lattice.SanityCheck(b, false), ErrIncorrectHash) -} - -func TestLattice(t *testing.T) { - suite.Run(t, new(LatticeTestSuite)) -} |