Browse Source

Fix absurd fee bug reported in #3281, with tests

pull/4/head
Duke Leto 6 years ago
parent
commit
e5aa9f617b
  1. 56
      qa/rpc-tests/wallet.py
  2. 19
      src/wallet/rpcwallet.cpp

56
qa/rpc-tests/wallet.py

@ -463,6 +463,62 @@ class WalletTest (BitcoinTestFramework):
assert_equal("not an integer" in errorString, True);
myzaddr = self.nodes[0].z_getnewaddress()
recipients = [ {"address": myzaddr, "amount": Decimal('0.0') } ]
errorString = ''
# Make sure that amount=0 transactions can use the default fee
# without triggering "absurd fee" errors
try:
myopid = self.nodes[0].z_sendmany(myzaddr, recipients)
assert(myopid)
except JSONRPCException,e:
errorString = e.error['message']
print errorString
assert(False)
# This fee is larger than the default fee and since amount=0
# it should trigger error
fee = Decimal('0.1')
recipients = [ {"address": myzaddr, "amount": Decimal('0.0') } ]
minconf = 1
errorString = ''
try:
myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, fee)
except JSONRPCException,e:
errorString = e.error['message']
assert('Small transaction amount' in errorString)
#### This fee is less than default and greater than amount, but still valid
fee = Decimal('0.0000001')
recipients = [ {"address": myzaddr, "amount": Decimal('0.00000001') } ]
minconf = 1
errorString = ''
try:
myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, fee)
assert(myopid)
except JSONRPCException,e:
errorString = e.error['message']
print errorString
assert(False)
### Make sure amount=0, fee=0 transaction are valid to add to mempool
# though miners decide whether to add to a block
fee = Decimal('0.0')
minconf = 1
recipients = [ {"address": myzaddr, "amount": Decimal('0.0') } ]
errorString = ''
try:
myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, fee)
assert(myopid)
except JSONRPCException,e:
errorString = e.error['message']
print errorString
assert(False)
if __name__ == '__main__':
WalletTest ().main ()

19
src/wallet/rpcwallet.cpp

@ -3698,7 +3698,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
}
// Fee in Zatoshis, not currency format)
CAmount nFee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE;
CAmount nFee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE;
CAmount nDefaultFee = nFee;
if (params.size() > 3) {
if (params[3].get_real() == 0.0) {
nFee = 0;
@ -3707,9 +3709,18 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
}
// Check that the user specified fee is sane.
if (nFee > nTotalOut) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s", FormatMoney(nFee), FormatMoney(nTotalOut)));
}
// This allows amount=0 (and all amount < nDefaultFee) transactions to use the default network fee
// or anything less than nDefaultFee instead of being forced to use a custom fee and leak metadata
if (nTotalOut < nDefaultFee) {
if (nFee > nDefaultFee) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Small transaction amount %s has fee %s that is greater than the default fee %s", FormatMoney(nTotalOut), FormatMoney(nFee), FormatMoney(nDefaultFee)));
}
} else {
// Check that the user specified fee is sane.
if (nFee > nTotalOut) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s", FormatMoney(nFee), FormatMoney(nTotalOut)));
}
}
}
// Use input parameters as the optional context info to be returned by z_getoperationstatus and z_getoperationresult.

Loading…
Cancel
Save