mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-11-24 06:25:55 +00:00
fix mempool accessing, rewrite get_mempool_entries_by_addresses
This commit is contained in:
parent
c5aade7e7f
commit
40a10edbb7
@ -1,14 +1,9 @@
|
||||
package rpchandlers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
@ -20,121 +15,71 @@ func HandleGetMempoolEntriesByAddresses(context *rpccontext.Context, _ *router.R
|
||||
|
||||
mempoolEntriesByAddresses := make([]*appmessage.MempoolEntryByAddress, 0)
|
||||
|
||||
if !getMempoolEntriesByAddressesRequest.FilterTransactionPool {
|
||||
transactionPoolTransactions := context.Domain.MiningManager().AllTransactions()
|
||||
transactionPoolEntriesByAddresses, err := extractMempoolEntriesByAddressesFromTransactions(
|
||||
context,
|
||||
getMempoolEntriesByAddressesRequest.Addresses,
|
||||
transactionPoolTransactions,
|
||||
false,
|
||||
)
|
||||
for _, addressString := range getMempoolEntriesByAddressesRequest.Addresses {
|
||||
|
||||
address, err := util.DecodeAddress(addressString, context.Config.NetParams().Prefix)
|
||||
if err != nil {
|
||||
rpcError := &appmessage.RPCError{}
|
||||
if !errors.As(err, &rpcError) {
|
||||
return nil, err
|
||||
}
|
||||
errorMessage := &appmessage.GetUTXOsByAddressesResponseMessage{}
|
||||
errorMessage.Error = rpcError
|
||||
errorMessage := &appmessage.GetMempoolEntriesByAddressesResponseMessage{}
|
||||
errorMessage.Error = appmessage.RPCErrorf("Could not decode address '%s': %s", addressString, err)
|
||||
return errorMessage, nil
|
||||
}
|
||||
mempoolEntriesByAddresses = append(mempoolEntriesByAddresses, transactionPoolEntriesByAddresses...)
|
||||
}
|
||||
|
||||
if getMempoolEntriesByAddressesRequest.IncludeOrphanPool {
|
||||
|
||||
orphanPoolTransactions := context.Domain.MiningManager().AllOrphanTransactions()
|
||||
orphanPoolEntriesByAddresse, err := extractMempoolEntriesByAddressesFromTransactions(
|
||||
context,
|
||||
getMempoolEntriesByAddressesRequest.Addresses,
|
||||
orphanPoolTransactions,
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
rpcError := &appmessage.RPCError{}
|
||||
if !errors.As(err, &rpcError) {
|
||||
return nil, err
|
||||
}
|
||||
errorMessage := &appmessage.GetUTXOsByAddressesResponseMessage{}
|
||||
errorMessage.Error = rpcError
|
||||
return errorMessage, nil
|
||||
}
|
||||
|
||||
mempoolEntriesByAddresses = append(mempoolEntriesByAddresses, orphanPoolEntriesByAddresse...)
|
||||
}
|
||||
|
||||
return appmessage.NewGetMempoolEntriesByAddressesResponseMessage(mempoolEntriesByAddresses), nil
|
||||
}
|
||||
|
||||
//TO DO: optimize extractMempoolEntriesByAddressesFromTransactions
|
||||
func extractMempoolEntriesByAddressesFromTransactions(context *rpccontext.Context, addresses []string, transactions []*externalapi.DomainTransaction, areOrphans bool) ([]*appmessage.MempoolEntryByAddress, error) {
|
||||
mempoolEntriesByAddresses := make([]*appmessage.MempoolEntryByAddress, 0)
|
||||
for _, addressString := range addresses {
|
||||
_, err := util.DecodeAddress(addressString, context.Config.ActiveNetParams.Prefix)
|
||||
if err != nil {
|
||||
return nil, appmessage.RPCErrorf("Could not decode address '%s': %s", addressString, err)
|
||||
}
|
||||
|
||||
sending := make([]*appmessage.MempoolEntry, 0)
|
||||
receiving := make([]*appmessage.MempoolEntry, 0)
|
||||
|
||||
for _, transaction := range transactions {
|
||||
if !getMempoolEntriesByAddressesRequest.FilterTransactionPool {
|
||||
|
||||
for i, input := range transaction.Inputs {
|
||||
// TODO: Fix this
|
||||
if input.UTXOEntry == nil {
|
||||
log.Errorf("Couldn't find UTXO entry for input %d in mempool transaction %s. This is a bug and should be fixed.", i, consensushashing.TransactionID(transaction))
|
||||
continue
|
||||
}
|
||||
|
||||
_, transactionSendingAddress, err := txscript.ExtractScriptPubKeyAddress(
|
||||
input.UTXOEntry.ScriptPublicKey(),
|
||||
context.Config.ActiveNetParams)
|
||||
sendingInMempool, receivingInMempool, err := context.Domain.MiningManager().GetTransactionsByAddresses()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addressString == transactionSendingAddress.String() {
|
||||
|
||||
if transaction, found := sendingInMempool[address]; found {
|
||||
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||
sending = append(
|
||||
sending,
|
||||
&appmessage.MempoolEntry{
|
||||
sending = append(sending, &appmessage.MempoolEntry{
|
||||
Fee: transaction.Fee,
|
||||
Transaction: rpcTransaction,
|
||||
IsOrphan: areOrphans,
|
||||
},
|
||||
)
|
||||
break //one input is enough
|
||||
}
|
||||
IsOrphan: false})
|
||||
}
|
||||
|
||||
for _, output := range transaction.Outputs {
|
||||
_, transactionReceivingAddress, err := txscript.ExtractScriptPubKeyAddress(
|
||||
output.ScriptPublicKey,
|
||||
context.Config.ActiveNetParams,
|
||||
)
|
||||
if transaction, found := receivingInMempool[address]; found {
|
||||
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||
receiving = append(receiving, &appmessage.MempoolEntry{
|
||||
Fee: transaction.Fee,
|
||||
Transaction: rpcTransaction,
|
||||
IsOrphan: false})
|
||||
}
|
||||
}
|
||||
if getMempoolEntriesByAddressesRequest.IncludeOrphanPool {
|
||||
|
||||
sendingInOrphanPool, receivingInOrphanPool, err := context.Domain.MiningManager().GetOrphanTransactionsByAddresses()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addressString == transactionReceivingAddress.String() {
|
||||
|
||||
if transaction, found := sendingInOrphanPool[address]; found {
|
||||
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||
receiving = append(
|
||||
receiving,
|
||||
&appmessage.MempoolEntry{
|
||||
sending = append(sending, &appmessage.MempoolEntry{
|
||||
Fee: transaction.Fee,
|
||||
Transaction: rpcTransaction,
|
||||
IsOrphan: areOrphans,
|
||||
},
|
||||
)
|
||||
break //one output is enough
|
||||
}
|
||||
IsOrphan: true})
|
||||
}
|
||||
|
||||
if transaction, found := receivingInOrphanPool[address]; found {
|
||||
rpcTransaction := appmessage.DomainTransactionToRPCTransaction(transaction)
|
||||
receiving = append(receiving, &appmessage.MempoolEntry{
|
||||
Fee: transaction.Fee,
|
||||
Transaction: rpcTransaction,
|
||||
IsOrphan: true})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Only append mempoolEntriesByAddress, if at least 1 mempoolEntry for the address is found.
|
||||
//This mimics the behaviour of GetUtxosByAddresses RPC call.
|
||||
if len(sending) > 0 || len(receiving) > 0 {
|
||||
mempoolEntriesByAddresses = append(
|
||||
mempoolEntriesByAddresses,
|
||||
&appmessage.MempoolEntryByAddress{
|
||||
Address: addressString,
|
||||
Address: address.String(),
|
||||
Sending: sending,
|
||||
Receiving: receiving,
|
||||
},
|
||||
@ -142,6 +87,5 @@ func extractMempoolEntriesByAddressesFromTransactions(context *rpccontext.Contex
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return mempoolEntriesByAddresses, nil
|
||||
return appmessage.NewGetMempoolEntriesByAddressesResponseMessage(mempoolEntriesByAddresses), nil
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ type factory struct{}
|
||||
func (f *factory) NewMiningManager(consensusReference consensusreference.ConsensusReference, params *dagconfig.Params,
|
||||
mempoolConfig *mempoolpkg.Config) MiningManager {
|
||||
|
||||
mempool := mempoolpkg.New(mempoolConfig, consensusReference)
|
||||
mempool := mempoolpkg.New(mempoolConfig, params, consensusReference)
|
||||
blockTemplateBuilder := blocktemplatebuilder.New(consensusReference, mempool, params.MaxBlockMass, params.CoinbasePayloadScriptPublicKeyMaxLength)
|
||||
|
||||
return &miningManager{
|
||||
|
||||
@ -95,7 +95,7 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) {
|
||||
mempoolConfig.MinimumRelayTransactionFee = test.minimumRelayTransactionFee
|
||||
tcAsConsensus := tc.(externalapi.Consensus)
|
||||
tcAsConsensusPointer := &tcAsConsensus
|
||||
mempool := New(mempoolConfig, consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
||||
mempool := New(mempoolConfig, tc.DAGParams(), consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
||||
|
||||
got := mempool.minimumRequiredTransactionRelayFee(test.size)
|
||||
if got != test.want {
|
||||
@ -184,7 +184,7 @@ func TestIsTransactionOutputDust(t *testing.T) {
|
||||
mempoolConfig.MinimumRelayTransactionFee = test.minimumRelayTransactionFee
|
||||
tcAsConsensus := tc.(externalapi.Consensus)
|
||||
tcAsConsensusPointer := &tcAsConsensus
|
||||
mempool := New(mempoolConfig, consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
||||
mempool := New(mempoolConfig, tc.DAGParams(), consensusreference.NewConsensusReference(&tcAsConsensusPointer)).(*mempool)
|
||||
|
||||
res := mempool.IsTransactionOutputDust(&test.txOut)
|
||||
if res != test.isDust {
|
||||
@ -306,7 +306,7 @@ func TestCheckTransactionStandardInIsolation(t *testing.T) {
|
||||
tcAsConsensus := tc.(externalapi.Consensus)
|
||||
tcAsConsensusPointer := &tcAsConsensus
|
||||
consensusReference := consensusreference.NewConsensusReference(&tcAsConsensusPointer)
|
||||
mempool := New(mempoolConfig, consensusReference).(*mempool)
|
||||
mempool := New(mempoolConfig, tc.DAGParams(), consensusReference).(*mempool)
|
||||
|
||||
// Ensure standardness is as expected.
|
||||
err := mempool.checkTransactionStandardInIsolation(test.tx)
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
)
|
||||
|
||||
func (mp *mempool) handleNewBlockTransactions(blockTransactions []*externalapi.DomainTransaction) (
|
||||
func (mp *mempool) handleNewBlockTransactions(blockTransactions []*externalapi.DomainTransaction, clone bool) (
|
||||
[]*externalapi.DomainTransaction, error) {
|
||||
|
||||
// Skip the coinbase transaction
|
||||
@ -30,7 +30,7 @@ func (mp *mempool) handleNewBlockTransactions(blockTransactions []*externalapi.D
|
||||
return nil, err
|
||||
}
|
||||
|
||||
acceptedOrphansFromThisTransaction, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(transaction)
|
||||
acceptedOrphansFromThisTransaction, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(transaction, clone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package mempool
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensusreference"
|
||||
"sync"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensusreference"
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
||||
)
|
||||
@ -12,6 +15,7 @@ type mempool struct {
|
||||
mtx sync.RWMutex
|
||||
|
||||
config *Config
|
||||
params *dagconfig.Params
|
||||
consensusReference consensusreference.ConsensusReference
|
||||
|
||||
mempoolUTXOSet *mempoolUTXOSet
|
||||
@ -20,9 +24,10 @@ type mempool struct {
|
||||
}
|
||||
|
||||
// New constructs a new mempool
|
||||
func New(config *Config, consensusReference consensusreference.ConsensusReference) miningmanagermodel.Mempool {
|
||||
func New(config *Config, params *dagconfig.Params, consensusReference consensusreference.ConsensusReference) miningmanagermodel.Mempool {
|
||||
mp := &mempool{
|
||||
config: config,
|
||||
params: params,
|
||||
consensusReference: consensusReference,
|
||||
}
|
||||
|
||||
@ -39,35 +44,57 @@ func (mp *mempool) ValidateAndInsertTransaction(transaction *externalapi.DomainT
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
return mp.validateAndInsertTransaction(transaction, isHighPriority, allowOrphan)
|
||||
return mp.validateAndInsertTransaction(transaction, isHighPriority, allowOrphan, true)
|
||||
}
|
||||
|
||||
func (mp *mempool) GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||
mp.mtx.RLock()
|
||||
defer mp.mtx.RUnlock()
|
||||
|
||||
return mp.transactionsPool.getTransaction(transactionID)
|
||||
return mp.transactionsPool.getTransaction(transactionID, true)
|
||||
}
|
||||
|
||||
func (mp *mempool) GetTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error,
|
||||
) {
|
||||
mp.mtx.RLock()
|
||||
defer mp.mtx.RUnlock()
|
||||
|
||||
return mp.transactionsPool.getTransactionsByAddresses(true)
|
||||
}
|
||||
|
||||
func (mp *mempool) AllTransactions() []*externalapi.DomainTransaction {
|
||||
mp.mtx.RLock()
|
||||
defer mp.mtx.RUnlock()
|
||||
|
||||
return mp.transactionsPool.getAllTransactions()
|
||||
return mp.transactionsPool.getAllTransactions(true)
|
||||
}
|
||||
|
||||
func (mp *mempool) GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||
mp.mtx.RLock()
|
||||
defer mp.mtx.RUnlock()
|
||||
|
||||
return mp.orphansPool.getOrphanTransaction(transactionID)
|
||||
return mp.orphansPool.getOrphanTransaction(transactionID, true)
|
||||
}
|
||||
|
||||
func (mp *mempool) GetOrphanTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error,
|
||||
) {
|
||||
mp.mtx.RLock()
|
||||
defer mp.mtx.RUnlock()
|
||||
|
||||
return mp.orphansPool.getOrphanTransactionsByAddresses(true)
|
||||
}
|
||||
|
||||
func (mp *mempool) AllOrphanTransactions() []*externalapi.DomainTransaction {
|
||||
mp.mtx.RLock()
|
||||
defer mp.mtx.RUnlock()
|
||||
|
||||
return mp.orphansPool.getAllOrphanTransactions()
|
||||
return mp.orphansPool.getAllOrphanTransactions(true)
|
||||
}
|
||||
|
||||
func (mp *mempool) TransactionCount() int {
|
||||
@ -83,21 +110,21 @@ func (mp *mempool) HandleNewBlockTransactions(transactions []*externalapi.Domain
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
return mp.handleNewBlockTransactions(transactions)
|
||||
return mp.handleNewBlockTransactions(transactions, true)
|
||||
}
|
||||
|
||||
func (mp *mempool) BlockCandidateTransactions() []*externalapi.DomainTransaction {
|
||||
mp.mtx.RLock()
|
||||
defer mp.mtx.RUnlock()
|
||||
|
||||
return mp.transactionsPool.allReadyTransactions()
|
||||
return mp.transactionsPool.allReadyTransactions(true)
|
||||
}
|
||||
|
||||
func (mp *mempool) RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error) {
|
||||
mp.mtx.Lock()
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
return mp.revalidateHighPriorityTransactions()
|
||||
return mp.revalidateHighPriorityTransactions(true)
|
||||
}
|
||||
|
||||
func (mp *mempool) RemoveTransactions(transactions []*externalapi.DomainTransaction, removeRedeemers bool) error {
|
||||
|
||||
@ -51,7 +51,7 @@ func (mpus *mempoolUTXOSet) addTransaction(transaction *model.MempoolTransaction
|
||||
func (mpus *mempoolUTXOSet) removeTransaction(transaction *model.MempoolTransaction) {
|
||||
for _, input := range transaction.Transaction().Inputs {
|
||||
// If the transaction creating the output spent by this input is in the mempool - restore it's UTXO
|
||||
if _, ok := mpus.mempool.transactionsPool.getTransaction(&input.PreviousOutpoint.TransactionID); ok {
|
||||
if _, ok := mpus.mempool.transactionsPool.getTransaction(&input.PreviousOutpoint.TransactionID, false); ok {
|
||||
mpus.poolUnspentOutputs[input.PreviousOutpoint] = input.UTXOEntry
|
||||
}
|
||||
delete(mpus.transactionByPreviousOutpoint, input.PreviousOutpoint)
|
||||
|
||||
@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
|
||||
@ -134,7 +136,7 @@ func (op *orphansPool) addOrphan(transaction *externalapi.DomainTransaction, isH
|
||||
return nil
|
||||
}
|
||||
|
||||
func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransaction *externalapi.DomainTransaction) (
|
||||
func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransaction *externalapi.DomainTransaction, clone bool) (
|
||||
acceptedOrphans []*externalapi.DomainTransaction, err error) {
|
||||
|
||||
acceptedOrphans = []*externalapi.DomainTransaction{}
|
||||
@ -169,10 +171,14 @@ func (op *orphansPool) processOrphansAfterAcceptedTransaction(acceptedTransactio
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if clone {
|
||||
acceptedOrphans = append(acceptedOrphans, orphan.Transaction().Clone())
|
||||
} else {
|
||||
acceptedOrphans = append(acceptedOrphans, orphan.Transaction())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return acceptedOrphans, nil
|
||||
}
|
||||
@ -329,17 +335,67 @@ func (op *orphansPool) randomNonHighPriorityOrphan() *model.OrphanTransaction {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (op *orphansPool) getOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||
func (op *orphansPool) getOrphanTransaction(transactionID *externalapi.DomainTransactionID, clone bool) (*externalapi.DomainTransaction, bool) {
|
||||
if orphanTransaction, ok := op.allOrphans[*transactionID]; ok {
|
||||
if clone {
|
||||
return orphanTransaction.Transaction().Clone(), true
|
||||
}
|
||||
return orphanTransaction.Transaction(), true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (op *orphansPool) getAllOrphanTransactions() []*externalapi.DomainTransaction {
|
||||
allOrphanTransactions := make([]*externalapi.DomainTransaction, 0, len(op.allOrphans))
|
||||
func (op *orphansPool) getOrphanTransactionsByAddresses(clone bool) (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error) {
|
||||
sending = make(map[util.Address]*externalapi.DomainTransaction)
|
||||
receiving = make(map[util.Address]*externalapi.DomainTransaction)
|
||||
var transaction *externalapi.DomainTransaction
|
||||
for _, mempoolTransaction := range op.allOrphans {
|
||||
allOrphanTransactions = append(allOrphanTransactions, mempoolTransaction.Transaction())
|
||||
if clone {
|
||||
transaction = mempoolTransaction.Transaction().Clone()
|
||||
} else {
|
||||
transaction = mempoolTransaction.Transaction()
|
||||
}
|
||||
for _, input := range transaction.Inputs {
|
||||
if input.UTXOEntry == nil { //this is not a bug, but a valid state of orphan transactions with missing outpoints.
|
||||
continue
|
||||
}
|
||||
_, address, err := txscript.ExtractScriptPubKeyAddress(input.UTXOEntry.ScriptPublicKey(), op.mempool.params)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if address == nil { //none standard tx
|
||||
continue
|
||||
}
|
||||
sending[address] = transaction
|
||||
for _, output := range transaction.Outputs {
|
||||
_, address, err := txscript.ExtractScriptPubKeyAddress(output.ScriptPublicKey, op.mempool.params)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if address == nil { //none standard tx
|
||||
continue
|
||||
}
|
||||
receiving[address] = transaction
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sending, receiving, nil
|
||||
}
|
||||
|
||||
func (op *orphansPool) getAllOrphanTransactions(clone bool) []*externalapi.DomainTransaction {
|
||||
allOrphanTransactions := make([]*externalapi.DomainTransaction, len(op.allOrphans))
|
||||
i := 0
|
||||
for _, mempoolTransaction := range op.allOrphans {
|
||||
if clone {
|
||||
allOrphanTransactions[i] = mempoolTransaction.Transaction().Clone()
|
||||
} else {
|
||||
allOrphanTransactions[i] = mempoolTransaction.Transaction()
|
||||
}
|
||||
}
|
||||
return allOrphanTransactions
|
||||
}
|
||||
|
||||
@ -6,12 +6,12 @@ import (
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
)
|
||||
|
||||
func (mp *mempool) revalidateHighPriorityTransactions() ([]*externalapi.DomainTransaction, error) {
|
||||
func (mp *mempool) revalidateHighPriorityTransactions(clone bool) ([]*externalapi.DomainTransaction, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "revalidateHighPriorityTransactions")
|
||||
defer onEnd()
|
||||
|
||||
validTransactions := []*externalapi.DomainTransaction{}
|
||||
|
||||
if !clone {
|
||||
for _, transaction := range mp.transactionsPool.highPriorityTransactions {
|
||||
isValid, err := mp.revalidateTransaction(transaction)
|
||||
if err != nil {
|
||||
@ -23,6 +23,19 @@ func (mp *mempool) revalidateHighPriorityTransactions() ([]*externalapi.DomainTr
|
||||
|
||||
validTransactions = append(validTransactions, transaction.Transaction())
|
||||
}
|
||||
} else {
|
||||
for _, transaction := range mp.transactionsPool.highPriorityTransactions {
|
||||
isValid, err := mp.revalidateTransaction(transaction)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isValid {
|
||||
continue
|
||||
}
|
||||
|
||||
validTransactions = append(validTransactions, transaction.Transaction().Clone())
|
||||
}
|
||||
}
|
||||
|
||||
return validTransactions, nil
|
||||
}
|
||||
|
||||
@ -6,7 +6,9 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
"github.com/kaspanet/kaspad/domain/miningmanager/mempool/model"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
|
||||
type transactionsPool struct {
|
||||
@ -130,14 +132,18 @@ func (tp *transactionsPool) expireOldTransactions() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tp *transactionsPool) allReadyTransactions() []*externalapi.DomainTransaction {
|
||||
func (tp *transactionsPool) allReadyTransactions(clone bool) []*externalapi.DomainTransaction {
|
||||
result := []*externalapi.DomainTransaction{}
|
||||
|
||||
for _, mempoolTransaction := range tp.allTransactions {
|
||||
if len(mempoolTransaction.ParentTransactionsInPool()) == 0 {
|
||||
if clone {
|
||||
result = append(result, mempoolTransaction.Transaction().Clone())
|
||||
} else {
|
||||
result = append(result, mempoolTransaction.Transaction())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@ -204,17 +210,63 @@ func (tp *transactionsPool) limitTransactionCount() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tp *transactionsPool) getTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||
func (tp *transactionsPool) getTransaction(transactionID *externalapi.DomainTransactionID, clone bool) (*externalapi.DomainTransaction, bool) {
|
||||
if mempoolTransaction, ok := tp.allTransactions[*transactionID]; ok {
|
||||
if clone {
|
||||
return mempoolTransaction.Transaction().Clone(), true
|
||||
}
|
||||
return mempoolTransaction.Transaction(), true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (tp *transactionsPool) getAllTransactions() []*externalapi.DomainTransaction {
|
||||
allTransactions := make([]*externalapi.DomainTransaction, 0, len(tp.allTransactions))
|
||||
func (tp *transactionsPool) getTransactionsByAddresses(clone bool) (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error) {
|
||||
sending = make(map[util.Address]*externalapi.DomainTransaction)
|
||||
receiving = make(map[util.Address]*externalapi.DomainTransaction)
|
||||
var transaction *externalapi.DomainTransaction
|
||||
for _, mempoolTransaction := range tp.allTransactions {
|
||||
allTransactions = append(allTransactions, mempoolTransaction.Transaction())
|
||||
if clone {
|
||||
transaction = mempoolTransaction.Transaction().Clone()
|
||||
} else {
|
||||
transaction = mempoolTransaction.Transaction()
|
||||
}
|
||||
for _, input := range transaction.Inputs {
|
||||
_, address, err := txscript.ExtractScriptPubKeyAddress(input.UTXOEntry.ScriptPublicKey(), tp.mempool.params)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if address == nil { //ignore none-standard script
|
||||
continue
|
||||
}
|
||||
sending[address] = transaction
|
||||
for _, output := range transaction.Outputs {
|
||||
_, address, err := txscript.ExtractScriptPubKeyAddress(output.ScriptPublicKey, tp.mempool.params)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if address == nil { //ignore none-standard script
|
||||
continue
|
||||
}
|
||||
receiving[address] = transaction
|
||||
}
|
||||
}
|
||||
}
|
||||
return sending, receiving, nil
|
||||
}
|
||||
|
||||
func (tp *transactionsPool) getAllTransactions(clone bool) []*externalapi.DomainTransaction {
|
||||
allTransactions := make([]*externalapi.DomainTransaction, len(tp.allTransactions))
|
||||
i := 0
|
||||
for _, mempoolTransaction := range tp.allTransactions {
|
||||
if clone {
|
||||
allTransactions[i] = mempoolTransaction.Transaction().Clone()
|
||||
} else {
|
||||
allTransactions[i] = mempoolTransaction.Transaction()
|
||||
}
|
||||
i++
|
||||
}
|
||||
return allTransactions
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainTransaction, isHighPriority bool,
|
||||
allowOrphan bool) (acceptedTransactions []*externalapi.DomainTransaction, err error) {
|
||||
allowOrphan bool, clone bool) (acceptedTransactions []*externalapi.DomainTransaction, err error) {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log,
|
||||
fmt.Sprintf("validateAndInsertTransaction %s", consensushashing.TransactionID(transaction)))
|
||||
@ -49,12 +49,16 @@ func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainT
|
||||
return nil, err
|
||||
}
|
||||
|
||||
acceptedOrphans, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(mempoolTransaction.Transaction())
|
||||
acceptedOrphans, err := mp.orphansPool.processOrphansAfterAcceptedTransaction(mempoolTransaction.Transaction(), clone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if clone {
|
||||
acceptedTransactions = append([]*externalapi.DomainTransaction{transaction.Clone()}, acceptedOrphans...)
|
||||
} else {
|
||||
acceptedTransactions = append([]*externalapi.DomainTransaction{transaction}, acceptedOrphans...)
|
||||
}
|
||||
|
||||
err = mp.transactionsPool.limitTransactionCount()
|
||||
if err != nil {
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensusreference"
|
||||
miningmanagermodel "github.com/kaspanet/kaspad/domain/miningmanager/model"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
|
||||
// MiningManager creates block templates for mining as well as maintaining
|
||||
@ -16,8 +17,16 @@ type MiningManager interface {
|
||||
ClearBlockTemplate()
|
||||
GetBlockTemplateBuilder() miningmanagermodel.BlockTemplateBuilder
|
||||
GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||
GetTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error)
|
||||
AllTransactions() []*externalapi.DomainTransaction
|
||||
GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||
GetOrphanTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error)
|
||||
AllOrphanTransactions() []*externalapi.DomainTransaction
|
||||
TransactionCount() int
|
||||
HandleNewBlockTransactions(txs []*externalapi.DomainTransaction) ([]*externalapi.DomainTransaction, error)
|
||||
@ -118,12 +127,26 @@ func (mm *miningManager) AllTransactions() []*externalapi.DomainTransaction {
|
||||
return mm.mempool.AllTransactions()
|
||||
}
|
||||
|
||||
func (mm *miningManager) GetTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error) {
|
||||
return mm.mempool.GetTransactionsByAddresses()
|
||||
}
|
||||
|
||||
func (mm *miningManager) GetOrphanTransaction(
|
||||
transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool) {
|
||||
|
||||
return mm.mempool.GetOrphanTransaction(transactionID)
|
||||
}
|
||||
|
||||
func (mm *miningManager) GetOrphanTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error) {
|
||||
return mm.mempool.GetTransactionsByAddresses()
|
||||
}
|
||||
|
||||
func (mm *miningManager) AllOrphanTransactions() []*externalapi.DomainTransaction {
|
||||
|
||||
return mm.mempool.AllOrphanTransactions()
|
||||
|
||||
@ -2,6 +2,7 @@ package model
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
|
||||
// Mempool maintains a set of known transactions that
|
||||
@ -13,8 +14,16 @@ type Mempool interface {
|
||||
acceptedTransactions []*externalapi.DomainTransaction, err error)
|
||||
RemoveTransactions(txs []*externalapi.DomainTransaction, removeRedeemers bool) error
|
||||
GetTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||
GetTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error)
|
||||
AllTransactions() []*externalapi.DomainTransaction
|
||||
GetOrphanTransaction(transactionID *externalapi.DomainTransactionID) (*externalapi.DomainTransaction, bool)
|
||||
GetOrphanTransactionsByAddresses() (
|
||||
sending map[util.Address]*externalapi.DomainTransaction,
|
||||
receiving map[util.Address]*externalapi.DomainTransaction,
|
||||
err error)
|
||||
AllOrphanTransactions() []*externalapi.DomainTransaction
|
||||
TransactionCount() int
|
||||
RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user