diff --git a/qa/rpc-tests/remove_sprout_shielding.py b/qa/rpc-tests/remove_sprout_shielding.py index e3364f7c2..e57ef3003 100755 --- a/qa/rpc-tests/remove_sprout_shielding.py +++ b/qa/rpc-tests/remove_sprout_shielding.py @@ -41,6 +41,7 @@ class RemoveSproutShieldingTest (BitcoinTestFramework): # Shield coinbase to Sprout on node 0. Should pass sprout_addr = self.nodes[0].z_getnewaddress('sprout') + sprout_addr_node2 = self.nodes[2].z_getnewaddress('sprout') myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), sprout_addr, 0)['opid'] wait_and_assert_operationid_status(self.nodes[0], myopid) print("taddr -> Sprout z_shieldcoinbase tx accepted before Canopy on node 0") @@ -69,6 +70,7 @@ class RemoveSproutShieldingTest (BitcoinTestFramework): # included in the next (or later) block, after Canopy has activated. self.nodes[0].generate(5) self.sync_all() + assert_equal(self.nodes[0].getblockchaininfo()['upgrades']['e9ff75a6']['status'], 'pending') # Shield coinbase to Sprout on node 0. Should fail sprout_addr = self.nodes[0].z_getnewaddress('sprout') @@ -101,8 +103,17 @@ class RemoveSproutShieldingTest (BitcoinTestFramework): wait_and_assert_operationid_status(self.nodes[0], merge_tx_1['opid']) print("Sprout -> Sprout z_mergetoaddress tx accepted at Canopy activation on node 0") + # Activate Canopy self.nodes[0].generate(1) self.sync_all() + assert_equal(self.nodes[0].getblockchaininfo()['upgrades']['e9ff75a6']['status'], 'active') + + # Generating a Sprout address should fail after Canopy. + assert_raises_message( + JSONRPCException, + "Invalid address type, \"sprout\" is not allowed after Canopy", + self.nodes[0].z_getnewaddress, 'sprout') + print("Sprout z_getnewaddress rejected at Canopy activation on node 0") # Shield coinbase to Sapling on node 0. Should pass sapling_addr = self.nodes[0].z_getnewaddress('sapling') @@ -115,7 +126,7 @@ class RemoveSproutShieldingTest (BitcoinTestFramework): self.sync_all() # Create z_mergetoaddress Sprout -> Sprout transaction on node 1. Should pass - merge_tx_2 = self.nodes[1].z_mergetoaddress(["ANY_SPROUT"], self.nodes[2].z_getnewaddress('sprout')) + merge_tx_2 = self.nodes[1].z_mergetoaddress(["ANY_SPROUT"], sprout_addr_node2) wait_and_assert_operationid_status(self.nodes[1], merge_tx_2['opid']) print("Sprout -> Sprout z_mergetoaddress tx accepted at NU5 activation on node 1") diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d2660b57f..4b81af3ea 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2911,6 +2911,7 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp) "z_getnewaddress ( type )\n" "\nReturns a new shielded address for receiving payments.\n" "\nWith no arguments, returns a Sapling address.\n" + "Generating a Sprout address is not allowed after Canopy has activated.\n" "\nArguments:\n" "1. \"type\" (string, optional, default=\"" + defaultType + "\") The type of address. One of [\"" + ADDR_TYPE_SPROUT + "\", \"" + ADDR_TYPE_SAPLING + "\"].\n" @@ -2931,8 +2932,16 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp) addrType = params[0].get_str(); } - KeyIO keyIO(Params()); + const auto& chainparams = Params(); + KeyIO keyIO(chainparams); if (addrType == ADDR_TYPE_SPROUT) { + if (chainparams.GetConsensus().NetworkUpgradeActive(chainActive.Height(), Consensus::UPGRADE_CANOPY)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid address type, \"" + + ADDR_TYPE_SPROUT + "\" is not allowed after Canopy"); + } + if (IsInitialBlockDownload(Params().GetConsensus())) { + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Error: Creating a Sprout address during initial block download is not supported."); + } return keyIO.EncodePaymentAddress(pwalletMain->GenerateNewSproutZKey()); } else if (addrType == ADDR_TYPE_SAPLING) { return keyIO.EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey()); diff --git a/src/wallet/test/rpc_wallet_tests.cpp b/src/wallet/test/rpc_wallet_tests.cpp index b1e111e22..00af9e086 100644 --- a/src/wallet/test/rpc_wallet_tests.cpp +++ b/src/wallet/test/rpc_wallet_tests.cpp @@ -812,6 +812,11 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_getnewaddress) { addr = CallRPC("z_getnewaddress sprout"); CheckHaveAddr(keyIO.DecodePaymentAddress(addr.get_str())); + // Requesting a sprout address during IBD should fail + bool ibd = TestSetIBD(true); + CheckRPCThrows("z_getnewaddress sprout", "Error: Creating a Sprout address during initial block download is not supported."); + TestSetIBD(ibd); + // Should throw on invalid argument CheckRPCThrows("z_getnewaddress garbage", "Invalid address type");