aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/dexon-consensus/core/db
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/dexon-foundation/dexon-consensus/core/db')
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/db/interfaces.go23
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go176
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/db/memory.go92
3 files changed, 255 insertions, 36 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/db/interfaces.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/db/interfaces.go
index 5e13dc604..ebbbbd475 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/db/interfaces.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/db/interfaces.go
@@ -22,6 +22,7 @@ import (
"fmt"
"github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg"
"github.com/dexon-foundation/dexon-consensus/core/types"
)
@@ -38,6 +39,17 @@ var (
ErrClosed = fmt.Errorf("db closed")
// ErrNotImplemented is the error that some interface is not implemented.
ErrNotImplemented = fmt.Errorf("not implemented")
+ // ErrInvalidCompactionChainTipHeight means the newly updated height of
+ // the tip of compaction chain is invalid, usually means it's smaller than
+ // current cached one.
+ ErrInvalidCompactionChainTipHeight = fmt.Errorf(
+ "invalid compaction chain tip height")
+ // ErrDKGPrivateKeyExists raised when attempting to save DKG private key
+ // that already saved.
+ ErrDKGPrivateKeyExists = errors.New("dkg private key exists")
+ // ErrDKGPrivateKeyDoesNotExist raised when the DKG private key of the
+ // requested round does not exists.
+ ErrDKGPrivateKeyDoesNotExist = errors.New("dkg private key does not exists")
)
// Database is the interface for a Database.
@@ -55,12 +67,23 @@ type Reader interface {
HasBlock(hash common.Hash) bool
GetBlock(hash common.Hash) (types.Block, error)
GetAllBlocks() (BlockIterator, error)
+
+ // GetCompactionChainTipInfo returns the block hash and finalization height
+ // of the tip block of compaction chain. Empty hash and zero height means
+ // the compaction chain is empty.
+ GetCompactionChainTipInfo() (common.Hash, uint64)
+
+ // DKG Private Key related methods.
+ HasDKGPrivateKey(round uint64) (bool, error)
+ GetDKGPrivateKey(round uint64) (dkg.PrivateKey, error)
}
// Writer defines the interface for writing blocks into DB.
type Writer interface {
UpdateBlock(block types.Block) error
PutBlock(block types.Block) error
+ PutCompactionChainTipInfo(common.Hash, uint64) error
+ PutDKGPrivateKey(uint64, dkg.PrivateKey) error
}
// BlockIterator defines an iterator on blocks hold
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go
index 6983d3a5e..3b5994b26 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go
@@ -18,14 +18,27 @@
package db
import (
- "encoding/json"
+ "encoding/binary"
"github.com/syndtr/goleveldb/leveldb"
"github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon/rlp"
)
+var (
+ blockKeyPrefix = []byte("b-")
+ compactionChainTipInfoKey = []byte("cc-tip")
+ dkgPrivateKeyKeyPrefix = []byte("dkg-prvs")
+)
+
+type compactionChainTipInfo struct {
+ Height uint64 `json:"height"`
+ Hash common.Hash `json:"hash"`
+}
+
// LevelDBBackedDB is a leveldb backed DB implementation.
type LevelDBBackedDB struct {
db *leveldb.DB
@@ -50,7 +63,7 @@ func (lvl *LevelDBBackedDB) Close() error {
// HasBlock implements the Reader.Has method.
func (lvl *LevelDBBackedDB) HasBlock(hash common.Hash) bool {
- exists, err := lvl.db.Has([]byte(hash[:]), nil)
+ exists, err := lvl.internalHasBlock(lvl.getBlockKey(hash))
if err != nil {
// TODO(missionliao): Modify the interface to return error.
panic(err)
@@ -58,18 +71,25 @@ func (lvl *LevelDBBackedDB) HasBlock(hash common.Hash) bool {
return exists
}
+func (lvl *LevelDBBackedDB) internalHasBlock(key []byte) (bool, error) {
+ exists, err := lvl.db.Has(key, nil)
+ if err != nil {
+ return false, err
+ }
+ return exists, nil
+}
+
// GetBlock implements the Reader.GetBlock method.
func (lvl *LevelDBBackedDB) GetBlock(
hash common.Hash) (block types.Block, err error) {
-
- queried, err := lvl.db.Get([]byte(hash[:]), nil)
+ queried, err := lvl.db.Get(lvl.getBlockKey(hash), nil)
if err != nil {
if err == leveldb.ErrNotFound {
err = ErrBlockDoesNotExist
}
return
}
- err = json.Unmarshal(queried, &block)
+ err = rlp.DecodeBytes(queried, &block)
if err != nil {
return
}
@@ -80,20 +100,20 @@ func (lvl *LevelDBBackedDB) GetBlock(
func (lvl *LevelDBBackedDB) UpdateBlock(block types.Block) (err error) {
// NOTE: we didn't handle changes of block hash (and it
// should not happen).
- marshaled, err := json.Marshal(&block)
+ marshaled, err := rlp.EncodeToBytes(&block)
if err != nil {
return
}
-
- if !lvl.HasBlock(block.Hash) {
+ blockKey := lvl.getBlockKey(block.Hash)
+ exists, err := lvl.internalHasBlock(blockKey)
+ if err != nil {
+ return
+ }
+ if !exists {
err = ErrBlockDoesNotExist
return
}
- err = lvl.db.Put(
- []byte(block.Hash[:]),
- marshaled,
- nil)
- if err != nil {
+ if err = lvl.db.Put(blockKey, marshaled, nil); err != nil {
return
}
return
@@ -101,19 +121,20 @@ func (lvl *LevelDBBackedDB) UpdateBlock(block types.Block) (err error) {
// PutBlock implements the Writer.PutBlock method.
func (lvl *LevelDBBackedDB) PutBlock(block types.Block) (err error) {
- marshaled, err := json.Marshal(&block)
+ marshaled, err := rlp.EncodeToBytes(&block)
if err != nil {
return
}
- if lvl.HasBlock(block.Hash) {
+ blockKey := lvl.getBlockKey(block.Hash)
+ exists, err := lvl.internalHasBlock(blockKey)
+ if err != nil {
+ return
+ }
+ if exists {
err = ErrBlockExists
return
}
- err = lvl.db.Put(
- []byte(block.Hash[:]),
- marshaled,
- nil)
- if err != nil {
+ if err = lvl.db.Put(blockKey, marshaled, nil); err != nil {
return
}
return
@@ -125,3 +146,118 @@ func (lvl *LevelDBBackedDB) GetAllBlocks() (BlockIterator, error) {
// TODO (mission): Implement this part via goleveldb's iterator.
return nil, ErrNotImplemented
}
+
+// PutCompactionChainTipInfo saves tip of compaction chain into the database.
+func (lvl *LevelDBBackedDB) PutCompactionChainTipInfo(
+ blockHash common.Hash, height uint64) error {
+ marshaled, err := rlp.EncodeToBytes(&compactionChainTipInfo{
+ Hash: blockHash,
+ Height: height,
+ })
+ if err != nil {
+ return err
+ }
+ // Check current cached tip info to make sure the one to be updated is
+ // valid.
+ info, err := lvl.internalGetCompactionChainTipInfo()
+ if err != nil {
+ return err
+ }
+ if info.Height >= height {
+ return ErrInvalidCompactionChainTipHeight
+ }
+ if err = lvl.db.Put(compactionChainTipInfoKey, marshaled, nil); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (lvl *LevelDBBackedDB) internalGetCompactionChainTipInfo() (
+ info compactionChainTipInfo, err error) {
+ queried, err := lvl.db.Get(compactionChainTipInfoKey, nil)
+ if err != nil {
+ if err == leveldb.ErrNotFound {
+ err = nil
+ }
+ return
+ }
+ if err = rlp.DecodeBytes(queried, &info); err != nil {
+ return
+ }
+ return
+}
+
+// GetCompactionChainTipInfo get the tip info of compaction chain into the
+// database.
+func (lvl *LevelDBBackedDB) GetCompactionChainTipInfo() (
+ hash common.Hash, height uint64) {
+ info, err := lvl.internalGetCompactionChainTipInfo()
+ if err != nil {
+ panic(err)
+ }
+ hash, height = info.Hash, info.Height
+ return
+}
+
+// HasDKGPrivateKey check existence of DKG private key of one round.
+func (lvl *LevelDBBackedDB) HasDKGPrivateKey(round uint64) (bool, error) {
+ exists, err := lvl.db.Has(lvl.getDKGPrivateKeyKey(round), nil)
+ if err != nil {
+ return false, err
+ }
+ return exists, nil
+}
+
+// GetDKGPrivateKey get DKG private key of one round.
+func (lvl *LevelDBBackedDB) GetDKGPrivateKey(round uint64) (
+ prv dkg.PrivateKey, err error) {
+ queried, err := lvl.db.Get(lvl.getDKGPrivateKeyKey(round), nil)
+ if err != nil {
+ if err == leveldb.ErrNotFound {
+ err = ErrDKGPrivateKeyDoesNotExist
+ }
+ return
+ }
+ if err = rlp.DecodeBytes(queried, &prv); err != nil {
+ return
+ }
+ return
+}
+
+// PutDKGPrivateKey save DKG private key of one round.
+func (lvl *LevelDBBackedDB) PutDKGPrivateKey(
+ round uint64, prv dkg.PrivateKey) error {
+ // Check existence.
+ exists, err := lvl.HasDKGPrivateKey(round)
+ if err != nil {
+ return err
+ }
+ if exists {
+ return ErrDKGPrivateKeyExists
+ }
+ marshaled, err := rlp.EncodeToBytes(&prv)
+ if err != nil {
+ return err
+ }
+ if err := lvl.db.Put(
+ lvl.getDKGPrivateKeyKey(round), marshaled, nil); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (lvl *LevelDBBackedDB) getBlockKey(hash common.Hash) (ret []byte) {
+ ret = make([]byte, len(blockKeyPrefix)+len(hash[:]))
+ copy(ret, blockKeyPrefix)
+ copy(ret[len(blockKeyPrefix):], hash[:])
+ return
+}
+
+func (lvl *LevelDBBackedDB) getDKGPrivateKeyKey(
+ round uint64) (ret []byte) {
+ ret = make([]byte, len(dkgPrivateKeyKeyPrefix)+8)
+ copy(ret, dkgPrivateKeyKeyPrefix)
+ binary.LittleEndian.PutUint64(
+ ret[len(dkgPrivateKeyKeyPrefix):], round)
+ return
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/db/memory.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/db/memory.go
index 4246e4fe1..7393de9db 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/db/memory.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/db/memory.go
@@ -24,6 +24,7 @@ import (
"sync"
"github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg"
"github.com/dexon-foundation/dexon-consensus/core/types"
)
@@ -41,10 +42,15 @@ func (seq *blockSeqIterator) NextBlock() (types.Block, error) {
// MemBackedDB is a memory backed DB implementation.
type MemBackedDB struct {
- blocksMutex sync.RWMutex
- blockHashSequence common.Hashes
- blocksByHash map[common.Hash]*types.Block
- persistantFilePath string
+ blocksLock sync.RWMutex
+ blockHashSequence common.Hashes
+ blocksByHash map[common.Hash]*types.Block
+ compactionChainTipLock sync.RWMutex
+ compactionChainTipHash common.Hash
+ compactionChainTipHeight uint64
+ dkgPrivateKeysLock sync.RWMutex
+ dkgPrivateKeys map[uint64]*dkg.PrivateKey
+ persistantFilePath string
}
// NewMemBackedDB initialize a memory-backed database.
@@ -53,6 +59,7 @@ func NewMemBackedDB(persistantFilePath ...string) (
dbInst = &MemBackedDB{
blockHashSequence: common.Hashes{},
blocksByHash: make(map[common.Hash]*types.Block),
+ dkgPrivateKeys: make(map[uint64]*dkg.PrivateKey),
}
if len(persistantFilePath) == 0 || len(persistantFilePath[0]) == 0 {
return
@@ -87,8 +94,8 @@ func NewMemBackedDB(persistantFilePath ...string) (
// HasBlock returns wheter or not the DB has a block identified with the hash.
func (m *MemBackedDB) HasBlock(hash common.Hash) bool {
- m.blocksMutex.RLock()
- defer m.blocksMutex.RUnlock()
+ m.blocksLock.RLock()
+ defer m.blocksLock.RUnlock()
_, ok := m.blocksByHash[hash]
return ok
@@ -96,8 +103,8 @@ func (m *MemBackedDB) HasBlock(hash common.Hash) bool {
// GetBlock returns a block given a hash.
func (m *MemBackedDB) GetBlock(hash common.Hash) (types.Block, error) {
- m.blocksMutex.RLock()
- defer m.blocksMutex.RUnlock()
+ m.blocksLock.RLock()
+ defer m.blocksLock.RUnlock()
return m.internalGetBlock(hash)
}
@@ -116,8 +123,8 @@ func (m *MemBackedDB) PutBlock(block types.Block) error {
return ErrBlockExists
}
- m.blocksMutex.Lock()
- defer m.blocksMutex.Unlock()
+ m.blocksLock.Lock()
+ defer m.blocksLock.Unlock()
m.blockHashSequence = append(m.blockHashSequence, block.Hash)
m.blocksByHash[block.Hash] = &block
@@ -130,13 +137,66 @@ func (m *MemBackedDB) UpdateBlock(block types.Block) error {
return ErrBlockDoesNotExist
}
- m.blocksMutex.Lock()
- defer m.blocksMutex.Unlock()
+ m.blocksLock.Lock()
+ defer m.blocksLock.Unlock()
m.blocksByHash[block.Hash] = &block
return nil
}
+// PutCompactionChainTipInfo saves tip of compaction chain into the database.
+func (m *MemBackedDB) PutCompactionChainTipInfo(
+ blockHash common.Hash, height uint64) error {
+ m.compactionChainTipLock.Lock()
+ defer m.compactionChainTipLock.Unlock()
+ if m.compactionChainTipHeight >= height {
+ return ErrInvalidCompactionChainTipHeight
+ }
+ m.compactionChainTipHeight = height
+ m.compactionChainTipHash = blockHash
+ return nil
+}
+
+// GetCompactionChainTipInfo get the tip info of compaction chain into the
+// database.
+func (m *MemBackedDB) GetCompactionChainTipInfo() (
+ hash common.Hash, height uint64) {
+ m.compactionChainTipLock.RLock()
+ defer m.compactionChainTipLock.RUnlock()
+ return m.compactionChainTipHash, m.compactionChainTipHeight
+}
+
+// HasDKGPrivateKey check existence of DKG private key of one round.
+func (m *MemBackedDB) HasDKGPrivateKey(round uint64) (bool, error) {
+ m.dkgPrivateKeysLock.RLock()
+ defer m.dkgPrivateKeysLock.RUnlock()
+ _, exists := m.dkgPrivateKeys[round]
+ return exists, nil
+}
+
+// GetDKGPrivateKey get DKG private key of one round.
+func (m *MemBackedDB) GetDKGPrivateKey(round uint64) (
+ dkg.PrivateKey, error) {
+ m.dkgPrivateKeysLock.RLock()
+ defer m.dkgPrivateKeysLock.RUnlock()
+ if prv, exists := m.dkgPrivateKeys[round]; exists {
+ return *prv, nil
+ }
+ return dkg.PrivateKey{}, ErrDKGPrivateKeyDoesNotExist
+}
+
+// PutDKGPrivateKey save DKG private key of one round.
+func (m *MemBackedDB) PutDKGPrivateKey(
+ round uint64, prv dkg.PrivateKey) error {
+ m.dkgPrivateKeysLock.Lock()
+ defer m.dkgPrivateKeysLock.Unlock()
+ if _, exists := m.dkgPrivateKeys[round]; exists {
+ return ErrDKGPrivateKeyExists
+ }
+ m.dkgPrivateKeys[round] = &prv
+ return nil
+}
+
// Close implement Closer interface, which would release allocated resource.
func (m *MemBackedDB) Close() (err error) {
// Save internal state to a pretty-print json file. It's a temporary way
@@ -145,8 +205,8 @@ func (m *MemBackedDB) Close() (err error) {
return
}
- m.blocksMutex.RLock()
- defer m.blocksMutex.RUnlock()
+ m.blocksLock.RLock()
+ defer m.blocksLock.RUnlock()
toDump := struct {
Sequence common.Hashes
@@ -167,8 +227,8 @@ func (m *MemBackedDB) Close() (err error) {
}
func (m *MemBackedDB) getBlockByIndex(idx int) (types.Block, error) {
- m.blocksMutex.RLock()
- defer m.blocksMutex.RUnlock()
+ m.blocksLock.RLock()
+ defer m.blocksLock.RUnlock()
if idx >= len(m.blockHashSequence) {
return types.Block{}, ErrIterationFinished