Auto merge of #3354 - leto:absurd_fee_bug, r=bitcartel
Fix absurd fee bug reported in #3281, with tests This was ported from the Hush `absurd_fee_bug` PR: https://github.com/MyHush/hush/pull/136 Tests executed with `./qa/pull-tester/rpc-tests.sh wallet` and pass on Ubuntu 16.04. Some tests were added for previously untested behavior as well. Closes #3281.
This commit is contained in:
commit
b9bd5ab42c
|
@ -463,6 +463,62 @@ class WalletTest (BitcoinTestFramework):
|
||||||
|
|
||||||
assert_equal("not an integer" in errorString, True);
|
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__':
|
if __name__ == '__main__':
|
||||||
WalletTest ().main ()
|
WalletTest ().main ()
|
||||||
|
|
|
@ -3704,6 +3704,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
// Fee in Zatoshis, not currency format)
|
// 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.size() > 3) {
|
||||||
if (params[3].get_real() == 0.0) {
|
if (params[3].get_real() == 0.0) {
|
||||||
nFee = 0;
|
nFee = 0;
|
||||||
|
@ -3711,9 +3713,18 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||||
nFee = AmountFromValue( params[3] );
|
nFee = AmountFromValue( params[3] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the user specified fee is sane.
|
// Check that the user specified fee is not absurd.
|
||||||
|
// 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 not absurd.
|
||||||
if (nFee > nTotalOut) {
|
if (nFee > nTotalOut) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s", FormatMoney(nFee), FormatMoney(nTotalOut)));
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s and also greater than the default fee", FormatMoney(nFee), FormatMoney(nTotalOut)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue