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):
|
if (x != high_fee_tx):
|
||||||
assert(x not in mempool)
|
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__':
|
if __name__ == '__main__':
|
||||||
PrioritiseTransactionTest().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 nValueOut = tx.GetValueOut();
|
||||||
CAmount nFees = nValueIn-nValueOut;
|
CAmount nFees = nValueIn-nValueOut;
|
||||||
|
// nModifiedFees includes any fee deltas from PrioritiseTransaction
|
||||||
|
CAmount nModifiedFees = nFees;
|
||||||
|
double nPriorityDummy = 0;
|
||||||
|
pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees);
|
||||||
|
|
||||||
CAmount inChainInputValue;
|
CAmount inChainInputValue;
|
||||||
double dPriority = view.GetPriority(tx, chainActive.Height(), 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
|
// Don't accept it if it can't get into a block
|
||||||
CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true);
|
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)
|
if (fLimitFree && nFees < txMinFee)
|
||||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
|
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
|
||||||
strprintf("%d < %d", nFees, txMinFee));
|
strprintf("%d < %d", nFees, txMinFee));
|
||||||
|
|
||||||
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
|
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));
|
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.
|
// Require that free transactions have sufficient priority to be mined in the next block.
|
||||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
|
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
|
// Continuously rate-limit free (really, very-low-fee) transactions
|
||||||
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
|
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
|
||||||
// be annoying or make others' transactions take longer to confirm.
|
// 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 CCriticalSection csFreeLimiter;
|
||||||
static double dFreeCount;
|
static double dFreeCount;
|
||||||
@ -1061,10 +1069,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
|
|||||||
uint64_t nConflictingCount = 0;
|
uint64_t nConflictingCount = 0;
|
||||||
CTxMemPool::setEntries allConflicting;
|
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
|
// If we don't hold the lock allConflicting might be incomplete; the
|
||||||
// subsequent RemoveStaged() and addUnchecked() calls don't guarantee
|
// subsequent RemoveStaged() and addUnchecked() calls don't guarantee
|
||||||
// mempool consistency for us.
|
// mempool consistency for us.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user