diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 3e007ca58..6d1c622a3 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -101,6 +101,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "z_sendmany", 1}, { "z_sendmany", 2}, { "z_getoperationstatus", 0}, + { "z_getoperationresult", 0}, { "z_importkey", 1 } }; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 88c11abad..5c2347daf 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -388,6 +388,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true }, { "wallet", "z_sendmany", &z_sendmany, true }, { "wallet", "z_getoperationstatus", &z_getoperationstatus, true }, + { "wallet", "z_getoperationresult", &z_getoperationresult, true }, { "wallet", "z_listoperationids", &z_listoperationids, true }, { "wallet", "z_getnewaddress", &z_getnewaddress, true }, { "wallet", "z_listaddresses", &z_listaddresses, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 986d12731..ebec18220 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -258,6 +258,7 @@ extern json_spirit::Value z_exportwallet(const json_spirit::Array& params, bool extern json_spirit::Value z_importwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp extern json_spirit::Value z_sendmany(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp extern json_spirit::Value z_getoperationstatus(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp +extern json_spirit::Value z_getoperationresult(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp extern json_spirit::Value z_listoperationids(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f1ee45dd1..d5132e775 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -42,6 +42,9 @@ using namespace libzcash; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; +// Private method: +Value z_getoperationstatus_IMPL(const Array&, bool); + std::string HelpRequiringPassphrase() { return pwalletMain && pwalletMain->IsCrypted() @@ -2832,6 +2835,25 @@ Value z_listaddresses(const Array& params, bool fHelp) return ret; } +Value z_getoperationresult(const Array& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return Value::null; + + if (fHelp || params.size() > 1) + throw runtime_error( + "z_getoperationresult ([\"operationid\", ... ]) \n" + "\nRetrieve the result and status of an operation which has finished, and then remove the operation from memory." + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. \"operationid\" (array, optional) A list of operation ids we are interested in. If not provided, examine all operations known to the node.\n" + "\nResult:\n" + "\" [object, ...]\" (array) A list of JSON objects\n" + ); + + // This call will remove finished operations + return z_getoperationstatus_IMPL(params, true); +} Value z_getoperationstatus(const Array& params, bool fHelp) { @@ -2841,14 +2863,20 @@ Value z_getoperationstatus(const Array& params, bool fHelp) if (fHelp || params.size() > 1) throw runtime_error( "z_getoperationstatus ([\"operationid\", ... ]) \n" - "\nGet operation status and any associated result or error data." + "\nGet operation status and any associated result or error data. The operation will remain in memory." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" - "1. \"operationid\" (array, optional) A list of operation ids we are interested in.\n" + "1. \"operationid\" (array, optional) A list of operation ids we are interested in. If not provided, examine all operations known to the node.\n" "\nResult:\n" "\" [object, ...]\" (array) A list of JSON objects\n" ); + + // This call is idempotent so we don't want to remove finished operations + return z_getoperationstatus_IMPL(params, false); +} +Value z_getoperationstatus_IMPL(const Array& params, bool fRemoveFinishedOperations=false) +{ LOCK2(cs_main, pwalletMain->cs_wallet); std::set filter; @@ -2876,11 +2904,15 @@ Value z_getoperationstatus(const Array& params, bool fHelp) } Value status = operation->getStatus(); - ret.push_back(status); - // Remove operation from memory when it has finished and the caller has retrieved the result and reason for finishing. - if (operation->isSuccess() || operation->isFailed() || operation->isCancelled()) { - q->popOperationForId(id); + if (fRemoveFinishedOperations) { + // Caller is only interested in retrieving finished results + if (operation->isSuccess() || operation->isFailed() || operation->isCancelled()) { + ret.push_back(status); + q->popOperationForId(id); + } + } else { + ret.push_back(status); } }