mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-25 00:06:49 +00:00

* [NOD-1500] Added Domain type and Constructor * [NOD-1500] Replaced dag+txpool with domain in flowContext * [NOD-1500] Replaced dag+txpool with domain in flowContext * [NOD-1500] Converters: domain objects from/to appmessage * [NOD-1500] Convert hashes to DomainHashes in appmessages * [NOD-1500] Remove references to daghash in dagconfig * [NOD-1500] Fixed all appmessage usages of hashes * [NOD-1500] Update all RPC to use domain * [NOD-1500] Big chunk of protocol flows re-wired to domain * [NOD-1500] Finished re-wiring all protocol flows to new Domain * [NOD-1500] Fix some mempool and kaspaminer compilation errors * [NOD-1500] Deleted util/{block,tx,daghash} and dbaccess * [NOD-1500] util.CoinbaseTransactionIndex -> transactionhelper.CoinbaseTransactionIndex * [NOD-1500] Fix txsigner * [NOD-1500] Removed all references to util/subnetworkid * [NOD-1500] Update RpcGetBlock related messages * [NOD-1500] Many more compilation fixes * [NOD-1500] Return full list of missing blocks for orphan resolution * [NOD-1500] Fixed handshake * [NOD-1500] Fixed flowcontext compilation * [NOD-1500] Update users of StartIBDIfRequired to handle error * [NOD-1500] Removed some more fields from RPC * [NOD-1500] Fix the getBlockTemplate flow * [NOD-1500] Fix HandleGetCurrentNetwork * [NOD-1500] Remove redundant code * [NOD-1500] Remove obsolete notifications * [NOD-1500] Split MiningManager and Consensus to separate fields in Domain * [NOD-1500] Update two wrong references to location of txscript * [NOD-1500] Added comments * [NOD-1500] Fix some tests * [NOD-1500] Removed serialization logic from appmessage * [NOD-1500] Rename database/serialization/messages.proto to dbobjects.proto * [NOD-1500] Delete integration tests * [NOD-1500] Remove txsort * [NOD-1500] Fix tiny bug * [NOD-1500] Remove rogue dependancy on bchd * [NOD-1500] Some stylistic fixes
106 lines
4.0 KiB
Go
106 lines
4.0 KiB
Go
package mempool
|
|
|
|
import (
|
|
"math"
|
|
|
|
consensusexternalapi "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const unacceptedBlueScore = math.MaxUint64
|
|
|
|
func newMempoolUTXOSet() *mempoolUTXOSet {
|
|
return &mempoolUTXOSet{
|
|
transactionByPreviousOutpoint: make(map[consensusexternalapi.DomainOutpoint]*consensusexternalapi.DomainTransaction),
|
|
poolUnspentOutputs: make(map[consensusexternalapi.DomainOutpoint]*consensusexternalapi.UTXOEntry),
|
|
}
|
|
}
|
|
|
|
type mempoolUTXOSet struct {
|
|
transactionByPreviousOutpoint map[consensusexternalapi.DomainOutpoint]*consensusexternalapi.DomainTransaction
|
|
poolUnspentOutputs map[consensusexternalapi.DomainOutpoint]*consensusexternalapi.UTXOEntry
|
|
}
|
|
|
|
// Populate UTXO Entries in the transaction, to allow chained txs.
|
|
func (mpus *mempoolUTXOSet) populateUTXOEntries(tx *consensusexternalapi.DomainTransaction) (parentsInPool []consensusexternalapi.DomainOutpoint) {
|
|
for _, txIn := range tx.Inputs {
|
|
if utxoEntry, exists := mpus.poolUnspentOutputs[txIn.PreviousOutpoint]; exists {
|
|
txIn.UTXOEntry = utxoEntry
|
|
parentsInPool = append(parentsInPool, txIn.PreviousOutpoint)
|
|
}
|
|
}
|
|
return parentsInPool
|
|
}
|
|
|
|
func (mpus *mempoolUTXOSet) checkExists(tx *consensusexternalapi.DomainTransaction) bool {
|
|
// Check if it was already spent.
|
|
for _, txIn := range tx.Inputs {
|
|
if _, exists := mpus.transactionByPreviousOutpoint[txIn.PreviousOutpoint]; exists {
|
|
return true
|
|
}
|
|
}
|
|
|
|
// Check if it creates an already existing UTXO
|
|
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(tx)}
|
|
for i := range tx.Outputs {
|
|
outpoint.Index = uint32(i)
|
|
if _, exists := mpus.poolUnspentOutputs[outpoint]; exists {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// addTx adds a transaction to the mempool UTXO set. It assumes that it doesn't double spend another transaction
|
|
// in the mempool, and that its outputs doesn't exist in the mempool UTXO set, and returns error otherwise.
|
|
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, consensusserialization.TransactionID(existingTx))
|
|
}
|
|
mpus.transactionByPreviousOutpoint[txIn.PreviousOutpoint] = tx
|
|
}
|
|
|
|
for i, txOut := range tx.Outputs {
|
|
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(tx), Index: uint32(i)}
|
|
if _, exists := mpus.poolUnspentOutputs[outpoint]; exists {
|
|
return errors.Errorf("outpoint %s already exists", outpoint)
|
|
}
|
|
mpus.poolUnspentOutputs[outpoint] = &consensusexternalapi.UTXOEntry{
|
|
Amount: txOut.Value,
|
|
ScriptPublicKey: txOut.ScriptPublicKey,
|
|
BlockBlueScore: unacceptedBlueScore,
|
|
IsCoinbase: false,
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// removeTx removes a transaction to the mempool UTXO set.
|
|
// Note: it doesn't re-add its previous outputs to the mempool UTXO set.
|
|
func (mpus *mempoolUTXOSet) removeTx(tx *consensusexternalapi.DomainTransaction) error {
|
|
for _, txIn := range tx.Inputs {
|
|
if _, exists := mpus.transactionByPreviousOutpoint[txIn.PreviousOutpoint]; !exists {
|
|
return errors.Errorf("outpoint %s doesn't exist", txIn.PreviousOutpoint)
|
|
}
|
|
delete(mpus.transactionByPreviousOutpoint, txIn.PreviousOutpoint)
|
|
}
|
|
|
|
outpoint := consensusexternalapi.DomainOutpoint{TransactionID: *consensusserialization.TransactionID(tx)}
|
|
for i := range tx.Outputs {
|
|
outpoint.Index = uint32(i)
|
|
if _, exists := mpus.poolUnspentOutputs[outpoint]; !exists {
|
|
return errors.Errorf("outpoint %s doesn't exist", outpoint)
|
|
}
|
|
delete(mpus.poolUnspentOutputs, outpoint)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (mpus *mempoolUTXOSet) poolTransactionBySpendingOutpoint(outpoint consensusexternalapi.DomainOutpoint) (*consensusexternalapi.DomainTransaction, bool) {
|
|
tx, exists := mpus.transactionByPreviousOutpoint[outpoint]
|
|
return tx, exists
|
|
}
|