Fix z_mergetoaddress sending from ANY_SPROUT/ANY_SAPLING when the wallet contains both note types
This commit is contained in:
parent
4c7b44bbdb
commit
a8055cfe10
|
@ -31,6 +31,7 @@ testScripts=(
|
||||||
'wallet_listnotes.py'
|
'wallet_listnotes.py'
|
||||||
'mergetoaddress_sprout.py'
|
'mergetoaddress_sprout.py'
|
||||||
'mergetoaddress_sapling.py'
|
'mergetoaddress_sapling.py'
|
||||||
|
'mergetoaddress_mixednotes.py'
|
||||||
'listtransactions.py'
|
'listtransactions.py'
|
||||||
'mempool_resurrect_test.py'
|
'mempool_resurrect_test.py'
|
||||||
'txn_doublespend.py'
|
'txn_doublespend.py'
|
||||||
|
|
|
@ -17,11 +17,12 @@ from decimal import Decimal
|
||||||
def assert_mergetoaddress_exception(expected_error_msg, merge_to_address_lambda):
|
def assert_mergetoaddress_exception(expected_error_msg, merge_to_address_lambda):
|
||||||
try:
|
try:
|
||||||
merge_to_address_lambda()
|
merge_to_address_lambda()
|
||||||
fail("Expected exception: %s" % expected_error_msg)
|
|
||||||
except JSONRPCException as e:
|
except JSONRPCException as e:
|
||||||
assert_equal(expected_error_msg, e.error['message'])
|
assert_equal(expected_error_msg, e.error['message'])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
fail("Expected JSONRPCException. Found %s" % repr(e))
|
fail("Expected JSONRPCException. Found %s" % repr(e))
|
||||||
|
else:
|
||||||
|
fail("Expected exception: %s" % expected_error_msg)
|
||||||
|
|
||||||
|
|
||||||
class MergeToAddressHelper:
|
class MergeToAddressHelper:
|
||||||
|
@ -152,6 +153,11 @@ class MergeToAddressHelper:
|
||||||
"Destination address is also the only source address, and all its funds are already merged.",
|
"Destination address is also the only source address, and all its funds are already merged.",
|
||||||
lambda: test.nodes[0].z_mergetoaddress([mytaddr], mytaddr))
|
lambda: test.nodes[0].z_mergetoaddress([mytaddr], mytaddr))
|
||||||
|
|
||||||
|
# Merging will fail for this specific case where it would spend a fee and do nothing
|
||||||
|
assert_mergetoaddress_exception(
|
||||||
|
"Cannot send from both Sprout and Sapling addresses using z_mergetoaddress",
|
||||||
|
lambda: test.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], mytaddr))
|
||||||
|
|
||||||
# Merge UTXOs from node 0 of value 30, standard fee of 0.00010000
|
# Merge UTXOs from node 0 of value 30, standard fee of 0.00010000
|
||||||
result = test.nodes[0].z_mergetoaddress([mytaddr, mytaddr2, mytaddr3], myzaddr)
|
result = test.nodes[0].z_mergetoaddress([mytaddr, mytaddr2, mytaddr3], myzaddr)
|
||||||
wait_and_assert_operationid_status(test.nodes[0], result['opid'])
|
wait_and_assert_operationid_status(test.nodes[0], result['opid'])
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# Copyright (c) 2019 The Zcash developers
|
||||||
|
# Distributed under the MIT software license, see the accompanying
|
||||||
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x."
|
||||||
|
|
||||||
|
from decimal import Decimal
|
||||||
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
|
from test_framework.util import assert_equal, get_coinbase_address, \
|
||||||
|
initialize_chain_clean, start_nodes, wait_and_assert_operationid_status
|
||||||
|
from mergetoaddress_helper import assert_mergetoaddress_exception
|
||||||
|
|
||||||
|
|
||||||
|
class MergeToAddressMixedNotes(BitcoinTestFramework):
|
||||||
|
def setup_nodes(self):
|
||||||
|
return start_nodes(4, self.options.tmpdir, [[
|
||||||
|
'-nuparams=5ba81b19:100', # Overwinter
|
||||||
|
'-nuparams=76b809bb:100', # Sapling
|
||||||
|
'-experimentalfeatures', '-zmergetoaddress'
|
||||||
|
]] * 4)
|
||||||
|
|
||||||
|
def setup_chain(self):
|
||||||
|
print("Initializing test directory " + self.options.tmpdir)
|
||||||
|
initialize_chain_clean(self.options.tmpdir, 4)
|
||||||
|
|
||||||
|
def run_test(self):
|
||||||
|
print "Mining blocks..."
|
||||||
|
self.nodes[0].generate(102)
|
||||||
|
self.sync_all()
|
||||||
|
|
||||||
|
# Send some ZEC to Sprout/Sapling addresses
|
||||||
|
coinbase_addr = get_coinbase_address(self.nodes[0])
|
||||||
|
sproutAddr = self.nodes[0].z_getnewaddress('sprout')
|
||||||
|
saplingAddr = self.nodes[0].z_getnewaddress('sapling')
|
||||||
|
t_addr = self.nodes[1].getnewaddress()
|
||||||
|
|
||||||
|
opid = self.nodes[0].z_sendmany(coinbase_addr, [{"address": sproutAddr, "amount": Decimal('10')}], 1, 0)
|
||||||
|
wait_and_assert_operationid_status(self.nodes[0], opid)
|
||||||
|
self.nodes[0].generate(1)
|
||||||
|
self.sync_all()
|
||||||
|
assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('10'))
|
||||||
|
assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('0'))
|
||||||
|
assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('0'))
|
||||||
|
# Make sure we cannot use "ANY_SPROUT" and "ANY_SAPLING" even if we only have Sprout Notes
|
||||||
|
assert_mergetoaddress_exception(
|
||||||
|
"Cannot send from both Sprout and Sapling addresses using z_mergetoaddress",
|
||||||
|
lambda: self.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], t_addr))
|
||||||
|
opid = self.nodes[0].z_sendmany(coinbase_addr, [{"address": saplingAddr, "amount": Decimal('10')}], 1, 0)
|
||||||
|
wait_and_assert_operationid_status(self.nodes[0], opid)
|
||||||
|
self.nodes[0].generate(1)
|
||||||
|
self.sync_all()
|
||||||
|
|
||||||
|
assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('0'))
|
||||||
|
|
||||||
|
# Merge Sprout -> taddr
|
||||||
|
result = self.nodes[0].z_mergetoaddress(["ANY_SPROUT"], t_addr, 0)
|
||||||
|
wait_and_assert_operationid_status(self.nodes[0], result['opid'])
|
||||||
|
self.nodes[0].generate(1)
|
||||||
|
self.sync_all()
|
||||||
|
|
||||||
|
assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('0'))
|
||||||
|
assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('10'))
|
||||||
|
assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('10'))
|
||||||
|
|
||||||
|
# Make sure we cannot use "ANY_SPROUT" and "ANY_SAPLING" even if we only have Sapling Notes
|
||||||
|
assert_mergetoaddress_exception(
|
||||||
|
"Cannot send from both Sprout and Sapling addresses using z_mergetoaddress",
|
||||||
|
lambda: self.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], t_addr))
|
||||||
|
# Merge Sapling -> taddr
|
||||||
|
result = self.nodes[0].z_mergetoaddress(["ANY_SAPLING"], t_addr, 0)
|
||||||
|
wait_and_assert_operationid_status(self.nodes[0], result['opid'])
|
||||||
|
self.nodes[0].generate(1)
|
||||||
|
self.sync_all()
|
||||||
|
|
||||||
|
assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('0'))
|
||||||
|
assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('0'))
|
||||||
|
assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('20'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
MergeToAddressMixedNotes().main()
|
|
@ -4532,8 +4532,15 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||||
if (!saplingActive && saplingEntries.size() > 0) {
|
if (!saplingActive && saplingEntries.size() > 0) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
|
||||||
}
|
}
|
||||||
|
// Do not include Sprout/Sapling notes if using "ANY_SAPLING"/"ANY_SPROUT" respectively
|
||||||
|
if (useAnySprout) {
|
||||||
|
saplingEntries.clear();
|
||||||
|
}
|
||||||
|
if (useAnySapling) {
|
||||||
|
sproutEntries.clear();
|
||||||
|
}
|
||||||
// Sending from both Sprout and Sapling is currently unsupported using z_mergetoaddress
|
// Sending from both Sprout and Sapling is currently unsupported using z_mergetoaddress
|
||||||
if (sproutEntries.size() > 0 && saplingEntries.size() > 0) {
|
if ((sproutEntries.size() > 0 && saplingEntries.size() > 0) || (useAnySprout && useAnySapling)) {
|
||||||
throw JSONRPCError(
|
throw JSONRPCError(
|
||||||
RPC_INVALID_PARAMETER,
|
RPC_INVALID_PARAMETER,
|
||||||
"Cannot send from both Sprout and Sapling addresses using z_mergetoaddress");
|
"Cannot send from both Sprout and Sapling addresses using z_mergetoaddress");
|
||||||
|
|
Loading…
Reference in New Issue