Mempool will accept tx with joinsplits and the default z_sendmany fee.
Issue #1851 shows that a zaddr->taddr can be rejected from mempools due to not meeting fee requirements given the size of the transaction. Fee calculation for joinsplit txs has not yet been agreed upon, so during this interim period, this patch ensures joinsplit txs using the default fee are not rejected due to an insufficient fee.
This commit is contained in:
parent
ba0625f25d
commit
9ddb6ad028
|
@ -150,6 +150,37 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework):
|
|||
errorString = e.error['message']
|
||||
assert_equal("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr" in errorString, True)
|
||||
|
||||
# Verify that mempools accept tx with joinsplits which have at least the default z_sendmany fee.
|
||||
# If this test passes, it confirms that issue #1851 has been resolved, where sending from
|
||||
# a zaddr to 1385 taddr recipients fails because the default fee was considered too low
|
||||
# given the tx size, resulting in mempool rejection.
|
||||
errorString = ''
|
||||
recipients = []
|
||||
num_t_recipients = 2500
|
||||
amount_per_recipient = Decimal('0.00000546') # dust threshold
|
||||
# Note that regtest chainparams does not require standard tx, so setting the amount to be
|
||||
# less than the dust threshold, e.g. 0.00000001 will not result in mempool rejection.
|
||||
for i in xrange(0,num_t_recipients):
|
||||
newtaddr = self.nodes[2].getnewaddress()
|
||||
recipients.append({"address":newtaddr, "amount":amount_per_recipient})
|
||||
myopid = self.nodes[0].z_sendmany(myzaddr, recipients)
|
||||
try:
|
||||
self.wait_and_assert_operationid_status(myopid)
|
||||
except JSONRPCException as e:
|
||||
print("JSONRPC error: "+e.error['message'])
|
||||
assert(False)
|
||||
except Exception as e:
|
||||
print("Unexpected exception caught during testing: "+str(sys.exc_info()[0]))
|
||||
assert(False)
|
||||
|
||||
self.sync_all()
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# check balance
|
||||
node2balance = amount_per_recipient * num_t_recipients
|
||||
assert_equal(self.nodes[2].getbalance(), node2balance)
|
||||
|
||||
# Send will succeed because the balance of non-coinbase utxos is 10.0
|
||||
try:
|
||||
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 9)
|
||||
|
@ -161,7 +192,8 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework):
|
|||
self.sync_all()
|
||||
|
||||
# check balance
|
||||
assert_equal(self.nodes[2].getbalance(), 9)
|
||||
node2balance = node2balance + 9
|
||||
assert_equal(self.nodes[2].getbalance(), node2balance)
|
||||
|
||||
# Check that chained joinsplits in a single tx are created successfully.
|
||||
recipients = []
|
||||
|
|
18
src/main.cpp
18
src/main.cpp
|
@ -26,6 +26,7 @@
|
|||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "validationinterface.h"
|
||||
#include "wallet/asyncrpcoperation_sendmany.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
@ -1170,12 +1171,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx));
|
||||
unsigned int nSize = entry.GetTxSize();
|
||||
|
||||
// Don't accept it if it can't get into a block
|
||||
CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
|
||||
if (fLimitFree && nFees < txMinFee)
|
||||
return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",
|
||||
hash.ToString(), nFees, txMinFee),
|
||||
REJECT_INSUFFICIENTFEE, "insufficient fee");
|
||||
// Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
|
||||
if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
|
||||
// In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
|
||||
} else {
|
||||
// Don't accept it if it can't get into a block
|
||||
CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
|
||||
if (fLimitFree && nFees < txMinFee)
|
||||
return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",
|
||||
hash.ToString(), nFees, txMinFee),
|
||||
REJECT_INSUFFICIENTFEE, "insufficient fee");
|
||||
}
|
||||
|
||||
// Require that free transactions have sufficient priority to be mined in the next block.
|
||||
if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
|
||||
|
|
Loading…
Reference in New Issue