Browse Source

RPC/Wallet: Pass CWallet as pointer to helper functions

0.15
Luke Dashjr 8 years ago
parent
commit
eca550f250
  1. 18
      src/rpc/misc.cpp
  2. 4
      src/rpc/rawtransaction.cpp
  3. 11
      src/rpc/server.h
  4. 125
      src/wallet/rpcdump.cpp
  5. 199
      src/wallet/rpcwallet.cpp

18
src/rpc/misc.cpp

@ -112,13 +112,17 @@ UniValue getinfo(const JSONRPCRequest& request)
class DescribeAddressVisitor : public boost::static_visitor<UniValue> class DescribeAddressVisitor : public boost::static_visitor<UniValue>
{ {
public: public:
CWallet * const pwallet;
DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {}
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
UniValue operator()(const CKeyID &keyID) const { UniValue operator()(const CKeyID &keyID) const {
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
CPubKey vchPubKey; CPubKey vchPubKey;
obj.push_back(Pair("isscript", false)); obj.push_back(Pair("isscript", false));
if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) { if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
obj.push_back(Pair("pubkey", HexStr(vchPubKey))); obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
} }
@ -129,7 +133,7 @@ public:
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
CScript subscript; CScript subscript;
obj.push_back(Pair("isscript", true)); obj.push_back(Pair("isscript", true));
if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) { if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
std::vector<CTxDestination> addresses; std::vector<CTxDestination> addresses;
txnouttype whichType; txnouttype whichType;
int nRequired; int nRequired;
@ -200,7 +204,7 @@ UniValue validateaddress(const JSONRPCRequest& request)
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest); UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwalletMain), dest);
ret.pushKVs(detail); ret.pushKVs(detail);
if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
@ -227,7 +231,7 @@ UniValue validateaddress(const JSONRPCRequest& request)
/** /**
* Used by addmultisigaddress / createmultisig: * Used by addmultisigaddress / createmultisig:
*/ */
CScript _createmultisig_redeemScript(const UniValue& params) CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params)
{ {
int nRequired = params[0].get_int(); int nRequired = params[0].get_int();
const UniValue& keys = params[1].get_array(); const UniValue& keys = params[1].get_array();
@ -249,14 +253,14 @@ CScript _createmultisig_redeemScript(const UniValue& params)
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
// Case 1: Bitcoin address and we have full public key: // Case 1: Bitcoin address and we have full public key:
CBitcoinAddress address(ks); CBitcoinAddress address(ks);
if (pwalletMain && address.IsValid()) if (pwallet && address.IsValid())
{ {
CKeyID keyID; CKeyID keyID;
if (!address.GetKeyID(keyID)) if (!address.GetKeyID(keyID))
throw runtime_error( throw runtime_error(
strprintf("%s does not refer to a key",ks)); strprintf("%s does not refer to a key",ks));
CPubKey vchPubKey; CPubKey vchPubKey;
if (!pwalletMain->GetPubKey(keyID, vchPubKey)) if (!pwallet->GetPubKey(keyID, vchPubKey))
throw runtime_error( throw runtime_error(
strprintf("no full public key for address %s",ks)); strprintf("no full public key for address %s",ks));
if (!vchPubKey.IsFullyValid()) if (!vchPubKey.IsFullyValid())
@ -320,7 +324,7 @@ UniValue createmultisig(const JSONRPCRequest& request)
} }
// Construct using pay-to-script-hash: // Construct using pay-to-script-hash:
CScript inner = _createmultisig_redeemScript(request.params); CScript inner = _createmultisig_redeemScript(pwalletMain, request.params);
CScriptID innerID(inner); CScriptID innerID(inner);
CBitcoinAddress address(innerID); CBitcoinAddress address(innerID);

4
src/rpc/rawtransaction.cpp

@ -603,7 +603,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
"The third optional argument (may be null) is an array of base58-encoded private\n" "The third optional argument (may be null) is an array of base58-encoded private\n"
"keys that, if given, will be the only keys used to sign the transaction.\n" "keys that, if given, will be the only keys used to sign the transaction.\n"
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
+ HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n"
#endif #endif
"\nArguments:\n" "\nArguments:\n"
@ -718,7 +718,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
} }
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
else if (pwalletMain) else if (pwalletMain)
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
#endif #endif
// Add previous txouts given in the RPC call: // Add previous txouts given in the RPC call:

11
src/rpc/server.h

@ -194,11 +194,18 @@ extern int64_t nWalletUnlockTime;
extern CAmount AmountFromValue(const UniValue& value); extern CAmount AmountFromValue(const UniValue& value);
extern UniValue ValueFromAmount(const CAmount& amount); extern UniValue ValueFromAmount(const CAmount& amount);
extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
extern std::string HelpRequiringPassphrase();
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
extern void EnsureWalletIsUnlocked(); // Needed even with !ENABLE_WALLET, to pass (ignored) pointers around
class CWallet;
#ifdef ENABLE_WALLET
// New code should accessing the wallet should be under the ../wallet/ directory
std::string HelpRequiringPassphrase(CWallet *);
void EnsureWalletIsUnlocked(CWallet *);
bool EnsureWalletIsAvailable(CWallet *, bool avoidException);
#endif
bool StartRPC(); bool StartRPC();
void InterruptRPC(); void InterruptRPC();

125
src/wallet/rpcdump.cpp

@ -29,9 +29,6 @@
using namespace std; using namespace std;
void EnsureWalletIsUnlocked();
bool EnsureWalletIsAvailable(bool avoidException);
std::string static EncodeDumpTime(int64_t nTime) { std::string static EncodeDumpTime(int64_t nTime) {
return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
} }
@ -77,7 +74,7 @@ std::string DecodeDumpString(const std::string &str) {
UniValue importprivkey(const JSONRPCRequest& request) UniValue importprivkey(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
@ -103,7 +100,7 @@ UniValue importprivkey(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
string strSecret = request.params[0].get_str(); string strSecret = request.params[0].get_str();
string strLabel = ""; string strLabel = "";
@ -153,41 +150,41 @@ UniValue importprivkey(const JSONRPCRequest& request)
return NullUniValue; return NullUniValue;
} }
void ImportAddress(const CBitcoinAddress& address, const string& strLabel); void ImportAddress(CWallet*, const CBitcoinAddress& address, const string& strLabel);
void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) void ImportScript(CWallet * const pwallet, const CScript& script, const string& strLabel, bool isRedeemScript)
{ {
if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) if (!isRedeemScript && ::IsMine(*pwallet, script) == ISMINE_SPENDABLE)
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
pwalletMain->MarkDirty(); pwallet->MarkDirty();
if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, 0 /* nCreateTime */)) if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, 0 /* nCreateTime */))
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
if (isRedeemScript) { if (isRedeemScript) {
if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) if (!pwallet->HaveCScript(script) && !pwallet->AddCScript(script))
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet");
ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); ImportAddress(pwallet, CBitcoinAddress(CScriptID(script)), strLabel);
} else { } else {
CTxDestination destination; CTxDestination destination;
if (ExtractDestination(script, destination)) { if (ExtractDestination(script, destination)) {
pwalletMain->SetAddressBook(destination, strLabel, "receive"); pwallet->SetAddressBook(destination, strLabel, "receive");
} }
} }
} }
void ImportAddress(const CBitcoinAddress& address, const string& strLabel) void ImportAddress(CWallet * const pwallet, const CBitcoinAddress& address, const string& strLabel)
{ {
CScript script = GetScriptForDestination(address.Get()); CScript script = GetScriptForDestination(address.Get());
ImportScript(script, strLabel, false); ImportScript(pwallet, script, strLabel, false);
// add to address book or update label // add to address book or update label
if (address.IsValid()) if (address.IsValid())
pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); pwallet->SetAddressBook(address.Get(), strLabel, "receive");
} }
UniValue importaddress(const JSONRPCRequest& request) UniValue importaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
@ -236,10 +233,10 @@ UniValue importaddress(const JSONRPCRequest& request)
if (address.IsValid()) { if (address.IsValid()) {
if (fP2SH) if (fP2SH)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead");
ImportAddress(address, strLabel); ImportAddress(pwalletMain, address, strLabel);
} else if (IsHex(request.params[0].get_str())) { } else if (IsHex(request.params[0].get_str())) {
std::vector<unsigned char> data(ParseHex(request.params[0].get_str())); std::vector<unsigned char> data(ParseHex(request.params[0].get_str()));
ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH); ImportScript(pwalletMain, CScript(data.begin(), data.end()), strLabel, fP2SH);
} else { } else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
} }
@ -255,7 +252,7 @@ UniValue importaddress(const JSONRPCRequest& request)
UniValue importprunedfunds(const JSONRPCRequest& request) UniValue importprunedfunds(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 2) if (request.fHelp || request.params.size() != 2)
@ -314,7 +311,7 @@ UniValue importprunedfunds(const JSONRPCRequest& request)
UniValue removeprunedfunds(const JSONRPCRequest& request) UniValue removeprunedfunds(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -350,7 +347,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request)
UniValue importpubkey(const JSONRPCRequest& request) UniValue importpubkey(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
@ -393,8 +390,8 @@ UniValue importpubkey(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel); ImportAddress(pwalletMain, CBitcoinAddress(pubKey.GetID()), strLabel);
ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); ImportScript(pwalletMain, GetScriptForRawPubKey(pubKey), strLabel, false);
if (fRescan) if (fRescan)
{ {
@ -408,7 +405,7 @@ UniValue importpubkey(const JSONRPCRequest& request)
UniValue importwallet(const JSONRPCRequest& request) UniValue importwallet(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -431,7 +428,7 @@ UniValue importwallet(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
ifstream file; ifstream file;
file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate);
@ -514,7 +511,7 @@ UniValue importwallet(const JSONRPCRequest& request)
UniValue dumpprivkey(const JSONRPCRequest& request) UniValue dumpprivkey(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -534,7 +531,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
string strAddress = request.params[0].get_str(); string strAddress = request.params[0].get_str();
CBitcoinAddress address; CBitcoinAddress address;
@ -552,7 +549,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
UniValue dumpwallet(const JSONRPCRequest& request) UniValue dumpwallet(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -568,7 +565,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
ofstream file; ofstream file;
file.open(request.params[0].get_str().c_str()); file.open(request.params[0].get_str().c_str());
@ -641,7 +638,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
} }
UniValue ProcessImport(const UniValue& data, const int64_t timestamp) UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int64_t timestamp)
{ {
try { try {
bool success = false; bool success = false;
@ -723,32 +720,32 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid P2SH address / script"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid P2SH address / script");
} }
pwalletMain->MarkDirty(); pwallet->MarkDirty();
if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript, timestamp)) { if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
if (!pwalletMain->HaveCScript(redeemScript) && !pwalletMain->AddCScript(redeemScript)) { if (!pwallet->HaveCScript(redeemScript) && !pwallet->AddCScript(redeemScript)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet");
} }
CBitcoinAddress redeemAddress = CBitcoinAddress(CScriptID(redeemScript)); CBitcoinAddress redeemAddress = CBitcoinAddress(CScriptID(redeemScript));
CScript redeemDestination = GetScriptForDestination(redeemAddress.Get()); CScript redeemDestination = GetScriptForDestination(redeemAddress.Get());
if (::IsMine(*pwalletMain, redeemDestination) == ISMINE_SPENDABLE) { if (::IsMine(*pwallet, redeemDestination) == ISMINE_SPENDABLE) {
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
} }
pwalletMain->MarkDirty(); pwallet->MarkDirty();
if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination, timestamp)) { if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
// add to address book or update label // add to address book or update label
if (address.IsValid()) { if (address.IsValid()) {
pwalletMain->SetAddressBook(address.Get(), label, "receive"); pwallet->SetAddressBook(address.Get(), label, "receive");
} }
// Import private keys. // Import private keys.
@ -773,20 +770,20 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp)
assert(key.VerifyPubKey(pubkey)); assert(key.VerifyPubKey(pubkey));
CKeyID vchAddress = pubkey.GetID(); CKeyID vchAddress = pubkey.GetID();
pwalletMain->MarkDirty(); pwallet->MarkDirty();
pwalletMain->SetAddressBook(vchAddress, label, "receive"); pwallet->SetAddressBook(vchAddress, label, "receive");
if (pwalletMain->HaveKey(vchAddress)) { if (pwallet->HaveKey(vchAddress)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Already have this key"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Already have this key");
} }
pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = timestamp; pwallet->mapKeyMetadata[vchAddress].nCreateTime = timestamp;
if (!pwalletMain->AddKeyPubKey(key, pubkey)) { if (!pwallet->AddKeyPubKey(key, pubkey)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
} }
pwalletMain->UpdateTimeFirstKey(timestamp); pwallet->UpdateTimeFirstKey(timestamp);
} }
} }
@ -829,31 +826,31 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp)
CScript pubKeyScript = GetScriptForDestination(pubKeyAddress.Get()); CScript pubKeyScript = GetScriptForDestination(pubKeyAddress.Get());
if (::IsMine(*pwalletMain, pubKeyScript) == ISMINE_SPENDABLE) { if (::IsMine(*pwallet, pubKeyScript) == ISMINE_SPENDABLE) {
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
} }
pwalletMain->MarkDirty(); pwallet->MarkDirty();
if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript, timestamp)) { if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
// add to address book or update label // add to address book or update label
if (pubKeyAddress.IsValid()) { if (pubKeyAddress.IsValid()) {
pwalletMain->SetAddressBook(pubKeyAddress.Get(), label, "receive"); pwallet->SetAddressBook(pubKeyAddress.Get(), label, "receive");
} }
// TODO Is this necessary? // TODO Is this necessary?
CScript scriptRawPubKey = GetScriptForRawPubKey(pubKey); CScript scriptRawPubKey = GetScriptForRawPubKey(pubKey);
if (::IsMine(*pwalletMain, scriptRawPubKey) == ISMINE_SPENDABLE) { if (::IsMine(*pwallet, scriptRawPubKey) == ISMINE_SPENDABLE) {
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
} }
pwalletMain->MarkDirty(); pwallet->MarkDirty();
if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey, timestamp)) { if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
@ -901,40 +898,40 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp)
} }
CKeyID vchAddress = pubKey.GetID(); CKeyID vchAddress = pubKey.GetID();
pwalletMain->MarkDirty(); pwallet->MarkDirty();
pwalletMain->SetAddressBook(vchAddress, label, "receive"); pwallet->SetAddressBook(vchAddress, label, "receive");
if (pwalletMain->HaveKey(vchAddress)) { if (pwallet->HaveKey(vchAddress)) {
return false; return false;
} }
pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = timestamp; pwallet->mapKeyMetadata[vchAddress].nCreateTime = timestamp;
if (!pwalletMain->AddKeyPubKey(key, pubKey)) { if (!pwallet->AddKeyPubKey(key, pubKey)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
} }
pwalletMain->UpdateTimeFirstKey(timestamp); pwallet->UpdateTimeFirstKey(timestamp);
success = true; success = true;
} }
// Import scriptPubKey only. // Import scriptPubKey only.
if (pubKeys.size() == 0 && keys.size() == 0) { if (pubKeys.size() == 0 && keys.size() == 0) {
if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) { if (::IsMine(*pwallet, script) == ISMINE_SPENDABLE) {
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
} }
pwalletMain->MarkDirty(); pwallet->MarkDirty();
if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, timestamp)) { if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
} }
if (scriptPubKey.getType() == UniValue::VOBJ) { if (scriptPubKey.getType() == UniValue::VOBJ) {
// add to address book or update label // add to address book or update label
if (address.IsValid()) { if (address.IsValid()) {
pwalletMain->SetAddressBook(address.Get(), label, "receive"); pwallet->SetAddressBook(address.Get(), label, "receive");
} }
} }
@ -1012,7 +1009,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
" [{ \"success\": true } , { \"success\": false, \"error\": { \"code\": -1, \"message\": \"Internal Server Error\"} }, ... ]\n"); " [{ \"success\": true } , { \"success\": false, \"error\": { \"code\": -1, \"message\": \"Internal Server Error\"} }, ... ]\n");
// clang-format on // clang-format on
if (!EnsureWalletIsAvailable(mainRequest.fHelp)) { if (!EnsureWalletIsAvailable(pwalletMain, mainRequest.fHelp)) {
return NullUniValue; return NullUniValue;
} }
@ -1032,7 +1029,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
} }
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
// Verify all timestamps are present before importing any keys. // Verify all timestamps are present before importing any keys.
const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0;
@ -1054,7 +1051,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
BOOST_FOREACH (const UniValue& data, requests.getValues()) { BOOST_FOREACH (const UniValue& data, requests.getValues()) {
const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp); const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp);
const UniValue result = ProcessImport(data, timestamp); const UniValue result = ProcessImport(pwalletMain, data, timestamp);
response.push_back(result); response.push_back(result);
if (!fRescan) { if (!fRescan) {

199
src/wallet/rpcwallet.cpp

@ -32,16 +32,16 @@ using namespace std;
int64_t nWalletUnlockTime; int64_t nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime;
std::string HelpRequiringPassphrase() std::string HelpRequiringPassphrase(CWallet * const pwallet)
{ {
return pwalletMain && pwalletMain->IsCrypted() return pwallet && pwallet->IsCrypted()
? "\nRequires wallet passphrase to be set with walletpassphrase call." ? "\nRequires wallet passphrase to be set with walletpassphrase call."
: ""; : "";
} }
bool EnsureWalletIsAvailable(bool avoidException) bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
{ {
if (!pwalletMain) if (!pwallet)
{ {
if (!avoidException) if (!avoidException)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
@ -51,9 +51,9 @@ bool EnsureWalletIsAvailable(bool avoidException)
return true; return true;
} }
void EnsureWalletIsUnlocked() void EnsureWalletIsUnlocked(CWallet * const pwallet)
{ {
if (pwalletMain->IsLocked()) if (pwallet->IsLocked())
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
} }
@ -106,7 +106,7 @@ string AccountFromValue(const UniValue& value)
UniValue getnewaddress(const JSONRPCRequest& request) UniValue getnewaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 1) if (request.fHelp || request.params.size() > 1)
@ -146,10 +146,10 @@ UniValue getnewaddress(const JSONRPCRequest& request)
} }
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) CBitcoinAddress GetAccountAddress(CWallet * const pwallet, string strAccount, bool bForceNew=false)
{ {
CPubKey pubKey; CPubKey pubKey;
if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) { if (!pwallet->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
} }
@ -158,7 +158,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
UniValue getaccountaddress(const JSONRPCRequest& request) UniValue getaccountaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -183,14 +183,14 @@ UniValue getaccountaddress(const JSONRPCRequest& request)
UniValue ret(UniValue::VSTR); UniValue ret(UniValue::VSTR);
ret = GetAccountAddress(strAccount).ToString(); ret = GetAccountAddress(pwalletMain, strAccount).ToString();
return ret; return ret;
} }
UniValue getrawchangeaddress(const JSONRPCRequest& request) UniValue getrawchangeaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 1) if (request.fHelp || request.params.size() > 1)
@ -225,7 +225,7 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request)
UniValue setaccount(const JSONRPCRequest& request) UniValue setaccount(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
@ -257,8 +257,8 @@ UniValue setaccount(const JSONRPCRequest& request)
if (pwalletMain->mapAddressBook.count(address.Get())) if (pwalletMain->mapAddressBook.count(address.Get()))
{ {
string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name; string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name;
if (address == GetAccountAddress(strOldAccount)) if (address == GetAccountAddress(pwalletMain, strOldAccount))
GetAccountAddress(strOldAccount, true); GetAccountAddress(pwalletMain, strOldAccount, true);
} }
pwalletMain->SetAddressBook(address.Get(), strAccount, "receive"); pwalletMain->SetAddressBook(address.Get(), strAccount, "receive");
} }
@ -271,7 +271,7 @@ UniValue setaccount(const JSONRPCRequest& request)
UniValue getaccount(const JSONRPCRequest& request) UniValue getaccount(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -303,7 +303,7 @@ UniValue getaccount(const JSONRPCRequest& request)
UniValue getaddressesbyaccount(const JSONRPCRequest& request) UniValue getaddressesbyaccount(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -338,9 +338,9 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request)
return ret; return ret;
} }
static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew)
{ {
CAmount curBalance = pwalletMain->GetBalance(); CAmount curBalance = pwallet->GetBalance();
// Check amount // Check amount
if (nValue <= 0) if (nValue <= 0)
@ -349,27 +349,27 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr
if (nValue > curBalance) if (nValue > curBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
if (pwalletMain->GetBroadcastTransactions() && !g_connman) if (pwallet->GetBroadcastTransactions() && !g_connman)
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
// Parse Bitcoin address // Parse Bitcoin address
CScript scriptPubKey = GetScriptForDestination(address); CScript scriptPubKey = GetScriptForDestination(address);
// Create and send the transaction // Create and send the transaction
CReserveKey reservekey(pwalletMain); CReserveKey reservekey(pwallet);
CAmount nFeeRequired; CAmount nFeeRequired;
std::string strError; std::string strError;
vector<CRecipient> vecSend; vector<CRecipient> vecSend;
int nChangePosRet = -1; int nChangePosRet = -1;
CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount}; CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
vecSend.push_back(recipient); vecSend.push_back(recipient);
if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) {
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
throw JSONRPCError(RPC_WALLET_ERROR, strError); throw JSONRPCError(RPC_WALLET_ERROR, strError);
} }
CValidationState state; CValidationState state;
if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
throw JSONRPCError(RPC_WALLET_ERROR, strError); throw JSONRPCError(RPC_WALLET_ERROR, strError);
} }
@ -377,14 +377,14 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr
UniValue sendtoaddress(const JSONRPCRequest& request) UniValue sendtoaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
throw runtime_error( throw runtime_error(
"sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n" "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n"
"\nSend an amount to a given address.\n" "\nSend an amount to a given address.\n"
+ HelpRequiringPassphrase() + + HelpRequiringPassphrase(pwalletMain) +
"\nArguments:\n" "\nArguments:\n"
"1. \"address\" (string, required) The bitcoin address to send to.\n" "1. \"address\" (string, required) The bitcoin address to send to.\n"
"2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
@ -426,16 +426,16 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
if (request.params.size() > 4) if (request.params.size() > 4)
fSubtractFeeFromAmount = request.params[4].get_bool(); fSubtractFeeFromAmount = request.params[4].get_bool();
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx); SendMoney(pwalletMain, address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
return wtx.GetHash().GetHex(); return wtx.GetHash().GetHex();
} }
UniValue listaddressgroupings(const JSONRPCRequest& request) UniValue listaddressgroupings(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp) if (request.fHelp)
@ -486,14 +486,14 @@ UniValue listaddressgroupings(const JSONRPCRequest& request)
UniValue signmessage(const JSONRPCRequest& request) UniValue signmessage(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 2) if (request.fHelp || request.params.size() != 2)
throw runtime_error( throw runtime_error(
"signmessage \"address\" \"message\"\n" "signmessage \"address\" \"message\"\n"
"\nSign a message with the private key of an address" "\nSign a message with the private key of an address"
+ HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"address\" (string, required) The bitcoin address to use for the private key.\n" "1. \"address\" (string, required) The bitcoin address to use for the private key.\n"
"2. \"message\" (string, required) The message to create a signature of.\n" "2. \"message\" (string, required) The message to create a signature of.\n"
@ -512,7 +512,7 @@ UniValue signmessage(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
string strAddress = request.params[0].get_str(); string strAddress = request.params[0].get_str();
string strMessage = request.params[1].get_str(); string strMessage = request.params[1].get_str();
@ -542,7 +542,7 @@ UniValue signmessage(const JSONRPCRequest& request)
UniValue getreceivedbyaddress(const JSONRPCRequest& request) UniValue getreceivedbyaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
@ -600,7 +600,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request)
UniValue getreceivedbyaccount(const JSONRPCRequest& request) UniValue getreceivedbyaccount(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
@ -657,7 +657,7 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request)
UniValue getbalance(const JSONRPCRequest& request) UniValue getbalance(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 3) if (request.fHelp || request.params.size() > 3)
@ -746,7 +746,7 @@ UniValue getbalance(const JSONRPCRequest& request)
UniValue getunconfirmedbalance(const JSONRPCRequest &request) UniValue getunconfirmedbalance(const JSONRPCRequest &request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 0) if (request.fHelp || request.params.size() > 0)
@ -762,7 +762,7 @@ UniValue getunconfirmedbalance(const JSONRPCRequest &request)
UniValue movecmd(const JSONRPCRequest& request) UniValue movecmd(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
@ -809,14 +809,14 @@ UniValue movecmd(const JSONRPCRequest& request)
UniValue sendfrom(const JSONRPCRequest& request) UniValue sendfrom(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) if (request.fHelp || request.params.size() < 3 || request.params.size() > 6)
throw runtime_error( throw runtime_error(
"sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n" "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
"\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address."
+ HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
" Specifying an account does not influence coin selection, but it does associate the newly created\n" " Specifying an account does not influence coin selection, but it does associate the newly created\n"
@ -861,14 +861,14 @@ UniValue sendfrom(const JSONRPCRequest& request)
if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty()) if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty())
wtx.mapValue["to"] = request.params[5].get_str(); wtx.mapValue["to"] = request.params[5].get_str();
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
// Check funds // Check funds
CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
if (nAmount > nBalance) if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
SendMoney(address.Get(), nAmount, false, wtx); SendMoney(pwalletMain, address.Get(), nAmount, false, wtx);
return wtx.GetHash().GetHex(); return wtx.GetHash().GetHex();
} }
@ -876,14 +876,14 @@ UniValue sendfrom(const JSONRPCRequest& request)
UniValue sendmany(const JSONRPCRequest& request) UniValue sendmany(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
throw runtime_error( throw runtime_error(
"sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n"
"\nSend multiple times. Amounts are double-precision floating point numbers." "\nSend multiple times. Amounts are double-precision floating point numbers."
+ HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
"2. \"amounts\" (string, required) A json object with addresses and amounts\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
@ -967,7 +967,7 @@ UniValue sendmany(const JSONRPCRequest& request)
vecSend.push_back(recipient); vecSend.push_back(recipient);
} }
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
// Check funds // Check funds
CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
@ -992,11 +992,11 @@ UniValue sendmany(const JSONRPCRequest& request)
} }
// Defined in rpc/misc.cpp // Defined in rpc/misc.cpp
extern CScript _createmultisig_redeemScript(const UniValue& params); extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params);
UniValue addmultisigaddress(const JSONRPCRequest& request) UniValue addmultisigaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
@ -1034,7 +1034,7 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
strAccount = AccountFromValue(request.params[2]); strAccount = AccountFromValue(request.params[2]);
// Construct using pay-to-script-hash: // Construct using pay-to-script-hash:
CScript inner = _createmultisig_redeemScript(request.params); CScript inner = _createmultisig_redeemScript(pwalletMain, request.params);
CScriptID innerID(inner); CScriptID innerID(inner);
pwalletMain->AddCScript(inner); pwalletMain->AddCScript(inner);
@ -1045,20 +1045,23 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
class Witnessifier : public boost::static_visitor<bool> class Witnessifier : public boost::static_visitor<bool>
{ {
public: public:
CWallet * const pwallet;
CScriptID result; CScriptID result;
Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {}
bool operator()(const CNoDestination &dest) const { return false; } bool operator()(const CNoDestination &dest) const { return false; }
bool operator()(const CKeyID &keyID) { bool operator()(const CKeyID &keyID) {
CPubKey pubkey; CPubKey pubkey;
if (pwalletMain) { if (pwallet) {
CScript basescript = GetScriptForDestination(keyID); CScript basescript = GetScriptForDestination(keyID);
isminetype typ; isminetype typ;
typ = IsMine(*pwalletMain, basescript, SIGVERSION_WITNESS_V0); typ = IsMine(*pwallet, basescript, SIGVERSION_WITNESS_V0);
if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE)
return false; return false;
CScript witscript = GetScriptForWitness(basescript); CScript witscript = GetScriptForWitness(basescript);
pwalletMain->AddCScript(witscript); pwallet->AddCScript(witscript);
result = CScriptID(witscript); result = CScriptID(witscript);
return true; return true;
} }
@ -1067,7 +1070,7 @@ public:
bool operator()(const CScriptID &scriptID) { bool operator()(const CScriptID &scriptID) {
CScript subscript; CScript subscript;
if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) { if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
int witnessversion; int witnessversion;
std::vector<unsigned char> witprog; std::vector<unsigned char> witprog;
if (subscript.IsWitnessProgram(witnessversion, witprog)) { if (subscript.IsWitnessProgram(witnessversion, witprog)) {
@ -1075,11 +1078,11 @@ public:
return true; return true;
} }
isminetype typ; isminetype typ;
typ = IsMine(*pwalletMain, subscript, SIGVERSION_WITNESS_V0); typ = IsMine(*pwallet, subscript, SIGVERSION_WITNESS_V0);
if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE)
return false; return false;
CScript witscript = GetScriptForWitness(subscript); CScript witscript = GetScriptForWitness(subscript);
pwalletMain->AddCScript(witscript); pwallet->AddCScript(witscript);
result = CScriptID(witscript); result = CScriptID(witscript);
return true; return true;
} }
@ -1089,7 +1092,7 @@ public:
UniValue addwitnessaddress(const JSONRPCRequest& request) UniValue addwitnessaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
@ -1119,7 +1122,7 @@ UniValue addwitnessaddress(const JSONRPCRequest& request)
if (!address.IsValid()) if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
Witnessifier w; Witnessifier w(pwalletMain);
CTxDestination dest = address.Get(); CTxDestination dest = address.Get();
bool ret = boost::apply_visitor(w, dest); bool ret = boost::apply_visitor(w, dest);
if (!ret) { if (!ret) {
@ -1145,7 +1148,7 @@ struct tallyitem
} }
}; };
UniValue ListReceived(const UniValue& params, bool fByAccounts) UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts)
{ {
// Minimum confirmations // Minimum confirmations
int nMinDepth = 1; int nMinDepth = 1;
@ -1164,7 +1167,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
// Tally // Tally
map<CBitcoinAddress, tallyitem> mapTally; map<CBitcoinAddress, tallyitem> mapTally;
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) for (map<uint256, CWalletTx>::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it)
{ {
const CWalletTx& wtx = (*it).second; const CWalletTx& wtx = (*it).second;
@ -1181,7 +1184,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
if (!ExtractDestination(txout.scriptPubKey, address)) if (!ExtractDestination(txout.scriptPubKey, address))
continue; continue;
isminefilter mine = IsMine(*pwalletMain, address); isminefilter mine = IsMine(*pwallet, address);
if(!(mine & filter)) if(!(mine & filter))
continue; continue;
@ -1197,7 +1200,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
// Reply // Reply
UniValue ret(UniValue::VARR); UniValue ret(UniValue::VARR);
map<string, tallyitem> mapAccountTally; map<string, tallyitem> mapAccountTally;
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwallet->mapAddressBook)
{ {
const CBitcoinAddress& address = item.first; const CBitcoinAddress& address = item.first;
const string& strAccount = item.second.name; const string& strAccount = item.second.name;
@ -1267,7 +1270,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
UniValue listreceivedbyaddress(const JSONRPCRequest& request) UniValue listreceivedbyaddress(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 3) if (request.fHelp || request.params.size() > 3)
@ -1304,12 +1307,12 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
return ListReceived(request.params, false); return ListReceived(pwalletMain, request.params, false);
} }
UniValue listreceivedbyaccount(const JSONRPCRequest& request) UniValue listreceivedbyaccount(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 3) if (request.fHelp || request.params.size() > 3)
@ -1341,7 +1344,7 @@ UniValue listreceivedbyaccount(const JSONRPCRequest& request)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
return ListReceived(request.params, true); return ListReceived(pwalletMain, request.params, true);
} }
static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
@ -1351,7 +1354,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
entry.push_back(Pair("address", addr.ToString())); entry.push_back(Pair("address", addr.ToString()));
} }
void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
{ {
CAmount nFee; CAmount nFee;
string strSentAccount; string strSentAccount;
@ -1369,14 +1372,14 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
BOOST_FOREACH(const COutputEntry& s, listSent) BOOST_FOREACH(const COutputEntry& s, listSent)
{ {
UniValue entry(UniValue::VOBJ); UniValue entry(UniValue::VOBJ);
if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) if(involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY))
entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("involvesWatchonly", true));
entry.push_back(Pair("account", strSentAccount)); entry.push_back(Pair("account", strSentAccount));
MaybePushAddress(entry, s.destination); MaybePushAddress(entry, s.destination);
entry.push_back(Pair("category", "send")); entry.push_back(Pair("category", "send"));
entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
if (pwalletMain->mapAddressBook.count(s.destination)) if (pwallet->mapAddressBook.count(s.destination))
entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name)); entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name));
entry.push_back(Pair("vout", s.vout)); entry.push_back(Pair("vout", s.vout));
entry.push_back(Pair("fee", ValueFromAmount(-nFee))); entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
if (fLong) if (fLong)
@ -1392,12 +1395,12 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
BOOST_FOREACH(const COutputEntry& r, listReceived) BOOST_FOREACH(const COutputEntry& r, listReceived)
{ {
string account; string account;
if (pwalletMain->mapAddressBook.count(r.destination)) if (pwallet->mapAddressBook.count(r.destination))
account = pwalletMain->mapAddressBook[r.destination].name; account = pwallet->mapAddressBook[r.destination].name;
if (fAllAccounts || (account == strAccount)) if (fAllAccounts || (account == strAccount))
{ {
UniValue entry(UniValue::VOBJ); UniValue entry(UniValue::VOBJ);
if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) if(involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY))
entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("involvesWatchonly", true));
entry.push_back(Pair("account", account)); entry.push_back(Pair("account", account));
MaybePushAddress(entry, r.destination); MaybePushAddress(entry, r.destination);
@ -1415,7 +1418,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
entry.push_back(Pair("category", "receive")); entry.push_back(Pair("category", "receive"));
} }
entry.push_back(Pair("amount", ValueFromAmount(r.amount))); entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
if (pwalletMain->mapAddressBook.count(r.destination)) if (pwallet->mapAddressBook.count(r.destination))
entry.push_back(Pair("label", account)); entry.push_back(Pair("label", account));
entry.push_back(Pair("vout", r.vout)); entry.push_back(Pair("vout", r.vout));
if (fLong) if (fLong)
@ -1445,7 +1448,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Un
UniValue listtransactions(const JSONRPCRequest& request) UniValue listtransactions(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 4) if (request.fHelp || request.params.size() > 4)
@ -1538,7 +1541,7 @@ UniValue listtransactions(const JSONRPCRequest& request)
{ {
CWalletTx *const pwtx = (*it).second.first; CWalletTx *const pwtx = (*it).second.first;
if (pwtx != 0) if (pwtx != 0)
ListTransactions(*pwtx, strAccount, 0, true, ret, filter); ListTransactions(pwalletMain, *pwtx, strAccount, 0, true, ret, filter);
CAccountingEntry *const pacentry = (*it).second.second; CAccountingEntry *const pacentry = (*it).second.second;
if (pacentry != 0) if (pacentry != 0)
AcentryToJSON(*pacentry, strAccount, ret); AcentryToJSON(*pacentry, strAccount, ret);
@ -1573,7 +1576,7 @@ UniValue listtransactions(const JSONRPCRequest& request)
UniValue listaccounts(const JSONRPCRequest& request) UniValue listaccounts(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 2) if (request.fHelp || request.params.size() > 2)
@ -1652,7 +1655,7 @@ UniValue listaccounts(const JSONRPCRequest& request)
UniValue listsinceblock(const JSONRPCRequest& request) UniValue listsinceblock(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp) if (request.fHelp)
@ -1743,7 +1746,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
CWalletTx tx = (*it).second; CWalletTx tx = (*it).second;
if (depth == -1 || tx.GetDepthInMainChain() < depth) if (depth == -1 || tx.GetDepthInMainChain() < depth)
ListTransactions(tx, "*", 0, true, transactions, filter); ListTransactions(pwalletMain, tx, "*", 0, true, transactions, filter);
} }
CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
@ -1758,7 +1761,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
UniValue gettransaction(const JSONRPCRequest& request) UniValue gettransaction(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
@ -1833,7 +1836,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
WalletTxToJSON(wtx, entry); WalletTxToJSON(wtx, entry);
UniValue details(UniValue::VARR); UniValue details(UniValue::VARR);
ListTransactions(wtx, "*", 0, false, details, filter); ListTransactions(pwalletMain, wtx, "*", 0, false, details, filter);
entry.push_back(Pair("details", details)); entry.push_back(Pair("details", details));
string strHex = EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags()); string strHex = EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags());
@ -1844,7 +1847,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
UniValue abandontransaction(const JSONRPCRequest& request) UniValue abandontransaction(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -1879,7 +1882,7 @@ UniValue abandontransaction(const JSONRPCRequest& request)
UniValue backupwallet(const JSONRPCRequest& request) UniValue backupwallet(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
@ -1905,14 +1908,14 @@ UniValue backupwallet(const JSONRPCRequest& request)
UniValue keypoolrefill(const JSONRPCRequest& request) UniValue keypoolrefill(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 1) if (request.fHelp || request.params.size() > 1)
throw runtime_error( throw runtime_error(
"keypoolrefill ( newsize )\n" "keypoolrefill ( newsize )\n"
"\nFills the keypool." "\nFills the keypool."
+ HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n"
"\nArguments\n" "\nArguments\n"
"1. newsize (numeric, optional, default=100) The new keypool size\n" "1. newsize (numeric, optional, default=100) The new keypool size\n"
"\nExamples:\n" "\nExamples:\n"
@ -1930,7 +1933,7 @@ UniValue keypoolrefill(const JSONRPCRequest& request)
kpSize = (unsigned int)request.params[0].get_int(); kpSize = (unsigned int)request.params[0].get_int();
} }
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked(pwalletMain);
pwalletMain->TopUpKeyPool(kpSize); pwalletMain->TopUpKeyPool(kpSize);
if (pwalletMain->GetKeyPoolSize() < kpSize) if (pwalletMain->GetKeyPoolSize() < kpSize)
@ -1949,7 +1952,7 @@ static void LockWallet(CWallet* pWallet)
UniValue walletpassphrase(const JSONRPCRequest& request) UniValue walletpassphrase(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2))
@ -2009,7 +2012,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
UniValue walletpassphrasechange(const JSONRPCRequest& request) UniValue walletpassphrasechange(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2))
@ -2055,7 +2058,7 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request)
UniValue walletlock(const JSONRPCRequest& request) UniValue walletlock(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0))
@ -2094,7 +2097,7 @@ UniValue walletlock(const JSONRPCRequest& request)
UniValue encryptwallet(const JSONRPCRequest& request) UniValue encryptwallet(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1)) if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1))
@ -2151,7 +2154,7 @@ UniValue encryptwallet(const JSONRPCRequest& request)
UniValue lockunspent(const JSONRPCRequest& request) UniValue lockunspent(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
@ -2240,7 +2243,7 @@ UniValue lockunspent(const JSONRPCRequest& request)
UniValue listlockunspent(const JSONRPCRequest& request) UniValue listlockunspent(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 0) if (request.fHelp || request.params.size() > 0)
@ -2289,7 +2292,7 @@ UniValue listlockunspent(const JSONRPCRequest& request)
UniValue settxfee(const JSONRPCRequest& request) UniValue settxfee(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
@ -2316,7 +2319,7 @@ UniValue settxfee(const JSONRPCRequest& request)
UniValue getwalletinfo(const JSONRPCRequest& request) UniValue getwalletinfo(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 0) if (request.fHelp || request.params.size() != 0)
@ -2362,7 +2365,7 @@ UniValue getwalletinfo(const JSONRPCRequest& request)
UniValue resendwallettransactions(const JSONRPCRequest& request) UniValue resendwallettransactions(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() != 0) if (request.fHelp || request.params.size() != 0)
@ -2390,7 +2393,7 @@ UniValue resendwallettransactions(const JSONRPCRequest& request)
UniValue listunspent(const JSONRPCRequest& request) UniValue listunspent(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() > 4) if (request.fHelp || request.params.size() > 4)
@ -2514,7 +2517,7 @@ UniValue listunspent(const JSONRPCRequest& request)
UniValue fundrawtransaction(const JSONRPCRequest& request) UniValue fundrawtransaction(const JSONRPCRequest& request)
{ {
if (!EnsureWalletIsAvailable(request.fHelp)) if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp))
return NullUniValue; return NullUniValue;
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
@ -2674,7 +2677,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
// calculation, but we should be able to refactor after priority is removed). // calculation, but we should be able to refactor after priority is removed).
// NOTE: this requires that all inputs must be in mapWallet (eg the tx should // NOTE: this requires that all inputs must be in mapWallet (eg the tx should
// be IsAllFromMe). // be IsAllFromMe).
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx) int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, CWallet &wallet)
{ {
CMutableTransaction txNew(tx); CMutableTransaction txNew(tx);
std::vector<pair<CWalletTx *, unsigned int>> vCoins; std::vector<pair<CWalletTx *, unsigned int>> vCoins;
@ -2682,11 +2685,11 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx)
// IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our
// wallet, with a valid index into the vout array. // wallet, with a valid index into the vout array.
for (auto& input : tx.vin) { for (auto& input : tx.vin) {
const auto mi = pwalletMain->mapWallet.find(input.prevout.hash); const auto mi = wallet.mapWallet.find(input.prevout.hash);
assert(mi != pwalletMain->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); assert(mi != wallet.mapWallet.end() && input.prevout.n < mi->second.tx->vout.size());
vCoins.emplace_back(make_pair(&(mi->second), input.prevout.n)); vCoins.emplace_back(make_pair(&(mi->second), input.prevout.n));
} }
if (!pwalletMain->DummySignTx(txNew, vCoins)) { if (!wallet.DummySignTx(txNew, vCoins)) {
// This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
// implies that we can sign for every input. // implies that we can sign for every input.
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that cannot be signed"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that cannot be signed");
@ -2802,7 +2805,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
// Calculate the expected size of the new transaction. // Calculate the expected size of the new transaction.
int64_t txSize = GetVirtualTransactionSize(*(wtx.tx)); int64_t txSize = GetVirtualTransactionSize(*(wtx.tx));
const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx); const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx, *pwallet);
// optional parameters // optional parameters
bool specifiedConfirmTarget = false; bool specifiedConfirmTarget = false;

Loading…
Cancel
Save