Skip to content

Commit a8dd236

Browse files
committed
RPC/Wallet: Pass CWallet as pointer to helper functions
>>> inspired by bitcoin/bitcoin@eca550f
1 parent fb64bbc commit a8dd236

File tree

11 files changed

+506
-302
lines changed

11 files changed

+506
-302
lines changed

src/rest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct CCoin {
6060
}
6161
};
6262

63-
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
63+
extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
6464
extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
6565
extern UniValue mempoolInfoToJSON();
6666
extern UniValue mempoolToJSON(bool fVerbose = false);
@@ -373,7 +373,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
373373

374374
case RF_JSON: {
375375
UniValue objTx(UniValue::VOBJ);
376-
TxToJSON(*tx, hashBlock, objTx);
376+
TxToJSON(nullptr, *tx, hashBlock, objTx);
377377
std::string strJSON = objTx.write() + "\n";
378378
req->WriteHeader("Content-Type", "application/json");
379379
req->WriteReply(HTTP_OK, strJSON);

src/rpc/blockchain.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static std::mutex cs_blockchange;
4242
static std::condition_variable cond_blockchange;
4343
static CUpdatedBlock latestblock;
4444

45-
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
45+
extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
4646

4747
UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request)
4848
{
@@ -147,7 +147,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
147147
const CTransaction& tx = *txIn;
148148
if (txDetails) {
149149
UniValue objTx(UniValue::VOBJ);
150-
TxToJSON(tx, UINT256_ZERO, objTx);
150+
TxToJSON(nullptr, tx, UINT256_ZERO, objTx);
151151
txs.push_back(objTx);
152152
} else
153153
txs.push_back(tx.GetHash().GetHex());

src/rpc/budget.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std
9797

9898
UniValue preparebudget(const JSONRPCRequest& request)
9999
{
100+
if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
101+
return NullUniValue;
102+
100103
if (request.fHelp || request.params.size() != 6)
101104
throw std::runtime_error(
102105
"preparebudget \"proposal-name\" \"url\" payment-count block-start \"pivx-address\" monthy-payment\n"
@@ -123,7 +126,7 @@ UniValue preparebudget(const JSONRPCRequest& request)
123126

124127
LOCK2(cs_main, pwalletMain->cs_wallet);
125128

126-
EnsureWalletIsUnlocked();
129+
EnsureWalletIsUnlocked(pwalletMain);
127130

128131
std::string strProposalName;
129132
std::string strURL;

src/rpc/masternode.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ UniValue startmasternode(const JSONRPCRequest& request)
402402

403403
bool fLock = (request.params[1].get_str() == "true" ? true : false);
404404

405-
EnsureWalletIsUnlocked();
405+
EnsureWalletIsUnlocked(pwalletMain);
406406

407407
if (strCommand == "local") {
408408
if (!fMasterNode) throw std::runtime_error("you must set masternode=1 in the configuration\n");
@@ -807,14 +807,17 @@ bool DecodeHexMnb(CMasternodeBroadcast& mnb, std::string strHexMnb) {
807807
}
808808
UniValue createmasternodebroadcast(const JSONRPCRequest& request)
809809
{
810+
if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
811+
return NullUniValue;
812+
810813
std::string strCommand;
811814
if (request.params.size() >= 1)
812815
strCommand = request.params[0].get_str();
813816
if (request.fHelp || (strCommand != "alias" && strCommand != "all") || (strCommand == "alias" && request.params.size() < 2))
814817
throw std::runtime_error(
815818
"createmasternodebroadcast \"command\" ( \"alias\")\n"
816819
"\nCreates a masternode broadcast message for one or all masternodes configured in masternode.conf\n" +
817-
HelpRequiringPassphrase() + "\n"
820+
HelpRequiringPassphrase(pwalletMain) + "\n"
818821

819822
"\nArguments:\n"
820823
"1. \"command\" (string, required) \"alias\" for single masternode, \"all\" for all masternodes\n"
@@ -845,7 +848,7 @@ UniValue createmasternodebroadcast(const JSONRPCRequest& request)
845848
"\nExamples:\n" +
846849
HelpExampleCli("createmasternodebroadcast", "alias mymn1") + HelpExampleRpc("createmasternodebroadcast", "alias mymn1"));
847850

848-
EnsureWalletIsUnlocked();
851+
EnsureWalletIsUnlocked(pwalletMain);
849852

850853
if (strCommand == "alias")
851854
{

src/rpc/mining.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ UniValue generateBlocks(const Consensus::Params& consensus,
7676

7777
UniValue generate(const JSONRPCRequest& request)
7878
{
79+
if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
80+
return NullUniValue;
81+
7982
if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
8083
throw std::runtime_error(
8184
"generate numblocks\n"
@@ -113,7 +116,7 @@ UniValue generate(const JSONRPCRequest& request)
113116

114117
if (fPoS) {
115118
// If we are in PoS, wallet must be unlocked.
116-
EnsureWalletIsUnlocked();
119+
EnsureWalletIsUnlocked(pwalletMain);
117120
} else {
118121
// Coinbase key
119122
reservekey = MakeUnique<CReserveKey>(pwalletMain);
@@ -273,6 +276,9 @@ UniValue getgenerate(const JSONRPCRequest& request)
273276

274277
UniValue setgenerate(const JSONRPCRequest& request)
275278
{
279+
if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
280+
return NullUniValue;
281+
276282
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
277283
throw std::runtime_error(
278284
"setgenerate generate ( genproclimit )\n"
@@ -291,8 +297,6 @@ UniValue setgenerate(const JSONRPCRequest& request)
291297
"\nTurn off generation\n" + HelpExampleCli("setgenerate", "false") +
292298
"\nUsing json rpc\n" + HelpExampleRpc("setgenerate", "true, 1"));
293299

294-
EnsureWallet();
295-
296300
if (Params().IsRegTestNet())
297301
throw JSONRPCError(RPC_INVALID_REQUEST, "Use the generate method instead of setgenerate on regtest");
298302

src/rpc/misc.cpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -227,16 +227,17 @@ class DescribeAddressVisitor : public boost::static_visitor<UniValue>
227227
isminetype mine;
228228

229229
public:
230-
DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}
230+
CWallet * const pwallet;
231+
232+
DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {}
231233

232234
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
233235

234236
UniValue operator()(const CKeyID &keyID) const {
235237
UniValue obj(UniValue::VOBJ);
236238
CPubKey vchPubKey;
237239
obj.pushKV("isscript", false);
238-
if (bool(mine & ISMINE_ALL)) {
239-
pwalletMain->GetPubKey(keyID, vchPubKey);
240+
if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
240241
obj.pushKV("pubkey", HexStr(vchPubKey));
241242
obj.pushKV("iscompressed", vchPubKey.IsCompressed());
242243
}
@@ -247,19 +248,20 @@ class DescribeAddressVisitor : public boost::static_visitor<UniValue>
247248
UniValue obj(UniValue::VOBJ);
248249
obj.pushKV("isscript", true);
249250
CScript subscript;
250-
pwalletMain->GetCScript(scriptID, subscript);
251-
std::vector<CTxDestination> addresses;
252-
txnouttype whichType;
253-
int nRequired;
254-
ExtractDestinations(subscript, whichType, addresses, nRequired);
255-
obj.pushKV("script", GetTxnOutputType(whichType));
256-
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
257-
UniValue a(UniValue::VARR);
258-
for (const CTxDestination& addr : addresses)
259-
a.push_back(EncodeDestination(addr));
260-
obj.pushKV("addresses", a);
261-
if (whichType == TX_MULTISIG)
262-
obj.pushKV("sigsrequired", nRequired);
251+
if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
252+
std::vector<CTxDestination> addresses;
253+
txnouttype whichType;
254+
int nRequired;
255+
ExtractDestinations(subscript, whichType, addresses, nRequired);
256+
obj.pushKV("script", GetTxnOutputType(whichType));
257+
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
258+
UniValue a(UniValue::VARR);
259+
for (const CTxDestination& addr : addresses)
260+
a.push_back(EncodeDestination(addr));
261+
obj.pushKV("addresses", a);
262+
if (whichType == TX_MULTISIG)
263+
obj.pushKV("sigsrequired", nRequired);
264+
}
263265
return obj;
264266
}
265267
};
@@ -334,16 +336,16 @@ typedef boost::variant<libzcash::InvalidEncoding, libzcash::SaplingPaymentAddres
334336
class DescribePaymentAddressVisitor : public boost::static_visitor<UniValue>
335337
{
336338
public:
337-
explicit DescribePaymentAddressVisitor(bool _isStaking) : isStaking(_isStaking) {}
339+
explicit DescribePaymentAddressVisitor(CWallet *_pwallet, bool _isStaking) : pwallet(_pwallet), isStaking(_isStaking) {}
338340
UniValue operator()(const libzcash::InvalidEncoding &zaddr) const { return UniValue(UniValue::VOBJ); }
339341

340342
UniValue operator()(const libzcash::SaplingPaymentAddress &zaddr) const {
341343
UniValue obj(UniValue::VOBJ);
342344
obj.pushKV("diversifier", HexStr(zaddr.d));
343345
obj.pushKV("diversifiedtransmissionkey", zaddr.pk_d.GetHex());
344346
#ifdef ENABLE_WALLET
345-
if (pwalletMain) {
346-
obj.pushKV("ismine", pwalletMain->HaveSpendingKeyForPaymentAddress(zaddr));
347+
if (pwallet) {
348+
obj.pushKV("ismine", pwallet->HaveSpendingKeyForPaymentAddress(zaddr));
347349
}
348350
#endif
349351
return obj;
@@ -355,19 +357,20 @@ class DescribePaymentAddressVisitor : public boost::static_visitor<UniValue>
355357
ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
356358

357359
#ifdef ENABLE_WALLET
358-
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
360+
isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO;
359361
ret.pushKV("ismine", bool(mine & (ISMINE_SPENDABLE_ALL | ISMINE_COLD)));
360362
ret.pushKV("isstaking", isStaking);
361363
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY));
362-
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
364+
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest);
363365
ret.pushKVs(detail);
364-
if (pwalletMain && pwalletMain->HasAddressBook(dest))
365-
ret.pushKV("label", pwalletMain->GetNameForAddressBookEntry(dest));
366+
if (pwallet && pwallet->HasAddressBook(dest))
367+
ret.pushKV("label", pwallet->GetNameForAddressBookEntry(dest));
366368
#endif
367369
return ret;
368370
}
369371

370372
private:
373+
CWallet * const pwallet;
371374
bool isStaking{false};
372375
};
373376

@@ -429,7 +432,7 @@ UniValue validateaddress(const JSONRPCRequest& request)
429432
ret.pushKV("isvalid", isValid);
430433
if (isValid) {
431434
ret.pushKV("address", strAddress);
432-
UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(isStakingAddress), finalAddress);
435+
UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(pwalletMain, isStakingAddress), finalAddress);
433436
ret.pushKVs(detail);
434437
}
435438

@@ -439,7 +442,7 @@ UniValue validateaddress(const JSONRPCRequest& request)
439442
/**
440443
* Used by addmultisigaddress / createmultisig:
441444
*/
442-
CScript _createmultisig_redeemScript(const UniValue& params)
445+
CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params)
443446
{
444447
int nRequired = params[0].get_int();
445448
const UniValue& keys = params[1].get_array();
@@ -461,14 +464,14 @@ CScript _createmultisig_redeemScript(const UniValue& params)
461464
#ifdef ENABLE_WALLET
462465
// Case 1: PIVX address and we have full public key:
463466
CTxDestination dest = DecodeDestination(ks);
464-
if (pwalletMain && IsValidDestination(dest)) {
467+
if (pwallet && IsValidDestination(dest)) {
465468
const CKeyID* keyID = boost::get<CKeyID>(&dest);
466469
if (!keyID) {
467470
throw std::runtime_error(
468471
strprintf("%s does not refer to a key", ks));
469472
}
470473
CPubKey vchPubKey;
471-
if (!pwalletMain->GetPubKey(*keyID, vchPubKey))
474+
if (!pwallet->GetPubKey(*keyID, vchPubKey))
472475
throw std::runtime_error(
473476
strprintf("no full public key for address %s", ks));
474477
if (!vchPubKey.IsFullyValid())
@@ -526,7 +529,7 @@ UniValue createmultisig(const JSONRPCRequest& request)
526529
HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\""));
527530

528531
// Construct using pay-to-script-hash:
529-
CScript inner = _createmultisig_redeemScript(request.params);
532+
CScript inner = _createmultisig_redeemScript(pwalletMain, request.params);
530533
CScriptID innerID(inner);
531534

532535
UniValue result(UniValue::VOBJ);

src/rpc/rawtransaction.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ static void PayloadToJSON(const CTransaction& tx, UniValue& entry)
5454
}
5555
}
5656

57-
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
57+
// pwallet can be nullptr. If not null, the json could include information available only to the wallet.
58+
void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
5859
{
5960
// Call into TxToUniv() in bitcoin-common to decode the transaction hex.
6061
//
@@ -64,11 +65,11 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
6465
TxToUniv(tx, uint256(), entry);
6566

6667
// Sapling
67-
if (pwalletMain && tx.IsShieldedTx()) {
68+
if (pwallet && tx.IsShieldedTx()) {
6869
// Add information that only this wallet knows about the transaction if is possible
69-
if (pwalletMain->HasSaplingSPKM()) {
70+
if (pwallet->HasSaplingSPKM()) {
7071
std::vector<libzcash::SaplingPaymentAddress> addresses =
71-
pwalletMain->GetSaplingScriptPubKeyMan()->FindMySaplingAddresses(tx);
72+
pwallet->GetSaplingScriptPubKeyMan()->FindMySaplingAddresses(tx);
7273
UniValue addrs(UniValue::VARR);
7374
for (const auto& addr : addresses) {
7475
addrs.push_back(KeyIO::EncodePaymentAddress(addr));
@@ -252,7 +253,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
252253

253254
UniValue result(UniValue::VOBJ);
254255
if (blockindex) result.pushKV("in_active_chain", in_active_chain);
255-
TxToJSON(*tx, hash_block, result);
256+
TxToJSON(pwalletMain, *tx, hash_block, result);
256257
return result;
257258
}
258259

@@ -420,7 +421,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request)
420421
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
421422

422423
UniValue result(UniValue::VOBJ);
423-
TxToJSON(CTransaction(std::move(mtx)), UINT256_ZERO, result);
424+
TxToJSON(pwalletMain, CTransaction(std::move(mtx)), UINT256_ZERO, result);
424425

425426
return result;
426427
}
@@ -610,7 +611,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
610611
"The third optional argument (may be null) is an array of base58-encoded private\n"
611612
"keys that, if given, will be the only keys used to sign the transaction.\n"
612613
#ifdef ENABLE_WALLET
613-
+ HelpRequiringPassphrase() + "\n"
614+
+ HelpRequiringPassphrase(pwalletMain) + "\n"
614615
#endif
615616

616617
"\nArguments:\n"
@@ -728,7 +729,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
728729
}
729730
#ifdef ENABLE_WALLET
730731
else if (pwalletMain)
731-
EnsureWalletIsUnlocked();
732+
EnsureWalletIsUnlocked(pwalletMain);
732733
#endif
733734

734735
// Add previous txouts given in the RPC call:

0 commit comments

Comments
 (0)