mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-06 06:06:49 +00:00
Fix bookkeeping of chained transactions in mempool (#1946)
* Fix bookkeeping of chained transactions in mempool * Fix golint error
This commit is contained in:
parent
13a09da848
commit
f452531df0
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func (mp *mempool) fillInputsAndGetMissingParents(transaction *externalapi.DomainTransaction) (
|
||||
parents model.OutpointToTransactionMap, missingOutpoints []*externalapi.DomainOutpoint, err error) {
|
||||
parents model.IDToTransactionMap, missingOutpoints []*externalapi.DomainOutpoint, err error) {
|
||||
|
||||
parentsInPool := mp.transactionsPool.getParentTransactionsInPool(transaction)
|
||||
|
||||
@ -34,9 +34,9 @@ func (mp *mempool) fillInputsAndGetMissingParents(transaction *externalapi.Domai
|
||||
return parentsInPool, nil, nil
|
||||
}
|
||||
|
||||
func fillInputs(transaction *externalapi.DomainTransaction, parentsInPool model.OutpointToTransactionMap) {
|
||||
func fillInputs(transaction *externalapi.DomainTransaction, parentsInPool model.IDToTransactionMap) {
|
||||
for _, input := range transaction.Inputs {
|
||||
parent, ok := parentsInPool[input.PreviousOutpoint]
|
||||
parent, ok := parentsInPool[input.PreviousOutpoint.TransactionID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
@ -7,6 +7,9 @@ import (
|
||||
// IDToTransactionMap maps transactionID to a MempoolTransaction
|
||||
type IDToTransactionMap map[externalapi.DomainTransactionID]*MempoolTransaction
|
||||
|
||||
// IDToTransactionsSliceMap maps transactionID to a slice MempoolTransaction
|
||||
type IDToTransactionsSliceMap map[externalapi.DomainTransactionID][]*MempoolTransaction
|
||||
|
||||
// OutpointToUTXOEntryMap maps an outpoint to a UTXOEntry
|
||||
type OutpointToUTXOEntryMap map[externalapi.DomainOutpoint]externalapi.UTXOEntry
|
||||
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
// MempoolTransaction represents a transaction inside the main TransactionPool
|
||||
type MempoolTransaction struct {
|
||||
transaction *externalapi.DomainTransaction
|
||||
parentTransactionsInPool OutpointToTransactionMap
|
||||
parentTransactionsInPool IDToTransactionMap
|
||||
isHighPriority bool
|
||||
addedAtDAAScore uint64
|
||||
}
|
||||
@ -16,7 +16,7 @@ type MempoolTransaction struct {
|
||||
// NewMempoolTransaction constructs a new MempoolTransaction
|
||||
func NewMempoolTransaction(
|
||||
transaction *externalapi.DomainTransaction,
|
||||
parentTransactionsInPool OutpointToTransactionMap,
|
||||
parentTransactionsInPool IDToTransactionMap,
|
||||
isHighPriority bool,
|
||||
addedAtDAAScore uint64,
|
||||
) *MempoolTransaction {
|
||||
@ -39,10 +39,15 @@ func (mt *MempoolTransaction) Transaction() *externalapi.DomainTransaction {
|
||||
}
|
||||
|
||||
// ParentTransactionsInPool a list of parent transactions that exist in the mempool, indexed by outpoint
|
||||
func (mt *MempoolTransaction) ParentTransactionsInPool() OutpointToTransactionMap {
|
||||
func (mt *MempoolTransaction) ParentTransactionsInPool() IDToTransactionMap {
|
||||
return mt.parentTransactionsInPool
|
||||
}
|
||||
|
||||
// RemoveParentTransactionInPool deletes a transaction from the parentTransactionsInPool set
|
||||
func (mt *MempoolTransaction) RemoveParentTransactionInPool(transactionID *externalapi.DomainTransactionID) {
|
||||
delete(mt.parentTransactionsInPool, *transactionID)
|
||||
}
|
||||
|
||||
// IsHighPriority returns whether this MempoolTransaction is a high-priority one
|
||||
func (mt *MempoolTransaction) IsHighPriority() bool {
|
||||
return mt.isHighPriority
|
||||
|
@ -27,9 +27,13 @@ func (mp *mempool) removeTransaction(transactionID *externalapi.DomainTransactio
|
||||
}
|
||||
|
||||
transactionsToRemove := []*model.MempoolTransaction{mempoolTransaction}
|
||||
redeemers := mp.transactionsPool.getRedeemers(mempoolTransaction)
|
||||
if removeRedeemers {
|
||||
redeemers := mp.transactionsPool.getRedeemers(mempoolTransaction)
|
||||
transactionsToRemove = append(transactionsToRemove, redeemers...)
|
||||
} else {
|
||||
for _, redeemer := range redeemers {
|
||||
redeemer.RemoveParentTransactionInPool(transactionID)
|
||||
}
|
||||
}
|
||||
|
||||
for _, transactionToRemove := range transactionsToRemove {
|
||||
|
@ -1,35 +1,36 @@
|
||||
package mempool
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/miningmanager/mempool/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
type transactionsPool struct {
|
||||
mempool *mempool
|
||||
allTransactions model.IDToTransactionMap
|
||||
highPriorityTransactions model.IDToTransactionMap
|
||||
chainedTransactionsByPreviousOutpoint model.OutpointToTransactionMap
|
||||
transactionsOrderedByFeeRate model.TransactionsOrderedByFeeRate
|
||||
lastExpireScanDAAScore uint64
|
||||
lastExpireScanTime time.Time
|
||||
mempool *mempool
|
||||
allTransactions model.IDToTransactionMap
|
||||
highPriorityTransactions model.IDToTransactionMap
|
||||
chainedTransactionsByParentID model.IDToTransactionsSliceMap
|
||||
transactionsOrderedByFeeRate model.TransactionsOrderedByFeeRate
|
||||
lastExpireScanDAAScore uint64
|
||||
lastExpireScanTime time.Time
|
||||
}
|
||||
|
||||
func newTransactionsPool(mp *mempool) *transactionsPool {
|
||||
return &transactionsPool{
|
||||
mempool: mp,
|
||||
allTransactions: model.IDToTransactionMap{},
|
||||
highPriorityTransactions: model.IDToTransactionMap{},
|
||||
chainedTransactionsByPreviousOutpoint: model.OutpointToTransactionMap{},
|
||||
transactionsOrderedByFeeRate: model.TransactionsOrderedByFeeRate{},
|
||||
lastExpireScanDAAScore: 0,
|
||||
lastExpireScanTime: time.Now(),
|
||||
mempool: mp,
|
||||
allTransactions: model.IDToTransactionMap{},
|
||||
highPriorityTransactions: model.IDToTransactionMap{},
|
||||
chainedTransactionsByParentID: model.IDToTransactionsSliceMap{},
|
||||
transactionsOrderedByFeeRate: model.TransactionsOrderedByFeeRate{},
|
||||
lastExpireScanDAAScore: 0,
|
||||
lastExpireScanTime: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (tp *transactionsPool) addTransaction(transaction *externalapi.DomainTransaction,
|
||||
parentTransactionsInPool model.OutpointToTransactionMap, isHighPriority bool) (*model.MempoolTransaction, error) {
|
||||
parentTransactionsInPool model.IDToTransactionMap, isHighPriority bool) (*model.MempoolTransaction, error) {
|
||||
|
||||
virtualDAAScore, err := tp.mempool.consensusReference.Consensus().GetVirtualDAAScore()
|
||||
if err != nil {
|
||||
@ -50,8 +51,13 @@ func (tp *transactionsPool) addTransaction(transaction *externalapi.DomainTransa
|
||||
func (tp *transactionsPool) addMempoolTransaction(transaction *model.MempoolTransaction) error {
|
||||
tp.allTransactions[*transaction.TransactionID()] = transaction
|
||||
|
||||
for outpoint, parentTransactionInPool := range transaction.ParentTransactionsInPool() {
|
||||
tp.chainedTransactionsByPreviousOutpoint[outpoint] = parentTransactionInPool
|
||||
for _, parentTransactionInPool := range transaction.ParentTransactionsInPool() {
|
||||
parentTransactionID := *parentTransactionInPool.TransactionID()
|
||||
if tp.chainedTransactionsByParentID[parentTransactionID] == nil {
|
||||
tp.chainedTransactionsByParentID[parentTransactionID] = []*model.MempoolTransaction{}
|
||||
}
|
||||
tp.chainedTransactionsByParentID[parentTransactionID] =
|
||||
append(tp.chainedTransactionsByParentID[parentTransactionID], transaction)
|
||||
}
|
||||
|
||||
tp.mempool.mempoolUTXOSet.addTransaction(transaction)
|
||||
@ -78,9 +84,7 @@ func (tp *transactionsPool) removeTransaction(transaction *model.MempoolTransact
|
||||
|
||||
delete(tp.highPriorityTransactions, *transaction.TransactionID())
|
||||
|
||||
for outpoint := range transaction.ParentTransactionsInPool() {
|
||||
delete(tp.chainedTransactionsByPreviousOutpoint, outpoint)
|
||||
}
|
||||
delete(tp.chainedTransactionsByParentID, *transaction.TransactionID())
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -132,13 +136,13 @@ func (tp *transactionsPool) allReadyTransactions() []*externalapi.DomainTransact
|
||||
}
|
||||
|
||||
func (tp *transactionsPool) getParentTransactionsInPool(
|
||||
transaction *externalapi.DomainTransaction) model.OutpointToTransactionMap {
|
||||
transaction *externalapi.DomainTransaction) model.IDToTransactionMap {
|
||||
|
||||
parentsTransactionsInPool := model.OutpointToTransactionMap{}
|
||||
parentsTransactionsInPool := model.IDToTransactionMap{}
|
||||
|
||||
for _, input := range transaction.Inputs {
|
||||
if transaction, ok := tp.allTransactions[input.PreviousOutpoint.TransactionID]; ok {
|
||||
parentsTransactionsInPool[input.PreviousOutpoint] = transaction
|
||||
parentsTransactionsInPool[*transaction.TransactionID()] = transaction
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,13 +157,9 @@ func (tp *transactionsPool) getRedeemers(transaction *model.MempoolTransaction)
|
||||
last := len(stack) - 1
|
||||
current, stack = stack[last], stack[:last]
|
||||
|
||||
outpoint := externalapi.DomainOutpoint{TransactionID: *current.TransactionID()}
|
||||
for i := range current.Transaction().Outputs {
|
||||
outpoint.Index = uint32(i)
|
||||
if redeemerTransaction, ok := tp.chainedTransactionsByPreviousOutpoint[outpoint]; ok {
|
||||
stack = append(stack, redeemerTransaction)
|
||||
redeemers = append(redeemers, redeemerTransaction)
|
||||
}
|
||||
for _, redeemerTransaction := range tp.chainedTransactionsByParentID[*current.TransactionID()] {
|
||||
stack = append(stack, redeemerTransaction)
|
||||
redeemers = append(redeemers, redeemerTransaction)
|
||||
}
|
||||
}
|
||||
return redeemers
|
||||
|
Loading…
x
Reference in New Issue
Block a user