diff options
Diffstat (limited to 'core/db')
-rw-r--r-- | core/db/interfaces.go | 8 | ||||
-rw-r--r-- | core/db/level-db.go | 45 | ||||
-rw-r--r-- | core/db/level-db_test.go | 38 | ||||
-rw-r--r-- | core/db/memory.go | 55 |
4 files changed, 131 insertions, 15 deletions
diff --git a/core/db/interfaces.go b/core/db/interfaces.go index ebbbbd4..e958611 100644 --- a/core/db/interfaces.go +++ b/core/db/interfaces.go @@ -50,6 +50,12 @@ var ( // ErrDKGPrivateKeyDoesNotExist raised when the DKG private key of the // requested round does not exists. ErrDKGPrivateKeyDoesNotExist = errors.New("dkg private key does not exists") + // ErrDKGMasterPrivateSharesExists raised when attempting to save DKG master private shares + // that already saved. + ErrDKGMasterPrivateSharesExists = errors.New("dkg master private shares exists") + // ErrDKGMasterPrivateSharesDoesNotExist raised when the DKG master private shares of the + // requested round does not exists. + ErrDKGMasterPrivateSharesDoesNotExist = errors.New("dkg master private shares does not exists") ) // Database is the interface for a Database. @@ -76,6 +82,7 @@ type Reader interface { // DKG Private Key related methods. HasDKGPrivateKey(round uint64) (bool, error) GetDKGPrivateKey(round uint64) (dkg.PrivateKey, error) + GetDKGMasterPrivateShares(round uint64) (shares dkg.PrivateKeyShares, err error) } // Writer defines the interface for writing blocks into DB. @@ -84,6 +91,7 @@ type Writer interface { PutBlock(block types.Block) error PutCompactionChainTipInfo(common.Hash, uint64) error PutDKGPrivateKey(uint64, dkg.PrivateKey) error + PutOrUpdateDKGMasterPrivateShares(round uint64, shares dkg.PrivateKeyShares) error } // BlockIterator defines an iterator on blocks hold diff --git a/core/db/level-db.go b/core/db/level-db.go index 1fe29fa..efa1fec 100644 --- a/core/db/level-db.go +++ b/core/db/level-db.go @@ -29,9 +29,10 @@ import ( ) var ( - blockKeyPrefix = []byte("b-") - compactionChainTipInfoKey = []byte("cc-tip") - dkgPrivateKeyKeyPrefix = []byte("dkg-prvs") + blockKeyPrefix = []byte("b-") + compactionChainTipInfoKey = []byte("cc-tip") + dkgPrivateKeyKeyPrefix = []byte("dkg-prvs") + dkgMasterPrivateSharesPrefix = []byte("dkg-master-private-shares") ) type compactionChainTipInfo struct { @@ -188,6 +189,11 @@ func (lvl *LevelDBBackedDB) HasDKGPrivateKey(round uint64) (bool, error) { return lvl.db.Has(lvl.getDKGPrivateKeyKey(round), nil) } +// HasDKGMasterPrivateSharesKey check existence of DKG master private shares of one round. +func (lvl *LevelDBBackedDB) HasDKGMasterPrivateSharesKey(round uint64) (bool, error) { + return lvl.db.Has(lvl.getDKGMasterPrivateSharesKey(round), nil) +} + // GetDKGPrivateKey get DKG private key of one round. func (lvl *LevelDBBackedDB) GetDKGPrivateKey(round uint64) ( prv dkg.PrivateKey, err error) { @@ -221,6 +227,32 @@ func (lvl *LevelDBBackedDB) PutDKGPrivateKey( lvl.getDKGPrivateKeyKey(round), marshaled, nil) } +// GetDKGMasterPrivateShares get DKG master private shares of one round. +func (lvl *LevelDBBackedDB) GetDKGMasterPrivateShares(round uint64) ( + shares dkg.PrivateKeyShares, err error) { + queried, err := lvl.db.Get(lvl.getDKGMasterPrivateSharesKey(round), nil) + if err != nil { + if err == leveldb.ErrNotFound { + err = ErrDKGMasterPrivateSharesDoesNotExist + } + return + } + + err = rlp.DecodeBytes(queried, &shares) + return +} + +// PutOrUpdateDKGMasterPrivateShares save DKG master private shares of one round. +func (lvl *LevelDBBackedDB) PutOrUpdateDKGMasterPrivateShares( + round uint64, shares dkg.PrivateKeyShares) error { + marshaled, err := rlp.EncodeToBytes(&shares) + if err != nil { + return err + } + return lvl.db.Put( + lvl.getDKGMasterPrivateSharesKey(round), marshaled, nil) +} + func (lvl *LevelDBBackedDB) getBlockKey(hash common.Hash) (ret []byte) { ret = make([]byte, len(blockKeyPrefix)+len(hash[:])) copy(ret, blockKeyPrefix) @@ -236,3 +268,10 @@ func (lvl *LevelDBBackedDB) getDKGPrivateKeyKey( ret[len(dkgPrivateKeyKeyPrefix):], round) return } + +func (lvl *LevelDBBackedDB) getDKGMasterPrivateSharesKey(round uint64) (ret []byte) { + ret = make([]byte, len(dkgMasterPrivateSharesPrefix)+8) + copy(ret, dkgMasterPrivateSharesPrefix) + binary.LittleEndian.PutUint64(ret[len(dkgMasterPrivateSharesPrefix):], round) + return +} diff --git a/core/db/level-db_test.go b/core/db/level-db_test.go index 40f9a60..4187d34 100644 --- a/core/db/level-db_test.go +++ b/core/db/level-db_test.go @@ -185,6 +185,44 @@ func (s *LevelDBTestSuite) TestDKGPrivateKey() { s.Require().Equal(bytes.Compare(p.Bytes(), tmpPrv.Bytes()), 0) } +func (s *LevelDBTestSuite) TestDKGMasterPrivateShares() { + dbName := fmt.Sprintf("test-db-%v-dkg-master-prv-shares.db", time.Now().UTC()) + dbInst, err := NewLevelDBBackedDB(dbName) + s.Require().NoError(err) + defer func(dbName string) { + err = dbInst.Close() + s.NoError(err) + err = os.RemoveAll(dbName) + s.NoError(err) + }(dbName) + + exists, err := dbInst.HasDKGMasterPrivateSharesKey(1) + s.Require().NoError(err) + s.Require().False(exists) + + _, err = dbInst.GetDKGMasterPrivateShares(1) + s.Require().Equal(err.Error(), ErrDKGMasterPrivateSharesDoesNotExist.Error()) + + privShares, _ := dkg.NewPrivateKeyShares(10) + + s.Require().NoError(dbInst.PutOrUpdateDKGMasterPrivateShares(1, *privShares)) + + tmpShares, err := dbInst.GetDKGMasterPrivateShares(1) + s.Require().NoError(err) + s.Require().True(tmpShares.Equal(privShares)) + + newPrivShares, _ := dkg.NewPrivateKeyShares(10) + + // This privShare will override the old noe. + s.Require().NoError(dbInst.PutOrUpdateDKGMasterPrivateShares(1, *newPrivShares)) + + newTmpShares, err := dbInst.GetDKGMasterPrivateShares(1) + s.Require().NoError(err) + s.Require().True(newTmpShares.Equal(newPrivShares)) + + s.Require().False(newTmpShares.Equal(&tmpShares)) +} + func TestLevelDB(t *testing.T) { suite.Run(t, new(LevelDBTestSuite)) } diff --git a/core/db/memory.go b/core/db/memory.go index 4bc08e7..548e41e 100644 --- a/core/db/memory.go +++ b/core/db/memory.go @@ -42,24 +42,27 @@ func (seq *blockSeqIterator) NextBlock() (types.Block, error) { // MemBackedDB is a memory backed DB implementation. type MemBackedDB struct { - 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 + 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 + dkgMasterPrivateSharesLock sync.RWMutex + dkgMasterPrivateShares map[uint64]*dkg.PrivateKeyShares + persistantFilePath string } // NewMemBackedDB initialize a memory-backed database. func NewMemBackedDB(persistantFilePath ...string) ( dbInst *MemBackedDB, err error) { dbInst = &MemBackedDB{ - blockHashSequence: common.Hashes{}, - blocksByHash: make(map[common.Hash]*types.Block), - dkgPrivateKeys: make(map[uint64]*dkg.PrivateKey), + blockHashSequence: common.Hashes{}, + blocksByHash: make(map[common.Hash]*types.Block), + dkgPrivateKeys: make(map[uint64]*dkg.PrivateKey), + dkgMasterPrivateShares: make(map[uint64]*dkg.PrivateKeyShares), } if len(persistantFilePath) == 0 || len(persistantFilePath[0]) == 0 { return @@ -197,6 +200,34 @@ func (m *MemBackedDB) PutDKGPrivateKey( return nil } +// HasDKGMasterPrivateShares check existence of DKG master private shares of one round. +func (m *MemBackedDB) HasDKGMasterPrivateShares(round uint64) (bool, error) { + m.dkgMasterPrivateSharesLock.RLock() + defer m.dkgMasterPrivateSharesLock.RUnlock() + _, exists := m.dkgMasterPrivateShares[round] + return exists, nil +} + +// GetDKGMasterPrivateShares get DKG master private shares of one round. +func (m *MemBackedDB) GetDKGMasterPrivateShares(round uint64) ( + dkg.PrivateKeyShares, error) { + m.dkgMasterPrivateSharesLock.RLock() + defer m.dkgMasterPrivateSharesLock.RUnlock() + if shares, exists := m.dkgMasterPrivateShares[round]; exists { + return *shares, nil + } + return dkg.PrivateKeyShares{}, ErrDKGMasterPrivateSharesDoesNotExist +} + +// PutOrUpdateDKGMasterPrivateShares save DKG master private shares of one round. +func (m *MemBackedDB) PutOrUpdateDKGMasterPrivateShares( + round uint64, shares dkg.PrivateKeyShares) error { + m.dkgMasterPrivateSharesLock.Lock() + defer m.dkgMasterPrivateSharesLock.Unlock() + m.dkgMasterPrivateShares[round] = &shares + 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 |