Skip to content

Commit d412525

Browse files
committed
[RPC] Add fUseShielded parameter to delegatestake/rawdelegatestake
to delegate coins from sapling addresses
1 parent 847d278 commit d412525

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

src/wallet/rpcwallet.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -827,11 +827,7 @@ UniValue listshieldedaddresses(const JSONRPCRequest& request)
827827
libzcash::SaplingIncomingViewingKey ivk;
828828
libzcash::SaplingExtendedFullViewingKey extfvk;
829829
for (libzcash::SaplingPaymentAddress addr : addresses) {
830-
if (fIncludeWatchonly || (
831-
pwalletMain->GetSaplingIncomingViewingKey(addr, ivk) &&
832-
pwalletMain->GetSaplingFullViewingKey(ivk, extfvk) &&
833-
pwalletMain->HaveSaplingSpendingKey(extfvk)
834-
)) {
830+
if (fIncludeWatchonly || pwalletMain->HaveSpendingKeyForPaymentAddress(addr)) {
835831
ret.push_back(KeyIO::EncodePaymentAddress(addr));
836832
}
837833
}
@@ -989,8 +985,8 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CWalletTx& wtxNew, CR
989985

990986
// Check that Cold Staking has been enforced or fForceNotEnabled = true
991987
bool fForceNotEnabled = false;
992-
if (params.size() > 5 && !params[5].isNull())
993-
fForceNotEnabled = params[5].get_bool();
988+
if (params.size() > 6 && !params[6].isNull())
989+
fForceNotEnabled = params[6].get_bool();
994990

995991
if (!sporkManager.IsSporkActive(SPORK_17_COLDSTAKING_ENFORCEMENT) && !fForceNotEnabled) {
996992
std::string errMsg = "Cold Staking disabled with SPORK 17.\n"
@@ -1059,16 +1055,36 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CWalletTx& wtxNew, CR
10591055
ownerAddressStr = EncodeDestination(ownerAddr);
10601056
}
10611057

1062-
// Get P2CS script for addresses
1063-
CScript scriptPubKey = GetScriptForStakeDelegation(*stakeKey, ownerKey);
1064-
10651058
// Create the transaction
1066-
CAmount nFeeRequired;
1067-
if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError, nullptr, ALL_COINS, (CAmount)0, fUseDelegated)) {
1068-
if (nValue + nFeeRequired > currBalance)
1069-
strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
1070-
LogPrintf("%s : %s\n", __func__, strError);
1071-
throw JSONRPCError(RPC_WALLET_ERROR, strError);
1059+
const bool fUseShielded = (params.size() > 5) && params[5].get_bool();
1060+
if (!fUseShielded) {
1061+
// Delegate transparent coins
1062+
CAmount nFeeRequired;
1063+
CScript scriptPubKey = GetScriptForStakeDelegation(*stakeKey, ownerKey);
1064+
if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError, nullptr, ALL_COINS, (CAmount)0, fUseDelegated)) {
1065+
if (nValue + nFeeRequired > currBalance)
1066+
strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
1067+
LogPrintf("%s : %s\n", __func__, strError);
1068+
throw JSONRPCError(RPC_WALLET_ERROR, strError);
1069+
}
1070+
} else {
1071+
// Delegate shielded coins
1072+
const Consensus::Params& consensus = Params().GetConsensus();
1073+
// Check network status
1074+
int nextBlockHeight = chainActive.Height() + 1;
1075+
if (!consensus.NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_V5_DUMMY)) {
1076+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling not active yet");
1077+
}
1078+
CAmount nFee = DEFAULT_SAPLING_FEE;
1079+
std::vector<SendManyRecipient> recipients = {SendManyRecipient(ownerKey, *stakeKey, nValue)};
1080+
TransactionBuilder txBuilder = TransactionBuilder(consensus, nextBlockHeight, pwalletMain);
1081+
SaplingOperation operation(txBuilder);
1082+
OperationResult res = operation.setSelectShieldedCoins(true)
1083+
->setRecipients(recipients)
1084+
->setFee(nFee)
1085+
->build();
1086+
if (!res) throw JSONRPCError(RPC_WALLET_ERROR, res.getError());
1087+
wtxNew = CWalletTx(pwalletMain, operation.getFinalTx());
10721088
}
10731089

10741090
UniValue result(UniValue::VOBJ);
@@ -1079,7 +1095,7 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CWalletTx& wtxNew, CR
10791095

10801096
UniValue delegatestake(const JSONRPCRequest& request)
10811097
{
1082-
if (request.fHelp || request.params.size() < 2 || request.params.size() > 6)
1098+
if (request.fHelp || request.params.size() < 2 || request.params.size() > 7)
10831099
throw std::runtime_error(
10841100
"delegatestake \"stakingaddress\" amount ( \"owneraddress\" fExternalOwner fUseDelegated fForceNotEnabled )\n"
10851101
"\nDelegate an amount to a given address for cold staking. The amount is a real and is rounded to the nearest 0.00000001\n" +
@@ -1093,7 +1109,8 @@ UniValue delegatestake(const JSONRPCRequest& request)
10931109
"4. \"fExternalOwner\" (boolean, optional, default = false) use the provided 'owneraddress' anyway, even if not present in this wallet.\n"
10941110
" WARNING: The owner of the keys to 'owneraddress' will be the only one allowed to spend these coins.\n"
10951111
"5. \"fUseDelegated\" (boolean, optional, default = false) include already delegated inputs if needed.\n"
1096-
"6. \"fForceNotEnabled\" (boolean, optional, default = false) force the creation even if SPORK 17 is disabled (for tests).\n"
1112+
"6. \"fFromShielded\" (boolean, optional, default = false) delegate shielded funds.\n"
1113+
"7. \"fForceNotEnabled\" (boolean, optional, default = false) ONLY FOR TESTING: force the creation even if SPORK 17 is disabled.\n"
10971114

10981115
"\nResult:\n"
10991116
"{\n"
@@ -1123,7 +1140,7 @@ UniValue delegatestake(const JSONRPCRequest& request)
11231140

11241141
UniValue rawdelegatestake(const JSONRPCRequest& request)
11251142
{
1126-
if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
1143+
if (request.fHelp || request.params.size() < 2 || request.params.size() > 7)
11271144
throw std::runtime_error(
11281145
"rawdelegatestake \"stakingaddress\" amount ( \"owneraddress\" fExternalOwner fUseDelegated )\n"
11291146
"\nDelegate an amount to a given address for cold staking. The amount is a real and is rounded to the nearest 0.00000001\n"
@@ -1133,11 +1150,13 @@ UniValue rawdelegatestake(const JSONRPCRequest& request)
11331150
"\nArguments:\n"
11341151
"1. \"stakingaddress\" (string, required) The pivx staking address to delegate.\n"
11351152
"2. \"amount\" (numeric, required) The amount in PIV to delegate for staking. eg 100\n"
1136-
"3. \"owneraddress\" (string, optional) The pivx address corresponding to the key that will be able to spend the stake. \n"
1153+
"3. \"owneraddress\" (string, optional) The pivx address corresponding to the key that will be able to spend the stake.\n"
11371154
" If not provided, or empty string, a new wallet address is generated.\n"
11381155
"4. \"fExternalOwner\" (boolean, optional, default = false) use the provided 'owneraddress' anyway, even if not present in this wallet.\n"
11391156
" WARNING: The owner of the keys to 'owneraddress' will be the only one allowed to spend these coins.\n"
1140-
"5. \"fUseDelegated (boolean, optional, default = false) include already delegated inputs if needed."
1157+
"5. \"fUseDelegated\" (boolean, optional, default = false) include already delegated inputs if needed.\n"
1158+
"6. \"fFromShielded\" (boolean, optional, default = false) delegate shielded funds.\n"
1159+
"7. \"fForceNotEnabled\" (boolean, optional, default = false) ONLY FOR TESTING: force the creation even if SPORK 17 is disabled (for tests).\n"
11411160

11421161
"\nResult:\n"
11431162
"{\n"
@@ -1535,7 +1554,7 @@ static SaplingOperation CreateShieldedTransaction(const JSONRPCRequest& request)
15351554
if (!Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_V5_DUMMY)) {
15361555
// If Sapling is not active, do not allow sending from or sending to Sapling addresses.
15371556
if (fromSapling || containsSaplingOutput) {
1538-
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
1557+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling not active yet");
15391558
}
15401559
}
15411560

0 commit comments

Comments
 (0)