diff --git a/domain/miningmanager/mempool/mempool.go b/domain/miningmanager/mempool/mempool.go index 6566719cb..3608f6bb2 100644 --- a/domain/miningmanager/mempool/mempool.go +++ b/domain/miningmanager/mempool/mempool.go @@ -27,7 +27,7 @@ func newMempool(consensus externalapi.Consensus, dagParams *dagconfig.Params) *m return mp } -func (mp *mempool) ValidateAndInsertTransaction(transaction *externalapi.DomainTransaction, isHighPriority bool) ( +func (mp *mempool) ValidateAndInsertTransaction(transaction *externalapi.DomainTransaction, neverExpires bool) ( acceptedTransactions []*externalapi.DomainTransaction, err error) { panic("mempool.ValidateAndInsertTransaction not implemented") // TODO (Mike) diff --git a/domain/miningmanager/mempool/model.go b/domain/miningmanager/mempool/model.go index 8235efb03..faa28fe41 100644 --- a/domain/miningmanager/mempool/model.go +++ b/domain/miningmanager/mempool/model.go @@ -6,12 +6,13 @@ import ( ) type idToTransaction map[externalapi.DomainTransactionID]*mempoolTransaction +type idToOrphan map[externalapi.DomainTransactionID]*orphanTransaction type mempoolTransaction struct { - transaction *externalapi.DomainTransaction - parentsInPool idToTransaction - isHighPriority bool - addAtDAAScore uint64 + transaction *externalapi.DomainTransaction + parentsInPool idToTransaction + neverExpires bool + addAtDAAScore uint64 } func (mt *mempoolTransaction) transactionID() *externalapi.DomainTransactionID { @@ -20,7 +21,7 @@ func (mt *mempoolTransaction) transactionID() *externalapi.DomainTransactionID { type orphanTransaction struct { transaction *externalapi.DomainTransaction - isHighPriority bool + neverExpires bool addedAtDAAScore uint64 } diff --git a/domain/miningmanager/mempool/orphan_pool.go b/domain/miningmanager/mempool/orphan_pool.go index 2c83ca6dc..0fbc7be77 100644 --- a/domain/miningmanager/mempool/orphan_pool.go +++ b/domain/miningmanager/mempool/orphan_pool.go @@ -1,12 +1,14 @@ package mempool -import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" +import ( + "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" +) -type previousOutpointToOrphans map[externalapi.DomainOutpoint]idToTransaction +type previousOutpointToOrphans map[externalapi.DomainOutpoint]idToOrphan type orphansPool struct { mempool *mempool - allOrphans idToTransaction + allOrphans idToOrphan orphanByPreviousOutpoint previousOutpointToOrphans lastExpireScan uint64 } @@ -14,14 +16,14 @@ type orphansPool struct { func newOrphansPool(mp *mempool) *orphansPool { return &orphansPool{ mempool: mp, - allOrphans: idToTransaction{}, + allOrphans: idToOrphan{}, orphanByPreviousOutpoint: previousOutpointToOrphans{}, lastExpireScan: 0, } } func (op *orphansPool) maybeAddOrphan(transaction *externalapi.DomainTransaction, - missingParents []*externalapi.DomainTransactionID, isHighPriority bool) error { + missingParents []*externalapi.DomainTransactionID, neverExpires bool) error { panic("orphansPool.maybeAddOrphan not implemented") // TODO (Mike) } @@ -36,8 +38,37 @@ func (op *orphansPool) unorphanTransaction(orphanTransactionID *externalapi.Doma panic("orphansPool.unorphanTransaction not implemented") // TODO (Mike) } -func (op *orphansPool) removeOrphan(orphanTransactionID *externalapi.DomainTransactionID) error { - panic("orphansPool.removeOrphan not implemented") // TODO (Mike) +func (op *orphansPool) removeOrphan(orphanTransactionID *externalapi.DomainTransactionID, removeRedeemers bool) { + var orphanTransaction *orphanTransaction + var ok bool + if orphanTransaction, ok = op.allOrphans[*orphanTransactionID]; !ok { + return + } + + // Remove orphan from allOrphans + delete(op.allOrphans, *orphanTransactionID) + + // Remove orphan from all relevant entries in orphanByPreviousOutpoint + for _, input := range orphanTransaction.transaction.Inputs { + if orphans, ok := op.orphanByPreviousOutpoint[input.PreviousOutpoint]; ok { + delete(orphans, orphanTransactionID) + if len(orphans) == 0 { + delete(op.orphanByPreviousOutpoint, input.PreviousOutpoint) + } + } + } + + // Recursively remove redeemers if requested. + // Since the size of the orphan pool is very limited - the recursion depth is properly bound. + if removeRedeemers { + outpoint := externalapi.DomainOutpoint{TransactionID: *orphanTransactionID} + for i := range orphanTransaction.transaction.Outputs { + outpoint.Index = uint32(i) + for _, orphanRedeemer := range op.orphanByPreviousOutpoint[outpoint] { + op.removeOrphan(orphanRedeemer.transactionID(), true) + } + } + } } func (op *orphansPool) expireOrphanTransactions() error { @@ -52,7 +83,7 @@ func (op *orphansPool) expireOrphanTransactions() error { for _, orphanTransaction := range op.allOrphans { // Never expire high priority transactions - if orphanTransaction.isHighPriority { + if orphanTransaction.neverExpires { continue } diff --git a/domain/miningmanager/mempool/transactions_pool.go b/domain/miningmanager/mempool/transactions_pool.go index 6bca3c671..7c26fad2d 100644 --- a/domain/miningmanager/mempool/transactions_pool.go +++ b/domain/miningmanager/mempool/transactions_pool.go @@ -48,7 +48,7 @@ func (tp *transactionsPool) expireOldTransactions() error { for _, mempoolTransaction := range tp.allTransactions { // Never expire high priority transactions - if mempoolTransaction.isHighPriority { + if mempoolTransaction.neverExpires { continue }