diff options
Diffstat (limited to 'core/shard_test.go')
-rw-r--r-- | core/shard_test.go | 225 |
1 files changed, 0 insertions, 225 deletions
diff --git a/core/shard_test.go b/core/shard_test.go deleted file mode 100644 index 84f230b..0000000 --- a/core/shard_test.go +++ /dev/null @@ -1,225 +0,0 @@ -// 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/>. - -package core - -import ( - "math/rand" - "testing" - "time" - - "github.com/dexon-foundation/dexon-consensus-core/common" - "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" - "github.com/dexon-foundation/dexon-consensus-core/core/crypto/ecdsa" - "github.com/dexon-foundation/dexon-consensus-core/core/test" - "github.com/dexon-foundation/dexon-consensus-core/core/types" - "github.com/stretchr/testify/suite" -) - -// testShardMgr wraps compaction chain and shard. -type testShardMgr struct { - shard *Shard - ccModule *compactionChain - app *test.App - db blockdb.BlockDatabase -} - -func (mgr *testShardMgr) prepareBlock( - chainID uint32) (b *types.Block, err error) { - - b = &types.Block{ - Position: types.Position{ - ChainID: chainID, - }} - err = mgr.shard.PrepareBlock(b, time.Now().UTC()) - return -} - -// Process describes the usage of Shard.ProcessBlock. -func (mgr *testShardMgr) processBlock(b *types.Block) (err error) { - var ( - delivered []*types.Block - verified []*types.Block - pendings = []*types.Block{b} - ) - if err = mgr.shard.SanityCheck(b); err != nil { - if err == ErrAckingBlockNotExists { - err = nil - } - return - } - for { - if len(pendings) == 0 { - break - } - b, pendings = pendings[0], pendings[1:] - if verified, delivered, err = mgr.shard.ProcessBlock(b); err != nil { - return - } - // Deliver blocks. - for _, b = range delivered { - if err = mgr.ccModule.processBlock(b); err != nil { - return - } - if err = mgr.db.Update(*b); err != nil { - return - } - mgr.app.BlockDelivered(*b) - } - // Update pending blocks for verified block (pass sanity check). - pendings = append(pendings, verified...) - } - return -} - -type ShardTestSuite struct { - suite.Suite -} - -func (s *ShardTestSuite) newTestShardMgr(cfg *types.Config) *testShardMgr { - var req = s.Require() - // Setup private key. - prvKey, err := ecdsa.NewPrivateKey() - req.Nil(err) - // Setup blockdb. - db, err := blockdb.NewMemBackedBlockDB() - req.Nil(err) - // Setup application. - app := test.NewApp() - // Setup shard. - return &testShardMgr{ - ccModule: newCompactionChain(db), - app: app, - db: db, - shard: NewShard( - cfg, - NewAuthenticator(prvKey), - app, - app, - db)} -} - -func (s *ShardTestSuite) TestBasicUsage() { - // One shard prepare blocks on chains randomly selected each time - // and process it. Those generated blocks and kept into a buffer, and - // process by other shard instances with random order. - var ( - blockNum = 100 - chainNum = uint32(19) - otherShardNum = 20 - req = s.Require() - err error - cfg = types.Config{ - NumChains: chainNum, - PhiRatio: float32(2) / float32(3), - K: 0, - MinBlockInterval: 0, - MaxBlockInterval: 3000 * time.Second, - } - master = s.newTestShardMgr(&cfg) - apps = []*test.App{master.app} - revealSeq = map[string]struct{}{} - ) - // Master-shard generates blocks. - for i := uint32(0); i < chainNum; i++ { - // Produce 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.Nil(err) - // We've ignored the error for "acking blocks don't exist". - req.Nil(master.processBlock(b)) - } - for i := 0; i < (blockNum - int(chainNum)); i++ { - b, err := master.prepareBlock(uint32(rand.Intn(int(chainNum)))) - req.NotNil(b) - req.Nil(err) - // We've ignored the error for "acking blocks don't exist". - req.Nil(master.processBlock(b)) - } - // Now we have some blocks, replay them on different shards. - iter, err := master.db.GetAll() - req.Nil(err) - revealer, err := test.NewRandomRevealer(iter) - req.Nil(err) - for i := 0; i < otherShardNum; i++ { - revealer.Reset() - revealed := "" - other := s.newTestShardMgr(&cfg) - for { - b, err := revealer.Next() - if err != nil { - if err == blockdb.ErrIterationFinished { - err = nil - break - } - } - req.Nil(err) - req.Nil(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 { - req.Nil(app.Verify()) - for j, otherApp := range apps { - if i >= j { - continue - } - req.Nil(app.Compare(otherApp)) - } - } -} - -func (s *ShardTestSuite) 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, - MaxBlockInterval: 3000 * time.Second, - } - shard = s.newTestShardMgr(&cfg).shard - auth = shard.authModule // Steal auth module from shard, :( - req = s.Require() - err error - ) - // A block properly signed should pass sanity check. - b := &types.Block{ - Position: types.Position{ChainID: 0}, - } - req.NoError(auth.SignBlock(b)) - req.NoError(shard.SanityCheck(b)) - // A block with incorrect signature should not pass sanity check. - b.Signature, err = auth.prvKey.Sign(common.NewRandomHash()) - req.NoError(err) - req.Equal(shard.SanityCheck(b), ErrIncorrectSignature) - // A block with incorrect hash should not pass sanity check. - b.Hash = common.NewRandomHash() - req.Equal(shard.SanityCheck(b), ErrIncorrectHash) -} - -func TestShard(t *testing.T) { - suite.Run(t, new(ShardTestSuite)) -} |