From 8a908e98279d7e80978cd412057eddd4a6bbf06c Mon Sep 17 00:00:00 2001 From: Wei-Ning Huang Date: Mon, 17 Sep 2018 17:45:49 +0800 Subject: core: move blockdb into core package and minor change on governance interface (#110) Since third party apps will possibly implement their only blockdb class, it make sense for the interface to be in core. Also add GetNumShards into the governance interface. --- blockdb/interfaces.go | 70 ------------- blockdb/level-db.go | 127 ----------------------- blockdb/level-db_test.go | 132 ------------------------ blockdb/memory.go | 179 --------------------------------- blockdb/memory_test.go | 134 ------------------------ core/blockdb/interfaces.go | 70 +++++++++++++ core/blockdb/level-db.go | 127 +++++++++++++++++++++++ core/blockdb/level-db_test.go | 132 ++++++++++++++++++++++++ core/blockdb/memory.go | 179 +++++++++++++++++++++++++++++++++ core/blockdb/memory_test.go | 134 ++++++++++++++++++++++++ core/compaction-chain.go | 2 +- core/compaction-chain_test.go | 2 +- core/consensus.go | 16 +-- core/consensus_test.go | 2 +- core/interfaces.go | 7 +- core/reliable-broadcast_test.go | 2 +- core/test/blocks-generator.go | 2 +- core/test/blocks-generator_test.go | 2 +- core/test/governance.go | 9 +- core/test/interface.go | 2 +- core/test/revealer.go | 2 +- core/test/revealer_test.go | 2 +- core/test/stopper.go | 2 +- core/test/stopper_test.go | 2 +- core/total-ordering_test.go | 2 +- integration_test/non-byzantine_test.go | 2 +- integration_test/utils.go | 2 +- integration_test/validator.go | 2 +- simulation/governance.go | 9 +- simulation/validator.go | 2 +- 30 files changed, 685 insertions(+), 672 deletions(-) delete mode 100644 blockdb/interfaces.go delete mode 100644 blockdb/level-db.go delete mode 100644 blockdb/level-db_test.go delete mode 100644 blockdb/memory.go delete mode 100644 blockdb/memory_test.go create mode 100644 core/blockdb/interfaces.go create mode 100644 core/blockdb/level-db.go create mode 100644 core/blockdb/level-db_test.go create mode 100644 core/blockdb/memory.go create mode 100644 core/blockdb/memory_test.go diff --git a/blockdb/interfaces.go b/blockdb/interfaces.go deleted file mode 100644 index fd176bc..0000000 --- a/blockdb/interfaces.go +++ /dev/null @@ -1,70 +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 -// . - -package blockdb - -import ( - "errors" - "fmt" - - "github.com/dexon-foundation/dexon-consensus-core/common" - "github.com/dexon-foundation/dexon-consensus-core/core/types" -) - -var ( - // ErrBlockExists is the error when block eixsts. - ErrBlockExists = errors.New("block exists") - // ErrBlockDoesNotExist is the error when block does not eixst. - ErrBlockDoesNotExist = errors.New("block does not exist") - // ErrIterationFinished is the error to check if the iteration is finished. - ErrIterationFinished = errors.New("iteration finished") - // ErrEmptyPath is the error when the required path is empty. - ErrEmptyPath = fmt.Errorf("empty path") - // ErrClosed is the error when using DB after it's closed. - ErrClosed = fmt.Errorf("db closed") - // ErrNotImplemented is the error that some interface is not implemented. - ErrNotImplemented = fmt.Errorf("not implemented") -) - -// BlockDatabase is the interface for a BlockDatabase. -type BlockDatabase interface { - Reader - Writer - - // Close allows database implementation able to - // release resource when finishing. - Close() error -} - -// Reader defines the interface for reading blocks into DB. -type Reader interface { - Has(hash common.Hash) bool - Get(hash common.Hash) (types.Block, error) - GetAll() (BlockIterator, error) -} - -// Writer defines the interface for writing blocks into DB. -type Writer interface { - Update(block types.Block) error - Put(block types.Block) error -} - -// BlockIterator defines an iterator on blocks hold -// in a DB. -type BlockIterator interface { - Next() (types.Block, error) -} diff --git a/blockdb/level-db.go b/blockdb/level-db.go deleted file mode 100644 index 79099c0..0000000 --- a/blockdb/level-db.go +++ /dev/null @@ -1,127 +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 -// . - -package blockdb - -import ( - "encoding/json" - - "github.com/syndtr/goleveldb/leveldb" - - "github.com/dexon-foundation/dexon-consensus-core/common" - "github.com/dexon-foundation/dexon-consensus-core/core/types" -) - -// LevelDBBackedBlockDB is a leveldb backed BlockDB implementation. -type LevelDBBackedBlockDB struct { - db *leveldb.DB -} - -// NewLevelDBBackedBlockDB initialize a leveldb-backed block database. -func NewLevelDBBackedBlockDB( - path string) (lvl *LevelDBBackedBlockDB, err error) { - - db, err := leveldb.OpenFile(path, nil) - if err != nil { - return - } - lvl = &LevelDBBackedBlockDB{db: db} - return -} - -// Close implement Closer interface, which would release allocated resource. -func (lvl *LevelDBBackedBlockDB) Close() error { - return lvl.db.Close() -} - -// Has implements the Reader.Has method. -func (lvl *LevelDBBackedBlockDB) Has(hash common.Hash) bool { - exists, err := lvl.db.Has([]byte(hash[:]), nil) - if err != nil { - // TODO(missionliao): Modify the interface to return error. - panic(err) - } - return exists -} - -// Get implements the Reader.Get method. -func (lvl *LevelDBBackedBlockDB) Get( - hash common.Hash) (block types.Block, err error) { - - queried, err := lvl.db.Get([]byte(hash[:]), nil) - if err != nil { - if err == leveldb.ErrNotFound { - err = ErrBlockDoesNotExist - } - return - } - err = json.Unmarshal(queried, &block) - if err != nil { - return - } - return -} - -// Update implements the Writer.Update method. -func (lvl *LevelDBBackedBlockDB) Update(block types.Block) (err error) { - // NOTE: we didn't handle changes of block hash (and it - // should not happen). - marshaled, err := json.Marshal(&block) - if err != nil { - return - } - - if !lvl.Has(block.Hash) { - err = ErrBlockDoesNotExist - return - } - err = lvl.db.Put( - []byte(block.Hash[:]), - marshaled, - nil) - if err != nil { - return - } - return -} - -// Put implements the Writer.Put method. -func (lvl *LevelDBBackedBlockDB) Put(block types.Block) (err error) { - marshaled, err := json.Marshal(&block) - if err != nil { - return - } - if lvl.Has(block.Hash) { - err = ErrBlockExists - return - } - err = lvl.db.Put( - []byte(block.Hash[:]), - marshaled, - nil) - if err != nil { - return - } - return -} - -// GetAll implements Reader.GetAll method, which allows callers -// to retrieve all blocks in DB. -func (lvl *LevelDBBackedBlockDB) GetAll() (BlockIterator, error) { - // TODO (mission): Implement this part via goleveldb's iterator. - return nil, ErrNotImplemented -} diff --git a/blockdb/level-db_test.go b/blockdb/level-db_test.go deleted file mode 100644 index 06829f0..0000000 --- a/blockdb/level-db_test.go +++ /dev/null @@ -1,132 +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 -// . - -package blockdb - -import ( - "fmt" - "testing" - "time" - - "os" - - "github.com/stretchr/testify/suite" - - "github.com/dexon-foundation/dexon-consensus-core/common" - "github.com/dexon-foundation/dexon-consensus-core/core/types" -) - -type LevelDBTestSuite struct { - suite.Suite -} - -func (s *LevelDBTestSuite) TestBasicUsage() { - dbName := fmt.Sprintf("test-db-%v.db", time.Now().UTC()) - db, err := NewLevelDBBackedBlockDB(dbName) - s.Require().Nil(err) - defer func(dbName string) { - err = db.Close() - s.Nil(err) - err = os.RemoveAll(dbName) - s.Nil(err) - }(dbName) - - // Queried something from an empty database. - hash1 := common.NewRandomHash() - _, err = db.Get(hash1) - s.Equal(ErrBlockDoesNotExist, err) - - // Update on an empty database should not success. - validator1 := types.ValidatorID{Hash: common.NewRandomHash()} - block1 := types.Block{ - ProposerID: validator1, - Hash: hash1, - Position: types.Position{ - Height: 1, - }, - } - err = db.Update(block1) - s.Equal(ErrBlockDoesNotExist, err) - - // Put to create a new record should just work fine. - err = db.Put(block1) - s.Nil(err) - - // Get it back should work fine. - queried, err := db.Get(block1.Hash) - s.Nil(err) - s.Equal(queried.ProposerID, block1.ProposerID) - - // Test Update. - now := time.Now().UTC() - queried.Timestamp = now - - err = db.Update(queried) - s.Nil(err) - - // Try to get it back via ValidatorID and height. - queried, err = db.Get(block1.Hash) - - s.Nil(err) - s.Equal(now, queried.Timestamp) -} - -func (s *LevelDBTestSuite) TestSyncIndex() { - dbName := fmt.Sprintf("test-db-%v-si.db", time.Now().UTC()) - db, err := NewLevelDBBackedBlockDB(dbName) - s.Require().Nil(err) - defer func(dbName string) { - err = db.Close() - s.Nil(err) - err = os.RemoveAll(dbName) - s.Nil(err) - }(dbName) - - // Create some blocks. - blocks := [10]types.Block{} - for i := range blocks { - block := types.Block{ - ProposerID: types.ValidatorID{Hash: common.NewRandomHash()}, - Hash: common.NewRandomHash(), - Position: types.Position{ - Height: uint64(i), - }, - } - db.Put(block) - blocks[i] = block - } - - // Save blocks to db. - err = db.Close() - s.Nil(err) - - // Load back blocks(syncIndex is called). - db, err = NewLevelDBBackedBlockDB(dbName) - s.Require().Nil(err) - - // Verify result. - for _, block := range blocks { - queried, err := db.Get(block.Hash) - s.Nil(err) - s.Equal(block.ProposerID, queried.ProposerID) - s.Equal(block.Position.Height, queried.Position.Height) - } -} - -func TestLevelDB(t *testing.T) { - suite.Run(t, new(LevelDBTestSuite)) -} diff --git a/blockdb/memory.go b/blockdb/memory.go deleted file mode 100644 index eeda477..0000000 --- a/blockdb/memory.go +++ /dev/null @@ -1,179 +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 -// . - -package blockdb - -import ( - "encoding/json" - "io/ioutil" - "os" - "sync" - - "github.com/dexon-foundation/dexon-consensus-core/common" - "github.com/dexon-foundation/dexon-consensus-core/core/types" -) - -type seqIterator struct { - idx int - db *MemBackedBlockDB -} - -func (seq *seqIterator) Next() (types.Block, error) { - curIdx := seq.idx - seq.idx++ - return seq.db.getByIndex(curIdx) -} - -// MemBackedBlockDB is a memory backed BlockDB implementation. -type MemBackedBlockDB struct { - blocksMutex sync.RWMutex - blockHashSequence common.Hashes - blocksByHash map[common.Hash]*types.Block - persistantFilePath string -} - -// NewMemBackedBlockDB initialize a memory-backed block database. -func NewMemBackedBlockDB(persistantFilePath ...string) (db *MemBackedBlockDB, err error) { - db = &MemBackedBlockDB{ - blockHashSequence: common.Hashes{}, - blocksByHash: make(map[common.Hash]*types.Block), - } - if len(persistantFilePath) == 0 || len(persistantFilePath[0]) == 0 { - return - } - db.persistantFilePath = persistantFilePath[0] - buf, err := ioutil.ReadFile(db.persistantFilePath) - if err != nil { - if !os.IsNotExist(err) { - // Something unexpected happened. - return - } - // It's expected behavior that file doesn't exists, we should not - // report error on it. - err = nil - return - } - - // Init this instance by file content, it's a temporary way - // to export those private field for JSON encoding. - toLoad := struct { - Sequence common.Hashes - ByHash map[common.Hash]*types.Block - }{} - err = json.Unmarshal(buf, &toLoad) - if err != nil { - return - } - db.blockHashSequence = toLoad.Sequence - db.blocksByHash = toLoad.ByHash - return -} - -// Has returns wheter or not the DB has a block identified with the hash. -func (m *MemBackedBlockDB) Has(hash common.Hash) bool { - m.blocksMutex.RLock() - defer m.blocksMutex.RUnlock() - - _, ok := m.blocksByHash[hash] - return ok -} - -// Get returns a block given a hash. -func (m *MemBackedBlockDB) Get(hash common.Hash) (types.Block, error) { - m.blocksMutex.RLock() - defer m.blocksMutex.RUnlock() - - return m.internalGet(hash) -} - -func (m *MemBackedBlockDB) internalGet(hash common.Hash) (types.Block, error) { - b, ok := m.blocksByHash[hash] - if !ok { - return types.Block{}, ErrBlockDoesNotExist - } - return *b, nil -} - -// Put inserts a new block into the database. -func (m *MemBackedBlockDB) Put(block types.Block) error { - if m.Has(block.Hash) { - return ErrBlockExists - } - - m.blocksMutex.Lock() - defer m.blocksMutex.Unlock() - - m.blockHashSequence = append(m.blockHashSequence, block.Hash) - m.blocksByHash[block.Hash] = &block - return nil -} - -// Update updates a block in the database. -func (m *MemBackedBlockDB) Update(block types.Block) error { - m.blocksMutex.Lock() - defer m.blocksMutex.Unlock() - - m.blocksByHash[block.Hash] = &block - return nil -} - -// Close implement Closer interface, which would release allocated resource. -func (m *MemBackedBlockDB) Close() (err error) { - // Save internal state to a pretty-print json file. It's a temporary way - // to dump private file via JSON encoding. - if len(m.persistantFilePath) == 0 { - return - } - - m.blocksMutex.RLock() - defer m.blocksMutex.RUnlock() - - toDump := struct { - Sequence common.Hashes - ByHash map[common.Hash]*types.Block - }{ - Sequence: m.blockHashSequence, - ByHash: m.blocksByHash, - } - - // Dump to JSON with 2-space indent. - buf, err := json.Marshal(&toDump) - if err != nil { - return - } - - err = ioutil.WriteFile(m.persistantFilePath, buf, 0644) - return -} - -func (m *MemBackedBlockDB) getByIndex(idx int) (types.Block, error) { - m.blocksMutex.RLock() - defer m.blocksMutex.RUnlock() - - if idx >= len(m.blockHashSequence) { - return types.Block{}, ErrIterationFinished - } - - hash := m.blockHashSequence[idx] - return m.internalGet(hash) -} - -// GetAll implement Reader.GetAll method, which allows caller -// to retrieve all blocks in DB. -func (m *MemBackedBlockDB) GetAll() (BlockIterator, error) { - return &seqIterator{db: m}, nil -} diff --git a/blockdb/memory_test.go b/blockdb/memory_test.go deleted file mode 100644 index 9a3cfa2..0000000 --- a/blockdb/memory_test.go +++ /dev/null @@ -1,134 +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 -// . - -package blockdb - -import ( - "os" - "testing" - - "github.com/dexon-foundation/dexon-consensus-core/common" - "github.com/dexon-foundation/dexon-consensus-core/core/types" - "github.com/stretchr/testify/suite" -) - -type MemBackedBlockDBTestSuite struct { - suite.Suite - - v0 types.ValidatorID - b00, b01, b02 *types.Block -} - -func (s *MemBackedBlockDBTestSuite) SetupSuite() { - s.v0 = types.ValidatorID{Hash: common.NewRandomHash()} - - genesisHash := common.NewRandomHash() - s.b00 = &types.Block{ - ProposerID: s.v0, - ParentHash: genesisHash, - Hash: genesisHash, - Position: types.Position{ - Height: 0, - }, - Acks: common.NewSortedHashes(common.Hashes{}), - } - s.b01 = &types.Block{ - ProposerID: s.v0, - ParentHash: s.b00.Hash, - Hash: common.NewRandomHash(), - Position: types.Position{ - Height: 1, - }, - Acks: common.NewSortedHashes(common.Hashes{s.b00.Hash}), - } - s.b02 = &types.Block{ - ProposerID: s.v0, - ParentHash: s.b01.Hash, - Hash: common.NewRandomHash(), - Position: types.Position{ - Height: 2, - }, - Acks: common.NewSortedHashes(common.Hashes{s.b01.Hash}), - } -} - -func (s *MemBackedBlockDBTestSuite) TestSaveAndLoad() { - // Make sure we are able to save/load from file. - dbPath := "test-save-and-load.db" - - // Make sure the file pointed by 'dbPath' doesn't exist. - _, err := os.Stat(dbPath) - s.Require().NotNil(err) - - db, err := NewMemBackedBlockDB(dbPath) - s.Require().Nil(err) - s.Require().NotNil(db) - defer func() { - if db != nil { - s.Nil(os.Remove(dbPath)) - db = nil - } - }() - - s.Nil(db.Put(*s.b00)) - s.Nil(db.Put(*s.b01)) - s.Nil(db.Put(*s.b02)) - s.Nil(db.Close()) - - // Load the json file back to check if all inserted blocks - // exists. - db, err = NewMemBackedBlockDB(dbPath) - s.Require().Nil(err) - s.Require().NotNil(db) - s.True(db.Has(s.b00.Hash)) - s.True(db.Has(s.b01.Hash)) - s.True(db.Has(s.b02.Hash)) - s.Nil(db.Close()) -} - -func (s *MemBackedBlockDBTestSuite) TestIteration() { - // Make sure the file pointed by 'dbPath' doesn't exist. - db, err := NewMemBackedBlockDB() - s.Require().Nil(err) - s.Require().NotNil(db) - - // Setup database. - s.Nil(db.Put(*s.b00)) - s.Nil(db.Put(*s.b01)) - s.Nil(db.Put(*s.b02)) - - // Check if we can iterate all 3 blocks. - iter, err := db.GetAll() - s.Require().Nil(err) - touched := common.Hashes{} - for { - b, err := iter.Next() - if err == ErrIterationFinished { - break - } - s.Require().Nil(err) - touched = append(touched, b.Hash) - } - s.Len(touched, 3) - s.Contains(touched, s.b00.Hash) - s.Contains(touched, s.b01.Hash) - s.Contains(touched, s.b02.Hash) -} - -func TestMemBackedBlockDB(t *testing.T) { - suite.Run(t, new(MemBackedBlockDBTestSuite)) -} diff --git a/core/blockdb/interfaces.go b/core/blockdb/interfaces.go new file mode 100644 index 0000000..fd176bc --- /dev/null +++ b/core/blockdb/interfaces.go @@ -0,0 +1,70 @@ +// 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 +// . + +package blockdb + +import ( + "errors" + "fmt" + + "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core/types" +) + +var ( + // ErrBlockExists is the error when block eixsts. + ErrBlockExists = errors.New("block exists") + // ErrBlockDoesNotExist is the error when block does not eixst. + ErrBlockDoesNotExist = errors.New("block does not exist") + // ErrIterationFinished is the error to check if the iteration is finished. + ErrIterationFinished = errors.New("iteration finished") + // ErrEmptyPath is the error when the required path is empty. + ErrEmptyPath = fmt.Errorf("empty path") + // ErrClosed is the error when using DB after it's closed. + ErrClosed = fmt.Errorf("db closed") + // ErrNotImplemented is the error that some interface is not implemented. + ErrNotImplemented = fmt.Errorf("not implemented") +) + +// BlockDatabase is the interface for a BlockDatabase. +type BlockDatabase interface { + Reader + Writer + + // Close allows database implementation able to + // release resource when finishing. + Close() error +} + +// Reader defines the interface for reading blocks into DB. +type Reader interface { + Has(hash common.Hash) bool + Get(hash common.Hash) (types.Block, error) + GetAll() (BlockIterator, error) +} + +// Writer defines the interface for writing blocks into DB. +type Writer interface { + Update(block types.Block) error + Put(block types.Block) error +} + +// BlockIterator defines an iterator on blocks hold +// in a DB. +type BlockIterator interface { + Next() (types.Block, error) +} diff --git a/core/blockdb/level-db.go b/core/blockdb/level-db.go new file mode 100644 index 0000000..79099c0 --- /dev/null +++ b/core/blockdb/level-db.go @@ -0,0 +1,127 @@ +// 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 +// . + +package blockdb + +import ( + "encoding/json" + + "github.com/syndtr/goleveldb/leveldb" + + "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core/types" +) + +// LevelDBBackedBlockDB is a leveldb backed BlockDB implementation. +type LevelDBBackedBlockDB struct { + db *leveldb.DB +} + +// NewLevelDBBackedBlockDB initialize a leveldb-backed block database. +func NewLevelDBBackedBlockDB( + path string) (lvl *LevelDBBackedBlockDB, err error) { + + db, err := leveldb.OpenFile(path, nil) + if err != nil { + return + } + lvl = &LevelDBBackedBlockDB{db: db} + return +} + +// Close implement Closer interface, which would release allocated resource. +func (lvl *LevelDBBackedBlockDB) Close() error { + return lvl.db.Close() +} + +// Has implements the Reader.Has method. +func (lvl *LevelDBBackedBlockDB) Has(hash common.Hash) bool { + exists, err := lvl.db.Has([]byte(hash[:]), nil) + if err != nil { + // TODO(missionliao): Modify the interface to return error. + panic(err) + } + return exists +} + +// Get implements the Reader.Get method. +func (lvl *LevelDBBackedBlockDB) Get( + hash common.Hash) (block types.Block, err error) { + + queried, err := lvl.db.Get([]byte(hash[:]), nil) + if err != nil { + if err == leveldb.ErrNotFound { + err = ErrBlockDoesNotExist + } + return + } + err = json.Unmarshal(queried, &block) + if err != nil { + return + } + return +} + +// Update implements the Writer.Update method. +func (lvl *LevelDBBackedBlockDB) Update(block types.Block) (err error) { + // NOTE: we didn't handle changes of block hash (and it + // should not happen). + marshaled, err := json.Marshal(&block) + if err != nil { + return + } + + if !lvl.Has(block.Hash) { + err = ErrBlockDoesNotExist + return + } + err = lvl.db.Put( + []byte(block.Hash[:]), + marshaled, + nil) + if err != nil { + return + } + return +} + +// Put implements the Writer.Put method. +func (lvl *LevelDBBackedBlockDB) Put(block types.Block) (err error) { + marshaled, err := json.Marshal(&block) + if err != nil { + return + } + if lvl.Has(block.Hash) { + err = ErrBlockExists + return + } + err = lvl.db.Put( + []byte(block.Hash[:]), + marshaled, + nil) + if err != nil { + return + } + return +} + +// GetAll implements Reader.GetAll method, which allows callers +// to retrieve all blocks in DB. +func (lvl *LevelDBBackedBlockDB) GetAll() (BlockIterator, error) { + // TODO (mission): Implement this part via goleveldb's iterator. + return nil, ErrNotImplemented +} diff --git a/core/blockdb/level-db_test.go b/core/blockdb/level-db_test.go new file mode 100644 index 0000000..06829f0 --- /dev/null +++ b/core/blockdb/level-db_test.go @@ -0,0 +1,132 @@ +// 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 +// . + +package blockdb + +import ( + "fmt" + "testing" + "time" + + "os" + + "github.com/stretchr/testify/suite" + + "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core/types" +) + +type LevelDBTestSuite struct { + suite.Suite +} + +func (s *LevelDBTestSuite) TestBasicUsage() { + dbName := fmt.Sprintf("test-db-%v.db", time.Now().UTC()) + db, err := NewLevelDBBackedBlockDB(dbName) + s.Require().Nil(err) + defer func(dbName string) { + err = db.Close() + s.Nil(err) + err = os.RemoveAll(dbName) + s.Nil(err) + }(dbName) + + // Queried something from an empty database. + hash1 := common.NewRandomHash() + _, err = db.Get(hash1) + s.Equal(ErrBlockDoesNotExist, err) + + // Update on an empty database should not success. + validator1 := types.ValidatorID{Hash: common.NewRandomHash()} + block1 := types.Block{ + ProposerID: validator1, + Hash: hash1, + Position: types.Position{ + Height: 1, + }, + } + err = db.Update(block1) + s.Equal(ErrBlockDoesNotExist, err) + + // Put to create a new record should just work fine. + err = db.Put(block1) + s.Nil(err) + + // Get it back should work fine. + queried, err := db.Get(block1.Hash) + s.Nil(err) + s.Equal(queried.ProposerID, block1.ProposerID) + + // Test Update. + now := time.Now().UTC() + queried.Timestamp = now + + err = db.Update(queried) + s.Nil(err) + + // Try to get it back via ValidatorID and height. + queried, err = db.Get(block1.Hash) + + s.Nil(err) + s.Equal(now, queried.Timestamp) +} + +func (s *LevelDBTestSuite) TestSyncIndex() { + dbName := fmt.Sprintf("test-db-%v-si.db", time.Now().UTC()) + db, err := NewLevelDBBackedBlockDB(dbName) + s.Require().Nil(err) + defer func(dbName string) { + err = db.Close() + s.Nil(err) + err = os.RemoveAll(dbName) + s.Nil(err) + }(dbName) + + // Create some blocks. + blocks := [10]types.Block{} + for i := range blocks { + block := types.Block{ + ProposerID: types.ValidatorID{Hash: common.NewRandomHash()}, + Hash: common.NewRandomHash(), + Position: types.Position{ + Height: uint64(i), + }, + } + db.Put(block) + blocks[i] = block + } + + // Save blocks to db. + err = db.Close() + s.Nil(err) + + // Load back blocks(syncIndex is called). + db, err = NewLevelDBBackedBlockDB(dbName) + s.Require().Nil(err) + + // Verify result. + for _, block := range blocks { + queried, err := db.Get(block.Hash) + s.Nil(err) + s.Equal(block.ProposerID, queried.ProposerID) + s.Equal(block.Position.Height, queried.Position.Height) + } +} + +func TestLevelDB(t *testing.T) { + suite.Run(t, new(LevelDBTestSuite)) +} diff --git a/core/blockdb/memory.go b/core/blockdb/memory.go new file mode 100644 index 0000000..eeda477 --- /dev/null +++ b/core/blockdb/memory.go @@ -0,0 +1,179 @@ +// 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 +// . + +package blockdb + +import ( + "encoding/json" + "io/ioutil" + "os" + "sync" + + "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core/types" +) + +type seqIterator struct { + idx int + db *MemBackedBlockDB +} + +func (seq *seqIterator) Next() (types.Block, error) { + curIdx := seq.idx + seq.idx++ + return seq.db.getByIndex(curIdx) +} + +// MemBackedBlockDB is a memory backed BlockDB implementation. +type MemBackedBlockDB struct { + blocksMutex sync.RWMutex + blockHashSequence common.Hashes + blocksByHash map[common.Hash]*types.Block + persistantFilePath string +} + +// NewMemBackedBlockDB initialize a memory-backed block database. +func NewMemBackedBlockDB(persistantFilePath ...string) (db *MemBackedBlockDB, err error) { + db = &MemBackedBlockDB{ + blockHashSequence: common.Hashes{}, + blocksByHash: make(map[common.Hash]*types.Block), + } + if len(persistantFilePath) == 0 || len(persistantFilePath[0]) == 0 { + return + } + db.persistantFilePath = persistantFilePath[0] + buf, err := ioutil.ReadFile(db.persistantFilePath) + if err != nil { + if !os.IsNotExist(err) { + // Something unexpected happened. + return + } + // It's expected behavior that file doesn't exists, we should not + // report error on it. + err = nil + return + } + + // Init this instance by file content, it's a temporary way + // to export those private field for JSON encoding. + toLoad := struct { + Sequence common.Hashes + ByHash map[common.Hash]*types.Block + }{} + err = json.Unmarshal(buf, &toLoad) + if err != nil { + return + } + db.blockHashSequence = toLoad.Sequence + db.blocksByHash = toLoad.ByHash + return +} + +// Has returns wheter or not the DB has a block identified with the hash. +func (m *MemBackedBlockDB) Has(hash common.Hash) bool { + m.blocksMutex.RLock() + defer m.blocksMutex.RUnlock() + + _, ok := m.blocksByHash[hash] + return ok +} + +// Get returns a block given a hash. +func (m *MemBackedBlockDB) Get(hash common.Hash) (types.Block, error) { + m.blocksMutex.RLock() + defer m.blocksMutex.RUnlock() + + return m.internalGet(hash) +} + +func (m *MemBackedBlockDB) internalGet(hash common.Hash) (types.Block, error) { + b, ok := m.blocksByHash[hash] + if !ok { + return types.Block{}, ErrBlockDoesNotExist + } + return *b, nil +} + +// Put inserts a new block into the database. +func (m *MemBackedBlockDB) Put(block types.Block) error { + if m.Has(block.Hash) { + return ErrBlockExists + } + + m.blocksMutex.Lock() + defer m.blocksMutex.Unlock() + + m.blockHashSequence = append(m.blockHashSequence, block.Hash) + m.blocksByHash[block.Hash] = &block + return nil +} + +// Update updates a block in the database. +func (m *MemBackedBlockDB) Update(block types.Block) error { + m.blocksMutex.Lock() + defer m.blocksMutex.Unlock() + + m.blocksByHash[block.Hash] = &block + return nil +} + +// Close implement Closer interface, which would release allocated resource. +func (m *MemBackedBlockDB) Close() (err error) { + // Save internal state to a pretty-print json file. It's a temporary way + // to dump private file via JSON encoding. + if len(m.persistantFilePath) == 0 { + return + } + + m.blocksMutex.RLock() + defer m.blocksMutex.RUnlock() + + toDump := struct { + Sequence common.Hashes + ByHash map[common.Hash]*types.Block + }{ + Sequence: m.blockHashSequence, + ByHash: m.blocksByHash, + } + + // Dump to JSON with 2-space indent. + buf, err := json.Marshal(&toDump) + if err != nil { + return + } + + err = ioutil.WriteFile(m.persistantFilePath, buf, 0644) + return +} + +func (m *MemBackedBlockDB) getByIndex(idx int) (types.Block, error) { + m.blocksMutex.RLock() + defer m.blocksMutex.RUnlock() + + if idx >= len(m.blockHashSequence) { + return types.Block{}, ErrIterationFinished + } + + hash := m.blockHashSequence[idx] + return m.internalGet(hash) +} + +// GetAll implement Reader.GetAll method, which allows caller +// to retrieve all blocks in DB. +func (m *MemBackedBlockDB) GetAll() (BlockIterator, error) { + return &seqIterator{db: m}, nil +} diff --git a/core/blockdb/memory_test.go b/core/blockdb/memory_test.go new file mode 100644 index 0000000..9a3cfa2 --- /dev/null +++ b/core/blockdb/memory_test.go @@ -0,0 +1,134 @@ +// 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 +// . + +package blockdb + +import ( + "os" + "testing" + + "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core/types" + "github.com/stretchr/testify/suite" +) + +type MemBackedBlockDBTestSuite struct { + suite.Suite + + v0 types.ValidatorID + b00, b01, b02 *types.Block +} + +func (s *MemBackedBlockDBTestSuite) SetupSuite() { + s.v0 = types.ValidatorID{Hash: common.NewRandomHash()} + + genesisHash := common.NewRandomHash() + s.b00 = &types.Block{ + ProposerID: s.v0, + ParentHash: genesisHash, + Hash: genesisHash, + Position: types.Position{ + Height: 0, + }, + Acks: common.NewSortedHashes(common.Hashes{}), + } + s.b01 = &types.Block{ + ProposerID: s.v0, + ParentHash: s.b00.Hash, + Hash: common.NewRandomHash(), + Position: types.Position{ + Height: 1, + }, + Acks: common.NewSortedHashes(common.Hashes{s.b00.Hash}), + } + s.b02 = &types.Block{ + ProposerID: s.v0, + ParentHash: s.b01.Hash, + Hash: common.NewRandomHash(), + Position: types.Position{ + Height: 2, + }, + Acks: common.NewSortedHashes(common.Hashes{s.b01.Hash}), + } +} + +func (s *MemBackedBlockDBTestSuite) TestSaveAndLoad() { + // Make sure we are able to save/load from file. + dbPath := "test-save-and-load.db" + + // Make sure the file pointed by 'dbPath' doesn't exist. + _, err := os.Stat(dbPath) + s.Require().NotNil(err) + + db, err := NewMemBackedBlockDB(dbPath) + s.Require().Nil(err) + s.Require().NotNil(db) + defer func() { + if db != nil { + s.Nil(os.Remove(dbPath)) + db = nil + } + }() + + s.Nil(db.Put(*s.b00)) + s.Nil(db.Put(*s.b01)) + s.Nil(db.Put(*s.b02)) + s.Nil(db.Close()) + + // Load the json file back to check if all inserted blocks + // exists. + db, err = NewMemBackedBlockDB(dbPath) + s.Require().Nil(err) + s.Require().NotNil(db) + s.True(db.Has(s.b00.Hash)) + s.True(db.Has(s.b01.Hash)) + s.True(db.Has(s.b02.Hash)) + s.Nil(db.Close()) +} + +func (s *MemBackedBlockDBTestSuite) TestIteration() { + // Make sure the file pointed by 'dbPath' doesn't exist. + db, err := NewMemBackedBlockDB() + s.Require().Nil(err) + s.Require().NotNil(db) + + // Setup database. + s.Nil(db.Put(*s.b00)) + s.Nil(db.Put(*s.b01)) + s.Nil(db.Put(*s.b02)) + + // Check if we can iterate all 3 blocks. + iter, err := db.GetAll() + s.Require().Nil(err) + touched := common.Hashes{} + for { + b, err := iter.Next() + if err == ErrIterationFinished { + break + } + s.Require().Nil(err) + touched = append(touched, b.Hash) + } + s.Len(touched, 3) + s.Contains(touched, s.b00.Hash) + s.Contains(touched, s.b01.Hash) + s.Contains(touched, s.b02.Hash) +} + +func TestMemBackedBlockDB(t *testing.T) { + suite.Run(t, new(MemBackedBlockDBTestSuite)) +} diff --git a/core/compaction-chain.go b/core/compaction-chain.go index 243bda0..9ac52b0 100644 --- a/core/compaction-chain.go +++ b/core/compaction-chain.go @@ -24,8 +24,8 @@ import ( "sync" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" "github.com/dexon-foundation/dexon-consensus-core/crypto" ) diff --git a/core/compaction-chain_test.go b/core/compaction-chain_test.go index 46d4e10..ae08ac0 100644 --- a/core/compaction-chain_test.go +++ b/core/compaction-chain_test.go @@ -21,8 +21,8 @@ import ( "testing" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" "github.com/dexon-foundation/dexon-consensus-core/crypto/eth" "github.com/stretchr/testify/suite" diff --git a/core/consensus.go b/core/consensus.go index 4b92994..5e56ab9 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -25,8 +25,8 @@ import ( "sync" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" "github.com/dexon-foundation/dexon-consensus-core/crypto" ) @@ -145,7 +145,7 @@ func NewConsensus( // Setup acking by information returned from Governace. rb := newReliableBroadcast() - rb.setChainNum(gov.GetChainNumber()) + rb.setChainNum(gov.GetNumChains()) for vID := range validatorSet { rb.addValidator(vID) } @@ -160,7 +160,7 @@ func NewConsensus( to := newTotalOrdering( uint64(gov.GetTotalOrderingK()), uint64(float32(len(validatorSet)-1)*gov.GetPhiRatio()+1), - gov.GetChainNumber()) + gov.GetNumChains()) con := &Consensus{ ID: types.NewValidatorID(prv.PublicKey()), @@ -179,9 +179,9 @@ func NewConsensus( ctxCancel: ctxCancel, } - con.baModules = make([]*agreement, con.gov.GetChainNumber()) - con.receivers = make([]*consensusReceiver, con.gov.GetChainNumber()) - for i := uint32(0); i < con.gov.GetChainNumber(); i++ { + con.baModules = make([]*agreement, con.gov.GetNumChains()) + con.receivers = make([]*consensusReceiver, con.gov.GetNumChains()) + for i := uint32(0); i < con.gov.GetNumChains(); i++ { chainID := i con.receivers[chainID] = &consensusReceiver{ consensus: con, @@ -208,8 +208,8 @@ func NewConsensus( // Run starts running DEXON Consensus. func (con *Consensus) Run() { - ticks := make([]chan struct{}, 0, con.gov.GetChainNumber()) - for i := uint32(0); i < con.gov.GetChainNumber(); i++ { + ticks := make([]chan struct{}, 0, con.gov.GetNumChains()) + for i := uint32(0); i < con.gov.GetNumChains(); i++ { tick := make(chan struct{}) ticks = append(ticks, tick) go con.runBA(i, tick) diff --git a/core/consensus_test.go b/core/consensus_test.go index 313600a..1e97993 100644 --- a/core/consensus_test.go +++ b/core/consensus_test.go @@ -22,8 +22,8 @@ import ( "testing" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/dexon-foundation/dexon-consensus-core/crypto/eth" diff --git a/core/interfaces.go b/core/interfaces.go index aa4756e..68f210e 100644 --- a/core/interfaces.go +++ b/core/interfaces.go @@ -87,8 +87,11 @@ type Governance interface { // Get block proposing interval (in milliseconds). GetBlockProposingInterval() int - // Get Number of Chains. - GetChainNumber() uint32 + // Get Number of shards. + GetNumShards() uint32 + + // Get Number of chains. + GetNumChains() uint32 // Get Genesis CRS. GetGenesisCRS() string diff --git a/core/reliable-broadcast_test.go b/core/reliable-broadcast_test.go index bced96a..b1fc672 100644 --- a/core/reliable-broadcast_test.go +++ b/core/reliable-broadcast_test.go @@ -27,8 +27,8 @@ import ( "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/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" ) diff --git a/core/test/blocks-generator.go b/core/test/blocks-generator.go index 64ddfe2..93867f1 100644 --- a/core/test/blocks-generator.go +++ b/core/test/blocks-generator.go @@ -23,8 +23,8 @@ import ( "math/rand" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" ) diff --git a/core/test/blocks-generator_test.go b/core/test/blocks-generator_test.go index d46a082..e607796 100644 --- a/core/test/blocks-generator_test.go +++ b/core/test/blocks-generator_test.go @@ -21,8 +21,8 @@ import ( "sort" "testing" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" "github.com/stretchr/testify/suite" ) diff --git a/core/test/governance.go b/core/test/governance.go index 0e5c249..64ca39f 100644 --- a/core/test/governance.go +++ b/core/test/governance.go @@ -85,8 +85,13 @@ func (g *Governance) GetPhiRatio() float32 { return 0.667 } -// GetChainNumber returns the number of chains. -func (g *Governance) GetChainNumber() uint32 { +// GetNumShards returns the number of shards. +func (g *Governance) GetNumShards() uint32 { + return 1 +} + +// GetNumChains returns the number of chains. +func (g *Governance) GetNumChains() uint32 { return uint32(len(g.Validators)) } diff --git a/core/test/interface.go b/core/test/interface.go index 9932262..0dc2382 100644 --- a/core/test/interface.go +++ b/core/test/interface.go @@ -18,7 +18,7 @@ package test import ( - "github.com/dexon-foundation/dexon-consensus-core/blockdb" + "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/types" ) diff --git a/core/test/revealer.go b/core/test/revealer.go index 95eeb7c..b8eb9b4 100644 --- a/core/test/revealer.go +++ b/core/test/revealer.go @@ -22,8 +22,8 @@ import ( "sort" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" ) diff --git a/core/test/revealer_test.go b/core/test/revealer_test.go index 032cab3..16d3b18 100644 --- a/core/test/revealer_test.go +++ b/core/test/revealer_test.go @@ -20,8 +20,8 @@ package test import ( "testing" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" "github.com/stretchr/testify/suite" ) diff --git a/core/test/stopper.go b/core/test/stopper.go index da4d205..7c75958 100644 --- a/core/test/stopper.go +++ b/core/test/stopper.go @@ -20,7 +20,7 @@ package test import ( "sync" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" + "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/types" ) diff --git a/core/test/stopper_test.go b/core/test/stopper_test.go index 2abd503..9a0e430 100644 --- a/core/test/stopper_test.go +++ b/core/test/stopper_test.go @@ -21,8 +21,8 @@ import ( "testing" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/types" "github.com/stretchr/testify/suite" ) diff --git a/core/total-ordering_test.go b/core/total-ordering_test.go index f0d2e34..d6805b8 100644 --- a/core/total-ordering_test.go +++ b/core/total-ordering_test.go @@ -22,8 +22,8 @@ import ( "strings" "testing" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "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/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/stretchr/testify/suite" diff --git a/integration_test/non-byzantine_test.go b/integration_test/non-byzantine_test.go index afda9b4..a5ecff6 100644 --- a/integration_test/non-byzantine_test.go +++ b/integration_test/non-byzantine_test.go @@ -21,7 +21,7 @@ import ( "testing" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" + "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/stretchr/testify/suite" diff --git a/integration_test/utils.go b/integration_test/utils.go index 7371223..de7e6ab 100644 --- a/integration_test/utils.go +++ b/integration_test/utils.go @@ -1,7 +1,7 @@ package integration import ( - "github.com/dexon-foundation/dexon-consensus-core/blockdb" + "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/dexon-foundation/dexon-consensus-core/crypto" diff --git a/integration_test/validator.go b/integration_test/validator.go index 5909b46..a110ab0 100644 --- a/integration_test/validator.go +++ b/integration_test/validator.go @@ -22,9 +22,9 @@ import ( "sort" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/common" "github.com/dexon-foundation/dexon-consensus-core/core" + "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/dexon-foundation/dexon-consensus-core/crypto" diff --git a/simulation/governance.go b/simulation/governance.go index 5220ae5..44f679d 100644 --- a/simulation/governance.go +++ b/simulation/governance.go @@ -85,8 +85,13 @@ func (g *simGovernance) GetBlockProposingInterval() int { return 0 } -// GetChainNumber returns number of chain. -func (g *simGovernance) GetChainNumber() uint32 { +// GetNumShards returns number of shards. +func (g *simGovernance) GetNumShards() uint32 { + return 1 +} + +// GetNumChains returns number of chains. +func (g *simGovernance) GetNumChains() uint32 { return g.chainNum } diff --git a/simulation/validator.go b/simulation/validator.go index 483912b..137c2c0 100644 --- a/simulation/validator.go +++ b/simulation/validator.go @@ -22,9 +22,9 @@ import ( "sort" "time" - "github.com/dexon-foundation/dexon-consensus-core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/common" "github.com/dexon-foundation/dexon-consensus-core/core" + "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/dexon-foundation/dexon-consensus-core/crypto" "github.com/dexon-foundation/dexon-consensus-core/simulation/config" -- cgit