[rpc] sendrawtransaction no longer bypasses minRelayTxFee
The prioritisetransaction API can always be used if a transaction needs to be submitted that bypasses minRelayTxFee. (cherry picked from commit bitcoin/bitcoin@ad727f4eaf) Signed-off-by: Daira Emma Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
1a57b52109
commit
a4346b2012
|
@ -25,7 +25,6 @@ class MempoolPackagesTest(BitcoinTestFramework):
|
||||||
def setup_network(self):
|
def setup_network(self):
|
||||||
base_args = [
|
base_args = [
|
||||||
"-maxorphantx=1000",
|
"-maxorphantx=1000",
|
||||||
"-relaypriority=0",
|
|
||||||
"-debug",
|
"-debug",
|
||||||
"-allowdeprecated=getnewaddress",
|
"-allowdeprecated=getnewaddress",
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,7 +29,6 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
||||||
args = [
|
args = [
|
||||||
"-blockmaxsize=11000",
|
"-blockmaxsize=11000",
|
||||||
"-maxorphantx=1000",
|
"-maxorphantx=1000",
|
||||||
"-relaypriority=true",
|
|
||||||
"-printpriority=1",
|
"-printpriority=1",
|
||||||
"-limitancestorcount=900",
|
"-limitancestorcount=900",
|
||||||
"-allowdeprecated=getnewaddress",
|
"-allowdeprecated=getnewaddress",
|
||||||
|
|
|
@ -156,7 +156,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||||
self.nodes = []
|
self.nodes = []
|
||||||
# Use node0 to mine blocks for input splitting
|
# Use node0 to mine blocks for input splitting
|
||||||
self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000",
|
self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000",
|
||||||
"-relaypriority=0", "-whitelist=127.0.0.1"]))
|
"-whitelist=127.0.0.1"]))
|
||||||
|
|
||||||
print("This test is time consuming, please be patient")
|
print("This test is time consuming, please be patient")
|
||||||
print("Splitting inputs to small size so we can generate low priority tx's")
|
print("Splitting inputs to small size so we can generate low priority tx's")
|
||||||
|
@ -188,17 +188,16 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Now we can connect the other nodes, didn't want to connect them earlier
|
# Now we can connect the other nodes, didn't want to connect them earlier
|
||||||
# so the estimates would not be affected by the splitting transactions
|
# so the estimates would not be affected by the splitting transactions
|
||||||
# Node1 mines small blocks but that are bigger than the expected transaction rate,
|
# Node1 mines small blocks but that are bigger than the expected transaction rate.
|
||||||
# and allows free transactions.
|
|
||||||
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
|
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
|
||||||
# (17k is room enough for 110 or so transactions)
|
# (17k is room enough for 110 or so transactions)
|
||||||
self.nodes.append(start_node(1, self.options.tmpdir,
|
self.nodes.append(start_node(1, self.options.tmpdir,
|
||||||
["-blockmaxsize=18000", "-maxorphantx=1000", "-relaypriority=0", "-debug=estimatefee"]))
|
["-blockmaxsize=18000", "-maxorphantx=1000", "-debug=estimatefee"]))
|
||||||
connect_nodes(self.nodes[1], 0)
|
connect_nodes(self.nodes[1], 0)
|
||||||
|
|
||||||
# Node2 is a stingy miner, that
|
# Node2 is a stingy miner, that
|
||||||
# produces too small blocks (room for only 70 or so transactions)
|
# produces too small blocks (room for only 70 or so transactions)
|
||||||
node2args = ["-blockmaxsize=12000", "-maxorphantx=1000", "-relaypriority=0"]
|
node2args = ["-blockmaxsize=12000", "-maxorphantx=1000"]
|
||||||
|
|
||||||
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
|
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
|
||||||
connect_nodes(self.nodes[0], 2)
|
connect_nodes(self.nodes[0], 2)
|
||||||
|
|
|
@ -479,8 +479,6 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||||
{
|
{
|
||||||
strUsage += HelpMessageOpt("-clockoffset=<n>", "Applies offset of <n> seconds to the actual time. Incompatible with -mocktime (default: 0)");
|
strUsage += HelpMessageOpt("-clockoffset=<n>", "Applies offset of <n> seconds to the actual time. Incompatible with -mocktime (default: 0)");
|
||||||
strUsage += HelpMessageOpt("-mocktime=<n>", "Replace actual time with <n> seconds since epoch. Incompatible with -clockoffset (default: 0)");
|
strUsage += HelpMessageOpt("-mocktime=<n>", "Replace actual time with <n> seconds since epoch. Incompatible with -clockoffset (default: 0)");
|
||||||
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY));
|
|
||||||
strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY));
|
|
||||||
strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit total size of signature and bundle caches to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE));
|
strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit total size of signature and bundle caches to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE));
|
||||||
strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE));
|
strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE));
|
||||||
}
|
}
|
||||||
|
@ -1227,7 +1225,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
if (nConnectTimeout <= 0)
|
if (nConnectTimeout <= 0)
|
||||||
nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
||||||
|
|
||||||
// Fee-per-kilobyte amount considered the same as "free"
|
// Fee-per-kilobyte amount required for mempool acceptance and relay
|
||||||
// If you are mining, be careful setting this:
|
// If you are mining, be careful setting this:
|
||||||
// if you set it to zero then
|
// if you set it to zero then
|
||||||
// a transaction spammer can cheaply fill blocks using
|
// a transaction spammer can cheaply fill blocks using
|
||||||
|
|
33
src/main.cpp
33
src/main.cpp
|
@ -1938,32 +1938,11 @@ bool AcceptToMemoryPool(
|
||||||
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), fSpendsCoinbase, nSigOps, consensusBranchId);
|
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), fSpendsCoinbase, nSigOps, consensusBranchId);
|
||||||
unsigned int nSize = entry.GetTxSize();
|
unsigned int nSize = entry.GetTxSize();
|
||||||
|
|
||||||
// Require that free transactions have sufficient priority to be mined in the next block.
|
// No transactions are allowed with modified fee below the minimum relay fee,
|
||||||
if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFeeForRelay(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
|
// except from disconnected blocks. The minimum relay fee will never be more
|
||||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
|
// than DEFAULT_FEE zatoshis.
|
||||||
}
|
if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFeeForRelay(nSize)) {
|
||||||
|
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "min relay fee not met");
|
||||||
// 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 && nModifiedFees < ::minRelayTxFee.GetFeeForRelay(nSize))
|
|
||||||
{
|
|
||||||
static CCriticalSection csFreeLimiter;
|
|
||||||
static double dFreeCount;
|
|
||||||
static int64_t nLastTime;
|
|
||||||
int64_t nNow = GetTime();
|
|
||||||
|
|
||||||
LOCK(csFreeLimiter);
|
|
||||||
|
|
||||||
// Use an exponentially decaying ~10-minute window:
|
|
||||||
dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
|
|
||||||
nLastTime = nNow;
|
|
||||||
// -limitfreerelay unit is thousand-bytes-per-minute
|
|
||||||
// At default rate it would take over a month to fill 1GB
|
|
||||||
if (dFreeCount >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000)
|
|
||||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction");
|
|
||||||
LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
|
|
||||||
dFreeCount += nSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fRejectAbsurdFee && nFees > maxTxFee) {
|
if (fRejectAbsurdFee && nFees > maxTxFee) {
|
||||||
|
@ -7175,7 +7154,7 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
|
||||||
LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
|
LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
|
||||||
}
|
}
|
||||||
// Has inputs but not accepted to mempool
|
// Has inputs but not accepted to mempool
|
||||||
// Probably non-standard or insufficient fee/priority
|
// Probably non-standard or insufficient fee
|
||||||
LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
|
LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
|
||||||
vEraseQueue.push_back(orphanHash);
|
vEraseQueue.push_back(orphanHash);
|
||||||
// Add the wtxid of this transaction to our reject filter.
|
// Add the wtxid of this transaction to our reject filter.
|
||||||
|
|
|
@ -135,8 +135,6 @@ static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
|
||||||
* Limits the impact of low-fee transaction floods. */
|
* Limits the impact of low-fee transaction floods. */
|
||||||
static const unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL;
|
static const unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL;
|
||||||
|
|
||||||
static const unsigned int DEFAULT_LIMITFREERELAY = 15;
|
|
||||||
static const bool DEFAULT_RELAYPRIORITY = false;
|
|
||||||
static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
|
static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
|
||||||
|
|
||||||
/** Default for -permitbaremultisig */
|
/** Default for -permitbaremultisig */
|
||||||
|
|
|
@ -68,7 +68,7 @@ UniValue getinfo(const UniValue& params, bool fHelp)
|
||||||
" \"keypoolsize\": xxxx, (numeric, optional) how many new keys are pre-generated\n"
|
" \"keypoolsize\": xxxx, (numeric, optional) how many new keys are pre-generated\n"
|
||||||
" \"unlocked_until\": ttt, (numeric, optional) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked, if wallet functionality is available and the wallet is encrypted\n"
|
" \"unlocked_until\": ttt, (numeric, optional) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked, if wallet functionality is available and the wallet is encrypted\n"
|
||||||
" \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n"
|
" \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n"
|
||||||
" \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
|
" \"relayfee\": x.xxxx, (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB\n"
|
||||||
" \"errors\": \"...\" (string) message describing the latest or highest-priority error\n"
|
" \"errors\": \"...\" (string) message describing the latest or highest-priority error\n"
|
||||||
" \"errorstimestamp\": \"...\" (string) timestamp associated with the latest or highest-priority error\n"
|
" \"errorstimestamp\": \"...\" (string) timestamp associated with the latest or highest-priority error\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
|
@ -516,7 +516,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp)
|
||||||
" }\n"
|
" }\n"
|
||||||
" ,...\n"
|
" ,...\n"
|
||||||
" ],\n"
|
" ],\n"
|
||||||
" \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
|
" \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB\n"
|
||||||
" \"localaddresses\": [ (array) list of local addresses\n"
|
" \"localaddresses\": [ (array) list of local addresses\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" \"address\": \"xxxx\", (string) network address\n"
|
" \"address\": \"xxxx\", (string) network address\n"
|
||||||
|
|
|
@ -1285,7 +1285,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp)
|
||||||
// push to local node and sync with wallets
|
// push to local node and sync with wallets
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
bool fMissingInputs;
|
bool fMissingInputs;
|
||||||
if (!AcceptToMemoryPool(chainparams, mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
|
if (!AcceptToMemoryPool(chainparams, mempool, state, tx, true, &fMissingInputs, !fOverrideFees)) {
|
||||||
if (state.IsInvalid()) {
|
if (state.IsInvalid()) {
|
||||||
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
|
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,22 +28,6 @@
|
||||||
|
|
||||||
class CAutoFile;
|
class CAutoFile;
|
||||||
|
|
||||||
inline double AllowFreeThreshold()
|
|
||||||
{
|
|
||||||
// 144 is the number of Bitcoin blocks per day. This has not been updated for Zcash,
|
|
||||||
// as it would make it harder to get shielded transactions into blocks by lowering the
|
|
||||||
// threshold at which we switch from priority-based selection of transactions into
|
|
||||||
// blocks to fee-based selection.
|
|
||||||
return COIN * 144 / 250;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool AllowFree(double dPriority)
|
|
||||||
{
|
|
||||||
// Large (in bytes) low-priority (new, small-coin) transactions
|
|
||||||
// need a fee.
|
|
||||||
return dPriority > AllowFreeThreshold();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Version from which we write `fee_estimates.dat` without priority information: 5.5.0-beta1 or later */
|
/** Version from which we write `fee_estimates.dat` without priority information: 5.5.0-beta1 or later */
|
||||||
static const int FEE_ESTIMATES_WITHOUT_PRIORITY_VERSION = 5050000;
|
static const int FEE_ESTIMATES_WITHOUT_PRIORITY_VERSION = 5050000;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue