Compare commits

..

2 Commits

Author SHA1 Message Date
Ori Newman
74d5181bea add more check 2023-09-25 01:55:06 +03:00
Ori Newman
0bbb307f84 Reject from mempool txs with too many outputs of less than 1 KAS 2023-09-25 01:36:54 +03:00
4 changed files with 22 additions and 60 deletions

View File

@@ -51,7 +51,6 @@ const (
RejectDifficulty RejectCode = 0x44
RejectImmatureSpend RejectCode = 0x45
RejectBadOrphan RejectCode = 0x64
RejectSpamTx RejectCode = 0x65
)
// Map of reject codes back strings for pretty printing.

View File

@@ -1,8 +1,6 @@
package mempool
import (
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"sync"
"github.com/kaspanet/kaspad/domain/consensusreference"
@@ -143,57 +141,7 @@ func (mp *mempool) BlockCandidateTransactions() []*externalapi.DomainTransaction
mp.mtx.RLock()
defer mp.mtx.RUnlock()
readyTxs := mp.transactionsPool.allReadyTransactions()
var candidateTxs []*externalapi.DomainTransaction
var spamTx *externalapi.DomainTransaction
var spamTxNewestUTXODaaScore uint64
for _, tx := range readyTxs {
if len(tx.Outputs) > len(tx.Inputs) {
numExtraOuts := len(tx.Outputs) - len(tx.Inputs)
if numExtraOuts > 2 && tx.Fee < uint64(numExtraOuts)*constants.SompiPerKaspa {
log.Debugf("Filtered spam tx %s", consensushashing.TransactionID(tx))
continue
}
hasCoinbaseInput := false
for _, input := range tx.Inputs {
if input.UTXOEntry.IsCoinbase() {
hasCoinbaseInput = true
break
}
}
if hasCoinbaseInput || tx.Fee > uint64(numExtraOuts)*constants.SompiPerKaspa {
candidateTxs = append(candidateTxs, tx)
} else {
txNewestUTXODaaScore := tx.Inputs[0].UTXOEntry.BlockDAAScore()
for _, input := range tx.Inputs {
if input.UTXOEntry.BlockDAAScore() > txNewestUTXODaaScore {
txNewestUTXODaaScore = input.UTXOEntry.BlockDAAScore()
}
}
if spamTx != nil {
if txNewestUTXODaaScore < spamTxNewestUTXODaaScore {
spamTx = tx
spamTxNewestUTXODaaScore = txNewestUTXODaaScore
}
} else {
spamTx = tx
spamTxNewestUTXODaaScore = txNewestUTXODaaScore
}
}
} else {
candidateTxs = append(candidateTxs, tx)
}
}
if spamTx != nil {
log.Debugf("Adding spam tx candidate %s", consensushashing.TransactionID(spamTx))
candidateTxs = append(candidateTxs, spamTx)
}
return candidateTxs
return mp.transactionsPool.allReadyTransactions()
}
func (mp *mempool) RevalidateHighPriorityTransactions() (validTransactions []*externalapi.DomainTransaction, err error) {

View File

@@ -138,6 +138,11 @@ func (tp *transactionsPool) allReadyTransactions() []*externalapi.DomainTransact
if len(mempoolTransaction.ParentTransactionsInPool()) == 0 {
result = append(result, mempoolTransaction.Transaction().Clone()) //this pointer leaves the mempool, and gets its utxo set to nil, hence we clone.
}
if numOutsLessThanOneKas, isSpamming := isTXSpamming(mempoolTransaction.Transaction()); isSpamming {
log.Warnf("Filtered from allReadyTransactions transaction %s with %d outputs with less than 1 KAS", mempoolTransaction.TransactionID(), numOutsLessThanOneKas)
continue
}
}
return result

View File

@@ -17,6 +17,11 @@ func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainT
fmt.Sprintf("validateAndInsertTransaction %s", consensushashing.TransactionID(transaction)))
defer onEnd()
if numOutsLessThanOneKas, isSpamming := isTXSpamming(transaction); isSpamming {
log.Warnf("Rejected from mempool transaction %s with %d outputs with less than 1 KAS", consensushashing.TransactionID(transaction), numOutsLessThanOneKas)
return nil, nil
}
// Populate mass in the beginning, it will be used in multiple places throughout the validation and insertion.
mp.consensusReference.Consensus().PopulateMass(transaction)
@@ -30,12 +35,6 @@ func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainT
return nil, err
}
numExtraOuts := len(transaction.Outputs) - len(transaction.Inputs)
if numExtraOuts > 2 && transaction.Fee < uint64(numExtraOuts)*constants.SompiPerKaspa {
log.Warnf("Rejected spam tx %s from mempool", consensushashing.TransactionID(transaction))
return nil, transactionRuleError(RejectSpamTx, fmt.Sprintf("Rejected spam tx %s from mempool", consensushashing.TransactionID(transaction)))
}
if len(missingOutpoints) > 0 {
if !allowOrphan {
str := fmt.Sprintf("Transaction %s is an orphan, where allowOrphan = false",
@@ -70,3 +69,14 @@ func (mp *mempool) validateAndInsertTransaction(transaction *externalapi.DomainT
return acceptedTransactions, nil
}
func isTXSpamming(transaction *externalapi.DomainTransaction) (int, bool) {
numOutsLessThanOneKas := 0
for _, output := range transaction.Outputs {
if output.Value < constants.SompiPerKaspa {
numOutsLessThanOneKas += 1
}
}
return numOutsLessThanOneKas, numOutsLessThanOneKas > len(transaction.Inputs)
}