kaspad/domain/blockdag/multiset.go
stasatdaglabs 8a4ece1101
[NOD-1223] Reorganize project (#868)
* [NOD-1223] Move all network stuff into a new network package.

* [NOD-1223] Delete the unused package testutil.

* [NOD-1223] Move infrastructure stuff into a new instrastructure package.

* [NOD-1223] Move domain stuff into a new domain package.
2020-08-13 17:27:25 +03:00

85 lines
2.3 KiB
Go

package blockdag
import (
"github.com/kaspanet/go-secp256k1"
"github.com/kaspanet/kaspad/network/domainmessage"
"github.com/pkg/errors"
)
// calcMultiset returns the multiset of the past UTXO of the given block.
func (node *blockNode) calcMultiset(dag *BlockDAG, acceptanceData MultiBlockTxsAcceptanceData,
selectedParentPastUTXO UTXOSet) (*secp256k1.MultiSet, error) {
return node.pastUTXOMultiSet(dag, acceptanceData, selectedParentPastUTXO)
}
func (node *blockNode) pastUTXOMultiSet(dag *BlockDAG, acceptanceData MultiBlockTxsAcceptanceData,
selectedParentPastUTXO UTXOSet) (*secp256k1.MultiSet, error) {
ms, err := node.selectedParentMultiset(dag)
if err != nil {
return nil, err
}
for _, blockAcceptanceData := range acceptanceData {
for _, txAcceptanceData := range blockAcceptanceData.TxAcceptanceData {
if !txAcceptanceData.IsAccepted {
continue
}
tx := txAcceptanceData.Tx.MsgTx()
var err error
ms, err = addTxToMultiset(ms, tx, selectedParentPastUTXO, node.blueScore)
if err != nil {
return nil, err
}
}
}
return ms, nil
}
// selectedParentMultiset returns the multiset of the node's selected
// parent. If the node is the genesis blockNode then it does not have
// a selected parent, in which case return a new, empty multiset.
func (node *blockNode) selectedParentMultiset(dag *BlockDAG) (*secp256k1.MultiSet, error) {
if node.isGenesis() {
return secp256k1.NewMultiset(), nil
}
ms, err := dag.multisetStore.multisetByBlockNode(node.selectedParent)
if err != nil {
return nil, err
}
return ms, nil
}
func addTxToMultiset(ms *secp256k1.MultiSet, tx *domainmessage.MsgTx, pastUTXO UTXOSet, blockBlueScore uint64) (*secp256k1.MultiSet, error) {
for _, txIn := range tx.TxIn {
entry, ok := pastUTXO.Get(txIn.PreviousOutpoint)
if !ok {
return nil, errors.Errorf("Couldn't find entry for outpoint %s", txIn.PreviousOutpoint)
}
var err error
ms, err = removeUTXOFromMultiset(ms, entry, &txIn.PreviousOutpoint)
if err != nil {
return nil, err
}
}
isCoinbase := tx.IsCoinBase()
for i, txOut := range tx.TxOut {
outpoint := *domainmessage.NewOutpoint(tx.TxID(), uint32(i))
entry := NewUTXOEntry(txOut, isCoinbase, blockBlueScore)
var err error
ms, err = addUTXOToMultiset(ms, entry, &outpoint)
if err != nil {
return nil, err
}
}
return ms, nil
}