mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-09-13 13:00:10 +00:00

* [NOD-1223] Delete unused files/packages. * [NOD-1223] Move signal and limits to the os package. * [NOD-1223] Put database and dbaccess into the db package. * [NOD-1223] Fold the logs package into the logger package. * [NOD-1223] Rename domainmessage to appmessage. * [NOD-1223] Rename to/from DomainMessage to AppMessage. * [NOD-1223] Move appmessage to the app packge. * [NOD-1223] Move protocol to the app packge. * [NOD-1223] Move the network package to the infrastructure packge. * [NOD-1223] Rename cmd to executables. * [NOD-1223] Fix go.doc in the logger package.
132 lines
3.1 KiB
Go
132 lines
3.1 KiB
Go
package blockdag
|
|
|
|
import (
|
|
"bytes"
|
|
"github.com/kaspanet/go-secp256k1"
|
|
"github.com/kaspanet/kaspad/infrastructure/db/dbaccess"
|
|
"github.com/kaspanet/kaspad/util/daghash"
|
|
"github.com/kaspanet/kaspad/util/locks"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type multisetStore struct {
|
|
dag *BlockDAG
|
|
new map[daghash.Hash]struct{}
|
|
loaded map[daghash.Hash]secp256k1.MultiSet
|
|
mtx *locks.PriorityMutex
|
|
}
|
|
|
|
func newMultisetStore(dag *BlockDAG) *multisetStore {
|
|
return &multisetStore{
|
|
dag: dag,
|
|
new: make(map[daghash.Hash]struct{}),
|
|
loaded: make(map[daghash.Hash]secp256k1.MultiSet),
|
|
}
|
|
}
|
|
|
|
func (store *multisetStore) setMultiset(node *blockNode, ms *secp256k1.MultiSet) {
|
|
store.loaded[*node.hash] = *ms
|
|
store.addToNewBlocks(node.hash)
|
|
}
|
|
|
|
func (store *multisetStore) addToNewBlocks(blockHash *daghash.Hash) {
|
|
store.new[*blockHash] = struct{}{}
|
|
}
|
|
|
|
func multisetNotFoundError(blockHash *daghash.Hash) error {
|
|
return errors.Errorf("Couldn't find multiset data for block %s", blockHash)
|
|
}
|
|
|
|
func (store *multisetStore) multisetByBlockNode(node *blockNode) (*secp256k1.MultiSet, error) {
|
|
ms, exists := store.multisetByBlockHash(node.hash)
|
|
if !exists {
|
|
return nil, multisetNotFoundError(node.hash)
|
|
}
|
|
return ms, nil
|
|
}
|
|
|
|
func (store *multisetStore) multisetByBlockHash(hash *daghash.Hash) (*secp256k1.MultiSet, bool) {
|
|
ms, ok := store.loaded[*hash]
|
|
return &ms, ok
|
|
}
|
|
|
|
// flushToDB writes all new multiset data to the database.
|
|
func (store *multisetStore) flushToDB(dbContext *dbaccess.TxContext) error {
|
|
if len(store.new) == 0 {
|
|
return nil
|
|
}
|
|
|
|
w := &bytes.Buffer{}
|
|
for hash := range store.new {
|
|
hash := hash // Copy hash to a new variable to avoid passing the same pointer
|
|
|
|
w.Reset()
|
|
ms, exists := store.loaded[hash]
|
|
if !exists {
|
|
return multisetNotFoundError(&hash)
|
|
}
|
|
|
|
err := serializeMultiset(w, &ms)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = store.storeMultiset(dbContext, &hash, w.Bytes())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (store *multisetStore) clearNewEntries() {
|
|
store.new = make(map[daghash.Hash]struct{})
|
|
}
|
|
|
|
func (store *multisetStore) init(dbContext dbaccess.Context) error {
|
|
cursor, err := dbaccess.MultisetCursor(dbContext)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer cursor.Close()
|
|
|
|
for ok := cursor.First(); ok; ok = cursor.Next() {
|
|
key, err := cursor.Key()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
hash, err := daghash.NewHash(key.Suffix())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
serializedMS, err := cursor.Value()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ms, err := deserializeMultiset(bytes.NewReader(serializedMS))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
store.loaded[*hash] = *ms
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// storeMultiset stores the multiset data to the database.
|
|
func (store *multisetStore) storeMultiset(dbContext dbaccess.Context, blockHash *daghash.Hash, serializedMS []byte) error {
|
|
exists, err := dbaccess.HasMultiset(dbContext, blockHash)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if exists {
|
|
return errors.Errorf("Can't override an existing multiset database entry for block %s", blockHash)
|
|
}
|
|
|
|
return dbaccess.StoreMultiset(dbContext, blockHash, serializedMS)
|
|
}
|