aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go')
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/db/level-db.go176
1 files changed, 156 insertions, 20 deletions
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
+}