aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2018-10-23 15:17:52 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-12 17:27:16 +0800
commit9f723203a14fbe3f4ac087d2b7309381d7d1b419 (patch)
tree560f4f7b31186bc0fa3ff7ee18b4aa079c5f6c7a /vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb
parent18b940c6840e1030be76945207fb5bdf6323d696 (diff)
downloadgo-tangerine-9f723203a14fbe3f4ac087d2b7309381d7d1b419.tar.gz
go-tangerine-9f723203a14fbe3f4ac087d2b7309381d7d1b419.tar.zst
go-tangerine-9f723203a14fbe3f4ac087d2b7309381d7d1b419.zip
vendor: use govendor to import dexon-consensus-core
Diffstat (limited to 'vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb')
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/interfaces.go70
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/level-db.go127
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/memory.go179
3 files changed, 376 insertions, 0 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/interfaces.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/interfaces.go
new file mode 100644
index 000000000..fd176bc11
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/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
+// <http://www.gnu.org/licenses/>.
+
+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/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/level-db.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/level-db.go
new file mode 100644
index 000000000..79099c0f1
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/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
+// <http://www.gnu.org/licenses/>.
+
+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/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/memory.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockdb/memory.go
new file mode 100644
index 000000000..eeda47772
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/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
+// <http://www.gnu.org/licenses/>.
+
+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
+}