mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-02-06 04:04:32 +00:00
Use fee deltas for determining mempool acceptance
This commit is contained in:
parent
9ef2a25603
commit
27fae3484c
@ -143,5 +143,45 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
|
||||
if (x != high_fee_tx):
|
||||
assert(x not in mempool)
|
||||
|
||||
# Create a free, low priority transaction. Should be rejected.
|
||||
utxo_list = self.nodes[0].listunspent()
|
||||
assert(len(utxo_list) > 0)
|
||||
utxo = utxo_list[0]
|
||||
|
||||
inputs = []
|
||||
outputs = {}
|
||||
inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]})
|
||||
outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
|
||||
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||
tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"]
|
||||
txid = self.nodes[0].sendrawtransaction(tx_hex)
|
||||
|
||||
# A tx that spends an in-mempool tx has 0 priority, so we can use it to
|
||||
# test the effect of using prioritise transaction for mempool acceptance
|
||||
inputs = []
|
||||
inputs.append({"txid": txid, "vout": 0})
|
||||
outputs = {}
|
||||
outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
|
||||
raw_tx2 = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||
tx2_hex = self.nodes[0].signrawtransaction(raw_tx2)["hex"]
|
||||
tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"]
|
||||
|
||||
try:
|
||||
self.nodes[0].sendrawtransaction(tx2_hex)
|
||||
except JSONRPCException as exp:
|
||||
assert_equal(exp.error['code'], -26) # insufficient fee
|
||||
assert(tx2_id not in self.nodes[0].getrawmempool())
|
||||
else:
|
||||
assert(False)
|
||||
|
||||
# This is a less than 1000-byte transaction, so just set the fee
|
||||
# to be the minimum for a 1000 byte transaction and check that it is
|
||||
# accepted.
|
||||
self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN))
|
||||
|
||||
print "Assert that prioritised free transaction is accepted to mempool"
|
||||
assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id)
|
||||
assert(tx2_id in self.nodes[0].getrawmempool())
|
||||
|
||||
if __name__ == '__main__':
|
||||
PrioritiseTransactionTest().main()
|
||||
|
18
src/main.cpp
18
src/main.cpp
@ -968,6 +968,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
|
||||
|
||||
CAmount nValueOut = tx.GetValueOut();
|
||||
CAmount nFees = nValueIn-nValueOut;
|
||||
// nModifiedFees includes any fee deltas from PrioritiseTransaction
|
||||
CAmount nModifiedFees = nFees;
|
||||
double nPriorityDummy = 0;
|
||||
pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees);
|
||||
|
||||
CAmount inChainInputValue;
|
||||
double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue);
|
||||
|
||||
@ -987,14 +992,17 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
|
||||
|
||||
// Don't accept it if it can't get into a block
|
||||
CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true);
|
||||
|
||||
// txMinFee takes into account priority/fee deltas, so compare using
|
||||
// nFees rather than nModifiedFees
|
||||
if (fLimitFree && nFees < txMinFee)
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
|
||||
strprintf("%d < %d", nFees, txMinFee));
|
||||
|
||||
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
|
||||
if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
|
||||
if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
|
||||
} else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
|
||||
} else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
|
||||
// Require that free transactions have sufficient priority to be mined in the next block.
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
|
||||
}
|
||||
@ -1002,7 +1010,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
|
||||
// Continuously rate-limit free (really, very-low-fee) transactions
|
||||
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
|
||||
// be annoying or make others' transactions take longer to confirm.
|
||||
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
|
||||
if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize))
|
||||
{
|
||||
static CCriticalSection csFreeLimiter;
|
||||
static double dFreeCount;
|
||||
@ -1061,10 +1069,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
|
||||
uint64_t nConflictingCount = 0;
|
||||
CTxMemPool::setEntries allConflicting;
|
||||
|
||||
CAmount nModifiedFees = nFees;
|
||||
double nPriorityDummy = 0;
|
||||
pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees);
|
||||
|
||||
// If we don't hold the lock allConflicting might be incomplete; the
|
||||
// subsequent RemoveStaged() and addUnchecked() calls don't guarantee
|
||||
// mempool consistency for us.
|
||||
|
Loading…
x
Reference in New Issue
Block a user