mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-1512] Implement utxo deserialization (#1003)
* [NOD-1512] Implement UTXO set deserialization * [NOD-1512] Remove redundant file * [NOD-1512] Don't use big endian for serialization * [NOD-1512] Use Read/Write element * [NOD-1512] Unexport ReadElement * [NOD-1512] Fix StageVirtualUTXOSet * [NOD-1512] Get rid of dagParams in consensusStateManager * [NOD-1512] Get rid of dagParams in consensusStateManager
This commit is contained in:
parent
52c73d3a08
commit
5566aaf95a
@ -180,7 +180,7 @@ func (u utxoSetIterator) Next() bool {
|
||||
return u.cursor.Next()
|
||||
}
|
||||
|
||||
func (u utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry *externalapi.UTXOEntry) {
|
||||
func (u utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry *externalapi.UTXOEntry, err error) {
|
||||
key, err := u.cursor.Key()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -188,20 +188,20 @@ func (u utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry
|
||||
|
||||
utxoEntryBytes, err := u.cursor.Value()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
outpoint, err = deserializeOutpoint(key.Suffix())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
utxoEntry, err = deserializeUTXOEntry(utxoEntryBytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return outpoint, utxoEntry
|
||||
return outpoint, utxoEntry, nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) StageVirtualUTXOSet(virtualUTXOSetIterator model.ReadOnlyUTXOSetIterator) error {
|
||||
@ -211,7 +211,11 @@ func (c consensusStateStore) StageVirtualUTXOSet(virtualUTXOSetIterator model.Re
|
||||
|
||||
c.stagedVirtualUTXOSet = make(model.UTXOCollection)
|
||||
for virtualUTXOSetIterator.Next() {
|
||||
outpoint, entry := virtualUTXOSetIterator.Get()
|
||||
outpoint, entry, err := virtualUTXOSetIterator.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, exists := c.stagedVirtualUTXOSet[*outpoint]; exists {
|
||||
return errors.Errorf("outpoint %s is found more than once in the given iterator", outpoint)
|
||||
}
|
||||
|
@ -136,7 +136,8 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
|
||||
)
|
||||
consensusStateManager, err := consensusstatemanager.New(
|
||||
dbManager,
|
||||
dagParams,
|
||||
dagParams.FinalityDepth(),
|
||||
dagParams.PruningDepth(),
|
||||
ghostdagManager,
|
||||
dagTopologyManager,
|
||||
dagTraversalManager,
|
||||
|
@ -12,5 +12,5 @@ type ReadOnlyUTXOSet interface {
|
||||
// ReadOnlyUTXOSet
|
||||
type ReadOnlyUTXOSetIterator interface {
|
||||
Next() bool
|
||||
Get() (outpoint *externalapi.DomainOutpoint, utxoEntry *externalapi.UTXOEntry)
|
||||
Get() (outpoint *externalapi.DomainOutpoint, utxoEntry *externalapi.UTXOEntry, err error)
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/merkle"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
@ -132,8 +132,8 @@ func (bp *blockProcessor) newBlockAcceptedIDMerkleRoot() (*externalapi.DomainHas
|
||||
}
|
||||
}
|
||||
sort.Slice(acceptedTransactions, func(i, j int) bool {
|
||||
acceptedTransactionIID := hashserialization.TransactionID(acceptedTransactions[i])
|
||||
acceptedTransactionJID := hashserialization.TransactionID(acceptedTransactions[j])
|
||||
acceptedTransactionIID := consensusserialization.TransactionID(acceptedTransactions[i])
|
||||
acceptedTransactionJID := consensusserialization.TransactionID(acceptedTransactions[j])
|
||||
return transactionid.Less(acceptedTransactionIID, acceptedTransactionJID)
|
||||
})
|
||||
|
||||
|
@ -3,7 +3,7 @@ package blockprocessor
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -17,7 +17,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock)
|
||||
return errors.Errorf("cannot insert blocks while in %s mode", mode.State)
|
||||
}
|
||||
|
||||
hash := hashserialization.HeaderHash(block.Header)
|
||||
hash := consensusserialization.HeaderHash(block.Header)
|
||||
if mode.State == externalapi.SyncStateHeadersFirst && len(block.Transactions) != 0 {
|
||||
return errors.Errorf("block %s contains transactions while validating in header only mode", hash)
|
||||
}
|
||||
@ -148,7 +148,7 @@ func (bp *blockProcessor) validateBlock(block *externalapi.DomainBlock, mode *ex
|
||||
return err
|
||||
}
|
||||
|
||||
blockHash := hashserialization.HeaderHash(block.Header)
|
||||
blockHash := consensusserialization.HeaderHash(block.Header)
|
||||
err = bp.blockValidator.ValidateProofOfWorkAndDifficulty(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -160,7 +160,7 @@ func (bp *blockProcessor) validateBlock(block *externalapi.DomainBlock, mode *ex
|
||||
if err != nil {
|
||||
if errors.As(err, &ruleerrors.RuleError{}) {
|
||||
bp.discardAllChanges()
|
||||
hash := hashserialization.HeaderHash(block.Header)
|
||||
hash := consensusserialization.HeaderHash(block.Header)
|
||||
bp.blockStatusStore.Stage(hash, externalapi.StatusInvalid)
|
||||
commitErr := bp.commitAllChanges()
|
||||
if commitErr != nil {
|
||||
@ -173,7 +173,7 @@ func (bp *blockProcessor) validateBlock(block *externalapi.DomainBlock, mode *ex
|
||||
}
|
||||
|
||||
func (bp *blockProcessor) validatePreProofOfWork(block *externalapi.DomainBlock) error {
|
||||
blockHash := hashserialization.HeaderHash(block.Header)
|
||||
blockHash := consensusserialization.HeaderHash(block.Header)
|
||||
|
||||
hasHeader, err := bp.hasHeader(blockHash)
|
||||
if err != nil {
|
||||
@ -192,7 +192,7 @@ func (bp *blockProcessor) validatePreProofOfWork(block *externalapi.DomainBlock)
|
||||
}
|
||||
|
||||
func (bp *blockProcessor) validatePostProofOfWork(block *externalapi.DomainBlock, mode *externalapi.SyncInfo) error {
|
||||
blockHash := hashserialization.HeaderHash(block.Header)
|
||||
blockHash := consensusserialization.HeaderHash(block.Header)
|
||||
|
||||
if mode.State != externalapi.SyncStateHeadersFirst {
|
||||
bp.blockStore.Stage(blockHash, block)
|
||||
|
@ -3,7 +3,7 @@ package blockvalidator
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
@ -40,7 +40,7 @@ func (v *blockValidator) checkBlockTransactionsFinalized(blockHash *externalapi.
|
||||
// Ensure all transactions in the block are finalized.
|
||||
for _, tx := range block.Transactions {
|
||||
if !v.isFinalizedTransaction(tx, ghostdagData.BlueScore, blockTime) {
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
return errors.Wrapf(ruleerrors.ErrUnfinalizedTx, "block contains unfinalized "+
|
||||
"transaction %s", txID)
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ package blockvalidator
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/merkle"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
@ -141,7 +141,7 @@ func (v *blockValidator) checkTransactionsInIsolation(block *externalapi.DomainB
|
||||
err := v.transactionValidator.ValidateTransactionInIsolation(tx)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "transaction %s failed isolation "+
|
||||
"check", hashserialization.TransactionID(tx))
|
||||
"check", consensusserialization.TransactionID(tx))
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ func (v *blockValidator) checkBlockHashMerkleRoot(block *externalapi.DomainBlock
|
||||
func (v *blockValidator) checkBlockDuplicateTransactions(block *externalapi.DomainBlock) error {
|
||||
existingTxIDs := make(map[externalapi.DomainTransactionID]struct{})
|
||||
for _, tx := range block.Transactions {
|
||||
id := hashserialization.TransactionID(tx)
|
||||
id := consensusserialization.TransactionID(tx)
|
||||
if _, exists := existingTxIDs[*id]; exists {
|
||||
return errors.Wrapf(ruleerrors.ErrDuplicateTx, "block contains duplicate "+
|
||||
"transaction %s", id)
|
||||
@ -175,7 +175,7 @@ func (v *blockValidator) checkBlockDoubleSpends(block *externalapi.DomainBlock)
|
||||
usedOutpoints := make(map[externalapi.DomainOutpoint]*externalapi.DomainTransactionID)
|
||||
for _, tx := range block.Transactions {
|
||||
for _, input := range tx.Inputs {
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
if spendingTxID, exists := usedOutpoints[input.PreviousOutpoint]; exists {
|
||||
return errors.Wrapf(ruleerrors.ErrDoubleSpendInSameBlock, "transaction %s spends "+
|
||||
"outpoint %s that was already spent by "+
|
||||
@ -193,14 +193,14 @@ func (v *blockValidator) checkBlockHasNoChainedTransactions(block *externalapi.D
|
||||
transactions := block.Transactions
|
||||
transactionsSet := make(map[externalapi.DomainTransactionID]struct{}, len(transactions))
|
||||
for _, transaction := range transactions {
|
||||
txID := hashserialization.TransactionID(transaction)
|
||||
txID := consensusserialization.TransactionID(transaction)
|
||||
transactionsSet[*txID] = struct{}{}
|
||||
}
|
||||
|
||||
for _, transaction := range transactions {
|
||||
for i, transactionInput := range transaction.Inputs {
|
||||
if _, ok := transactionsSet[transactionInput.PreviousOutpoint.TransactionID]; ok {
|
||||
txID := hashserialization.TransactionID(transaction)
|
||||
txID := consensusserialization.TransactionID(transaction)
|
||||
return errors.Wrapf(ruleerrors.ErrChainedTransactions, "block contains chained "+
|
||||
"transactions: Input %d of transaction %s spend "+
|
||||
"an output of transaction %s", i, txID, transactionInput.PreviousOutpoint.TransactionID)
|
||||
|
@ -3,8 +3,8 @@ package blockvalidator
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -81,7 +81,7 @@ func (v *blockValidator) validateMedianTime(header *externalapi.DomainBlockHeade
|
||||
return nil
|
||||
}
|
||||
|
||||
hash := hashserialization.HeaderHash(header)
|
||||
hash := consensusserialization.HeaderHash(header)
|
||||
ghostdagData, err := v.ghostdagDataStore.Get(v.databaseContext, hash)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -33,7 +33,7 @@ func (v *blockValidator) ValidateHeaderInIsolation(blockHash *externalapi.Domain
|
||||
}
|
||||
|
||||
func (v *blockValidator) checkParentsLimit(header *externalapi.DomainBlockHeader) error {
|
||||
hash := hashserialization.HeaderHash(header)
|
||||
hash := consensusserialization.HeaderHash(header)
|
||||
if len(header.ParentHashes) == 0 && *hash != *v.genesisHash {
|
||||
return errors.Wrapf(ruleerrors.ErrNoParents, "block has no parents")
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package blockvalidator
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -78,7 +78,7 @@ func (v *blockValidator) checkProofOfWork(header *externalapi.DomainBlockHeader)
|
||||
// to avoid proof of work checks is set.
|
||||
if !v.skipPoW {
|
||||
// The block hash must be less than the claimed target.
|
||||
hash := hashserialization.HeaderHash(header)
|
||||
hash := consensusserialization.HeaderHash(header)
|
||||
hashNum := hashes.ToBig(hash)
|
||||
if hashNum.Cmp(target) > 0 {
|
||||
return errors.Wrapf(ruleerrors.ErrUnexpectedDifficulty, "block hash of %064x is higher than "+
|
||||
|
@ -179,7 +179,10 @@ func (csm *consensusStateManager) RestorePastUTXOSetIterator(blockHash *external
|
||||
|
||||
pastUTXO := model.NewUTXODiff()
|
||||
for virtualUTXOSetIterator.Next() {
|
||||
outpoint, utxoEntry := virtualUTXOSetIterator.Get()
|
||||
outpoint, utxoEntry, err := virtualUTXOSetIterator.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pastUTXO.ToAdd[*outpoint] = utxoEntry
|
||||
}
|
||||
|
||||
@ -223,7 +226,7 @@ func (u utxoSetIterator) Next() bool {
|
||||
return u.index != len(u.pairs)
|
||||
}
|
||||
|
||||
func (u utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry *externalapi.UTXOEntry) {
|
||||
func (u utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry *externalapi.UTXOEntry, err error) {
|
||||
pair := u.pairs[u.index]
|
||||
return &pair.outpoint, pair.entry
|
||||
return &pair.outpoint, pair.entry, nil
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ package consensusstatemanager
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
)
|
||||
|
||||
// consensusStateManager manages the node's consensus state
|
||||
type consensusStateManager struct {
|
||||
dagParams *dagconfig.Params
|
||||
finalityDepth uint64
|
||||
pruningDepth uint64
|
||||
databaseContext model.DBManager
|
||||
|
||||
ghostdagManager model.GHOSTDAGManager
|
||||
@ -37,7 +37,8 @@ type consensusStateManager struct {
|
||||
// New instantiates a new ConsensusStateManager
|
||||
func New(
|
||||
databaseContext model.DBManager,
|
||||
dagParams *dagconfig.Params,
|
||||
finalityDepth uint64,
|
||||
pruningDepth uint64,
|
||||
ghostdagManager model.GHOSTDAGManager,
|
||||
dagTopologyManager model.DAGTopologyManager,
|
||||
dagTraversalManager model.DAGTraversalManager,
|
||||
@ -60,7 +61,8 @@ func New(
|
||||
headerTipsStore model.HeaderTipsStore) (model.ConsensusStateManager, error) {
|
||||
|
||||
csm := &consensusStateManager{
|
||||
dagParams: dagParams,
|
||||
finalityDepth: finalityDepth,
|
||||
pruningDepth: pruningDepth,
|
||||
databaseContext: databaseContext,
|
||||
|
||||
ghostdagManager: ghostdagManager,
|
||||
|
@ -25,7 +25,7 @@ func (csm *consensusStateManager) virtualFinalityPoint(virtualGHOSTDAGData *mode
|
||||
*externalapi.DomainHash, error) {
|
||||
|
||||
return csm.dagTraversalManager.HighestChainBlockBelowBlueScore(
|
||||
model.VirtualBlockHash, virtualGHOSTDAGData.BlueScore-csm.dagParams.FinalityDepth())
|
||||
model.VirtualBlockHash, virtualGHOSTDAGData.BlueScore-csm.finalityDepth)
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) isViolatingFinality(
|
||||
|
@ -3,8 +3,9 @@ package consensusstatemanager
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/multiset"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization"
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) calculateMultiset(
|
||||
@ -47,7 +48,7 @@ func addTransactionToMultiset(multiset model.Multiset, transaction *externalapi.
|
||||
|
||||
for i, output := range transaction.Outputs {
|
||||
outpoint := &externalapi.DomainOutpoint{
|
||||
TransactionID: *hashserialization.TransactionID(transaction),
|
||||
TransactionID: *consensusserialization.TransactionID(transaction),
|
||||
Index: uint32(i),
|
||||
}
|
||||
utxoEntry := &externalapi.UTXOEntry{
|
||||
@ -68,7 +69,7 @@ func addTransactionToMultiset(multiset model.Multiset, transaction *externalapi.
|
||||
func addUTXOToMultiset(multiset model.Multiset, entry *externalapi.UTXOEntry,
|
||||
outpoint *externalapi.DomainOutpoint) error {
|
||||
|
||||
serializedUTXO, err := hashserialization.SerializeUTXO(entry, outpoint)
|
||||
serializedUTXO, err := consensusserialization.SerializeUTXO(entry, outpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -80,7 +81,7 @@ func addUTXOToMultiset(multiset model.Multiset, entry *externalapi.UTXOEntry,
|
||||
func removeUTXOFromMultiset(multiset model.Multiset, entry *externalapi.UTXOEntry,
|
||||
outpoint *externalapi.DomainOutpoint) error {
|
||||
|
||||
serializedUTXO, err := hashserialization.SerializeUTXO(entry, outpoint)
|
||||
serializedUTXO, err := consensusserialization.SerializeUTXO(entry, outpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -89,14 +90,10 @@ func removeUTXOFromMultiset(multiset model.Multiset, entry *externalapi.UTXOEntr
|
||||
return nil
|
||||
}
|
||||
|
||||
func calcMultisetFromUTXOSetIterator(iterator model.ReadOnlyUTXOSetIterator) (model.Multiset, error) {
|
||||
func calcMultisetFromProtoUTXOSet(protoUTXOSet *utxoserialization.ProtoUTXOSet) (model.Multiset, error) {
|
||||
ms := multiset.New()
|
||||
for iterator.Next() {
|
||||
entry, outpoint := iterator.Get()
|
||||
err := addUTXOToMultiset(ms, outpoint, entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, utxo := range protoUTXOSet.Utxos {
|
||||
ms.Add(utxo.EntryOutpointPair)
|
||||
}
|
||||
return ms, nil
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package consensusstatemanager
|
||||
|
||||
import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -34,8 +37,13 @@ func (csm *consensusStateManager) setPruningPointUTXOSet(serializedUTXOSet []byt
|
||||
return err
|
||||
}
|
||||
|
||||
utxoSetIterator := deserializeUTXOSet(serializedUTXOSet)
|
||||
utxoSetMultiSet, err := calcMultisetFromUTXOSetIterator(utxoSetIterator)
|
||||
protoUTXOSet := &utxoserialization.ProtoUTXOSet{}
|
||||
err = proto.Unmarshal(serializedUTXOSet, protoUTXOSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
utxoSetMultiSet, err := calcMultisetFromProtoUTXOSet(protoUTXOSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -56,7 +64,7 @@ func (csm *consensusStateManager) setPruningPointUTXOSet(serializedUTXOSet []byt
|
||||
return err
|
||||
}
|
||||
|
||||
csm.consensusStateStore.StageVirtualUTXOSet(utxoSetIterator)
|
||||
csm.consensusStateStore.StageVirtualUTXOSet(protoUTXOSetToReadOnlyUTXOSetIterator(protoUTXOSet))
|
||||
|
||||
err = csm.ghostdagManager.GHOSTDAG(model.VirtualBlockHash)
|
||||
if err != nil {
|
||||
@ -94,8 +102,30 @@ func (csm *consensusStateManager) commitSetPruningPointUTXOSetAll() error {
|
||||
return dbTx.Commit()
|
||||
}
|
||||
|
||||
func deserializeUTXOSet(serializedUTXOSet []byte) model.ReadOnlyUTXOSetIterator {
|
||||
panic("implement me")
|
||||
type protoUTXOSetIterator struct {
|
||||
utxoSet *utxoserialization.ProtoUTXOSet
|
||||
index int
|
||||
}
|
||||
|
||||
func (p protoUTXOSetIterator) Next() bool {
|
||||
p.index++
|
||||
return p.index != len(p.utxoSet.Utxos)
|
||||
}
|
||||
|
||||
func (p protoUTXOSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry *externalapi.UTXOEntry, err error) {
|
||||
entry, outpoint, err := consensusserialization.DeserializeUTXO(p.utxoSet.Utxos[p.index].EntryOutpointPair)
|
||||
if err != nil {
|
||||
if consensusserialization.IsMalformedError(err) {
|
||||
return nil, nil, errors.Wrap(ruleerrors.ErrMalformedUTXO, "malformed utxo")
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return outpoint, entry, nil
|
||||
}
|
||||
|
||||
func protoUTXOSetToReadOnlyUTXOSetIterator(protoUTXOSet *utxoserialization.ProtoUTXOSet) model.ReadOnlyUTXOSetIterator {
|
||||
return &protoUTXOSetIterator{utxoSet: protoUTXOSet}
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) HeaderTipsPruningPoint() (*externalapi.DomainHash, error) {
|
||||
@ -120,9 +150,5 @@ func (csm *consensusStateManager) HeaderTipsPruningPoint() (*externalapi.DomainH
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return csm.dagTraversalManager.HighestChainBlockBelowBlueScore(virtualHeaderHash, virtualHeaderGHOSTDAGData.BlueScore-pruningDepth())
|
||||
}
|
||||
|
||||
func pruningDepth() uint64 {
|
||||
panic("unimplemented")
|
||||
return csm.dagTraversalManager.HighestChainBlockBelowBlueScore(virtualHeaderHash, virtualHeaderGHOSTDAGData.BlueScore-csm.pruningDepth)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package utxoalgebra
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
|
||||
@ -33,7 +33,7 @@ func DiffAddTransaction(utxoDiff *model.UTXODiff, transaction *externalapi.Domai
|
||||
isCoinbase := transactionhelper.IsCoinBase(transaction)
|
||||
for i, output := range transaction.Outputs {
|
||||
outpoint := &externalapi.DomainOutpoint{
|
||||
TransactionID: *hashserialization.TransactionID(transaction),
|
||||
TransactionID: *consensusserialization.TransactionID(transaction),
|
||||
Index: uint32(i),
|
||||
}
|
||||
entry := &externalapi.UTXOEntry{
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/merkle"
|
||||
|
||||
@ -104,8 +104,8 @@ func calculateAcceptedIDMerkleRoot(multiblockAcceptanceData model.AcceptanceData
|
||||
}
|
||||
sort.Slice(acceptedTransactions, func(i, j int) bool {
|
||||
return transactionid.Less(
|
||||
hashserialization.TransactionID(acceptedTransactions[i]),
|
||||
hashserialization.TransactionID(acceptedTransactions[j]))
|
||||
consensusserialization.TransactionID(acceptedTransactions[i]),
|
||||
consensusserialization.TransactionID(acceptedTransactions[j]))
|
||||
})
|
||||
|
||||
return merkle.CalculateIDMerkleRoot(acceptedTransactions)
|
||||
@ -122,8 +122,8 @@ func (csm *consensusStateManager) validateCoinbaseTransaction(blockHash *externa
|
||||
return err
|
||||
}
|
||||
|
||||
coinbaseTransactionHash := hashserialization.TransactionHash(coinbaseTransaction)
|
||||
expectedCoinbaseTransactionHash := hashserialization.TransactionHash(expectedCoinbaseTransaction)
|
||||
coinbaseTransactionHash := consensusserialization.TransactionHash(coinbaseTransaction)
|
||||
expectedCoinbaseTransactionHash := consensusserialization.TransactionHash(expectedCoinbaseTransaction)
|
||||
if *coinbaseTransactionHash != *expectedCoinbaseTransactionHash {
|
||||
return errors.Wrap(ruleerrors.ErrBadCoinbaseTransaction, "coinbase transaction is not built as expected")
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization"
|
||||
)
|
||||
|
||||
// pruningManager resolves and manages the current pruning point
|
||||
@ -241,7 +241,7 @@ func (pm *pruningManager) deleteBlock(blockHash *externalapi.DomainHash) (alread
|
||||
}
|
||||
|
||||
func serializeUTXOSetIterator(iter model.ReadOnlyUTXOSetIterator) ([]byte, error) {
|
||||
serializedUtxo, err := hashserialization.ReadOnlyUTXOSetToProtoUTXOSet(iter)
|
||||
serializedUtxo, err := utxoserialization.ReadOnlyUTXOSetToProtoUTXOSet(iter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package ruleerrors
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -233,6 +233,8 @@ var (
|
||||
ErrBadPruningPointUTXOSet = newRuleError("ErrBadPruningPointUTXOSet")
|
||||
|
||||
ErrMissingBlockHeaderInIBD = newRuleError("ErrMissingBlockHeaderInIBD")
|
||||
|
||||
ErrMalformedUTXO = newRuleError("ErrMalformedUTXO")
|
||||
)
|
||||
|
||||
// RuleError identifies a rule violation. It is used to indicate that
|
||||
@ -291,7 +293,7 @@ type InvalidTransaction struct {
|
||||
}
|
||||
|
||||
func (invalid InvalidTransaction) String() string {
|
||||
return fmt.Sprintf("(%v: %s)", hashserialization.TransactionID(invalid.Transaction), invalid.err)
|
||||
return fmt.Sprintf("(%v: %s)", consensusserialization.TransactionID(invalid.Transaction), invalid.err)
|
||||
}
|
||||
|
||||
// ErrInvalidTransactionsInNewBlock indicates that some transactions in a new block are invalid
|
||||
|
@ -1,4 +1,4 @@
|
||||
package hashserialization
|
||||
package consensusserialization
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
@ -21,6 +21,8 @@ var (
|
||||
// errNoEncodingForType signifies that there's no encoding for the given type.
|
||||
var errNoEncodingForType = errors.New("there's no encoding for this type")
|
||||
|
||||
var errMalformed = errors.New("errMalformed")
|
||||
|
||||
// WriteElement writes the little endian representation of element to w.
|
||||
func WriteElement(w io.Writer, element interface{}) error {
|
||||
// Attempt to write the element based on the concrete type via fast
|
||||
@ -102,3 +104,85 @@ func writeElements(w io.Writer, elements ...interface{}) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// readElement reads the next sequence of bytes from r using little endian
|
||||
// depending on the concrete type of element pointed to.
|
||||
func readElement(r io.Reader, element interface{}) error {
|
||||
// Attempt to read the element based on the concrete type via fast
|
||||
// type assertions first.
|
||||
switch e := element.(type) {
|
||||
case *int32:
|
||||
rv, err := binaryserializer.Uint32(r, littleEndian)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = int32(rv)
|
||||
return nil
|
||||
|
||||
case *uint32:
|
||||
rv, err := binaryserializer.Uint32(r, littleEndian)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = rv
|
||||
return nil
|
||||
|
||||
case *int64:
|
||||
rv, err := binaryserializer.Uint64(r, littleEndian)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = int64(rv)
|
||||
return nil
|
||||
|
||||
case *uint64:
|
||||
rv, err := binaryserializer.Uint64(r, littleEndian)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = rv
|
||||
return nil
|
||||
|
||||
case *uint8:
|
||||
rv, err := binaryserializer.Uint8(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = rv
|
||||
return nil
|
||||
|
||||
case *bool:
|
||||
rv, err := binaryserializer.Uint8(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rv == 0x00 {
|
||||
*e = false
|
||||
} else if rv == 0x01 {
|
||||
*e = true
|
||||
} else {
|
||||
return errors.Wrapf(errMalformed, "in order to keep serialization canonical, true has to"+
|
||||
" always be 0x01")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.Wrapf(errNoEncodingForType, "couldn't find a way to read type %T", element)
|
||||
}
|
||||
|
||||
// readElements reads multiple items from r. It is equivalent to multiple
|
||||
// calls to readElement.
|
||||
func readElements(r io.Reader, elements ...interface{}) error {
|
||||
for _, element := range elements {
|
||||
err := readElement(r, element)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsMalformedError returns whether the error indicates a malformed data source
|
||||
func IsMalformedError(err error) bool {
|
||||
return errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, errMalformed)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package hashserialization
|
||||
package consensusserialization
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
@ -1,4 +1,4 @@
|
||||
package hashserialization
|
||||
package consensusserialization
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
131
domain/consensus/utils/consensusserialization/utxo.go
Normal file
131
domain/consensus/utils/consensusserialization/utxo.go
Normal file
@ -0,0 +1,131 @@
|
||||
package consensusserialization
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
const uint32Size = 4
|
||||
|
||||
// SerializeUTXO returns the byte-slice representation for given UTXOEntry-outpoint pair
|
||||
func SerializeUTXO(entry *externalapi.UTXOEntry, outpoint *externalapi.DomainOutpoint) ([]byte, error) {
|
||||
w := &bytes.Buffer{}
|
||||
|
||||
err := serializeOutpoint(w, outpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = serializeUTXOEntry(w, entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return w.Bytes(), nil
|
||||
}
|
||||
|
||||
// DeserializeUTXO deserializes the given byte slice to UTXOEntry-outpoint pair
|
||||
func DeserializeUTXO(utxoBytes []byte) (entry *externalapi.UTXOEntry, outpoint *externalapi.DomainOutpoint, err error) {
|
||||
r := bytes.NewReader(utxoBytes)
|
||||
outpoint, err = deserializeOutpoint(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
entry, err = deserializeUTXOEntry(r)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return entry, outpoint, nil
|
||||
}
|
||||
|
||||
func serializeOutpoint(w io.Writer, outpoint *externalapi.DomainOutpoint) error {
|
||||
_, err := w.Write(outpoint.TransactionID[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WriteElement(w, outpoint.Index)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deserializeOutpoint(r io.Reader) (*externalapi.DomainOutpoint, error) {
|
||||
transactionIDBytes := make([]byte, externalapi.DomainHashSize)
|
||||
_, err := io.ReadFull(r, transactionIDBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
transactionID, err := transactionid.FromBytes(transactionIDBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
indexBytes := make([]byte, uint32Size)
|
||||
_, err = io.ReadFull(r, indexBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var index uint32
|
||||
err = readElement(r, &index)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &externalapi.DomainOutpoint{
|
||||
TransactionID: *transactionID,
|
||||
Index: index,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func serializeUTXOEntry(w io.Writer, entry *externalapi.UTXOEntry) error {
|
||||
err := writeElements(w, entry.BlockBlueScore, entry.Amount, entry.IsCoinbase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := uint64(len(entry.ScriptPublicKey))
|
||||
err = WriteElement(w, count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(entry.ScriptPublicKey)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deserializeUTXOEntry(r io.Reader) (*externalapi.UTXOEntry, error) {
|
||||
entry := &externalapi.UTXOEntry{}
|
||||
err := readElements(r, entry.BlockBlueScore, entry.Amount, entry.IsCoinbase)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
count := uint64(len(entry.ScriptPublicKey))
|
||||
err = readElement(r, count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = r.Read(entry.ScriptPublicKey)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package hashserialization
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// outpointIndexByteOrder is the byte order for serializing the outpoint index.
|
||||
// It uses big endian to ensure that when outpoint is used as database key, the
|
||||
// keys will be iterated in an ascending order by the outpoint index.
|
||||
var outpointIndexByteOrder = binary.BigEndian
|
||||
|
||||
const (
|
||||
outpointLen = externalapi.DomainHashSize + 4
|
||||
entryMinLen = 8 + 1 + 8 + 8
|
||||
averageScriptPubKeySize = 20
|
||||
)
|
||||
|
||||
// ReadOnlyUTXOSetToProtoUTXOSet converts ReadOnlyUTXOSetIterator to ProtoUTXOSet
|
||||
func ReadOnlyUTXOSetToProtoUTXOSet(iter model.ReadOnlyUTXOSetIterator) (*ProtoUTXOSet, error) {
|
||||
protoUTXOSet := &ProtoUTXOSet{
|
||||
Utxos: []*ProtoUTXO{},
|
||||
}
|
||||
|
||||
for iter.Next() {
|
||||
outpoint, entry := iter.Get()
|
||||
|
||||
serializedOutpoint := bytes.NewBuffer(make([]byte, 0, outpointLen))
|
||||
err := serializeOutpoint(serializedOutpoint, outpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serializedEntry := bytes.NewBuffer(make([]byte, 0, entryMinLen+averageScriptPubKeySize))
|
||||
err = serializeUTXOEntry(serializedEntry, entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
protoUTXOSet.Utxos = append(protoUTXOSet.Utxos, &ProtoUTXO{
|
||||
Entry: serializedEntry.Bytes(),
|
||||
Outpoint: serializedOutpoint.Bytes(),
|
||||
})
|
||||
}
|
||||
return protoUTXOSet, nil
|
||||
}
|
||||
|
||||
// SerializeUTXO returns the byte-slice representation for given UTXOEntry
|
||||
func SerializeUTXO(entry *externalapi.UTXOEntry, outpoint *externalapi.DomainOutpoint) ([]byte, error) {
|
||||
w := &bytes.Buffer{}
|
||||
|
||||
err := serializeOutpoint(w, outpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = serializeUTXOEntry(w, entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return w.Bytes(), nil
|
||||
}
|
||||
|
||||
func serializeOutpoint(w io.Writer, outpoint *externalapi.DomainOutpoint) error {
|
||||
_, err := w.Write(outpoint.TransactionID[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf [4]byte
|
||||
outpointIndexByteOrder.PutUint32(buf[:], outpoint.Index)
|
||||
_, err = w.Write(buf[:])
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func serializeUTXOEntry(w io.Writer, entry *externalapi.UTXOEntry) error {
|
||||
err := writeElements(w, entry.BlockBlueScore, entry.Amount, entry.IsCoinbase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := uint64(len(entry.ScriptPublicKey))
|
||||
err = WriteElement(w, count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(entry.ScriptPublicKey)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -2,8 +2,8 @@ package merkle
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
@ -47,7 +47,7 @@ func hashMerkleBranches(left, right *externalapi.DomainHash) *externalapi.Domain
|
||||
func CalculateHashMerkleRoot(transactions []*externalapi.DomainTransaction) *externalapi.DomainHash {
|
||||
txHashes := make([]*externalapi.DomainHash, len(transactions))
|
||||
for i, tx := range transactions {
|
||||
txHashes[i] = hashserialization.TransactionHash(tx)
|
||||
txHashes[i] = consensusserialization.TransactionHash(tx)
|
||||
}
|
||||
return merkleRoot(txHashes)
|
||||
}
|
||||
@ -57,7 +57,7 @@ func CalculateHashMerkleRoot(transactions []*externalapi.DomainTransaction) *ext
|
||||
func CalculateIDMerkleRoot(transactions []*externalapi.DomainTransaction) *externalapi.DomainHash {
|
||||
txIDs := make([]*externalapi.DomainHash, len(transactions))
|
||||
for i, tx := range transactions {
|
||||
txIDs[i] = (*externalapi.DomainHash)(hashserialization.TransactionID(tx))
|
||||
txIDs[i] = (*externalapi.DomainHash)(consensusserialization.TransactionID(tx))
|
||||
}
|
||||
return merkleRoot(txIDs)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -362,7 +362,7 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *external
|
||||
// The final hash is the double sha256 of both the serialized modified
|
||||
// transaction and the hash type (encoded as a 4-byte little-endian
|
||||
// value) appended.
|
||||
return hashserialization.TransactionHashForSigning(&txCopy, uint32(hashType)), nil
|
||||
return consensusserialization.TransactionHashForSigning(&txCopy, uint32(hashType)), nil
|
||||
}
|
||||
|
||||
// asSmallInt returns the passed opcode, which must be true according to
|
||||
|
@ -1,3 +1,3 @@
|
||||
//go:generate protoc --go_out=. --go-grpc_out=. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative utxo.proto
|
||||
|
||||
package hashserialization
|
||||
package utxoserialization
|
30
domain/consensus/utils/utxoserialization/utxo.go
Normal file
30
domain/consensus/utils/utxoserialization/utxo.go
Normal file
@ -0,0 +1,30 @@
|
||||
package utxoserialization
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
)
|
||||
|
||||
// ReadOnlyUTXOSetToProtoUTXOSet converts ReadOnlyUTXOSetIterator to ProtoUTXOSet
|
||||
func ReadOnlyUTXOSetToProtoUTXOSet(iter model.ReadOnlyUTXOSetIterator) (*ProtoUTXOSet, error) {
|
||||
protoUTXOSet := &ProtoUTXOSet{
|
||||
Utxos: []*ProtoUTXO{},
|
||||
}
|
||||
|
||||
for iter.Next() {
|
||||
outpoint, entry, err := iter.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serializedUTXOBytes, err := consensusserialization.SerializeUTXO(entry, outpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
protoUTXOSet.Utxos = append(protoUTXOSet.Utxos, &ProtoUTXO{
|
||||
EntryOutpointPair: serializedUTXOBytes,
|
||||
})
|
||||
}
|
||||
return protoUTXOSet, nil
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.12.4
|
||||
// protoc v3.12.3
|
||||
// source: utxo.proto
|
||||
|
||||
package hashserialization
|
||||
package utxoserialization
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
@ -30,8 +30,7 @@ type ProtoUTXO struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Entry []byte `protobuf:"bytes,1,opt,name=entry,proto3" json:"entry,omitempty"`
|
||||
Outpoint []byte `protobuf:"bytes,2,opt,name=outpoint,proto3" json:"outpoint,omitempty"`
|
||||
EntryOutpointPair []byte `protobuf:"bytes,1,opt,name=entryOutpointPair,proto3" json:"entryOutpointPair,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ProtoUTXO) Reset() {
|
||||
@ -66,16 +65,9 @@ func (*ProtoUTXO) Descriptor() ([]byte, []int) {
|
||||
return file_utxo_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ProtoUTXO) GetEntry() []byte {
|
||||
func (x *ProtoUTXO) GetEntryOutpointPair() []byte {
|
||||
if x != nil {
|
||||
return x.Entry
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ProtoUTXO) GetOutpoint() []byte {
|
||||
if x != nil {
|
||||
return x.Outpoint
|
||||
return x.EntryOutpointPair
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -130,22 +122,21 @@ func (x *ProtoUTXOSet) GetUtxos() []*ProtoUTXO {
|
||||
var File_utxo_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_utxo_proto_rawDesc = []byte{
|
||||
0x0a, 0x0a, 0x75, 0x74, 0x78, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x68, 0x61,
|
||||
0x73, 0x68, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22,
|
||||
0x3d, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x42,
|
||||
0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x12, 0x32,
|
||||
0x0a, 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
|
||||
0x68, 0x61, 0x73, 0x68, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x52, 0x05, 0x75, 0x74, 0x78,
|
||||
0x6f, 0x73, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64,
|
||||
0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75,
|
||||
0x73, 0x2f, 0x75, 0x74, 0x69, 0x6c, 0x73, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x73, 0x65, 0x72, 0x69,
|
||||
0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
0x0a, 0x0a, 0x75, 0x74, 0x78, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x75, 0x74,
|
||||
0x78, 0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22,
|
||||
0x39, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x12, 0x2c, 0x0a, 0x11,
|
||||
0x65, 0x6e, 0x74, 0x72, 0x79, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x69,
|
||||
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x4f, 0x75,
|
||||
0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x61, 0x69, 0x72, 0x22, 0x42, 0x0a, 0x0c, 0x50, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x12, 0x32, 0x0a, 0x05, 0x75, 0x74,
|
||||
0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x74, 0x78, 0x6f,
|
||||
0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x55, 0x54, 0x58, 0x4f, 0x52, 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x42, 0x45,
|
||||
0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73,
|
||||
0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x64, 0x6f, 0x6d,
|
||||
0x61, 0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2f, 0x75, 0x74,
|
||||
0x69, 0x6c, 0x73, 0x2f, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -162,11 +153,11 @@ func file_utxo_proto_rawDescGZIP() []byte {
|
||||
|
||||
var file_utxo_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_utxo_proto_goTypes = []interface{}{
|
||||
(*ProtoUTXO)(nil), // 0: hashserialization.ProtoUTXO
|
||||
(*ProtoUTXOSet)(nil), // 1: hashserialization.ProtoUTXOSet
|
||||
(*ProtoUTXO)(nil), // 0: utxoserialization.ProtoUTXO
|
||||
(*ProtoUTXOSet)(nil), // 1: utxoserialization.ProtoUTXOSet
|
||||
}
|
||||
var file_utxo_proto_depIdxs = []int32{
|
||||
0, // 0: hashserialization.ProtoUTXOSet.utxos:type_name -> hashserialization.ProtoUTXO
|
||||
0, // 0: utxoserialization.ProtoUTXOSet.utxos:type_name -> utxoserialization.ProtoUTXO
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
@ -1,11 +1,10 @@
|
||||
syntax = "proto3";
|
||||
package hashserialization;
|
||||
package utxoserialization;
|
||||
|
||||
option go_package = "github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization";
|
||||
option go_package = "github.com/kaspanet/kaspad/domain/consensus/utils/utxoserialization";
|
||||
|
||||
message ProtoUTXO {
|
||||
bytes entry = 1;
|
||||
bytes outpoint = 2;
|
||||
bytes entryOutpointPair = 1;
|
||||
}
|
||||
|
||||
message ProtoUTXOSet {
|
@ -2,7 +2,7 @@ package blocktemplatebuilder
|
||||
|
||||
import (
|
||||
consensusexternalapi "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"math"
|
||||
"math/rand"
|
||||
@ -103,7 +103,7 @@ func (btb *blockTemplateBuilder) selectTransactions(candidateTxs []*candidateTx)
|
||||
if txsForBlockTemplate.totalMass+selectedTx.Mass < txsForBlockTemplate.totalMass ||
|
||||
txsForBlockTemplate.totalMass+selectedTx.Mass > btb.policy.BlockMaxMass {
|
||||
log.Tracef("Tx %s would exceed the max block mass. "+
|
||||
"As such, stopping.", hashserialization.TransactionID(tx))
|
||||
"As such, stopping.", consensusserialization.TransactionID(tx))
|
||||
break
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ func (btb *blockTemplateBuilder) selectTransactions(candidateTxs []*candidateTx)
|
||||
log.Tracef("Tx %s would exceed the gas limit in "+
|
||||
"subnetwork %s. Removing all remaining txs from this "+
|
||||
"subnetwork.",
|
||||
hashserialization.TransactionID(tx), subnetworkID)
|
||||
consensusserialization.TransactionID(tx), subnetworkID)
|
||||
for _, candidateTx := range candidateTxs {
|
||||
// candidateTxs are ordered by subnetwork, so we can safely assume
|
||||
// that transactions after subnetworkID will not be relevant.
|
||||
@ -146,7 +146,7 @@ func (btb *blockTemplateBuilder) selectTransactions(candidateTxs []*candidateTx)
|
||||
txsForBlockTemplate.totalFees += selectedTx.Fee
|
||||
|
||||
log.Tracef("Adding tx %s (feePerMegaGram %d)",
|
||||
hashserialization.TransactionID(tx), selectedTx.Fee*1e6/selectedTx.Mass)
|
||||
consensusserialization.TransactionID(tx), selectedTx.Fee*1e6/selectedTx.Mass)
|
||||
|
||||
markCandidateTxForDeletion(selectedTx)
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus"
|
||||
consensusexternalapi "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
@ -133,7 +133,7 @@ type orphanTx struct {
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
func (mp *mempool) removeOrphan(tx *consensusexternalapi.DomainTransaction, removeRedeemers bool) {
|
||||
// Nothing to do if passed tx is not an orphan.
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
otx, exists := mp.orphans[*txID]
|
||||
if !exists {
|
||||
return
|
||||
@ -234,7 +234,7 @@ func (mp *mempool) addOrphan(tx *consensusexternalapi.DomainTransaction) {
|
||||
// This will periodically remove any expired orphans and evict a random
|
||||
// orphan if space is still needed.
|
||||
mp.limitNumOrphans()
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
mp.orphans[*txID] = &orphanTx{
|
||||
tx: tx,
|
||||
expiration: mstime.Now().Add(orphanTTL),
|
||||
@ -247,7 +247,7 @@ func (mp *mempool) addOrphan(tx *consensusexternalapi.DomainTransaction) {
|
||||
mp.orphansByPrev[txIn.PreviousOutpoint][*txID] = tx
|
||||
}
|
||||
|
||||
log.Debugf("Stored orphan transaction %s (total: %d)", hashserialization.TransactionID(tx),
|
||||
log.Debugf("Stored orphan transaction %s (total: %d)", consensusserialization.TransactionID(tx),
|
||||
len(mp.orphans))
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ func (mp *mempool) haveTransaction(txID *consensusexternalapi.DomainTransactionI
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
func (mp *mempool) removeBlockTransactionsFromPool(txs []*consensusexternalapi.DomainTransaction) error {
|
||||
for _, tx := range txs[util.CoinbaseTransactionIndex+1:] {
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
|
||||
if _, exists := mp.fetchTxDesc(txID); !exists {
|
||||
continue
|
||||
@ -363,7 +363,7 @@ func (mp *mempool) removeBlockTransactionsFromPool(txs []*consensusexternalapi.D
|
||||
//
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
func (mp *mempool) removeTransactionAndItsChainedTransactions(tx *consensusexternalapi.DomainTransaction) error {
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
// Remove any transactions which rely on this one.
|
||||
for i := uint32(0); i < uint32(len(tx.Outputs)); i++ {
|
||||
prevOut := consensusexternalapi.DomainOutpoint{TransactionID: *txID, Index: i}
|
||||
@ -397,7 +397,7 @@ func (mp *mempool) cleanTransactionFromSets(tx *consensusexternalapi.DomainTrans
|
||||
return err
|
||||
}
|
||||
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
delete(mp.pool, *txID)
|
||||
delete(mp.chainedTransactions, *txID)
|
||||
|
||||
@ -410,7 +410,7 @@ func (mp *mempool) cleanTransactionFromSets(tx *consensusexternalapi.DomainTrans
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
|
||||
func (mp *mempool) updateBlockTransactionChainedTransactions(tx *consensusexternalapi.DomainTransaction) {
|
||||
prevOut := consensusexternalapi.DomainOutpoint{TransactionID: *hashserialization.TransactionID(tx)}
|
||||
prevOut := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(tx)}
|
||||
for txOutIdx := range tx.Outputs {
|
||||
// Skip to the next available output if there are none.
|
||||
prevOut.Index = uint32(txOutIdx)
|
||||
@ -424,7 +424,7 @@ func (mp *mempool) updateBlockTransactionChainedTransactions(tx *consensusextern
|
||||
if txDesc.depCount == 0 {
|
||||
// Transaction may be already removed by recursive calls, if removeRedeemers is true.
|
||||
// So avoid moving it into main pool
|
||||
txDescID := hashserialization.TransactionID(txDesc.DomainTransaction)
|
||||
txDescID := consensusserialization.TransactionID(txDesc.DomainTransaction)
|
||||
if _, ok := mp.chainedTransactions[*txDescID]; ok {
|
||||
delete(mp.chainedTransactions, *txDescID)
|
||||
mp.pool[*txDescID] = txDesc
|
||||
@ -438,7 +438,7 @@ func (mp *mempool) updateBlockTransactionChainedTransactions(tx *consensusextern
|
||||
//
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
func (mp *mempool) removeChainTransaction(tx *consensusexternalapi.DomainTransaction) {
|
||||
delete(mp.chainedTransactions, *hashserialization.TransactionID(tx))
|
||||
delete(mp.chainedTransactions, *consensusserialization.TransactionID(tx))
|
||||
for _, txIn := range tx.Inputs {
|
||||
delete(mp.chainedTransactionByPreviousOutpoint, txIn.PreviousOutpoint)
|
||||
}
|
||||
@ -452,10 +452,10 @@ func (mp *mempool) removeChainTransaction(tx *consensusexternalapi.DomainTransac
|
||||
//
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
func (mp *mempool) removeDoubleSpends(tx *consensusexternalapi.DomainTransaction) error {
|
||||
txID := *hashserialization.TransactionID(tx)
|
||||
txID := *consensusserialization.TransactionID(tx)
|
||||
for _, txIn := range tx.Inputs {
|
||||
if txRedeemer, ok := mp.mempoolUTXOSet.poolTransactionBySpendingOutpoint(txIn.PreviousOutpoint); ok {
|
||||
if !(*hashserialization.TransactionID(txRedeemer) == txID) {
|
||||
if !(*consensusserialization.TransactionID(txRedeemer) == txID) {
|
||||
err := mp.removeTransactionAndItsChainedTransactions(txRedeemer)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -478,7 +478,7 @@ func (mp *mempool) addTransaction(tx *consensusexternalapi.DomainTransaction, ma
|
||||
DomainTransaction: tx,
|
||||
depCount: len(parentsInPool),
|
||||
}
|
||||
txID := *hashserialization.TransactionID(tx)
|
||||
txID := *consensusserialization.TransactionID(tx)
|
||||
|
||||
if len(parentsInPool) == 0 {
|
||||
mp.pool[txID] = txDescriptor
|
||||
@ -508,7 +508,7 @@ func (mp *mempool) checkPoolDoubleSpend(tx *consensusexternalapi.DomainTransacti
|
||||
if txR, exists := mp.mempoolUTXOSet.poolTransactionBySpendingOutpoint(txIn.PreviousOutpoint); exists {
|
||||
str := fmt.Sprintf("output %s already spent by "+
|
||||
"transaction %s in the memory pool",
|
||||
txIn.PreviousOutpoint, hashserialization.TransactionID(txR))
|
||||
txIn.PreviousOutpoint, consensusserialization.TransactionID(txR))
|
||||
return txRuleError(RejectDuplicate, str)
|
||||
}
|
||||
}
|
||||
@ -540,7 +540,7 @@ func (mp *mempool) fetchTxDesc(txID *consensusexternalapi.DomainTransactionID) (
|
||||
//
|
||||
// This function MUST be called with the mempool lock held (for writes).
|
||||
func (mp *mempool) maybeAcceptTransaction(tx *consensusexternalapi.DomainTransaction, rejectDupOrphans bool) ([]consensusexternalapi.DomainOutpoint, *txDescriptor, error) {
|
||||
txID := hashserialization.TransactionID(tx)
|
||||
txID := consensusserialization.TransactionID(tx)
|
||||
|
||||
// Don't accept the transaction if it already exists in the pool. This
|
||||
// applies to orphan transactions as well when the reject duplicate
|
||||
@ -679,7 +679,7 @@ func (mp *mempool) processOrphans(acceptedTx *consensusexternalapi.DomainTransac
|
||||
firstElement := processList.Remove(processList.Front())
|
||||
processItem := firstElement.(*consensusexternalapi.DomainTransaction)
|
||||
|
||||
prevOut := consensusexternalapi.DomainOutpoint{TransactionID: *hashserialization.TransactionID(processItem)}
|
||||
prevOut := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(processItem)}
|
||||
for txOutIdx := range processItem.Outputs {
|
||||
// Look up all orphans that redeem the output that is
|
||||
// now available. This will typically only be one, but
|
||||
@ -759,7 +759,7 @@ func (mp *mempool) processOrphans(acceptedTx *consensusexternalapi.DomainTransac
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (mp *mempool) ValidateAndInsertTransaction(tx *consensusexternalapi.DomainTransaction, allowOrphan bool) error {
|
||||
log.Tracef("Processing transaction %s", hashserialization.TransactionID(tx))
|
||||
log.Tracef("Processing transaction %s", consensusserialization.TransactionID(tx))
|
||||
|
||||
// Protect concurrent access.
|
||||
mp.mtx.Lock()
|
||||
@ -801,7 +801,7 @@ func (mp *mempool) ValidateAndInsertTransaction(tx *consensusexternalapi.DomainT
|
||||
// which is not really always the case.
|
||||
str := fmt.Sprintf("orphan transaction %s references "+
|
||||
"outputs of unknown or fully-spent "+
|
||||
"transaction %s", hashserialization.TransactionID(tx), missingParents[0])
|
||||
"transaction %s", consensusserialization.TransactionID(tx), missingParents[0])
|
||||
return txRuleError(RejectDuplicate, str)
|
||||
}
|
||||
|
||||
@ -870,7 +870,7 @@ func (mp *mempool) HandleNewBlockTransactions(txs []*consensusexternalapi.Domain
|
||||
for _, tx := range txs[util.CoinbaseTransactionIndex+1:] {
|
||||
err := mp.removeDoubleSpends(tx)
|
||||
if err != nil {
|
||||
log.Infof("Failed removing tx from mempool: %s, '%s'", hashserialization.TransactionID(tx), err)
|
||||
log.Infof("Failed removing tx from mempool: %s, '%s'", consensusserialization.TransactionID(tx), err)
|
||||
}
|
||||
mp.removeOrphan(tx, false)
|
||||
acceptedOrphans := mp.processOrphans(tx)
|
||||
@ -888,7 +888,7 @@ func (mp *mempool) RemoveTransactions(txs []*consensusexternalapi.DomainTransact
|
||||
for _, tx := range txs {
|
||||
err := mp.removeDoubleSpends(tx)
|
||||
if err != nil {
|
||||
log.Infof("Failed removing tx from mempool: %s, '%s'", hashserialization.TransactionID(tx), err)
|
||||
log.Infof("Failed removing tx from mempool: %s, '%s'", consensusserialization.TransactionID(tx), err)
|
||||
}
|
||||
mp.removeOrphan(tx, true)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package mempool
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/blockdag"
|
||||
consensusexternalapi "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -39,7 +39,7 @@ func (mpus *mempoolUTXOSet) checkExists(tx *consensusexternalapi.DomainTransacti
|
||||
}
|
||||
|
||||
// Check if it creates an already existing UTXO
|
||||
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *hashserialization.TransactionID(tx)}
|
||||
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(tx)}
|
||||
for i := range tx.Outputs {
|
||||
outpoint.Index = uint32(i)
|
||||
if _, exists := mpus.poolUnspentOutputs[outpoint]; exists {
|
||||
@ -54,13 +54,13 @@ func (mpus *mempoolUTXOSet) checkExists(tx *consensusexternalapi.DomainTransacti
|
||||
func (mpus *mempoolUTXOSet) addTx(tx *consensusexternalapi.DomainTransaction) error {
|
||||
for _, txIn := range tx.Inputs {
|
||||
if existingTx, exists := mpus.transactionByPreviousOutpoint[txIn.PreviousOutpoint]; exists {
|
||||
return errors.Errorf("outpoint %s is already used by %s", txIn.PreviousOutpoint, hashserialization.TransactionID(existingTx))
|
||||
return errors.Errorf("outpoint %s is already used by %s", txIn.PreviousOutpoint, consensusserialization.TransactionID(existingTx))
|
||||
}
|
||||
mpus.transactionByPreviousOutpoint[txIn.PreviousOutpoint] = tx
|
||||
}
|
||||
|
||||
for i, txOut := range tx.Outputs {
|
||||
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *hashserialization.TransactionID(tx), Index: uint32(i)}
|
||||
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(tx), Index: uint32(i)}
|
||||
if _, exists := mpus.poolUnspentOutputs[outpoint]; exists {
|
||||
return errors.Errorf("outpoint %s already exists", outpoint)
|
||||
}
|
||||
@ -84,7 +84,7 @@ func (mpus *mempoolUTXOSet) removeTx(tx *consensusexternalapi.DomainTransaction)
|
||||
delete(mpus.transactionByPreviousOutpoint, txIn.PreviousOutpoint)
|
||||
}
|
||||
|
||||
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *hashserialization.TransactionID(tx)}
|
||||
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(tx)}
|
||||
for i := range tx.Outputs {
|
||||
outpoint.Index = uint32(i)
|
||||
if _, exists := mpus.poolUnspentOutputs[outpoint]; !exists {
|
||||
|
Loading…
x
Reference in New Issue
Block a user