diff --git a/qa/rpc-tests/shieldcoinbase_donation.py b/qa/rpc-tests/shieldcoinbase_donation.py new file mode 100755 index 000000000..34686058a --- /dev/null +++ b/qa/rpc-tests/shieldcoinbase_donation.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016-2025 The Hush developers +# Distributed under the GPLv3 software license, see the accompanying +# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises, assert_true, \ + wait_and_assert_operationid_status + +import time +from decimal import Decimal + +def assert_success(result): + assert_equal(result['result'], 'success') + +def assert_error(result): + assert_equal(result['result'], 'error') + +class LockZinsTest (BitcoinTestFramework): + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + self.num_nodes = 2 + self.options.nocleanup = 1 # do not delete datadir after test run + #self.options.nocleanup = 0 + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.supply = 555 + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg and port as third + '-ac_name=ZZZ', + #'-ac_algo=randomx', + #'-testnode=1', # why does this make the test node hang before run_test() ? + '-conf='+self.options.tmpdir+'/node0/regtest/ZZZ.conf', + '-port=63367', + '-rpcport=63368', + '-ac_supply=' + str(self.supply), + '-ac_reward=100000000', + '-ac_private=1', + '-allowlist=127.0.0.1', + '-regtest', + '--daemon', + #'-debug', + #'-zrpc', + #'-zdebug', + ##'-zrpcunsafe' + ],[ + '-ac_name=ZZZ', + '-conf='+self.options.tmpdir+'/node1/regtest/ZZZ.conf', + '-port=63357', + '-rpcport=63358', + '-ac_supply=' + str(self.supply), + '-ac_reward=100000000', + '-ac_private=1', + '-allowlist=127.0.0.1', + '-regtest', + '--daemon', + #'-debug', + #'-zrpc', + #'-zdebug', + ##'-zrpcunsafe' + ]] + ) + self.is_network_split = False + self.rpc = self.nodes[0] + self.sync_all() + print("Done setting up network") + + def run_test (self): + print("Mining blocks...") + rpc0 = self.nodes[0] + rpc1 = self.nodes[1] + + # mine initial ac_supply + rpc0.generate(1) + rpc1.generate(1) + self.sync_all() + + zaddr1 = rpc0.z_getnewaddress() + #rpc0.z_exportkey(zaddr1) + + # first we test the default situation where no donation is given and + # it defaults to 0 + response = rpc0.z_shieldcoinbase('*', zaddr1, 0, 1) + opid = response['opid'] + shieldingValue = response['shieldingValue'] + + assert_true( shieldingValue >= self.supply ) + + print("opid=" + opid) + + time.sleep(2) # give some time for the ztx to complete + + # 555 supply plus magic utxo = 555.02070592 + totalSupply = 55502070592 # in puposhis + expectedAmount = totalSupply + + json = rpc0.z_getoperationstatus() + txid = json[0]['result']['txid'] + + wait_and_assert_operationid_status(rpc0, opid) + + rawtx0 = rpc0.z_viewtransaction(txid) + assert_equal( rawtx0['outputs'][0]['valueZat'] , expectedAmount, '5% donation sends correct sendAmount') + + # now we test giving a donation parameter + donation = 5 + response = rpc1.z_shieldcoinbase('*', zaddr1, 0, 1, donation) + opid = response['opid'] + shieldingValue = response['shieldingValue'] + + assert_true( shieldingValue >= self.supply ) + + rpc0.generate(1) + rpc1.generate(1) + self.sync_all() + + print("opid=" + opid) + + time.sleep(2) # give some time for the ztx to complete + + # 555 supply plus magic utxo = 555.02070592 + totalSupply = 55502070592 + expectedAmount = 52726967062 # 95% of above supply, rounded to closest satoshi + + json = rpc1.z_getoperationstatus() + txid = json[0]['result']['txid'] + + wait_and_assert_operationid_status(rpc1, opid) + + #TODO: sync with testing zaddr in src/wallet/asyncrpcoperation_shieldcoinbase.cpp + rpc1.z_importkey(testing_privkey) + + rawtx1 = rpc1.z_viewtransaction(txid) + assert_equal( rawtx1['outputs'][0]['valueZat'] , totalSupply - expectedAmount, '5% donation sends correct donationAmount') + + +if __name__ == '__main__': + LockZinsTest ().main() diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 7a39d90bf..adb8c748e 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -214,9 +214,9 @@ bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) c m_op->builder_.AddTransparentInput(COutPoint(t.txid, t.vout), t.scriptPubKey, t.amount); } } - + //TODO: TESTING zaddr only, only use on regtest //TODO: randomly select from a set - auto dzaddr = "zs1..."; + auto dzaddr = "zregtestsapling1y30nwg0clsu6gcyrnvht8hdyfk3vwtszlh6kc4z5hv9hmpxzg2g0nx7c60xeecggm9x9gma96t4"; auto donationZaddr = DecodePaymentAddress(dzaddr); if (!IsValidPaymentAddress(donationZaddr)) { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid donation zaddr, Unknown address format: ") + dzaddr); @@ -233,7 +233,7 @@ bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) c auto donationZout = boost::get(donationZaddr); m_op->builder_.AddSaplingOutput(ovk, donationZout, donationAmount); - fprintf(stderr,"%s: donation=%ld, sendAmount=%ld, donationAmount=%ld\n", __func__, donation, sendAmount, donationAmount); + LogPrintf("%s: donation=%ld, sendAmount=%ld, donationAmount=%ld\n", __func__, donation, sendAmount, donationAmount); // zdust as third output, so donation txs are indistinguishable from // non-donation z_shieldcoinbase txs diff --git a/test.sh b/test.sh index a48d5f3f8..dba7a8c15 100755 --- a/test.sh +++ b/test.sh @@ -7,4 +7,5 @@ export PYTHONPATH=./qa/rpc-tests/test_framework/ #./qa/rpc-tests/ac_private.py -./qa/rpc-tests/lockzins.py --tracerpc +# ./qa/rpc-tests/lockzins.py --tracerpc + ./qa/rpc-tests/shieldcoinbase_donation.py --tracerpc