From 8aa93b98e1b69ffafb66af4482b07cc262e7700c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 9 Mar 2017 20:29:01 +0000 Subject: [PATCH 01/27] Bugfix: wallet: Increment "update counter" only after actually making the applicable db changes to avoid potential races Also does all "update counter" access via IncrementUpdateCounter --- src/wallet/walletdb.cpp | 105 ++++++++++++++-------------------------- src/wallet/walletdb.h | 21 ++++++++ 2 files changed, 57 insertions(+), 69 deletions(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 0e7b50007caf..16a0bbf814bd 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -69,48 +69,39 @@ static std::atomic nWalletDBUpdateCounter; bool CWalletDB::WriteName(const std::string& strAddress, const std::string& strName) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::NAME), strAddress), strName); + return WriteIC(std::make_pair(std::string(DBKeys::NAME), strAddress), strName); } bool CWalletDB::EraseName(const std::string& strAddress) { // This should only be used for sending addresses, never for receiving addresses, // receiving addresses must always have an address book entry if they're not change return. - nWalletDBUpdateCounter++; - return batch.Erase(std::make_pair(std::string(DBKeys::NAME), strAddress)); + return EraseIC(std::make_pair(std::string(DBKeys::NAME), strAddress)); } bool CWalletDB::WritePurpose(const std::string& strAddress, const std::string& strPurpose) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::PURPOSE), strAddress), strPurpose); + return WriteIC(std::make_pair(std::string(DBKeys::PURPOSE), strAddress), strPurpose); } bool CWalletDB::ErasePurpose(const std::string& strPurpose) { - nWalletDBUpdateCounter++; - return batch.Erase(std::make_pair(std::string(DBKeys::PURPOSE), strPurpose)); + return EraseIC(std::make_pair(std::string(DBKeys::PURPOSE), strPurpose)); } bool CWalletDB::WriteTx(const CWalletTx& wtx) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::TX), wtx.GetHash()), wtx); + return WriteIC(std::make_pair(std::string(DBKeys::TX), wtx.GetHash()), wtx); } bool CWalletDB::EraseTx(uint256 hash) { - nWalletDBUpdateCounter++; - return batch.Erase(std::make_pair(std::string(DBKeys::TX), hash)); + return EraseIC(std::make_pair(std::string(DBKeys::TX), hash)); } bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta) { - nWalletDBUpdateCounter++; - - if (!batch.Write(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), - keyMeta, false)) + if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta, false)) return false; // hash pubkey/privkey to accelerate wallet load @@ -119,7 +110,7 @@ bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, c vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end()); vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end()); - return batch.Write(std::make_pair(std::string(DBKeys::KEY), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false); + return WriteIC(std::make_pair(std::string(DBKeys::KEY), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false); } bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, @@ -127,17 +118,16 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, const CKeyMetadata& keyMeta) { const bool fEraseUnencryptedKey = true; - nWalletDBUpdateCounter++; - if (!batch.Write(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), - keyMeta)) + if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta)) return false; - if (!batch.Write(std::make_pair(std::string(DBKeys::CRYPTED_KEY), vchPubKey), vchCryptedSecret, false)) + if (!WriteIC(std::make_pair(std::string(DBKeys::CRYPTED_KEY), vchPubKey), vchCryptedSecret, false)) return false; if (fEraseUnencryptedKey) { - batch.Erase(std::make_pair(std::string(DBKeys::KEY), vchPubKey)); + EraseIC(std::make_pair(std::string(DBKeys::KEY), vchPubKey)); } + return true; } @@ -145,21 +135,17 @@ bool CWalletDB::WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta) { - nWalletDBUpdateCounter++; - - if (!batch.Write(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) + if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) return false; - return batch.Write(std::make_pair(std::string(DBKeys::SAP_KEY), ivk), key, false); + return WriteIC(std::make_pair(std::string(DBKeys::SAP_KEY), ivk), key, false); } bool CWalletDB::WriteSaplingPaymentAddress( const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk) { - nWalletDBUpdateCounter++; - - return batch.Write(std::make_pair(std::string(DBKeys::SAP_ADDR), addr), ivk, false); + return WriteIC(std::make_pair(std::string(DBKeys::SAP_ADDR), addr), ivk, false); } bool CWalletDB::WriteCryptedSaplingZKey( @@ -168,25 +154,23 @@ bool CWalletDB::WriteCryptedSaplingZKey( const CKeyMetadata &keyMeta) { const bool fEraseUnencryptedKey = true; - nWalletDBUpdateCounter++; auto ivk = extfvk.fvk.in_viewing_key(); - if (!batch.Write(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) + if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) return false; - if (!batch.Write(std::make_pair(std::string(DBKeys::SAP_KEY_CRIPTED), ivk), std::make_pair(extfvk, vchCryptedSecret), false)) + if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEY_CRIPTED), ivk), std::make_pair(extfvk, vchCryptedSecret), false)) return false; if (fEraseUnencryptedKey) { - batch.Erase(std::make_pair(std::string(DBKeys::SAP_KEY), ivk)); + EraseIC(std::make_pair(std::string(DBKeys::SAP_KEY), ivk)); } return true; } bool CWalletDB::WriteSaplingCommonOVK(const uint256& ovk) { - nWalletDBUpdateCounter++; - return batch.Write(std::string(DBKeys::SAP_COMMON_OVK), ovk); + return WriteIC(std::string(DBKeys::SAP_COMMON_OVK), ovk); } bool CWalletDB::ReadSaplingCommonOVK(uint256& ovkRet) @@ -196,40 +180,33 @@ bool CWalletDB::ReadSaplingCommonOVK(uint256& ovkRet) bool CWalletDB::WriteWitnessCacheSize(int64_t nWitnessCacheSize) { - nWalletDBUpdateCounter++; - return batch.Write(std::string(DBKeys::SAP_WITNESS_CACHE_SIZE), nWitnessCacheSize); + return WriteIC(std::string(DBKeys::SAP_WITNESS_CACHE_SIZE), nWitnessCacheSize); } bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::MASTER_KEY), nID), kMasterKey, true); + return WriteIC(std::make_pair(std::string(DBKeys::MASTER_KEY), nID), kMasterKey, true); } bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::CSCRIPT), hash), redeemScript, false); + return WriteIC(std::make_pair(std::string(DBKeys::CSCRIPT), hash), redeemScript, false); } bool CWalletDB::WriteWatchOnly(const CScript& dest) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::WATCHS), dest), '1'); + return WriteIC(std::make_pair(std::string(DBKeys::WATCHS), dest), '1'); } bool CWalletDB::EraseWatchOnly(const CScript& dest) { - - nWalletDBUpdateCounter++; - return batch.Erase(std::make_pair(std::string(DBKeys::WATCHS), dest)); + return EraseIC(std::make_pair(std::string(DBKeys::WATCHS), dest)); } bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) { - nWalletDBUpdateCounter++; - batch.Write(std::string(DBKeys::BESTBLOCK), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan - return batch.Write(std::string(DBKeys::BESTBLOCK_NOMERKLE), locator); + WriteIC(std::string(DBKeys::BESTBLOCK), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan + return WriteIC(std::string(DBKeys::BESTBLOCK_NOMERKLE), locator); } bool CWalletDB::ReadBestBlock(CBlockLocator& locator) @@ -240,35 +217,30 @@ bool CWalletDB::ReadBestBlock(CBlockLocator& locator) bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext) { - nWalletDBUpdateCounter++; - return batch.Write(std::string(DBKeys::ORDERPOSNEXT), nOrderPosNext); + return WriteIC(std::string(DBKeys::ORDERPOSNEXT), nOrderPosNext); } bool CWalletDB::WriteStakeSplitThreshold(const CAmount& nStakeSplitThreshold) { - nWalletDBUpdateCounter++; - return batch.Write(std::string(DBKeys::STAKE_SPLIT_THRESHOLD), nStakeSplitThreshold); + return WriteIC(std::string(DBKeys::STAKE_SPLIT_THRESHOLD), nStakeSplitThreshold); } bool CWalletDB::WriteUseCustomFee(bool fUse) { - nWalletDBUpdateCounter++; - return batch.Write(std::string(DBKeys::USE_CUSTOM_FEE), fUse); + return WriteIC(std::string(DBKeys::USE_CUSTOM_FEE), fUse); } bool CWalletDB::WriteCustomFeeValue(const CAmount& nFee) { - nWalletDBUpdateCounter++; - return batch.Write(std::string(DBKeys::CUSTOM_FEE_VALUE), nFee); + return WriteIC(std::string(DBKeys::CUSTOM_FEE_VALUE), nFee); } bool CWalletDB::WriteAutoCombineSettings(bool fEnable, CAmount nCombineThreshold) { - nWalletDBUpdateCounter++; std::pair pSettings; pSettings.first = fEnable; pSettings.second = nCombineThreshold; - return batch.Write(std::string(DBKeys::AUTOCOMBINE), pSettings, true); + return WriteIC(std::string(DBKeys::AUTOCOMBINE), pSettings, true); } bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool) @@ -278,14 +250,12 @@ bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool) bool CWalletDB::WritePool(int64_t nPool, const CKeyPool& keypool) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::POOL), nPool), keypool); + return WriteIC(std::make_pair(std::string(DBKeys::POOL), nPool), keypool); } bool CWalletDB::ErasePool(int64_t nPool) { - nWalletDBUpdateCounter++; - return batch.Erase(std::make_pair(std::string(DBKeys::POOL), nPool)); + return EraseIC(std::make_pair(std::string(DBKeys::POOL), nPool)); } bool CWalletDB::WriteMinVersion(int nVersion) @@ -295,10 +265,9 @@ bool CWalletDB::WriteMinVersion(int nVersion) bool CWalletDB::WriteHDChain(const CHDChain& chain) { - nWalletDBUpdateCounter++; std::string key = chain.chainType == HDChain::ChainCounterType::Sapling ? DBKeys::SAP_HDCHAIN : DBKeys::HDCHAIN; - return batch.Write(key, chain); + return WriteIC(key, chain); } DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) @@ -1140,14 +1109,12 @@ bool CWalletDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path bool CWalletDB::WriteDestData(const std::string& address, const std::string& key, const std::string& value) { - nWalletDBUpdateCounter++; - return batch.Write(std::make_pair(std::string(DBKeys::DESTDATA), std::make_pair(address, key)), value); + return WriteIC(std::make_pair(std::string(DBKeys::DESTDATA), std::make_pair(address, key)), value); } bool CWalletDB::EraseDestData(const std::string& address, const std::string& key) { - nWalletDBUpdateCounter++; - return batch.Erase(std::make_pair(std::string(DBKeys::DESTDATA), std::make_pair(address, key))); + return EraseIC(std::make_pair(std::string(DBKeys::DESTDATA), std::make_pair(address, key))); } void CWalletDB::IncrementUpdateCounter() diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 981750975fdb..5b26f0185903 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -114,6 +114,27 @@ class CKeyMetadata */ class CWalletDB { +private: + template + bool WriteIC(const K& key, const T& value, bool fOverwrite = true) + { + if (!batch.Write(key, value, fOverwrite)) { + return false; + } + IncrementUpdateCounter(); + return true; + } + + template + bool EraseIC(const K& key) + { + if (!batch.Erase(key)) { + return false; + } + IncrementUpdateCounter(); + return true; + } + public: CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : batch(dbw, pszMode, _fFlushOnClose) From 8edb74f54ecd675a29a88fb45f9c0dbaa8611104 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Fri, 2 Apr 2021 19:10:37 +0200 Subject: [PATCH 02/27] Bug: increment counter when writing minversion --- src/wallet/walletdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 16a0bbf814bd..7da29dfbf506 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -260,7 +260,7 @@ bool CWalletDB::ErasePool(int64_t nPool) bool CWalletDB::WriteMinVersion(int nVersion) { - return batch.Write(std::string(DBKeys::MINVERSION), nVersion); + return WriteIC(std::string(DBKeys::MINVERSION), nVersion); } bool CWalletDB::WriteHDChain(const CHDChain& chain) From 9cfb711242be87755dabdcb137022abed5b14510 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 9 Mar 2017 20:56:58 +0000 Subject: [PATCH 03/27] CWalletDB: Store the update counter per wallet --- src/wallet/db.cpp | 10 ++++++++++ src/wallet/db.h | 5 +++++ src/wallet/wallet.cpp | 2 +- src/wallet/walletdb.cpp | 27 +++++++++------------------ src/wallet/walletdb.h | 11 +++++------ 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 7ea9dfbab1e8..639a61b236fe 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -428,6 +428,16 @@ void CDB::Flush() env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0); } +void CWalletDBWrapper::IncrementUpdateCounter() +{ + ++nUpdateCounter; +} + +unsigned int CWalletDBWrapper::GetUpdateCounter() +{ + return nUpdateCounter.load(); +} + void CDB::Close() { if (!pdb) diff --git a/src/wallet/db.h b/src/wallet/db.h index a280a64007bf..22c4380a8206 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -14,6 +14,7 @@ #include "sync.h" #include "version.h" +#include #include #include #include @@ -121,10 +122,14 @@ class CWalletDBWrapper */ void Flush(bool shutdown); + void IncrementUpdateCounter(); + unsigned int GetUpdateCounter(); + private: /** BerkeleyDB specific */ CDBEnv *env; std::string strFile; + std::atomic nUpdateCounter; /** Return whether this database handle is a dummy for testing. * Only to be used at a low level, application should ideally not care diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d7a9b7aa054d..1f65b973da67 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4309,7 +4309,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) } LogPrintf("Rescan completed in %15dms\n", GetTimeMillis() - nWalletRescanTime); walletInstance->SetBestChain(chainActive.GetLocator()); - CWalletDB::IncrementUpdateCounter(); + walletInstance->dbw->IncrementUpdateCounter(); // Restore wallet transaction metadata after -zapwallettxes=1 if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.GetArg("-zapwallettxes", "1") != "2") { diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 7da29dfbf506..7022096983a4 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -61,7 +61,6 @@ namespace DBKeys { } // namespace DBKeys -static std::atomic nWalletDBUpdateCounter; // // CWalletDB @@ -798,18 +797,20 @@ void MaybeCompactWalletDB() return; } - static unsigned int nLastSeen = CWalletDB::GetUpdateCounter(); - static unsigned int nLastFlushed = CWalletDB::GetUpdateCounter(); + CWalletDBWrapper& dbh = pwalletMain->GetDBHandle(); + + static unsigned int nLastSeen = dbh.GetUpdateCounter(); + static unsigned int nLastFlushed = dbh.GetUpdateCounter(); static int64_t nLastWalletUpdate = GetTime(); - if (nLastSeen != CWalletDB::GetUpdateCounter()) { - nLastSeen = CWalletDB::GetUpdateCounter(); + if (nLastSeen != dbh.GetUpdateCounter()) { + nLastSeen = dbh.GetUpdateCounter(); nLastWalletUpdate = GetTime(); } - if (nLastFlushed != CWalletDB::GetUpdateCounter() && GetTime() - nLastWalletUpdate >= 2) { - if (CDB::PeriodicFlush(pwalletMain->GetDBHandle())) { - nLastFlushed = CWalletDB::GetUpdateCounter(); + if (nLastFlushed != dbh.GetUpdateCounter() && GetTime() - nLastWalletUpdate >= 2) { + if (CDB::PeriodicFlush(dbh)) { + nLastFlushed = dbh.GetUpdateCounter(); } } fOneThread = false; @@ -1117,16 +1118,6 @@ bool CWalletDB::EraseDestData(const std::string& address, const std::string& key return EraseIC(std::make_pair(std::string(DBKeys::DESTDATA), std::make_pair(address, key))); } -void CWalletDB::IncrementUpdateCounter() -{ - nWalletDBUpdateCounter++; -} - -unsigned int CWalletDB::GetUpdateCounter() -{ - return nWalletDBUpdateCounter; -} - bool CWalletDB::TxnBegin() { return batch.TxnBegin(); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 5b26f0185903..ea9fca79a35b 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -121,7 +121,7 @@ class CWalletDB if (!batch.Write(key, value, fOverwrite)) { return false; } - IncrementUpdateCounter(); + m_dbw.IncrementUpdateCounter(); return true; } @@ -131,13 +131,14 @@ class CWalletDB if (!batch.Erase(key)) { return false; } - IncrementUpdateCounter(); + m_dbw.IncrementUpdateCounter(); return true; } public: CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : - batch(dbw, pszMode, _fFlushOnClose) + batch(dbw, pszMode, _fFlushOnClose), + m_dbw(dbw) { } @@ -218,9 +219,6 @@ class CWalletDB /* verifies the database file */ static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr); - static void IncrementUpdateCounter(); - static unsigned int GetUpdateCounter(); - //! Begin a new transaction bool TxnBegin(); //! Commit current transaction @@ -233,6 +231,7 @@ class CWalletDB bool WriteVersion(int nVersion); private: CDB batch; + CWalletDBWrapper& m_dbw; CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); From f9d7fe13fbdffe74d6e660df0a38f697010a6af8 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 11:43:32 +0200 Subject: [PATCH 04/27] refactor: move bdb (bitdb) interaction from init.cpp to wallet.cpp >>> based on bitcoin@2bb1c87700a80f0b20b4b2cbd68a0d82a18dbcc0 this will remove db.h from init.cpp --- src/init.cpp | 9 ++++----- src/wallet/wallet.cpp | 5 +++++ src/wallet/wallet.h | 3 +++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 002ff1f954b3..80f59edd872e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,10 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin developers +// Copyright (c) 2009-2021 The Bitcoin developers // Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2011-2013 The PPCoin developers // Copyright (c) 2013-2014 The NovaCoin Developers // Copyright (c) 2014-2018 The BlackCoin Developers -// Copyright (c) 2015-2020 The PIVX developers +// Copyright (c) 2015-2021 The PIVX developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -58,7 +58,6 @@ #include "zpivchain.h" #ifdef ENABLE_WALLET -#include "wallet/db.h" #include "wallet/wallet.h" #include "wallet/rpcwallet.h" @@ -223,7 +222,7 @@ void PrepareShutdown() StopHTTPServer(); #ifdef ENABLE_WALLET if (pwalletMain) - bitdb.Flush(false); + pwalletMain->Flush(false); GenerateBitcoins(false, NULL, 0); #endif StopMapPort(); @@ -303,7 +302,7 @@ void PrepareShutdown() } #ifdef ENABLE_WALLET if (pwalletMain) - bitdb.Flush(true); + pwalletMain->Flush(true); #endif if (pEvoNotificationInterface) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1f65b973da67..401aaa5daa2d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2069,6 +2069,11 @@ std::set CWalletTx::GetConflicts() const return result; } +void CWallet::Flush(bool shutdown) +{ + bitdb.Flush(shutdown); +} + bool CWallet::Verify() { if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 545bef77de88..5acc189af31e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1128,6 +1128,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface //! Get wallet transactions that conflict with given transaction (spend same outputs) std::set GetConflicts(const uint256& txid) const; + //! Flush wallet (bitdb flush) + void Flush(bool shutdown=false); + //! Verify the wallet database and perform salvage if required static bool Verify(); From dc2e0227b4f919e81619159a9bfa4dfaf4bee58d Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 11:44:01 +0200 Subject: [PATCH 05/27] [Refactor] fix WalletTestingSetup fixture --- src/wallet/test/wallet_test_fixture.cpp | 25 ++++++++++--------------- src/wallet/test/wallet_test_fixture.h | 10 ++++++---- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index cbfeaca0e3fe..df083e6db1c6 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2016 The Bitcoin Core developers -// Copyright (c) 2020 The PIVX developers +// Copyright (c) 2016-2021 The Bitcoin Core developers +// Copyright (c) 2020-2021 The PIVX developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,34 +7,29 @@ #include "rpc/server.h" #include "wallet/db.h" -#include "wallet/wallet.h" #include "wallet/rpcwallet.h" - -void clean() -{ - delete pwalletMain; - pwalletMain = nullptr; - - bitdb.Flush(true); - bitdb.Reset(); -} +#include "wallet/wallet.h" WalletTestingSetup::WalletTestingSetup(const std::string& chainName): SaplingTestingSetup(chainName) { - clean(); // todo: research why we have an initialized bitdb here. bitdb.MakeMock(); - RegisterWalletRPCCommands(tableRPC); bool fFirstRun; std::unique_ptr dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat")); pwalletMain = new CWallet(std::move(dbw)); pwalletMain->LoadWallet(fFirstRun); RegisterValidationInterface(pwalletMain); + + RegisterWalletRPCCommands(tableRPC); } WalletTestingSetup::~WalletTestingSetup() { UnregisterValidationInterface(pwalletMain); - clean(); + delete pwalletMain; + pwalletMain = nullptr; + + bitdb.Flush(true); + bitdb.Reset(); } diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h index 616ce9926214..85579febf5d1 100644 --- a/src/wallet/test/wallet_test_fixture.h +++ b/src/wallet/test/wallet_test_fixture.h @@ -1,12 +1,14 @@ -// Copyright (c) 2016 The Bitcoin Core developers +// Copyright (c) 2016-2021 The Bitcoin Core developers +// Copyright (c) 2020-2021 The PIVX developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_WALLET_TEST_FIXTURE_H -#define BITCOIN_WALLET_TEST_FIXTURE_H +#ifndef PIVX_WALLET_TEST_FIXTURE_H +#define PIVX_WALLET_TEST_FIXTURE_H #include "test/librust/sapling_test_fixture.h" + /** Testing setup and teardown for wallet. */ struct WalletTestingSetup : public SaplingTestingSetup @@ -20,5 +22,5 @@ struct WalletRegTestingSetup : public WalletTestingSetup WalletRegTestingSetup() : WalletTestingSetup(CBaseChainParams::REGTEST) {} }; -#endif +#endif // PIVX_WALLET_TEST_FIXTURE_H From fb64bbc60a2734bbb824d3ce9c5b157816b47832 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 11:53:53 +0200 Subject: [PATCH 06/27] [Doc] Remove ThreadFlushWalletDB from developer notes It was removed in #2150 --- doc/developer-notes.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 16c2170cbc6d..5a12586d56c2 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -301,8 +301,6 @@ Threads - DumpAddresses : Dumps IP addresses of nodes to peers.dat. -- ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms. - - ThreadRPCServer : Remote procedure call handler, listens on port 8332 for connections and services them. - BitcoinMiner : Generates PIVs (if wallet is enabled). From a8dd236c1869785dae6a60cf4bdc8bdb8e3367aa Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 17:28:31 +0200 Subject: [PATCH 07/27] RPC/Wallet: Pass CWallet as pointer to helper functions >>> inspired by bitcoin@eca550f2501f3f2bbe682bdc3cb8b90c90c90275 --- src/rest.cpp | 4 +- src/rpc/blockchain.cpp | 4 +- src/rpc/budget.cpp | 5 +- src/rpc/masternode.cpp | 9 +- src/rpc/mining.cpp | 10 +- src/rpc/misc.cpp | 59 ++--- src/rpc/rawtransaction.cpp | 17 +- src/rpc/rpcevo.cpp | 44 ++-- src/rpc/server.h | 13 +- src/wallet/rpcdump.cpp | 192 +++++++++------- src/wallet/rpcwallet.cpp | 451 +++++++++++++++++++++++++------------ 11 files changed, 506 insertions(+), 302 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index bfe3f0a021e1..217a014bf2ce 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -60,7 +60,7 @@ struct CCoin { } }; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); extern UniValue mempoolInfoToJSON(); extern UniValue mempoolToJSON(bool fVerbose = false); @@ -373,7 +373,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) case RF_JSON: { UniValue objTx(UniValue::VOBJ); - TxToJSON(*tx, hashBlock, objTx); + TxToJSON(nullptr, *tx, hashBlock, objTx); std::string strJSON = objTx.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a3d8d975e68a..bdc5461fed9d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -42,7 +42,7 @@ static std::mutex cs_blockchange; static std::condition_variable cond_blockchange; static CUpdatedBlock latestblock; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry); UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request) { @@ -147,7 +147,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx const CTransaction& tx = *txIn; if (txDetails) { UniValue objTx(UniValue::VOBJ); - TxToJSON(tx, UINT256_ZERO, objTx); + TxToJSON(nullptr, tx, UINT256_ZERO, objTx); txs.push_back(objTx); } else txs.push_back(tx.GetHash().GetHex()); diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 071a894a6b3b..1cc3ce2ef858 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -97,6 +97,9 @@ void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std UniValue preparebudget(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 6) throw std::runtime_error( "preparebudget \"proposal-name\" \"url\" payment-count block-start \"pivx-address\" monthy-payment\n" @@ -123,7 +126,7 @@ UniValue preparebudget(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); std::string strProposalName; std::string strURL; diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 4bdcd83d70de..08aec8b103b5 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -402,7 +402,7 @@ UniValue startmasternode(const JSONRPCRequest& request) bool fLock = (request.params[1].get_str() == "true" ? true : false); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); if (strCommand == "local") { if (!fMasterNode) throw std::runtime_error("you must set masternode=1 in the configuration\n"); @@ -807,6 +807,9 @@ bool DecodeHexMnb(CMasternodeBroadcast& mnb, std::string strHexMnb) { } UniValue createmasternodebroadcast(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + std::string strCommand; if (request.params.size() >= 1) strCommand = request.params[0].get_str(); @@ -814,7 +817,7 @@ UniValue createmasternodebroadcast(const JSONRPCRequest& request) throw std::runtime_error( "createmasternodebroadcast \"command\" ( \"alias\")\n" "\nCreates a masternode broadcast message for one or all masternodes configured in masternode.conf\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"command\" (string, required) \"alias\" for single masternode, \"all\" for all masternodes\n" @@ -845,7 +848,7 @@ UniValue createmasternodebroadcast(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("createmasternodebroadcast", "alias mymn1") + HelpExampleRpc("createmasternodebroadcast", "alias mymn1")); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); if (strCommand == "alias") { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 2fe468f85006..e01abbafd56e 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -76,6 +76,9 @@ UniValue generateBlocks(const Consensus::Params& consensus, UniValue generate(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) throw std::runtime_error( "generate numblocks\n" @@ -113,7 +116,7 @@ UniValue generate(const JSONRPCRequest& request) if (fPoS) { // If we are in PoS, wallet must be unlocked. - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); } else { // Coinbase key reservekey = MakeUnique(pwalletMain); @@ -273,6 +276,9 @@ UniValue getgenerate(const JSONRPCRequest& request) UniValue setgenerate(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "setgenerate generate ( genproclimit )\n" @@ -291,8 +297,6 @@ UniValue setgenerate(const JSONRPCRequest& request) "\nTurn off generation\n" + HelpExampleCli("setgenerate", "false") + "\nUsing json rpc\n" + HelpExampleRpc("setgenerate", "true, 1")); - EnsureWallet(); - if (Params().IsRegTestNet()) throw JSONRPCError(RPC_INVALID_REQUEST, "Use the generate method instead of setgenerate on regtest"); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 7ae80a8d0235..3a7b4d1fa472 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -227,7 +227,9 @@ class DescribeAddressVisitor : public boost::static_visitor isminetype mine; public: - DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {} + CWallet * const pwallet; + + DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } @@ -235,8 +237,7 @@ class DescribeAddressVisitor : public boost::static_visitor UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.pushKV("isscript", false); - if (bool(mine & ISMINE_ALL)) { - pwalletMain->GetPubKey(keyID, vchPubKey); + if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) { obj.pushKV("pubkey", HexStr(vchPubKey)); obj.pushKV("iscompressed", vchPubKey.IsCompressed()); } @@ -247,19 +248,20 @@ class DescribeAddressVisitor : public boost::static_visitor UniValue obj(UniValue::VOBJ); obj.pushKV("isscript", true); CScript subscript; - pwalletMain->GetCScript(scriptID, subscript); - std::vector addresses; - txnouttype whichType; - int nRequired; - ExtractDestinations(subscript, whichType, addresses, nRequired); - obj.pushKV("script", GetTxnOutputType(whichType)); - obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); - UniValue a(UniValue::VARR); - for (const CTxDestination& addr : addresses) - a.push_back(EncodeDestination(addr)); - obj.pushKV("addresses", a); - if (whichType == TX_MULTISIG) - obj.pushKV("sigsrequired", nRequired); + if (pwallet && pwallet->GetCScript(scriptID, subscript)) { + std::vector addresses; + txnouttype whichType; + int nRequired; + ExtractDestinations(subscript, whichType, addresses, nRequired); + obj.pushKV("script", GetTxnOutputType(whichType)); + obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); + UniValue a(UniValue::VARR); + for (const CTxDestination& addr : addresses) + a.push_back(EncodeDestination(addr)); + obj.pushKV("addresses", a); + if (whichType == TX_MULTISIG) + obj.pushKV("sigsrequired", nRequired); + } return obj; } }; @@ -334,7 +336,7 @@ typedef boost::variant { public: - explicit DescribePaymentAddressVisitor(bool _isStaking) : isStaking(_isStaking) {} + explicit DescribePaymentAddressVisitor(CWallet *_pwallet, bool _isStaking) : pwallet(_pwallet), isStaking(_isStaking) {} UniValue operator()(const libzcash::InvalidEncoding &zaddr) const { return UniValue(UniValue::VOBJ); } UniValue operator()(const libzcash::SaplingPaymentAddress &zaddr) const { @@ -342,8 +344,8 @@ class DescribePaymentAddressVisitor : public boost::static_visitor obj.pushKV("diversifier", HexStr(zaddr.d)); obj.pushKV("diversifiedtransmissionkey", zaddr.pk_d.GetHex()); #ifdef ENABLE_WALLET - if (pwalletMain) { - obj.pushKV("ismine", pwalletMain->HaveSpendingKeyForPaymentAddress(zaddr)); + if (pwallet) { + obj.pushKV("ismine", pwallet->HaveSpendingKeyForPaymentAddress(zaddr)); } #endif return obj; @@ -355,19 +357,20 @@ class DescribePaymentAddressVisitor : public boost::static_visitor ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())); #ifdef ENABLE_WALLET - isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; + isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO; ret.pushKV("ismine", bool(mine & (ISMINE_SPENDABLE_ALL | ISMINE_COLD))); ret.pushKV("isstaking", isStaking); ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); - UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); + UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest); ret.pushKVs(detail); - if (pwalletMain && pwalletMain->HasAddressBook(dest)) - ret.pushKV("label", pwalletMain->GetNameForAddressBookEntry(dest)); + if (pwallet && pwallet->HasAddressBook(dest)) + ret.pushKV("label", pwallet->GetNameForAddressBookEntry(dest)); #endif return ret; } private: + CWallet * const pwallet; bool isStaking{false}; }; @@ -429,7 +432,7 @@ UniValue validateaddress(const JSONRPCRequest& request) ret.pushKV("isvalid", isValid); if (isValid) { ret.pushKV("address", strAddress); - UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(isStakingAddress), finalAddress); + UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(pwalletMain, isStakingAddress), finalAddress); ret.pushKVs(detail); } @@ -439,7 +442,7 @@ UniValue validateaddress(const JSONRPCRequest& request) /** * 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(); const UniValue& keys = params[1].get_array(); @@ -461,14 +464,14 @@ CScript _createmultisig_redeemScript(const UniValue& params) #ifdef ENABLE_WALLET // Case 1: PIVX address and we have full public key: CTxDestination dest = DecodeDestination(ks); - if (pwalletMain && IsValidDestination(dest)) { + if (pwallet && IsValidDestination(dest)) { const CKeyID* keyID = boost::get(&dest); if (!keyID) { throw std::runtime_error( strprintf("%s does not refer to a key", ks)); } CPubKey vchPubKey; - if (!pwalletMain->GetPubKey(*keyID, vchPubKey)) + if (!pwallet->GetPubKey(*keyID, vchPubKey)) throw std::runtime_error( strprintf("no full public key for address %s", ks)); if (!vchPubKey.IsFullyValid()) @@ -526,7 +529,7 @@ UniValue createmultisig(const JSONRPCRequest& request) HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(request.params); + CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); CScriptID innerID(inner); UniValue result(UniValue::VOBJ); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index a5b526ff89fc..8fe6334a1da1 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -54,7 +54,8 @@ static void PayloadToJSON(const CTransaction& tx, UniValue& entry) } } -void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) +// pwallet can be nullptr. If not null, the json could include information available only to the wallet. +void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { // Call into TxToUniv() in bitcoin-common to decode the transaction hex. // @@ -64,11 +65,11 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) TxToUniv(tx, uint256(), entry); // Sapling - if (pwalletMain && tx.IsShieldedTx()) { + if (pwallet && tx.IsShieldedTx()) { // Add information that only this wallet knows about the transaction if is possible - if (pwalletMain->HasSaplingSPKM()) { + if (pwallet->HasSaplingSPKM()) { std::vector addresses = - pwalletMain->GetSaplingScriptPubKeyMan()->FindMySaplingAddresses(tx); + pwallet->GetSaplingScriptPubKeyMan()->FindMySaplingAddresses(tx); UniValue addrs(UniValue::VARR); for (const auto& addr : addresses) { addrs.push_back(KeyIO::EncodePaymentAddress(addr)); @@ -252,7 +253,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); if (blockindex) result.pushKV("in_active_chain", in_active_chain); - TxToJSON(*tx, hash_block, result); + TxToJSON(pwalletMain, *tx, hash_block, result); return result; } @@ -420,7 +421,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); UniValue result(UniValue::VOBJ); - TxToJSON(CTransaction(std::move(mtx)), UINT256_ZERO, result); + TxToJSON(pwalletMain, CTransaction(std::move(mtx)), UINT256_ZERO, result); return result; } @@ -610,7 +611,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) "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" #ifdef ENABLE_WALLET - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" #endif "\nArguments:\n" @@ -728,7 +729,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) } #ifdef ENABLE_WALLET else if (pwalletMain) - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); #endif // Add previous txouts given in the RPC call: diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 4e83f4deccad..9c0b977ca399 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -272,10 +272,9 @@ static std::string TxInErrorToString(int i, const CTxIn& txin, const std::string return strprintf("Input %d (%s): %s", i, txin.prevout.ToStringShort(), strError); } -static OperationResult SignTransaction(CMutableTransaction& tx) +static OperationResult SignTransaction(CWallet* const pwallet, CMutableTransaction& tx) { - EnsureWalletIsUnlocked(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); const CTransaction txConst(tx); for (unsigned int i = 0; i < tx.vin.size(); i++) { CTxIn& txin = tx.vin[i]; @@ -286,7 +285,7 @@ static OperationResult SignTransaction(CMutableTransaction& tx) SigVersion sv = tx.GetRequiredSigVersion(); txin.scriptSig.clear(); SignatureData sigdata; - if (!ProduceSignature(MutableTransactionSignatureCreator(pwalletMain, &tx, i, coin.out.nValue, SIGHASH_ALL), + if (!ProduceSignature(MutableTransactionSignatureCreator(pwallet, &tx, i, coin.out.nValue, SIGHASH_ALL), coin.out.scriptPubKey, sigdata, sv, false)) { return errorOut(TxInErrorToString(i, txin, "signature failed")); } @@ -295,11 +294,8 @@ static OperationResult SignTransaction(CMutableTransaction& tx) return OperationResult(true); } -static std::string SignAndSendSpecialTx(CMutableTransaction& tx, const ProRegPL& pl) +static std::string SignAndSendSpecialTx(CWallet* const pwallet, CMutableTransaction& tx, const ProRegPL& pl) { - EnsureWallet(); - EnsureWalletIsUnlocked(); - SetTxPayload(tx, pl); CValidationState state; @@ -307,7 +303,7 @@ static std::string SignAndSendSpecialTx(CMutableTransaction& tx, const ProRegPL& throw JSONRPCError(RPC_MISC_ERROR, FormatStateMessage(state)); } - const OperationResult& sigRes = SignTransaction(tx); + const OperationResult& sigRes = SignTransaction(pwallet, tx); if (!sigRes) { throw JSONRPCError(RPC_INTERNAL_ERROR, sigRes.getError()); } @@ -379,6 +375,9 @@ static ProRegPL ParseProRegPLParams(const UniValue& params, unsigned int paramId // handles protx_register, and protx_register_prepare static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 7 || request.params.size() > 9) { throw std::runtime_error( (fSignAndSend ? @@ -391,7 +390,7 @@ static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) "key and then passed to \"protx_register_submit\".\n" "The collateral is specified through \"collateralHash\" and \"collateralIndex\" and must be an unspent transaction output.\n" ) - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" + GetHelpString(1, collateralHash) + GetHelpString(2, collateralIndex) @@ -421,8 +420,7 @@ static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) } if (fSignAndSend) CheckEvoUpgradeEnforcement(); - EnsureWallet(); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); @@ -471,7 +469,7 @@ static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) if (fSignAndSend) { SignSpecialTxPayloadByString(pl, keyCollateral); // prove we own the collateral // check the payload, add the tx inputs sigs, and send the tx. - return SignAndSendSpecialTx(tx, pl); + return SignAndSendSpecialTx(pwalletMain, tx, pl); } // external signing with collateral key pl.vchSig.clear(); @@ -495,12 +493,15 @@ UniValue protx_register_prepare(const JSONRPCRequest& request) UniValue protx_register_submit(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 2) { throw std::runtime_error( "protx_register_submit \"tx\" \"sig\"\n" "\nSubmits the specified ProTx to the network. This command will also sign the inputs of the transaction\n" "which were previously added by \"protx_register_prepare\" to cover transaction fees\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"tx\" (string, required) The serialized transaction previously returned by \"protx_register_prepare\"\n" "2. \"sig\" (string, required) The signature signed with the collateral key. Must be in base64 format.\n" @@ -512,8 +513,7 @@ UniValue protx_register_submit(const JSONRPCRequest& request) } CheckEvoUpgradeEnforcement(); - EnsureWallet(); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); @@ -536,17 +536,20 @@ UniValue protx_register_submit(const JSONRPCRequest& request) pl.vchSig = DecodeBase64(request.params[1].get_str().c_str()); // check the payload, add the tx inputs sigs, and send the tx. - return SignAndSendSpecialTx(tx, pl); + return SignAndSendSpecialTx(pwalletMain, tx, pl); } UniValue protx_register_fund(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 6 || request.params.size() > 8) { throw std::runtime_error( "protx_register_fund \"collateralAddress\" \"ipAndPort\" \"ownerAddress\" \"operatorAddress\" \"votingAddress\" \"payoutAddress\" (operatorReward \"operatorPayoutAddress\")\n" "\nCreates, funds and sends a ProTx to the network. The resulting transaction will move 10000 PIV\n" "to the address specified by collateralAddress and will then function as masternode collateral.\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" + GetHelpString(1, collateralAddress) + GetHelpString(2, ipAndPort_register) @@ -564,8 +567,7 @@ UniValue protx_register_fund(const JSONRPCRequest& request) } CheckEvoUpgradeEnforcement(); - EnsureWallet(); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); @@ -594,7 +596,7 @@ UniValue protx_register_fund(const JSONRPCRequest& request) // update payload on tx (with final collateral outpoint) pl.vchSig.clear(); // check the payload, add the tx inputs sigs, and send the tx. - return SignAndSendSpecialTx(tx, pl); + return SignAndSendSpecialTx(pwalletMain, tx, pl); } #endif //ENABLE_WALLET diff --git a/src/rpc/server.h b/src/rpc/server.h index 37f7ba51aaec..71caf1754d47 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -194,13 +194,18 @@ extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const UniValue& value); extern UniValue ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); -extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(std::string methodname, std::string args); extern std::string HelpExampleRpc(std::string methodname, std::string args); -extern void EnsureWalletIsUnlocked(bool fAllowAnonOnly = false); -// Ensure the wallet's existence. -extern void EnsureWallet(); +// 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* const pwallet); +bool EnsureWalletIsAvailable(CWallet* const pwallet, bool avoidException); +void EnsureWalletIsUnlocked(CWallet *pwallet, bool fAllowAnonOnly = false); +#endif bool StartRPC(); void InterruptRPC(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index f476efde8d24..228be36ca926 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -76,11 +76,14 @@ bool IsStakingDerPath(KeyOriginInfo keyOrigin) UniValue importprivkey(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw std::runtime_error( "importprivkey \"pivxprivkey\" ( \"label\" rescan fStakingAddress )\n" "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"pivxprivkey\" (string, required) The private key (see dumpprivkey)\n" @@ -118,7 +121,7 @@ UniValue importprivkey(const JSONRPCRequest& request) CKeyID vchAddress = pubkey.GetID(); { LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); pwalletMain->MarkDirty(); pwalletMain->SetAddressBook(vchAddress, strLabel, ( @@ -146,6 +149,9 @@ UniValue importprivkey(const JSONRPCRequest& request) UniValue abortrescan(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 0) throw std::runtime_error( "abortrescan\n" @@ -159,43 +165,45 @@ UniValue abortrescan(const JSONRPCRequest& request) + HelpExampleRpc("abortrescan", "") ); - EnsureWallet(); if (!pwalletMain->IsScanning() || pwalletMain->IsAbortingRescan()) return false; pwalletMain->AbortRescan(); return true; } -void ImportAddress(const CTxDestination& dest, const std::string& strLabel, const std::string& strPurpose); +static void ImportAddress(CWallet* const pwallet, const CTxDestination& dest, const std::string& strLabel, const std::string& strPurpose); -void ImportScript(const CScript& script, const std::string& strLabel, bool isRedeemScript) +static void ImportScript(CWallet* const pwallet, const CScript& script, const std::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"); - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) + if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); 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"); - ImportAddress(CScriptID(script), strLabel, "receive"); + ImportAddress(pwallet, CScriptID(script), strLabel, "receive"); } } -void ImportAddress(const CTxDestination& dest, const std::string& strLabel, const std::string& strPurpose) +static void ImportAddress(CWallet* const pwallet, const CTxDestination& dest, const std::string& strLabel, const std::string& strPurpose) { CScript script = GetScriptForDestination(dest); - ImportScript(script, strLabel, false); + ImportScript(pwallet, script, strLabel, false); // add to address book or update label if (IsValidDestination(dest)) { - pwalletMain->SetAddressBook(dest, strLabel, strPurpose); + pwallet->SetAddressBook(dest, strLabel, strPurpose); } } UniValue importaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw std::runtime_error( "importaddress \"script\" ( \"label\" rescan )\n" @@ -237,13 +245,13 @@ UniValue importaddress(const JSONRPCRequest& request) if (IsValidDestination(dest)) { if (fP2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); - ImportAddress(dest, strLabel, isStakingAddress ? + ImportAddress(pwalletMain, dest, strLabel, isStakingAddress ? AddressBook::AddressBookPurpose::COLD_STAKING : AddressBook::AddressBookPurpose::RECEIVE); } else if (IsHex(request.params[0].get_str())) { std::vector 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 { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid PIVX address or script"); } @@ -258,6 +266,9 @@ UniValue importaddress(const JSONRPCRequest& request) UniValue importpubkey(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw std::runtime_error( "importpubkey \"pubkey\" ( \"label\" rescan )\n" @@ -296,8 +307,8 @@ UniValue importpubkey(const JSONRPCRequest& request) { LOCK2(cs_main, pwalletMain->cs_wallet); - ImportAddress(pubKey.GetID(), strLabel, "receive"); - ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); + ImportAddress(pwalletMain, pubKey.GetID(), strLabel, "receive"); + ImportScript(pwalletMain, GetScriptForRawPubKey(pubKey), strLabel, false); } if (fRescan) { pwalletMain->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */); @@ -310,11 +321,14 @@ UniValue importpubkey(const JSONRPCRequest& request) // TODO: Needs further review over the HD flow, staking addresses and multisig import. UniValue importwallet(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "importwallet \"filename\"\n" "\nImports keys from a wallet dump file (see dumpwallet).\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"filename\" (string, required) The wallet file\n" @@ -341,7 +355,7 @@ UniValue importwallet(const JSONRPCRequest& request) bool fGood = true; { LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); nTimeBegin = chainActive.Tip()->GetBlockTime(); int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg()); @@ -432,12 +446,15 @@ UniValue importwallet(const JSONRPCRequest& request) UniValue dumpprivkey(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "dumpprivkey \"pivxaddress\"\n" "\nReveals the private key corresponding to 'pivxaddress'.\n" "Then the importprivkey can be used with this output\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address for the private key\n" @@ -450,7 +467,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); std::string strAddress = request.params[0].get_str(); CTxDestination dest = DecodeDestination(strAddress); @@ -467,11 +484,14 @@ UniValue dumpprivkey(const JSONRPCRequest& request) UniValue dumpwallet(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "dumpwallet \"filename\"\n" "\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"filename\" (string, required) The filename\n" @@ -496,7 +516,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); ScriptPubKeyMan* spk_man = pwalletMain->GetScriptPubKeyMan(); @@ -613,7 +633,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) return reply; } -UniValue processImport(const UniValue& data, const int64_t timestamp) +static UniValue processImport(CWallet* const pwallet, const UniValue& data, const int64_t timestamp) { try { bool success = false; @@ -694,32 +714,32 @@ UniValue processImport(const UniValue& data, const int64_t timestamp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid P2SH address / script"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript)) { + if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript)) { 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"); } CTxDestination redeem_dest = CScriptID(redeemScript); CScript redeemDestination = GetScriptForDestination(redeem_dest); - 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"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination)) { + if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } // add to address book or update label if (IsValidDestination(dest)) { - pwalletMain->SetAddressBook(dest, label, "receive"); + pwallet->SetAddressBook(dest, label, "receive"); } // Import private keys. @@ -736,21 +756,21 @@ UniValue processImport(const UniValue& data, const int64_t timestamp) assert(key.VerifyPubKey(pubkey)); CKeyID vchAddress = pubkey.GetID(); - pwalletMain->MarkDirty(); - pwalletMain->SetAddressBook(vchAddress, label, "receive"); + pwallet->MarkDirty(); + pwallet->SetAddressBook(vchAddress, label, "receive"); - if (pwalletMain->HaveKey(vchAddress)) { + if (pwallet->HaveKey(vchAddress)) { 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"); } - if (timestamp < pwalletMain->nTimeFirstKey) { - pwalletMain->nTimeFirstKey = timestamp; + if (timestamp < pwallet->nTimeFirstKey) { + pwallet->nTimeFirstKey = timestamp; } } } @@ -789,31 +809,31 @@ UniValue processImport(const UniValue& data, const int64_t timestamp) CScript pubKeyScript = GetScriptForDestination(pubkey_dest); - 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"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript)) { + if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } // add to address book or update label if (IsValidDestination(pubkey_dest)) { - pwalletMain->SetAddressBook(pubkey_dest, label, "receive"); + pwallet->SetAddressBook(pubkey_dest, label, "receive"); } // TODO Is this necessary? 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"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey)) { + if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -848,21 +868,21 @@ UniValue processImport(const UniValue& data, const int64_t timestamp) } CKeyID vchAddress = pubKey.GetID(); - pwalletMain->MarkDirty(); - pwalletMain->SetAddressBook(vchAddress, label, "receive"); + pwallet->MarkDirty(); + pwallet->SetAddressBook(vchAddress, label, "receive"); - if (pwalletMain->HaveKey(vchAddress)) { + if (pwallet->HaveKey(vchAddress)) { throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); } - 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"); } - if (timestamp < pwalletMain->nTimeFirstKey) { - pwalletMain->nTimeFirstKey = timestamp; + if (timestamp < pwallet->nTimeFirstKey) { + pwallet->nTimeFirstKey = timestamp; } success = true; @@ -870,20 +890,20 @@ UniValue processImport(const UniValue& data, const int64_t timestamp) // Import scriptPubKey only. 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"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) { + if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } if (scriptPubKey.getType() == UniValue::VOBJ) { // add to address book or update label if (IsValidDestination(dest)) { - pwalletMain->SetAddressBook(dest, label, "receive"); + pwallet->SetAddressBook(dest, label, "receive"); } } @@ -923,11 +943,14 @@ static int64_t GetImportTimestamp(const UniValue& data, int64_t now) UniValue importmulti(const JSONRPCRequest& mainRequest) { + if (!EnsureWalletIsAvailable(pwalletMain, mainRequest.fHelp)) + return NullUniValue; + if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2) throw std::runtime_error( "importmulti \"requests\" ( \"options\" )\n" "\nImport addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. requests (array, required) Data to be imported\n" @@ -972,8 +995,6 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) "{ \"scriptPubKey\": { \"address\": \"\" }, \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") + HelpExampleCli("importmulti", "'[{ \"scriptPubKey\": { \"address\": \"\" }, \"timestamp\":1455191478 }]' '{ \"rescan\": false}'")); - EnsureWallet(); - RPCTypeCheck(mainRequest.params, {UniValue::VARR, UniValue::VOBJ}); const UniValue& requests = mainRequest.params[0]; @@ -1000,7 +1021,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) UniValue response(UniValue::VARR); { LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Verify all timestamps are present before importing any keys. int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; @@ -1018,7 +1039,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) for (const UniValue& data: requests.getValues()) { 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); if (!fRescan) { @@ -1076,11 +1097,14 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) UniValue bip38encrypt(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "bip38encrypt \"pivxaddress\" \"passphrase\"\n" "\nEncrypts a private key corresponding to 'pivxaddress'.\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address for the private key (you must hold the key already)\n" @@ -1095,7 +1119,7 @@ UniValue bip38encrypt(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); std::string strAddress = request.params[0].get_str(); std::string strPassphrase = request.params[1].get_str(); @@ -1122,11 +1146,14 @@ UniValue bip38encrypt(const JSONRPCRequest& request) UniValue bip38decrypt(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "bip38decrypt \"pivxaddress\" \"passphrase\"\n" "\nDecrypts and then imports password protected private key.\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"encryptedkey\" (string, required) The encrypted private key\n" @@ -1169,7 +1196,7 @@ UniValue bip38decrypt(const JSONRPCRequest& request) CKeyID vchAddress = pubkey.GetID(); { LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); pwalletMain->MarkDirty(); pwalletMain->SetAddressBook(vchAddress, "", AddressBook::AddressBookPurpose::RECEIVE); @@ -1193,11 +1220,14 @@ UniValue bip38decrypt(const JSONRPCRequest& request) UniValue importsaplingkey(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw std::runtime_error( "importsaplingkey \"key\" ( rescan startHeight )\n" "\nAdds a key (as returned by exportsaplingkey) to your wallet.\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"key\" (string, required) The zkey (see exportsaplingkey)\n" @@ -1223,8 +1253,6 @@ UniValue importsaplingkey(const JSONRPCRequest& request) + HelpExampleRpc("importsaplingkey", "\"mykey\", \"no\"") ); - EnsureWallet(); - // Whether to perform rescan after import bool fRescan = true; bool fIgnoreExistingKey = true; @@ -1251,7 +1279,7 @@ UniValue importsaplingkey(const JSONRPCRequest& request) CBlockIndex* pindexRescan{nullptr}; { LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Height to rescan from int nRescanHeight = 0; @@ -1292,11 +1320,14 @@ UniValue importsaplingkey(const JSONRPCRequest& request) UniValue importsaplingviewingkey(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw std::runtime_error( "importsaplingviewingkey \"vkey\" ( rescan startHeight )\n" "\nAdds a viewing key (as returned by exportsaplingviewingkey) to your wallet.\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"vkey\" (string, required) The viewing key (see exportsaplingviewingkey)\n" @@ -1322,8 +1353,6 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) + HelpExampleRpc("importsaplingviewingkey", "\"vkey\", \"no\"") ); - EnsureWallet(); - // Whether to perform rescan after import bool fRescan = true; bool fIgnoreExistingKey = true; @@ -1350,7 +1379,7 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) CBlockIndex* pindexRescan{nullptr}; { LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Height to rescan from int nRescanHeight = 0; @@ -1395,12 +1424,15 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) UniValue exportsaplingviewingkey(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "exportsaplingviewingkey \"shield_addr\"\n" "\nReveals the viewing key corresponding to 'shield_addr'.\n" "Then the importsaplingviewingkey can be used with this output\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"shield_addr\" (string, required) The shield addr for the viewing key\n" @@ -1413,10 +1445,9 @@ UniValue exportsaplingviewingkey(const JSONRPCRequest& request) + HelpExampleRpc("exportsaplingviewingkey", "\"myaddress\"") ); - EnsureWallet(); LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); std::string strAddress = request.params[0].get_str(); auto address = KeyIO::DecodePaymentAddress(strAddress); @@ -1434,12 +1465,15 @@ UniValue exportsaplingviewingkey(const JSONRPCRequest& request) UniValue exportsaplingkey(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "exportsaplingkey \"shield_addr\"\n" "\nReveals the key corresponding to the 'shield_addr'.\n" "Then the importsaplingkey can be used with this output\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"addr\" (string, required) The shield addr for the private key\n" @@ -1452,11 +1486,9 @@ UniValue exportsaplingkey(const JSONRPCRequest& request) + HelpExampleRpc("exportsaplingkey", "\"myaddress\"") ); - EnsureWallet(); - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); std::string strAddress = request.params[0].get_str(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ab2b664223e7..8fb84de52f4d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -37,21 +37,26 @@ int64_t nWalletUnlockTime; static RecursiveMutex cs_nWalletUnlockTime; -std::string HelpRequiringPassphrase() +std::string HelpRequiringPassphrase(CWallet* const pwallet) { - return pwalletMain && pwalletMain->IsCrypted() ? "\nRequires wallet passphrase to be set with walletpassphrase call." : ""; + return pwallet && pwallet->IsCrypted() ? "\nRequires wallet passphrase to be set with walletpassphrase call." : ""; } -void EnsureWalletIsUnlocked(bool fAllowAnonOnly) +bool EnsureWalletIsAvailable(CWallet* const pwallet, bool avoidException) { - if (pwalletMain->IsLocked() || (!fAllowAnonOnly && pwalletMain->fWalletUnlockStaking)) - throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); + if (!pwallet) { + if (!avoidException) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (wallet disabled)"); + else + return false; + } + return true; } -void EnsureWallet() +void EnsureWalletIsUnlocked(CWallet* const pwallet, bool fAllowAnonOnly) { - if (!pwalletMain) - throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: No wallet loaded in the system"); + if (pwallet->IsLocked() || (!fAllowAnonOnly && pwallet->fWalletUnlockStaking)) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); } void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) @@ -88,17 +93,17 @@ std::string LabelFromValue(const UniValue& value) return label; } -CTxDestination GetNewAddressFromLabel(const std::string purpose, const UniValue ¶ms, - const CChainParams::Base58Type addrType = CChainParams::PUBKEY_ADDRESS) +static CTxDestination GetNewAddressFromLabel(CWallet* const pwallet, const std::string purpose, const UniValue ¶ms, + const CChainParams::Base58Type addrType = CChainParams::PUBKEY_ADDRESS) { - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Parse the label first so we don't generate a key if there's an error std::string label; if (!params.isNull() && params.size() > 0) label = LabelFromValue(params[0]); CTxDestination address; - PairResult r = pwalletMain->getNewAddress(address, label, purpose, addrType); + PairResult r = pwallet->getNewAddress(address, label, purpose, addrType); if(!r.result) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, *r.status); return address; @@ -127,9 +132,8 @@ UniValue getaddressinfo(const JSONRPCRequest& request) { CWallet* const pwallet = pwalletMain; - if (!pwallet) { + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - } const std::string example_address = "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\""; @@ -254,9 +258,8 @@ UniValue getaddressinfo(const JSONRPCRequest& request) UniValue getaddressesbylabel(const JSONRPCRequest& request) { CWallet* const pwallet = pwalletMain; - if (!pwallet) { + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - } if (request.fHelp || request.params.size() != 1) throw std::runtime_error( @@ -301,9 +304,8 @@ UniValue getaddressesbylabel(const JSONRPCRequest& request) UniValue listlabels(const JSONRPCRequest& request) { CWallet* const pwallet = pwalletMain; - if (!pwallet) { + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - } if (request.fHelp || request.params.size() > 1) throw std::runtime_error( @@ -369,6 +371,9 @@ CPubKey parseWIFKey(std::string strKey, CWallet* pwallet) UniValue upgradewallet(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 0) throw std::runtime_error("upgradewallet\n" "Bump the wallet features to the latest supported version. Non-HD wallets will be upgraded to HD wallet functionality. " @@ -378,10 +383,10 @@ UniValue upgradewallet(const JSONRPCRequest& request) "Enabling the Sapling key manager. Sapling keys will be deterministically derived by the same HD wallet seed.\n" "Wallets that are running the latest Sapling version will not be upgraded" "\nNote that you will need to MAKE A NEW BACKUP of your wallet after upgrade it.\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" + HelpExampleCli("upgradewallet", "") + HelpExampleRpc("upgradewallet", "") ); - EnsureWallet(); LOCK2(cs_main, pwalletMain->cs_wallet); // Do not do anything to wallets already upgraded @@ -389,7 +394,7 @@ UniValue upgradewallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Cannot upgrade the wallet. The wallet is already running the latest version"); } - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Get version int prev_version = pwalletMain->GetVersion(); @@ -410,16 +415,16 @@ UniValue upgradewallet(const JSONRPCRequest& request) UniValue sethdseed(const JSONRPCRequest& request) { CWallet* pwallet = pwalletMain; - - if (!pwallet) { + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - } if (request.fHelp || request.params.size() > 2) throw std::runtime_error("sethdseed ( newkeypool \"seed\" )\n" "Set or generate a new HD wallet seed. Non-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n" "HD will have a new HD seed set so that new keys added to the keypool will be derived from this new seed.\n" - "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed.\n\n" + "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed.\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" + "\nArguments:\n" "1. newkeypool (boolean, optional, default true): Whether to flush old unused addresses, including change addresses, from the keypool and regenerate it.\n" " If true, the next address from getnewaddress and change address from getrawchangeaddress will be from this new seed.\n" @@ -474,6 +479,9 @@ UniValue sethdseed(const JSONRPCRequest& request) UniValue getnewaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getnewaddress ( \"label\" )\n" @@ -490,11 +498,13 @@ UniValue getnewaddress(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getnewaddress", "") + HelpExampleRpc("getnewaddress", "")); - return EncodeDestination(GetNewAddressFromLabel(AddressBook::AddressBookPurpose::RECEIVE, request.params)); + return EncodeDestination(GetNewAddressFromLabel(pwalletMain, AddressBook::AddressBookPurpose::RECEIVE, request.params)); } UniValue getnewstakingaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; if (request.fHelp || request.params.size() > 1) throw std::runtime_error( @@ -511,16 +521,19 @@ UniValue getnewstakingaddress(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getnewstakingaddress", "") + HelpExampleRpc("getnewstakingaddress", "")); - return EncodeDestination(GetNewAddressFromLabel("coldstaking", request.params, CChainParams::STAKING_ADDRESS), CChainParams::STAKING_ADDRESS); + return EncodeDestination(GetNewAddressFromLabel(pwalletMain, "coldstaking", request.params, CChainParams::STAKING_ADDRESS), CChainParams::STAKING_ADDRESS); } UniValue getnewshieldaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getnewshieldaddress\n" "\nReturns a new shield address for receiving payments.\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nResult:\n" "\"address\" (string) The new shield address.\n" @@ -530,17 +543,18 @@ UniValue getnewshieldaddress(const JSONRPCRequest& request) + HelpExampleRpc("getnewshieldaddress", "") ); - EnsureWallet(); - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); return KeyIO::EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey()); } UniValue listshieldunspent(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 4) throw std::runtime_error( "listshieldunspent ( minconf maxconf includeWatchonly [\"shield_addr\",...] )\n" @@ -580,8 +594,6 @@ UniValue listshieldunspent(const JSONRPCRequest& request) + HelpExampleRpc("listshieldunspent", "6 9999999 false \"[\\\"ptestsapling1h0w73csah2aq0a32h42kr7tq4htlt5wfn4ejxfnm56f6ehjvek7k4e244g6v8v3pgylmz5ea8jh\\\",\\\"ptestsapling1h0w73csah2aq0a32h42kr7tq4htlt5wfn4ejxfnm56f6ehjvek7k4e244g6v8v3pgylmz5ea8jh\\\"]\"") ); - EnsureWallet(); - RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM, UniValue::VBOOL, UniValue::VARR}); int nMinDepth = request.params.size() > 0 ? request.params[0].get_int() : 1; @@ -670,6 +682,9 @@ UniValue listshieldunspent(const JSONRPCRequest& request) UniValue delegatoradd(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "delegatoradd \"addr\" ( \"label\" )\n" @@ -705,6 +720,9 @@ UniValue delegatoradd(const JSONRPCRequest& request) UniValue delegatorremove(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "delegatorremove \"addr\"\n" @@ -742,7 +760,7 @@ UniValue delegatorremove(const JSONRPCRequest& request) return pwalletMain->SetAddressBook(*keyID, label, AddressBook::AddressBookPurpose::DELEGABLE); } -UniValue ListaddressesForPurpose(const std::string strPurpose) +static UniValue ListaddressesForPurpose(CWallet* const pwallet, const std::string strPurpose) { const CChainParams::Base58Type addrType = ( AddressBook::IsColdStakingPurpose(strPurpose) ? @@ -750,8 +768,8 @@ UniValue ListaddressesForPurpose(const std::string strPurpose) CChainParams::PUBKEY_ADDRESS); UniValue ret(UniValue::VARR); { - LOCK(pwalletMain->cs_wallet); - for (auto it = pwalletMain->NewAddressBookIterator(); it.IsValid(); it.Next()) { + LOCK(pwallet->cs_wallet); + for (auto it = pwallet->NewAddressBookIterator(); it.IsValid(); it.Next()) { auto addrBook = it.GetValue(); if (addrBook.purpose != strPurpose) continue; auto dest = it.GetCTxDestKey(); @@ -768,6 +786,9 @@ UniValue ListaddressesForPurpose(const std::string strPurpose) UniValue listdelegators(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "listdelegators ( fBlacklist )\n" @@ -792,12 +813,15 @@ UniValue listdelegators(const JSONRPCRequest& request) const bool fBlacklist = (request.params.size() > 0 ? request.params[0].get_bool() : false); return (fBlacklist ? - ListaddressesForPurpose(AddressBook::AddressBookPurpose::DELEGABLE) : - ListaddressesForPurpose(AddressBook::AddressBookPurpose::DELEGATOR)); + ListaddressesForPurpose(pwalletMain, AddressBook::AddressBookPurpose::DELEGABLE) : + ListaddressesForPurpose(pwalletMain, AddressBook::AddressBookPurpose::DELEGATOR)); } UniValue liststakingaddresses(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 0) throw std::runtime_error( "liststakingaddresses \"addr\"\n" @@ -816,11 +840,14 @@ UniValue liststakingaddresses(const JSONRPCRequest& request) HelpExampleCli("liststakingaddresses" , "") + HelpExampleRpc("liststakingaddresses", "")); - return ListaddressesForPurpose(AddressBook::AddressBookPurpose::COLD_STAKING); + return ListaddressesForPurpose(pwalletMain, AddressBook::AddressBookPurpose::COLD_STAKING); } UniValue listshieldaddresses(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "listshieldaddresses ( includeWatchonly )\n" @@ -840,7 +867,6 @@ UniValue listshieldaddresses(const JSONRPCRequest& request) + HelpExampleRpc("listshieldaddresses", "") ); - EnsureWallet(); LOCK2(cs_main, pwalletMain->cs_wallet); bool fIncludeWatchonly = false; @@ -864,6 +890,9 @@ UniValue listshieldaddresses(const JSONRPCRequest& request) UniValue getrawchangeaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getrawchangeaddress\n" @@ -896,6 +925,9 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) UniValue setlabel(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "setlabel \"pivxaddress\" \"label\"\n" @@ -922,52 +954,49 @@ UniValue setlabel(const JSONRPCRequest& request) return NullUniValue; } -void SendMoney(const CTxDestination& address, CAmount nValue, CTransactionRef& tx) +static void SendMoney(CWallet* const pwallet, const CTxDestination& address, CAmount nValue, CTransactionRef& tx) { + LOCK2(cs_main, pwallet->cs_wallet); + // Check amount if (nValue <= 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); - if (nValue > pwalletMain->GetAvailableBalance()) + if (nValue > pwallet->GetAvailableBalance()) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); if (!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - std::string strError; - if (pwalletMain->IsLocked()) { - strError = "Error: Wallet locked, unable to create transaction!"; - LogPrintf("SendMoney() : %s", strError); - throw JSONRPCError(RPC_WALLET_ERROR, strError); - } - // Parse PIVX address CScript scriptPubKey = GetScriptForDestination(address); // Create and send the transaction - CReserveKey reservekey(pwalletMain); + CReserveKey reservekey(pwallet); CAmount nFeeRequired; - if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, tx, reservekey, nFeeRequired, strError, nullptr, ALL_COINS, (CAmount)0)) { - if (nValue + nFeeRequired > pwalletMain->GetAvailableBalance()) + std::string strError; + if (!pwallet->CreateTransaction(scriptPubKey, nValue, tx, reservekey, nFeeRequired, strError, nullptr, ALL_COINS, (CAmount)0)) { + if (nValue + nFeeRequired > pwallet->GetAvailableBalance()) 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)); - LogPrintf("SendMoney() : %s\n", strError); + LogPrintf("%s: %s\n", __func__, strError); throw JSONRPCError(RPC_WALLET_ERROR, strError); } - const CWallet::CommitResult&& res = pwalletMain->CommitTransaction(tx, reservekey, g_connman.get()); + const CWallet::CommitResult&& res = pwallet->CommitTransaction(tx, reservekey, g_connman.get()); if (res.status != CWallet::CommitStatus::OK) throw JSONRPCError(RPC_WALLET_ERROR, res.ToString()); } -static SaplingOperation CreateShieldedTransaction(const JSONRPCRequest& request); +static SaplingOperation CreateShieldedTransaction(CWallet* const pwallet, const JSONRPCRequest& request); /* * redirect sendtoaddress/sendmany inputs to shieldsendmany implementation (CreateShieldedTransaction) */ -static UniValue ShieldSendManyTo(const UniValue& sendTo, - const std::string& commentStr, - const std::string& toStr, - int nMinDepth, - bool fIncludeDelegated) +static UniValue ShieldSendManyTo(CWallet * const pwallet, + const UniValue& sendTo, + const std::string& commentStr, + const std::string& toStr, + int nMinDepth, + bool fIncludeDelegated) { // convert params to 'shieldsendmany' format JSONRPCRequest req; @@ -988,7 +1017,7 @@ static UniValue ShieldSendManyTo(const UniValue& sendTo, req.params.push_back(nMinDepth); // send - SaplingOperation operation = CreateShieldedTransaction(req); + SaplingOperation operation = CreateShieldedTransaction(pwallet, req); std::string txid; auto res = operation.send(txid); if (!res) @@ -996,12 +1025,12 @@ static UniValue ShieldSendManyTo(const UniValue& sendTo, // add comments const uint256& txHash = uint256S(txid); - assert(pwalletMain->mapWallet.count(txHash)); + assert(pwallet->mapWallet.count(txHash)); if (!commentStr.empty()) { - pwalletMain->mapWallet.at(txHash).mapValue["comment"] = commentStr; + pwallet->mapWallet.at(txHash).mapValue["comment"] = commentStr; } if (!toStr.empty()) { - pwalletMain->mapWallet.at(txHash).mapValue["to"] = toStr; + pwallet->mapWallet.at(txHash).mapValue["to"] = toStr; } return txid; @@ -1009,11 +1038,14 @@ static UniValue ShieldSendManyTo(const UniValue& sendTo, UniValue sendtoaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) throw std::runtime_error( "sendtoaddress \"pivxaddress\" amount ( \"comment\" \"comment-to\" )\n" "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address to send to.\n" @@ -1032,7 +1064,7 @@ UniValue sendtoaddress(const JSONRPCRequest& request) HelpExampleCli("sendtoaddress", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" 0.1 \"donation\" \"seans outpost\"") + HelpExampleRpc("sendtoaddress", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", 0.1, \"donation\", \"seans outpost\"")); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now @@ -1051,17 +1083,16 @@ UniValue sendtoaddress(const JSONRPCRequest& request) if (isShielded) { UniValue sendTo(UniValue::VOBJ); sendTo.pushKV(addrStr, request.params[1]); - return ShieldSendManyTo(sendTo, commentStr, toStr, 1, false); + return ShieldSendManyTo(pwalletMain, sendTo, commentStr, toStr, 1, false); } const CTxDestination& address = *Standard::GetTransparentDestination(destination); - LOCK2(cs_main, pwalletMain->cs_wallet); // Amount CAmount nAmount = AmountFromValue(request.params[1]); CTransactionRef tx; - SendMoney(address, nAmount, tx); + SendMoney(pwalletMain, address, nAmount, tx); // Wallet comments CWalletTx& wtx = pwalletMain->mapWallet.at(tx->GetHash()); @@ -1073,9 +1104,9 @@ UniValue sendtoaddress(const JSONRPCRequest& request) return wtx.GetHash().GetHex(); } -UniValue CreateColdStakeDelegation(const UniValue& params, CTransactionRef& txNew, CReserveKey& reservekey) +static UniValue CreateColdStakeDelegation(CWallet* const pwallet, const UniValue& params, CTransactionRef& txNew, CReserveKey& reservekey) { - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Check that Cold Staking has been enforced or fForceNotEnabled = true bool fForceNotEnabled = false; @@ -1111,12 +1142,11 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CTransactionRef& txNe fUseDelegated = params[4].get_bool(); // Check amount - CAmount currBalance = pwalletMain->GetAvailableBalance() + (fUseDelegated ? pwalletMain->GetDelegatedBalance() : 0); + CAmount currBalance = pwallet->GetAvailableBalance() + (fUseDelegated ? pwallet->GetDelegatedBalance() : 0); if (nValue > currBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); std::string strError; - EnsureWalletIsUnlocked(); // Get Owner Address std::string ownerAddressStr; @@ -1130,7 +1160,7 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CTransactionRef& txNe ownerKey = *boost::get(&dest); // Check that the owner address belongs to this wallet, or fForceExternalAddr is true bool fForceExternalAddr = params.size() > 3 && !params[3].isNull() ? params[3].get_bool() : false; - if (!fForceExternalAddr && !pwalletMain->HaveKey(ownerKey)) { + if (!fForceExternalAddr && !pwallet->HaveKey(ownerKey)) { std::string errMsg = strprintf("The provided owneraddress \"%s\" is not present in this wallet.\n", params[2].get_str()); errMsg += "Set 'fExternalOwner' argument to true, in order to force the stake delegation to an external owner address.\n" "e.g. delegatestake stakingaddress amount owneraddress true.\n" @@ -1140,7 +1170,7 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CTransactionRef& txNe ownerAddressStr = params[2].get_str(); } else { // Get new owner address from keypool - CTxDestination ownerAddr = GetNewAddressFromLabel("delegated", NullUniValue); + CTxDestination ownerAddr = GetNewAddressFromLabel(pwallet, "delegated", NullUniValue); CKeyID* pOwnerKey = boost::get(&ownerAddr); assert(pOwnerKey); ownerKey = *pOwnerKey; @@ -1157,7 +1187,7 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CTransactionRef& txNe CAmount nFeeRequired; CScript scriptPubKey = fV6Enforced ? GetScriptForStakeDelegation(*stakeKey, ownerKey) : GetScriptForStakeDelegationLOF(*stakeKey, ownerKey); - if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, txNew, reservekey, nFeeRequired, strError, nullptr, ALL_COINS, (CAmount)0, fUseDelegated)) { + if (!pwallet->CreateTransaction(scriptPubKey, nValue, txNew, reservekey, nFeeRequired, strError, nullptr, ALL_COINS, (CAmount)0, fUseDelegated)) { if (nValue + nFeeRequired > currBalance) 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)); LogPrintf("%s : %s\n", __func__, strError); @@ -1172,7 +1202,7 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CTransactionRef& txNe throw JSONRPCError(RPC_INVALID_PARAMETER, "SHIELD in maintenance (SPORK 20)"); } std::vector recipients = {SendManyRecipient(ownerKey, *stakeKey, nValue, fV6Enforced)}; - SaplingOperation operation(consensus, nextBlockHeight, pwalletMain); + SaplingOperation operation(consensus, nextBlockHeight, pwallet); OperationResult res = operation.setSelectShieldedCoins(true) ->setRecipients(recipients) ->build(); @@ -1188,11 +1218,14 @@ UniValue CreateColdStakeDelegation(const UniValue& params, CTransactionRef& txNe UniValue delegatestake(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 7) throw std::runtime_error( "delegatestake \"stakingaddress\" amount ( \"owneraddress\" fExternalOwner fUseDelegated fFromShield fForceNotEnabled )\n" "\nDelegate an amount to a given address for cold staking. The amount is a real and is rounded to the nearest 0.00000001\n" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"stakingaddress\" (string, required) The pivx staking address to delegate.\n" @@ -1217,6 +1250,8 @@ UniValue delegatestake(const JSONRPCRequest& request) HelpExampleCli("delegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\" 1000 \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"") + HelpExampleRpc("delegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\", 1000, \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"")); + EnsureWalletIsUnlocked(pwalletMain); + // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); @@ -1225,7 +1260,7 @@ UniValue delegatestake(const JSONRPCRequest& request) CTransactionRef wtx; CReserveKey reservekey(pwalletMain); - UniValue ret = CreateColdStakeDelegation(request.params, wtx, reservekey); + UniValue ret = CreateColdStakeDelegation(pwalletMain, request.params, wtx, reservekey); const CWallet::CommitResult& res = pwalletMain->CommitTransaction(wtx, reservekey, g_connman.get()); if (res.status != CWallet::CommitStatus::OK) @@ -1237,12 +1272,15 @@ UniValue delegatestake(const JSONRPCRequest& request) UniValue rawdelegatestake(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 7) throw std::runtime_error( "rawdelegatestake \"stakingaddress\" amount ( \"owneraddress\" fExternalOwner fUseDelegated fFromShield )\n" "\nDelegate an amount to a given address for cold staking. The amount is a real and is rounded to the nearest 0.00000001\n" "\nDelegate transaction is returned as json object." + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"stakingaddress\" (string, required) The pivx staking address to delegate.\n" @@ -1263,6 +1301,8 @@ UniValue rawdelegatestake(const JSONRPCRequest& request) HelpExampleCli("rawdelegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\" 1000 \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"") + HelpExampleRpc("rawdelegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\", 1000, \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"")); + EnsureWalletIsUnlocked(pwalletMain); + // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); @@ -1271,16 +1311,16 @@ UniValue rawdelegatestake(const JSONRPCRequest& request) CTransactionRef wtx; CReserveKey reservekey(pwalletMain); - CreateColdStakeDelegation(request.params, wtx, reservekey); + CreateColdStakeDelegation(pwalletMain, request.params, wtx, reservekey); return EncodeHexTx(*wtx); } -CAmount getBalanceShieldedAddr(Optional& filterAddress, int minDepth = 1, bool ignoreUnspendable=true) { +static CAmount getBalanceShieldedAddr(CWallet* const pwallet, Optional& filterAddress, int minDepth = 1, bool ignoreUnspendable=true) { CAmount balance = 0; std::vector saplingEntries; - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); pwalletMain->GetSaplingScriptPubKeyMan()->GetFilteredNotes(saplingEntries, filterAddress, minDepth, true, ignoreUnspendable); for (auto & entry : saplingEntries) { balance += CAmount(entry.note.value()); @@ -1290,7 +1330,7 @@ CAmount getBalanceShieldedAddr(Optional& filter UniValue getshieldbalance(const JSONRPCRequest& request) { - if (!pwalletMain) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -1339,17 +1379,21 @@ UniValue getshieldbalance(const JSONRPCRequest& request) } const bool fIncludeWatchonly = request.params.size() > 2 && request.params[2].get_bool(); - CAmount nBalance = getBalanceShieldedAddr(address, nMinDepth, !fIncludeWatchonly); + CAmount nBalance = getBalanceShieldedAddr(pwalletMain, address, nMinDepth, !fIncludeWatchonly); return ValueFromAmount(nBalance); } UniValue viewshieldtransaction(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "viewshieldtransaction \"txid\"\n" "\nGet detailed shield information about in-wallet transaction \"txid\"\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" + "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "\nResult:\n" @@ -1390,7 +1434,7 @@ UniValue viewshieldtransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Sapling wallet not initialized."); } - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now @@ -1518,12 +1562,11 @@ UniValue viewshieldtransaction(const JSONRPCRequest& request) return entry; } -static SaplingOperation CreateShieldedTransaction(const JSONRPCRequest& request) +static SaplingOperation CreateShieldedTransaction(CWallet* const pwallet, const JSONRPCRequest& request) { - EnsureWalletIsUnlocked(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nextBlockHeight = chainActive.Height() + 1; - SaplingOperation operation(Params().GetConsensus(), nextBlockHeight, pwalletMain); + SaplingOperation operation(Params().GetConsensus(), nextBlockHeight, pwallet); // Param 0: source of funds. Can either be a valid address, sapling address, // or the string "from_transparent"|"from_trans_cold"|"from_shield" @@ -1547,7 +1590,7 @@ static SaplingOperation CreateShieldedTransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or shield addr."); } libzcash::SaplingPaymentAddress fromShieldedAddress = *boost::get(&res); - if (!pwalletMain->HaveSpendingKeyForPaymentAddress(fromShieldedAddress)) { + if (!pwallet->HaveSpendingKeyForPaymentAddress(fromShieldedAddress)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, shield addr spending key not found."); } // send from user-supplied shield address @@ -1674,13 +1717,17 @@ static SaplingOperation CreateShieldedTransaction(const JSONRPCRequest& request) UniValue shieldsendmany(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) throw std::runtime_error( "shieldsendmany \"fromaddress\" [{\"address\":... ,\"amount\":...},...] ( minconf fee )\n" "\nSend to many recipients. Amounts are decimal numbers with at most 8 digits of precision." "\nChange generated from a transparent addr flows to a new transparent addr address, while change generated from a shield addr returns to itself." "\nWhen sending coinbase UTXOs to a shield addr, change is not allowed. The entire value of the UTXO(s) must be consumed." - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" + "\nArguments:\n" "1. \"fromaddress\" (string, required) The transparent addr or shield addr to send the funds from.\n" " It can also be the string \"from_transparent\"|\"from_shield\" to send the funds\n" @@ -1706,11 +1753,13 @@ UniValue shieldsendmany(const JSONRPCRequest& request) "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", [{\"address\": \"ps1ra969yfhvhp73rw5ak2xvtcm9fkuqsnmad7qln79mphhdrst3lwu9vvv03yuyqlh42p42st47qd\" ,\"amount\": 5.0}]") ); + EnsureWalletIsUnlocked(pwalletMain); + // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); - SaplingOperation operation = CreateShieldedTransaction(request); + SaplingOperation operation = CreateShieldedTransaction(pwalletMain, request); std::string txHash; auto res = operation.send(txHash); if (!res) @@ -1720,6 +1769,9 @@ UniValue shieldsendmany(const JSONRPCRequest& request) UniValue rawshieldsendmany(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) throw std::runtime_error( "rawshieldsendmany \"fromaddress\" [{\"address\":... ,\"amount\":...},...] ( minconf fee )\n" @@ -1727,7 +1779,8 @@ UniValue rawshieldsendmany(const JSONRPCRequest& request) "\nAmounts are decimal numbers with at most 8 digits of precision." "\nChange generated from a transparent addr flows to a new transparent addr address, while change generated from a shield addr returns to itself." "\nWhen sending coinbase UTXOs to a shield addr, change is not allowed. The entire value of the UTXO(s) must be consumed." - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" + "\nArguments:\n" "1. \"fromaddress\" (string, required) The transparent addr or shield addr to send the funds from.\n" " It can also be the string \"from_transparent\"|\"from_shield\" to send the funds\n" @@ -1754,16 +1807,21 @@ UniValue rawshieldsendmany(const JSONRPCRequest& request) "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", [{\"address\": \"ps1ra969yfhvhp73rw5ak2xvtcm9fkuqsnmad7qln79mphhdrst3lwu9vvv03yuyqlh42p42st47qd\" ,\"amount\": 5.0}]") ); + EnsureWalletIsUnlocked(pwalletMain); + // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); - CTransaction tx = CreateShieldedTransaction(request).getFinalTx(); + CTransaction tx = CreateShieldedTransaction(pwalletMain, request).getFinalTx(); return EncodeHexTx(tx); } UniValue listaddressgroupings(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp) throw std::runtime_error( "listaddressgroupings\n" @@ -1814,11 +1872,14 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) UniValue signmessage(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "signmessage \"pivxaddress\" \"message\"\n" "\nSign a message with the private key of an address" + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address to use for the private key.\n" @@ -1839,7 +1900,7 @@ UniValue signmessage(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); std::string strAddress = request.params[0].get_str(); std::string strMessage = request.params[1].get_str(); @@ -1869,6 +1930,9 @@ UniValue signmessage(const JSONRPCRequest& request) UniValue getreceivedbyaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "getreceivedbyaddress \"pivxaddress\" ( minconf )\n" @@ -1930,6 +1994,9 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) UniValue getreceivedbylabel(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "getreceivedbylabel \"label\" ( minconf )\n" @@ -1988,6 +2055,9 @@ UniValue getreceivedbylabel(const JSONRPCRequest& request) UniValue getbalance(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || (request.params.size() > 4 )) throw std::runtime_error( "getbalance ( minconf includeWatchonly includeDelegated includeShield )\n" @@ -2033,6 +2103,9 @@ UniValue getbalance(const JSONRPCRequest& request) UniValue getcoldstakingbalance(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || (request.params.size() != 0)) throw std::runtime_error( "getcoldstakingbalance\n" @@ -2058,6 +2131,9 @@ UniValue getcoldstakingbalance(const JSONRPCRequest& request) UniValue getdelegatedbalance(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || (request.params.size() != 0)) throw std::runtime_error( "getdelegatedbalance\n" @@ -2084,6 +2160,9 @@ UniValue getdelegatedbalance(const JSONRPCRequest& request) UniValue getunconfirmedbalance(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 0) throw std::runtime_error( "getunconfirmedbalance\n" @@ -2101,9 +2180,9 @@ UniValue getunconfirmedbalance(const JSONRPCRequest& request) /* * Only used for t->t transactions (via sendmany RPC) */ -static UniValue legacy_sendmany(const UniValue& sendTo, int nMinDepth, std::string comment, bool fIncludeDelegated) +static UniValue legacy_sendmany(CWallet* const pwallet, const UniValue& sendTo, int nMinDepth, std::string comment, bool fIncludeDelegated) { - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -2133,37 +2212,30 @@ static UniValue legacy_sendmany(const UniValue& sendTo, int nMinDepth, std::stri vecSend.emplace_back(scriptPubKey, nAmount, false); } - EnsureWalletIsUnlocked(); - // Check funds - if (totalAmount > pwalletMain->GetLegacyBalance(filter, nMinDepth)) { + if (totalAmount > pwallet->GetLegacyBalance(filter, nMinDepth)) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Wallet has insufficient funds"); } // Send - CReserveKey keyChange(pwalletMain); + CReserveKey keyChange(pwallet); CAmount nFeeRequired = 0; std::string strFailReason; int nChangePosInOut = -1; - bool fCreated = pwalletMain->CreateTransaction(vecSend, - txNew, - keyChange, - nFeeRequired, - nChangePosInOut, - strFailReason, - nullptr, // coinControl - ALL_COINS, // inputType - true, // sign - 0, // nFeePay - fIncludeDelegated); + bool fCreated = pwallet->CreateTransaction(vecSend, txNew, keyChange, nFeeRequired, nChangePosInOut, strFailReason, + nullptr, // coinControl + ALL_COINS, // inputType + true, // sign + 0, // nFeePay + fIncludeDelegated); if (!fCreated) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); - const CWallet::CommitResult& res = pwalletMain->CommitTransaction(txNew, keyChange, g_connman.get()); + const CWallet::CommitResult& res = pwallet->CommitTransaction(txNew, keyChange, g_connman.get()); if (res.status != CWallet::CommitStatus::OK) throw JSONRPCError(RPC_WALLET_ERROR, res.ToString()); // Set comment - CWalletTx& wtx = pwalletMain->mapWallet.at(txNew->GetHash()); + CWalletTx& wtx = pwallet->mapWallet.at(txNew->GetHash()); if (!comment.empty()) { wtx.mapValue["comment"] = comment; } @@ -2177,12 +2249,15 @@ static UniValue legacy_sendmany(const UniValue& sendTo, int nMinDepth, std::stri */ UniValue sendmany(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw std::runtime_error( "sendmany \"\" {\"address\":amount,...} ( minconf \"comment\" includeDelegated )\n" "\nSend to multiple destinations. Recipients are transparent or shield PIVX addresses.\n" "\nAmounts are double-precision floating point numbers.\n" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"dummy\" (string, required) Must be set to \"\" for backwards compatibility.\n" @@ -2211,7 +2286,7 @@ UniValue sendmany(const JSONRPCRequest& request) HelpExampleRpc("sendmany", "\"\", \"{\\\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\\\":0.01,\\\"DAD3Y6ivr8nPQLT1NEPX84DxGCw9jz9Jvg\\\":0.02}\", 6, \"testing\"") ); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now @@ -2239,18 +2314,21 @@ UniValue sendmany(const JSONRPCRequest& request) } if (fShieldSend) { - return ShieldSendManyTo(sendTo, comment, "", nMinDepth, fIncludeDelegated); + return ShieldSendManyTo(pwalletMain, sendTo, comment, "", nMinDepth, fIncludeDelegated); } // All recipients are transparent: use Legacy sendmany t->t - return legacy_sendmany(sendTo, nMinDepth, comment, fIncludeDelegated); + return legacy_sendmany(pwalletMain, sendTo, nMinDepth, comment, fIncludeDelegated); } // 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) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw std::runtime_error( "addmultisigaddress nrequired [\"key\",...] ( \"label\" )\n" @@ -2283,7 +2361,7 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) label = LabelFromValue(request.params[2]); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(request.params); + CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); CScriptID innerID(inner); pwalletMain->AddCScript(inner); @@ -2305,7 +2383,7 @@ struct tallyitem { } }; -UniValue ListReceived(const UniValue& params, bool by_label, int nBlockHeight) +static UniValue ListReceived(CWallet* const pwallet, const UniValue& params, bool by_label, int nBlockHeight) { // Minimum confirmations int nMinDepth = 1; @@ -2335,7 +2413,7 @@ UniValue ListReceived(const UniValue& params, bool by_label, int nBlockHeight) // Tally std::map mapTally; - for (std::map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + for (std::map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (!IsFinalTx(wtx.tx, nBlockHeight)) { @@ -2357,7 +2435,7 @@ UniValue ListReceived(const UniValue& params, bool by_label, int nBlockHeight) continue; } - isminefilter mine = IsMine(*pwalletMain, address); + isminefilter mine = IsMine(*pwallet, address); if (!(mine & filter)) { continue; } @@ -2373,7 +2451,7 @@ UniValue ListReceived(const UniValue& params, bool by_label, int nBlockHeight) // Create mapAddressBook iterator // If we aren't filtering, go from begin() to end() - auto itAddr = pwalletMain->NewAddressBookIterator(); + auto itAddr = pwallet->NewAddressBookIterator(); // If we are filtering, find() the applicable entry if (has_filtered_address) { itAddr.SetFilter(filtered_address); @@ -2449,6 +2527,9 @@ UniValue ListReceived(const UniValue& params, bool by_label, int nBlockHeight) UniValue listreceivedbyaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 4) throw std::runtime_error( "listreceivedbyaddress ( minconf includeempty includeWatchonly addressFilter)\n" @@ -2485,11 +2566,14 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); int nBlockHeight = chainActive.Height(); - return ListReceived(request.params, false, nBlockHeight); + return ListReceived(pwalletMain, request.params, false, nBlockHeight); } UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size()==0 || request.params.size() >2) throw std::runtime_error( "listreceivedbyshieldaddress \"address\" ( minconf )\n" @@ -2590,6 +2674,9 @@ UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) UniValue listreceivedbylabel(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 3) throw std::runtime_error( "listreceivedbylabel ( minconf includeempty includeWatchonly)\n" @@ -2621,11 +2708,14 @@ UniValue listreceivedbylabel(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); int nBlockHeight = chainActive.Height(); - return ListReceived(request.params, true, nBlockHeight); + return ListReceived(pwalletMain, request.params, true, nBlockHeight); } UniValue listcoldutxos(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "listcoldutxos ( nonWhitelistedOnly )\n" @@ -2707,7 +2797,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) entry.pushKV("address", EncodeDestination(dest)); } -void ListTransactions(const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) +static void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) { CAmount nFee; std::list listReceived; @@ -2721,13 +2811,13 @@ void ListTransactions(const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& if ((!listSent.empty() || nFee != 0)) { for (const COutputEntry& s : listSent) { UniValue entry(UniValue::VOBJ); - if (involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) + if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) entry.pushKV("involvesWatchonly", true); MaybePushAddress(entry, s.destination); entry.pushKV("category", "send"); entry.pushKV("amount", ValueFromAmount(-s.amount)); - if (pwalletMain->HasAddressBook(s.destination)) { - entry.pushKV("label", pwalletMain->GetNameForAddressBookEntry(s.destination)); + if (pwallet->HasAddressBook(s.destination)) { + entry.pushKV("label", pwallet->GetNameForAddressBookEntry(s.destination)); } entry.pushKV("vout", s.vout); entry.pushKV("fee", ValueFromAmount(-nFee)); @@ -2742,10 +2832,10 @@ void ListTransactions(const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& if (listReceived.size() > 0 && depth >= nMinDepth) { for (const COutputEntry& r : listReceived) { std::string label; - if (pwalletMain->HasAddressBook(r.destination)) - label = pwalletMain->GetNameForAddressBookEntry(r.destination); + if (pwallet->HasAddressBook(r.destination)) + label = pwallet->GetNameForAddressBookEntry(r.destination); UniValue entry(UniValue::VOBJ); - if (involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) + if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) entry.pushKV("involvesWatchonly", true); MaybePushAddress(entry, r.destination); if (wtx.IsCoinBase()) { @@ -2759,7 +2849,7 @@ void ListTransactions(const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& entry.pushKV("category", "receive"); } entry.pushKV("amount", ValueFromAmount(r.amount)); - if (pwalletMain->HasAddressBook(r.destination)) { + if (pwallet->HasAddressBook(r.destination)) { entry.pushKV("label", label); } entry.pushKV("vout", r.vout); @@ -2772,6 +2862,9 @@ void ListTransactions(const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& UniValue listtransactions(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 6) throw std::runtime_error( "listtransactions ( \"dummy\" count from includeWatchonly includeDelegated )\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions.\n" @@ -2856,7 +2949,7 @@ UniValue listtransactions(const JSONRPCRequest& request) // iterate backwards until we have nCount items to return: for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx* const pwtx = (*it).second; - ListTransactions(*pwtx, 0, true, ret, filter); + ListTransactions(pwalletMain, *pwtx, 0, true, ret, filter); if ((int)ret.size() >= (nCount + nFrom)) break; } // ret is newest to oldest @@ -2887,6 +2980,9 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue listsinceblock(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp) throw std::runtime_error( "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n" @@ -2964,7 +3060,7 @@ UniValue listsinceblock(const JSONRPCRequest& request) CWalletTx tx = (*it).second; 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]; @@ -2979,6 +3075,9 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue gettransaction(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "gettransaction \"txid\" ( includeWatchonly )\n" @@ -3048,7 +3147,7 @@ UniValue gettransaction(const JSONRPCRequest& request) WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(wtx, 0, false, details, filter); + ListTransactions(pwalletMain, wtx, 0, false, details, filter); entry.pushKV("details", details); std::string strHex = EncodeHexTx(*wtx.tx); @@ -3059,6 +3158,9 @@ UniValue gettransaction(const JSONRPCRequest& request) UniValue abandontransaction(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "abandontransaction \"txid\"\n" @@ -3077,9 +3179,6 @@ UniValue abandontransaction(const JSONRPCRequest& request) "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); - EnsureWallet(); - EnsureWalletIsUnlocked(); - // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now pwalletMain->BlockUntilSyncedToCurrentChain(); @@ -3100,6 +3199,9 @@ UniValue abandontransaction(const JSONRPCRequest& request) UniValue backupwallet(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "backupwallet \"destination\"\n" @@ -3127,11 +3229,14 @@ UniValue backupwallet(const JSONRPCRequest& request) UniValue keypoolrefill(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "keypoolrefill ( newsize )\n" "\nFills the keypool." + - HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments\n" "1. newsize (numeric, optional, default=100) The new keypool size\n" @@ -3149,7 +3254,7 @@ UniValue keypoolrefill(const JSONRPCRequest& request) kpSize = (unsigned int)request.params[0].get_int(); } - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); pwalletMain->TopUpKeyPool(kpSize); if (pwalletMain->GetKeyPoolSize() < kpSize) @@ -3169,6 +3274,9 @@ static void LockWallet(CWallet* pWallet) UniValue walletpassphrase(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() < 2 || request.params.size() > 3)) throw std::runtime_error( "walletpassphrase \"passphrase\" timeout ( stakingonly )\n" @@ -3243,6 +3351,9 @@ UniValue walletpassphrase(const JSONRPCRequest& request) UniValue walletpassphrasechange(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) throw std::runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" @@ -3286,6 +3397,9 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) UniValue walletlock(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) throw std::runtime_error( "walletlock\n" @@ -3326,6 +3440,9 @@ UniValue walletlock(const JSONRPCRequest& request) UniValue encryptwallet(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1)) throw std::runtime_error( "encryptwallet \"passphrase\"\n" @@ -3381,6 +3498,9 @@ UniValue encryptwallet(const JSONRPCRequest& request) UniValue listunspent(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 5) throw std::runtime_error( "listunspent ( minconf maxconf [\"address\",...] watchonlyconfig [query_options])\n" @@ -3556,6 +3676,9 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue lockunspent(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n" @@ -3680,6 +3803,9 @@ UniValue lockunspent(const JSONRPCRequest& request) UniValue listlockunspent(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 0) throw std::runtime_error( "listlockunspent\n" @@ -3725,6 +3851,9 @@ UniValue listlockunspent(const JSONRPCRequest& request) UniValue settxfee(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) throw std::runtime_error( "settxfee amount\n" @@ -3751,6 +3880,9 @@ UniValue settxfee(const JSONRPCRequest& request) UniValue getwalletinfo(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 0) throw std::runtime_error( "getwalletinfo\n" @@ -3829,6 +3961,9 @@ UniValue getwalletinfo(const JSONRPCRequest& request) UniValue getstakingstatus(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 0) throw std::runtime_error( "getstakingstatus\n" @@ -3887,6 +4022,9 @@ UniValue getstakingstatus(const JSONRPCRequest& request) UniValue setstakesplitthreshold(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "setstakesplitthreshold value\n\n" @@ -3895,7 +4033,7 @@ UniValue setstakesplitthreshold(const JSONRPCRequest& request) "higher than the threshold) as possible.\n" "E.g. If the coinstake input + the block reward is 2000, and the split threshold is 499, the corresponding\n" "coinstake transaction will have 4 outputs (of 500 PIV each)." - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. value (numeric, required) Threshold value (in PIV).\n" @@ -3924,6 +4062,9 @@ UniValue setstakesplitthreshold(const JSONRPCRequest& request) UniValue getstakesplitthreshold(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 0) throw std::runtime_error( "getstakesplitthreshold\n" @@ -3940,6 +4081,9 @@ UniValue getstakesplitthreshold(const JSONRPCRequest& request) UniValue autocombinerewards(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + bool fEnable; if (request.params.size() >= 1) fEnable = request.params[0].get_bool(); @@ -3978,6 +4122,9 @@ UniValue autocombinerewards(const JSONRPCRequest& request) UniValue setautocombinethreshold(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.empty() || request.params.size() > 2) throw std::runtime_error( "setautocombinethreshold enable ( value )\n" @@ -3999,8 +4146,6 @@ UniValue setautocombinethreshold(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("setautocombinethreshold", "500.12") + HelpExampleRpc("setautocombinethreshold", "500.12")); - EnsureWallet(); - RPCTypeCheck(request.params, {UniValue::VBOOL, UniValue::VNUM}); bool fEnable = request.params[0].get_bool(); @@ -4037,6 +4182,9 @@ UniValue setautocombinethreshold(const JSONRPCRequest& request) UniValue getautocombinethreshold(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || !request.params.empty()) throw std::runtime_error( "getautocombinethreshold\n" @@ -4051,8 +4199,6 @@ UniValue getautocombinethreshold(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getautocombinethreshold", "") + HelpExampleRpc("getautocombinethreshold", "")); - EnsureWallet(); - LOCK(pwalletMain->cs_wallet); UniValue result(UniValue::VOBJ); @@ -4093,6 +4239,9 @@ UniValue printAddresses() UniValue getsaplingnotescount(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getsaplingnotescount ( minconf )\n" @@ -4129,6 +4278,9 @@ UniValue getsaplingnotescount(const JSONRPCRequest& request) UniValue rescanblockchain(const JSONRPCRequest& request) { + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() > 2) { throw std::runtime_error( "rescanblockchain (start_height) (stop_height)\n" @@ -4147,7 +4299,6 @@ UniValue rescanblockchain(const JSONRPCRequest& request) ); } - EnsureWallet(); WalletRescanReserver reserver(pwalletMain); if (!reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); From 0e21e09fb7cb1c440cc92e6a2128a0dedfd4ddde Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 17:30:12 +0200 Subject: [PATCH 08/27] [Cleanup] Remove un-used printAddresses() function in rpcwallet --- src/wallet/rpcwallet.cpp | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8fb84de52f4d..c9a2682b3381 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4208,35 +4208,6 @@ UniValue getautocombinethreshold(const JSONRPCRequest& request) return result; } -UniValue printAddresses() -{ - std::vector vCoins; - pwalletMain->AvailableCoins(&vCoins); - std::map mapAddresses; - for (const COutput& out : vCoins) { - CTxDestination utxoAddress; - ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, utxoAddress); - std::string strAdd = EncodeDestination(utxoAddress); - - if (mapAddresses.find(strAdd) == mapAddresses.end()) //if strAdd is not already part of the map - mapAddresses[strAdd] = (double)out.tx->tx->vout[out.i].nValue / (double)COIN; - else - mapAddresses[strAdd] += (double)out.tx->tx->vout[out.i].nValue / (double)COIN; - } - - UniValue ret(UniValue::VARR); - for (std::map::const_iterator it = mapAddresses.begin(); it != mapAddresses.end(); ++it) { - UniValue obj(UniValue::VOBJ); - const std::string* strAdd = &(*it).first; - const double* nBalance = &(*it).second; - obj.pushKV("Address ", *strAdd); - obj.pushKV("Balance ", *nBalance); - ret.push_back(obj); - } - - return ret; -} - UniValue getsaplingnotescount(const JSONRPCRequest& request) { if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) From 325baaa1388e2518ba253f250422b92f8917ad72 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 18:16:24 +0200 Subject: [PATCH 09/27] RPC: Do all wallet access through new GetWalletForJSONRPCRequest >>> inspired by bitcoin@d77ad6d41666b4c41abe1ba3b63300df1903643e currently pwalletMain local variables shadow the global. These will be renamed to pwallet in the next commit (kept separate for ease of review) --- src/rpc/budget.cpp | 2 + src/rpc/masternode.cpp | 12 ++++ src/rpc/mining.cpp | 6 ++ src/rpc/misc.cpp | 6 ++ src/rpc/rawtransaction.cpp | 6 +- src/rpc/rpcevo.cpp | 8 ++- src/rpc/server.h | 1 + src/wallet/rpcdump.cpp | 28 ++++++++ src/wallet/rpcwallet.cpp | 140 ++++++++++++++++++++++++++++++++++--- 9 files changed, 196 insertions(+), 13 deletions(-) diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 1cc3ce2ef858..1795b9cebe12 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -97,6 +97,8 @@ void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std UniValue preparebudget(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 08aec8b103b5..301a69e03f47 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -355,6 +355,11 @@ UniValue startmasternode(const JSONRPCRequest& request) throw JSONRPCError(RPC_MISC_ERROR, "startmasternode is not supported when deterministic masternode list is active (DIP3)"); } + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + std::string strCommand; if (request.params.size() >= 1) { strCommand = request.params[0].get_str(); @@ -512,6 +517,11 @@ UniValue createmasternodekey (const JSONRPCRequest& request) UniValue getmasternodeoutputs (const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + return NullUniValue; + if (request.fHelp || (request.params.size() != 0)) throw std::runtime_error( "getmasternodeoutputs\n" @@ -807,6 +817,8 @@ bool DecodeHexMnb(CMasternodeBroadcast& mnb, std::string strHexMnb) { } UniValue createmasternodebroadcast(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e01abbafd56e..022a58cffe52 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -76,6 +76,8 @@ UniValue generateBlocks(const Consensus::Params& consensus, UniValue generate(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -276,6 +278,8 @@ UniValue getgenerate(const JSONRPCRequest& request) UniValue setgenerate(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -442,6 +446,8 @@ static UniValue BIP22ValidationResult(const CValidationState& state) #ifdef ENABLE_MINING_RPC UniValue getblocktemplate(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getblocktemplate ( \"jsonrequestobject\" )\n" diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 3a7b4d1fa472..459833cf355d 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -47,6 +47,8 @@ UniValue getsupplyinfo(const JSONRPCRequest& request); **/ UniValue getinfo(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (request.fHelp || request.params.size() != 0) throw std::runtime_error( "getinfo\n" @@ -376,6 +378,8 @@ class DescribePaymentAddressVisitor : public boost::static_visitor UniValue validateaddress(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "validateaddress \"pivxaddress\"\n" @@ -502,6 +506,8 @@ CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& pa UniValue createmultisig(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) throw std::runtime_error( "createmultisig nrequired [\"key\",...]\n" diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 8fe6334a1da1..d4ca1436bca5 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -253,7 +253,8 @@ UniValue getrawtransaction(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); if (blockindex) result.pushKV("in_active_chain", in_active_chain); - TxToJSON(pwalletMain, *tx, hash_block, result); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + TxToJSON(pwallet, *tx, hash_block, result); return result; } @@ -421,7 +422,8 @@ UniValue decoderawtransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); UniValue result(UniValue::VOBJ); - TxToJSON(pwalletMain, CTransaction(std::move(mtx)), UINT256_ZERO, result); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + TxToJSON(pwallet, CTransaction(std::move(mtx)), UINT256_ZERO, result); return result; } diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 9c0b977ca399..4d968c974ba7 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -375,6 +375,8 @@ static ProRegPL ParseProRegPLParams(const UniValue& params, unsigned int paramId // handles protx_register, and protx_register_prepare static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -493,6 +495,8 @@ UniValue protx_register_prepare(const JSONRPCRequest& request) UniValue protx_register_submit(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -541,6 +545,8 @@ UniValue protx_register_submit(const JSONRPCRequest& request) UniValue protx_register_fund(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -706,7 +712,7 @@ UniValue protx_list(const JSONRPCRequest& request) CheckEvoUpgradeEnforcement(); #ifdef ENABLE_WALLET - CWallet* const pwallet = pwalletMain; + CWallet* const pwallet = GetWalletForJSONRPCRequest(request); #else CWallet* const pwallet = nullptr; #endif diff --git a/src/rpc/server.h b/src/rpc/server.h index 71caf1754d47..4eb31234f2f9 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -202,6 +202,7 @@ class CWallet; #ifdef ENABLE_WALLET // New code should accessing the wallet should be under the ../wallet/ directory +CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request); std::string HelpRequiringPassphrase(CWallet* const pwallet); bool EnsureWalletIsAvailable(CWallet* const pwallet, bool avoidException); void EnsureWalletIsUnlocked(CWallet *pwallet, bool fAllowAnonOnly = false); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 228be36ca926..16eb07c2777b 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -76,6 +76,8 @@ bool IsStakingDerPath(KeyOriginInfo keyOrigin) UniValue importprivkey(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -149,6 +151,8 @@ UniValue importprivkey(const JSONRPCRequest& request) UniValue abortrescan(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -201,6 +205,8 @@ static void ImportAddress(CWallet* const pwallet, const CTxDestination& dest, co UniValue importaddress(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -266,6 +272,8 @@ UniValue importaddress(const JSONRPCRequest& request) UniValue importpubkey(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -321,6 +329,8 @@ UniValue importpubkey(const JSONRPCRequest& request) // TODO: Needs further review over the HD flow, staking addresses and multisig import. UniValue importwallet(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -446,6 +456,8 @@ UniValue importwallet(const JSONRPCRequest& request) UniValue dumpprivkey(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -484,6 +496,8 @@ UniValue dumpprivkey(const JSONRPCRequest& request) UniValue dumpwallet(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -943,6 +957,8 @@ static int64_t GetImportTimestamp(const UniValue& data, int64_t now) UniValue importmulti(const JSONRPCRequest& mainRequest) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(mainRequest); + if (!EnsureWalletIsAvailable(pwalletMain, mainRequest.fHelp)) return NullUniValue; @@ -1097,6 +1113,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) UniValue bip38encrypt(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1146,6 +1164,8 @@ UniValue bip38encrypt(const JSONRPCRequest& request) UniValue bip38decrypt(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1220,6 +1240,8 @@ UniValue bip38decrypt(const JSONRPCRequest& request) UniValue importsaplingkey(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1320,6 +1342,8 @@ UniValue importsaplingkey(const JSONRPCRequest& request) UniValue importsaplingviewingkey(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1424,6 +1448,8 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) UniValue exportsaplingviewingkey(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1465,6 +1491,8 @@ UniValue exportsaplingviewingkey(const JSONRPCRequest& request) UniValue exportsaplingkey(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c9a2682b3381..c67f60ece98c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -37,6 +37,11 @@ int64_t nWalletUnlockTime; static RecursiveMutex cs_nWalletUnlockTime; +CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request) +{ + return pwalletMain; +} + std::string HelpRequiringPassphrase(CWallet* const pwallet) { return pwallet && pwallet->IsCrypted() ? "\nRequires wallet passphrase to be set with walletpassphrase call." : ""; @@ -130,7 +135,7 @@ bool HaveKey(const CWallet* wallet, const CKey& key) UniValue getaddressinfo(const JSONRPCRequest& request) { - CWallet* const pwallet = pwalletMain; + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; @@ -202,7 +207,7 @@ UniValue getaddressinfo(const JSONRPCRequest& request) //ret.pushKV("ischange", pwallet->IsChange(scriptPubKey)); ScriptPubKeyMan* spk_man = pwallet->GetScriptPubKeyMan(); - SaplingScriptPubKeyMan* sspk_man = pwalletMain->GetSaplingScriptPubKeyMan(); + SaplingScriptPubKeyMan* sspk_man = pwallet->GetSaplingScriptPubKeyMan(); CKeyMetadata* meta = nullptr; if (spk_man && pTransDest) { @@ -218,7 +223,7 @@ UniValue getaddressinfo(const JSONRPCRequest& request) // shield destination const libzcash::SaplingPaymentAddress pa = *Standard::GetShieldedDestination(dest); libzcash::SaplingExtendedSpendingKey extsk; - if (pwalletMain->GetSaplingExtendedSpendingKey(pa, extsk)) { + if (pwallet->GetSaplingExtendedSpendingKey(pa, extsk)) { const auto& ivk = extsk.expsk.full_viewing_key().in_viewing_key(); auto it = sspk_man->mapSaplingZKeyMetadata.find(ivk); if (it != sspk_man->mapSaplingZKeyMetadata.end()) { @@ -257,7 +262,8 @@ UniValue getaddressinfo(const JSONRPCRequest& request) UniValue getaddressesbylabel(const JSONRPCRequest& request) { - CWallet* const pwallet = pwalletMain; + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; @@ -287,7 +293,7 @@ UniValue getaddressesbylabel(const JSONRPCRequest& request) // Find all addresses that have the given label UniValue ret(UniValue::VOBJ); - for (auto it = pwalletMain->NewAddressBookIterator(); it.IsValid(); it.Next()) { + for (auto it = pwallet->NewAddressBookIterator(); it.IsValid(); it.Next()) { auto addrBook = it.GetValue(); if (!addrBook.isShielded() && addrBook.name == label) { ret.pushKV(EncodeDestination(*it.GetCTxDestKey(), AddressBook::IsColdStakingPurpose(addrBook.purpose)), AddressBookDataToJSON(addrBook, false)); @@ -303,7 +309,8 @@ UniValue getaddressesbylabel(const JSONRPCRequest& request) UniValue listlabels(const JSONRPCRequest& request) { - CWallet* const pwallet = pwalletMain; + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; @@ -341,7 +348,7 @@ UniValue listlabels(const JSONRPCRequest& request) // Add to a set to sort by label name, then insert into Univalue array std::set label_set; - for (auto it = pwalletMain->NewAddressBookIterator(); it.IsValid(); it.Next()) { + for (auto it = pwallet->NewAddressBookIterator(); it.IsValid(); it.Next()) { auto addrBook = it.GetValue(); if (purpose.empty() || addrBook.purpose == purpose) { label_set.insert(addrBook.name); @@ -371,6 +378,8 @@ CPubKey parseWIFKey(std::string strKey, CWallet* pwallet) UniValue upgradewallet(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -414,7 +423,8 @@ UniValue upgradewallet(const JSONRPCRequest& request) UniValue sethdseed(const JSONRPCRequest& request) { - CWallet* pwallet = pwalletMain; + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; @@ -423,7 +433,7 @@ UniValue sethdseed(const JSONRPCRequest& request) "Set or generate a new HD wallet seed. Non-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n" "HD will have a new HD seed set so that new keys added to the keypool will be derived from this new seed.\n" "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed.\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. newkeypool (boolean, optional, default true): Whether to flush old unused addresses, including change addresses, from the keypool and regenerate it.\n" @@ -444,7 +454,7 @@ UniValue sethdseed(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); LOCK2(cs_main, pwallet->cs_wallet); @@ -479,6 +489,8 @@ UniValue sethdseed(const JSONRPCRequest& request) UniValue getnewaddress(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -503,6 +515,8 @@ UniValue getnewaddress(const JSONRPCRequest& request) UniValue getnewstakingaddress(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -526,6 +540,8 @@ UniValue getnewstakingaddress(const JSONRPCRequest& request) UniValue getnewshieldaddress(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -552,6 +568,8 @@ UniValue getnewshieldaddress(const JSONRPCRequest& request) UniValue listshieldunspent(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -682,6 +700,8 @@ UniValue listshieldunspent(const JSONRPCRequest& request) UniValue delegatoradd(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -720,6 +740,8 @@ UniValue delegatoradd(const JSONRPCRequest& request) UniValue delegatorremove(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -786,6 +808,8 @@ static UniValue ListaddressesForPurpose(CWallet* const pwallet, const std::strin UniValue listdelegators(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -819,6 +843,8 @@ UniValue listdelegators(const JSONRPCRequest& request) UniValue liststakingaddresses(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -845,6 +871,8 @@ UniValue liststakingaddresses(const JSONRPCRequest& request) UniValue listshieldaddresses(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -890,6 +918,8 @@ UniValue listshieldaddresses(const JSONRPCRequest& request) UniValue getrawchangeaddress(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -925,6 +955,8 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) UniValue setlabel(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1038,6 +1070,8 @@ static UniValue ShieldSendManyTo(CWallet * const pwallet, UniValue sendtoaddress(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1218,6 +1252,8 @@ static UniValue CreateColdStakeDelegation(CWallet* const pwallet, const UniValue UniValue delegatestake(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1272,6 +1308,8 @@ UniValue delegatestake(const JSONRPCRequest& request) UniValue rawdelegatestake(const JSONRPCRequest& request) { + CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; @@ -1330,6 +1368,8 @@ static CAmount getBalanceShieldedAddr(CWallet* const pwallet, Optional Date: Thu, 22 Apr 2021 18:56:13 +0200 Subject: [PATCH 10/27] [Trivial] Rename pwalletMain --> pwallet for local variables in RPC --- src/rpc/budget.cpp | 22 +- src/rpc/masternode.cpp | 26 +- src/rpc/mining.cpp | 35 +- src/rpc/misc.cpp | 30 +- src/rpc/rawtransaction.cpp | 24 +- src/rpc/rpcevo.cpp | 43 ++- src/rpc/server.h | 2 +- src/wallet/rpcdump.cpp | 260 +++++++------- src/wallet/rpcwallet.cpp | 719 +++++++++++++++++++------------------ 9 files changed, 583 insertions(+), 578 deletions(-) diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 1795b9cebe12..763b4ed0fde2 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -97,9 +97,9 @@ void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std UniValue preparebudget(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 6) @@ -122,13 +122,9 @@ UniValue preparebudget(const JSONRPCRequest& request) HelpExampleCli("preparebudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500") + HelpExampleRpc("preparebudget", "\"test-proposal\" \"https://forum.pivx.org/t/test-proposal\" 2 820800 \"D9oc6C3dttUbv8zd7zGNq1qKBGf4ZQ1XEE\" 500")); - if (!pwalletMain) { - throw JSONRPCError(RPC_IN_WARMUP, "Try again after active chain is loaded"); - } - - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); std::string strProposalName; std::string strURL; @@ -150,19 +146,19 @@ UniValue preparebudget(const JSONRPCRequest& request) CTransactionRef wtx; // make our change address - CReserveKey keyChange(pwalletMain); - if (!pwalletMain->CreateBudgetFeeTX(wtx, nHash, keyChange, false)) { // 50 PIV collateral for proposal + CReserveKey keyChange(pwallet); + if (!pwallet->CreateBudgetFeeTX(wtx, nHash, keyChange, false)) { // 50 PIV collateral for proposal throw std::runtime_error("Error making collateral transaction for proposal. Please check your wallet balance."); } //send the tx to the network - const CWallet::CommitResult& res = pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get()); + const CWallet::CommitResult& res = pwallet->CommitTransaction(wtx, keyChange, g_connman.get()); if (res.status != CWallet::CommitStatus::OK) throw JSONRPCError(RPC_WALLET_ERROR, res.ToString()); // Store proposal name as a comment - assert(pwalletMain->mapWallet.count(wtx->GetHash())); - pwalletMain->mapWallet.at(wtx->GetHash()).SetComment("Proposal: " + strProposalName); + assert(pwallet->mapWallet.count(wtx->GetHash())); + pwallet->mapWallet.at(wtx->GetHash()).SetComment("Proposal: " + strProposalName); return wtx->GetHash().ToString(); } diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 301a69e03f47..d34a96aad04a 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -355,9 +355,9 @@ UniValue startmasternode(const JSONRPCRequest& request) throw JSONRPCError(RPC_MISC_ERROR, "startmasternode is not supported when deterministic masternode list is active (DIP3)"); } - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; std::string strCommand; @@ -407,7 +407,7 @@ UniValue startmasternode(const JSONRPCRequest& request) bool fLock = (request.params[1].get_str() == "true" ? true : false); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); if (strCommand == "local") { if (!fMasterNode) throw std::runtime_error("you must set masternode=1 in the configuration\n"); @@ -415,7 +415,7 @@ UniValue startmasternode(const JSONRPCRequest& request) if (activeMasternode.GetStatus() != ACTIVE_MASTERNODE_STARTED) { activeMasternode.ResetStatus(); if (fLock) - pwalletMain->Lock(); + pwallet->Lock(); } return activeMasternode.GetStatusMessage(); @@ -444,7 +444,7 @@ UniValue startmasternode(const JSONRPCRequest& request) RelayMNB(mnb, fSuccess, successful, failed); } if (fLock) - pwalletMain->Lock(); + pwallet->Lock(); UniValue returnObj(UniValue::VOBJ); returnObj.pushKV("overall", strprintf("Successfully started %d masternodes, failed to start %d, total %d", successful, failed, successful + failed)); @@ -484,7 +484,7 @@ UniValue startmasternode(const JSONRPCRequest& request) } if (fLock) - pwalletMain->Lock(); + pwallet->Lock(); if(!found) { statusObj.pushKV("success", false); @@ -517,9 +517,9 @@ UniValue createmasternodekey (const JSONRPCRequest& request) UniValue getmasternodeoutputs (const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || (request.params.size() != 0)) @@ -544,7 +544,7 @@ UniValue getmasternodeoutputs (const JSONRPCRequest& request) coinsFilter.fIncludeDelegated = false; coinsFilter.nCoinType = ONLY_10000; std::vector possibleCoins; - pwalletMain->AvailableCoins(&possibleCoins, nullptr, coinsFilter); + pwallet->AvailableCoins(&possibleCoins, nullptr, coinsFilter); UniValue ret(UniValue::VARR); for (COutput& out : possibleCoins) { @@ -817,9 +817,9 @@ bool DecodeHexMnb(CMasternodeBroadcast& mnb, std::string strHexMnb) { } UniValue createmasternodebroadcast(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; std::string strCommand; @@ -829,7 +829,7 @@ UniValue createmasternodebroadcast(const JSONRPCRequest& request) throw std::runtime_error( "createmasternodebroadcast \"command\" ( \"alias\")\n" "\nCreates a masternode broadcast message for one or all masternodes configured in masternode.conf\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"command\" (string, required) \"alias\" for single masternode, \"all\" for all masternodes\n" @@ -860,7 +860,7 @@ UniValue createmasternodebroadcast(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("createmasternodebroadcast", "alias mymn1") + HelpExampleRpc("createmasternodebroadcast", "alias mymn1")); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); if (strCommand == "alias") { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 022a58cffe52..177952a29cec 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -27,7 +27,7 @@ #ifdef ENABLE_WALLET UniValue generateBlocks(const Consensus::Params& consensus, - CWallet* wallet, + CWallet* const pwallet, bool fPoS, const int nGenerate, int nHeight, @@ -40,13 +40,13 @@ UniValue generateBlocks(const Consensus::Params& consensus, // Get available coins std::vector availableCoins; - if (fPoS && !wallet->StakeableCoins(&availableCoins)) { + if (fPoS && !pwallet->StakeableCoins(&availableCoins)) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "No available coins to stake"); } std::unique_ptr pblocktemplate(fPoS ? - BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(CScript(), wallet, true, &availableCoins) : - CreateNewBlockWithScript(*coinbaseScript, wallet)); + BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(CScript(), pwallet, true, &availableCoins) : + CreateNewBlockWithScript(*coinbaseScript, pwallet)); if (!pblocktemplate.get()) break; std::shared_ptr pblock = std::make_shared(pblocktemplate->block); @@ -76,9 +76,9 @@ UniValue generateBlocks(const Consensus::Params& consensus, UniValue generate(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) @@ -118,10 +118,10 @@ UniValue generate(const JSONRPCRequest& request) if (fPoS) { // If we are in PoS, wallet must be unlocked. - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); } else { // Coinbase key - reservekey = MakeUnique(pwalletMain); + reservekey = MakeUnique(pwallet); CPubKey pubkey; if (!reservekey->GetReservedKey(pubkey)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Error: Cannot get key from keypool"); coinbaseScript = GetScriptForDestination(pubkey.GetID()); @@ -129,7 +129,7 @@ UniValue generate(const JSONRPCRequest& request) // Create the blocks UniValue blockHashes = generateBlocks(consensus, - pwalletMain, + pwallet, fPoS, nGenerate, nHeight, @@ -147,6 +147,11 @@ UniValue generate(const JSONRPCRequest& request) UniValue generatetoaddress(const JSONRPCRequest& request) { + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "generatetoaddress numblocks \"address\"\n" @@ -180,7 +185,7 @@ UniValue generatetoaddress(const JSONRPCRequest& request) bool fPoS = consensus.NetworkUpgradeActive(nHeight + 1, Consensus::UPGRADE_POS); return generateBlocks(consensus, - pwalletMain, + pwallet, fPoS, nGenerate, nHeight, @@ -278,9 +283,9 @@ UniValue getgenerate(const JSONRPCRequest& request) UniValue setgenerate(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -321,7 +326,7 @@ UniValue setgenerate(const JSONRPCRequest& request) gArgs.GetArg("-gen", "") = (fGenerate ? "1" : "0"); gArgs.GetArg("-genproclimit", "") = itostr(nGenProcLimit); - GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit); + GenerateBitcoins(fGenerate, pwallet, nGenProcLimit); return NullUniValue; } @@ -446,7 +451,7 @@ static UniValue BIP22ValidationResult(const CValidationState& state) #ifdef ENABLE_MINING_RPC UniValue getblocktemplate(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (request.fHelp || request.params.size() > 1) throw std::runtime_error( @@ -633,7 +638,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request) pblocktemplate = NULL; } CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptDummy, pwalletMain, false); + pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptDummy, pwallet, false); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 459833cf355d..cc7c43154157 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -47,7 +47,7 @@ UniValue getsupplyinfo(const JSONRPCRequest& request); **/ UniValue getinfo(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (request.fHelp || request.params.size() != 0) throw std::runtime_error( @@ -85,7 +85,7 @@ UniValue getinfo(const JSONRPCRequest& request) HelpExampleCli("getinfo", "") + HelpExampleRpc("getinfo", "")); #ifdef ENABLE_WALLET - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); #else LOCK(cs_main); #endif @@ -116,10 +116,10 @@ UniValue getinfo(const JSONRPCRequest& request) obj.pushKV("protocolversion", PROTOCOL_VERSION); obj.pushKV("services", services); #ifdef ENABLE_WALLET - if (pwalletMain) { - obj.pushKV("walletversion", pwalletMain->GetVersion()); - obj.pushKV("balance", ValueFromAmount(pwalletMain->GetAvailableBalance())); - obj.pushKV("staking status", (pwalletMain->pStakerStatus->IsActive() ? "Staking Active" : "Staking Not Active")); + if (pwallet) { + obj.pushKV("walletversion", pwallet->GetVersion()); + obj.pushKV("balance", ValueFromAmount(pwallet->GetAvailableBalance())); + obj.pushKV("staking status", (pwallet->pStakerStatus->IsActive() ? "Staking Active" : "Staking Not Active")); } #endif obj.pushKV("blocks", (int)chainActive.Height()); @@ -137,12 +137,12 @@ UniValue getinfo(const JSONRPCRequest& request) obj.pushKV("shieldsupply", supply_info["shieldsupply"]); #ifdef ENABLE_WALLET - if (pwalletMain) { - obj.pushKV("keypoololdest", pwalletMain->GetOldestKeyPoolTime()); - size_t kpExternalSize = pwalletMain->KeypoolCountExternalKeys(); + if (pwallet) { + obj.pushKV("keypoololdest", pwallet->GetOldestKeyPoolTime()); + size_t kpExternalSize = pwallet->KeypoolCountExternalKeys(); obj.pushKV("keypoolsize", (int64_t)kpExternalSize); } - if (pwalletMain && pwalletMain->IsCrypted()) + if (pwallet && pwallet->IsCrypted()) obj.pushKV("unlocked_until", nWalletUnlockTime); obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); #endif @@ -378,7 +378,7 @@ class DescribePaymentAddressVisitor : public boost::static_visitor UniValue validateaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (request.fHelp || request.params.size() != 1) throw std::runtime_error( @@ -412,7 +412,7 @@ UniValue validateaddress(const JSONRPCRequest& request) HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")); #ifdef ENABLE_WALLET - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : nullptr); + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); #else LOCK(cs_main); #endif @@ -436,7 +436,7 @@ UniValue validateaddress(const JSONRPCRequest& request) ret.pushKV("isvalid", isValid); if (isValid) { ret.pushKV("address", strAddress); - UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(pwalletMain, isStakingAddress), finalAddress); + UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(pwallet, isStakingAddress), finalAddress); ret.pushKVs(detail); } @@ -506,7 +506,7 @@ CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& pa UniValue createmultisig(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) throw std::runtime_error( @@ -535,7 +535,7 @@ UniValue createmultisig(const JSONRPCRequest& request) HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); + CScript inner = _createmultisig_redeemScript(pwallet, request.params); CScriptID innerID(inner); UniValue result(UniValue::VOBJ); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index d4ca1436bca5..ea780e5c0c48 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -485,6 +485,11 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std:: UniValue fundrawtransaction(const JSONRPCRequest& request) { + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "fundrawtransaction \"hexstring\" ( options )\n" @@ -526,12 +531,9 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") ); - if (!pwalletMain) - throw std::runtime_error("wallet not initialized"); - // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); RPCTypeCheck(request.params, {UniValue::VSTR}); @@ -591,7 +593,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) CMutableTransaction tx(origTx); CAmount nFeeOut; std::string strFailReason; - if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) + if(!pwallet->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); @@ -604,6 +606,8 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) UniValue signrawtransaction(const JSONRPCRequest& request) { + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw std::runtime_error( "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n" @@ -613,7 +617,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) "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" #ifdef ENABLE_WALLET - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" #endif "\nArguments:\n" @@ -662,7 +666,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) HelpExampleCli("signrawtransaction", "\"myhex\"") + HelpExampleRpc("signrawtransaction", "\"myhex\"")); #ifdef ENABLE_WALLET - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); #else LOCK(cs_main); #endif @@ -730,8 +734,8 @@ UniValue signrawtransaction(const JSONRPCRequest& request) } } #ifdef ENABLE_WALLET - else if (pwalletMain) - EnsureWalletIsUnlocked(pwalletMain); + else if (pwallet) + EnsureWalletIsUnlocked(pwallet); #endif // Add previous txouts given in the RPC call: @@ -801,7 +805,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) } #ifdef ENABLE_WALLET - const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain); + const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet); #else const CKeyStore& keystore = tempKeystore; #endif diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 4d968c974ba7..a593bcae1a4d 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -317,7 +317,6 @@ static std::string SignAndSendSpecialTx(CWallet* const pwallet, CMutableTransact // Parses inputs (starting from index paramIdx) and returns ProReg payload static ProRegPL ParseProRegPLParams(const UniValue& params, unsigned int paramIdx) { - assert(pwalletMain); assert(params.size() > paramIdx + 4); assert(params.size() < paramIdx + 8); ProRegPL pl; @@ -375,9 +374,9 @@ static ProRegPL ParseProRegPLParams(const UniValue& params, unsigned int paramId // handles protx_register, and protx_register_prepare static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 7 || request.params.size() > 9) { @@ -392,7 +391,7 @@ static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) "key and then passed to \"protx_register_submit\".\n" "The collateral is specified through \"collateralHash\" and \"collateralIndex\" and must be an unspent transaction output.\n" ) - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" + GetHelpString(1, collateralHash) + GetHelpString(2, collateralIndex) @@ -422,10 +421,10 @@ static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) } if (fSignAndSend) CheckEvoUpgradeEnforcement(); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); const uint256& collateralHash = ParseHashV(request.params[0], "collateralHash"); const int32_t collateralIndex = request.params[1].get_int(); @@ -459,19 +458,19 @@ static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("collateral type not supported: %s-%d", collateralHash.ToString(), collateralIndex)); } CKey keyCollateral; - if (fSignAndSend && !pwalletMain->GetKey(*keyID, keyCollateral)) { + if (fSignAndSend && !pwallet->GetKey(*keyID, keyCollateral)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("collateral key not in wallet: %s", EncodeDestination(txDest))); } // make sure fee calculation works pl.vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE); - FundSpecialTx(pwalletMain, tx, pl); + FundSpecialTx(pwallet, tx, pl); if (fSignAndSend) { SignSpecialTxPayloadByString(pl, keyCollateral); // prove we own the collateral // check the payload, add the tx inputs sigs, and send the tx. - return SignAndSendSpecialTx(pwalletMain, tx, pl); + return SignAndSendSpecialTx(pwallet, tx, pl); } // external signing with collateral key pl.vchSig.clear(); @@ -495,9 +494,9 @@ UniValue protx_register_prepare(const JSONRPCRequest& request) UniValue protx_register_submit(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) { @@ -505,7 +504,7 @@ UniValue protx_register_submit(const JSONRPCRequest& request) "protx_register_submit \"tx\" \"sig\"\n" "\nSubmits the specified ProTx to the network. This command will also sign the inputs of the transaction\n" "which were previously added by \"protx_register_prepare\" to cover transaction fees\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"tx\" (string, required) The serialized transaction previously returned by \"protx_register_prepare\"\n" "2. \"sig\" (string, required) The signature signed with the collateral key. Must be in base64 format.\n" @@ -517,10 +516,10 @@ UniValue protx_register_submit(const JSONRPCRequest& request) } CheckEvoUpgradeEnforcement(); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); CMutableTransaction tx; if (!DecodeHexTx(tx, request.params[0].get_str())) { @@ -540,14 +539,14 @@ UniValue protx_register_submit(const JSONRPCRequest& request) pl.vchSig = DecodeBase64(request.params[1].get_str().c_str()); // check the payload, add the tx inputs sigs, and send the tx. - return SignAndSendSpecialTx(pwalletMain, tx, pl); + return SignAndSendSpecialTx(pwallet, tx, pl); } UniValue protx_register_fund(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 6 || request.params.size() > 8) { @@ -555,7 +554,7 @@ UniValue protx_register_fund(const JSONRPCRequest& request) "protx_register_fund \"collateralAddress\" \"ipAndPort\" \"ownerAddress\" \"operatorAddress\" \"votingAddress\" \"payoutAddress\" (operatorReward \"operatorPayoutAddress\")\n" "\nCreates, funds and sends a ProTx to the network. The resulting transaction will move 10000 PIV\n" "to the address specified by collateralAddress and will then function as masternode collateral.\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" + GetHelpString(1, collateralAddress) + GetHelpString(2, ipAndPort_register) @@ -573,10 +572,10 @@ UniValue protx_register_fund(const JSONRPCRequest& request) } CheckEvoUpgradeEnforcement(); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); const CTxDestination& collateralDest(ParsePubKeyIDFromAddress(request.params[0].get_str())); const CScript& collateralScript = GetScriptForDestination(collateralDest); @@ -590,7 +589,7 @@ UniValue protx_register_fund(const JSONRPCRequest& request) tx.nType = CTransaction::TxType::PROREG; tx.vout.emplace_back(collAmt, collateralScript); - FundSpecialTx(pwalletMain, tx, pl); + FundSpecialTx(pwallet, tx, pl); for (uint32_t i = 0; i < tx.vout.size(); i++) { if (tx.vout[i].nValue == collAmt && tx.vout[i].scriptPubKey == collateralScript) { @@ -602,7 +601,7 @@ UniValue protx_register_fund(const JSONRPCRequest& request) // update payload on tx (with final collateral outpoint) pl.vchSig.clear(); // check the payload, add the tx inputs sigs, and send the tx. - return SignAndSendSpecialTx(pwalletMain, tx, pl); + return SignAndSendSpecialTx(pwallet, tx, pl); } #endif //ENABLE_WALLET diff --git a/src/rpc/server.h b/src/rpc/server.h index 4eb31234f2f9..d8544fbc2d23 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -199,10 +199,10 @@ extern std::string HelpExampleRpc(std::string methodname, std::string args); // Needed even with !ENABLE_WALLET, to pass (ignored) pointers around class CWallet; +CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request); #ifdef ENABLE_WALLET // New code should accessing the wallet should be under the ../wallet/ directory -CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request); std::string HelpRequiringPassphrase(CWallet* const pwallet); bool EnsureWalletIsAvailable(CWallet* const pwallet, bool avoidException); void EnsureWalletIsUnlocked(CWallet *pwallet, bool fAllowAnonOnly = false); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 16eb07c2777b..729f94671c0e 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -76,16 +76,16 @@ bool IsStakingDerPath(KeyOriginInfo keyOrigin) UniValue importprivkey(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw std::runtime_error( "importprivkey \"pivxprivkey\" ( \"label\" rescan fStakingAddress )\n" "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"pivxprivkey\" (string, required) The private key (see dumpprivkey)\n" @@ -108,7 +108,7 @@ UniValue importprivkey(const JSONRPCRequest& request) const std::string strLabel = (request.params.size() > 1 ? request.params[1].get_str() : ""); const bool fRescan = (request.params.size() > 2 ? request.params[2].get_bool() : true); - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (fRescan && !reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -122,28 +122,28 @@ UniValue importprivkey(const JSONRPCRequest& request) assert(key.VerifyPubKey(pubkey)); CKeyID vchAddress = pubkey.GetID(); { - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); - pwalletMain->MarkDirty(); - pwalletMain->SetAddressBook(vchAddress, strLabel, ( + pwallet->MarkDirty(); + pwallet->SetAddressBook(vchAddress, strLabel, ( fStakingAddress ? AddressBook::AddressBookPurpose::COLD_STAKING : AddressBook::AddressBookPurpose::RECEIVE)); // Don't throw error in case a key is already there - if (pwalletMain->HaveKey(vchAddress)) + if (pwallet->HaveKey(vchAddress)) return NullUniValue; // whenever a key is imported, we need to scan the whole chain - pwalletMain->UpdateTimeFirstKey(1); - pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; + pwallet->UpdateTimeFirstKey(1); + pwallet->mapKeyMetadata[vchAddress].nCreateTime = 1; - if (!pwalletMain->AddKeyPubKey(key, pubkey)) + if (!pwallet->AddKeyPubKey(key, pubkey)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } if (fRescan) { - pwalletMain->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */); + pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */); } return NullUniValue; @@ -151,9 +151,9 @@ UniValue importprivkey(const JSONRPCRequest& request) UniValue abortrescan(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 0) @@ -169,8 +169,8 @@ UniValue abortrescan(const JSONRPCRequest& request) + HelpExampleRpc("abortrescan", "") ); - if (!pwalletMain->IsScanning() || pwalletMain->IsAbortingRescan()) return false; - pwalletMain->AbortRescan(); + if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) return false; + pwallet->AbortRescan(); return true; } @@ -205,9 +205,9 @@ static void ImportAddress(CWallet* const pwallet, const CTxDestination& dest, co UniValue importaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) @@ -234,7 +234,7 @@ UniValue importaddress(const JSONRPCRequest& request) // Whether to perform rescan after import const bool fRescan = (request.params.size() > 2 ? request.params[2].get_bool() : true); - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (fRescan && !reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -243,7 +243,7 @@ UniValue importaddress(const JSONRPCRequest& request) const bool fP2SH = (request.params.size() > 3 ? request.params[3].get_bool() : false); { - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); bool isStakingAddress = false; CTxDestination dest = DecodeDestination(request.params[0].get_str(), isStakingAddress); @@ -251,20 +251,20 @@ UniValue importaddress(const JSONRPCRequest& request) if (IsValidDestination(dest)) { if (fP2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); - ImportAddress(pwalletMain, dest, strLabel, isStakingAddress ? + ImportAddress(pwallet, dest, strLabel, isStakingAddress ? AddressBook::AddressBookPurpose::COLD_STAKING : AddressBook::AddressBookPurpose::RECEIVE); } else if (IsHex(request.params[0].get_str())) { std::vector data(ParseHex(request.params[0].get_str())); - ImportScript(pwalletMain, CScript(data.begin(), data.end()), strLabel, fP2SH); + ImportScript(pwallet, CScript(data.begin(), data.end()), strLabel, fP2SH); } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid PIVX address or script"); } } if (fRescan) { - pwalletMain->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */); - pwalletMain->ReacceptWalletTransactions(); + pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */); + pwallet->ReacceptWalletTransactions(); } return NullUniValue; @@ -272,9 +272,9 @@ UniValue importaddress(const JSONRPCRequest& request) UniValue importpubkey(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) @@ -300,7 +300,7 @@ UniValue importpubkey(const JSONRPCRequest& request) // Whether to perform rescan after import const bool fRescan = (request.params.size() > 2 ? request.params[2].get_bool() : true); - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (fRescan && !reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -313,14 +313,14 @@ UniValue importpubkey(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); { - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - ImportAddress(pwalletMain, pubKey.GetID(), strLabel, "receive"); - ImportScript(pwalletMain, GetScriptForRawPubKey(pubKey), strLabel, false); + ImportAddress(pwallet, pubKey.GetID(), strLabel, "receive"); + ImportScript(pwallet, GetScriptForRawPubKey(pubKey), strLabel, false); } if (fRescan) { - pwalletMain->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */); - pwalletMain->ReacceptWalletTransactions(); + pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */); + pwallet->ReacceptWalletTransactions(); } return NullUniValue; @@ -329,16 +329,16 @@ UniValue importpubkey(const JSONRPCRequest& request) // TODO: Needs further review over the HD flow, staking addresses and multisig import. UniValue importwallet(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "importwallet \"filename\"\n" "\nImports keys from a wallet dump file (see dumpwallet).\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"filename\" (string, required) The wallet file\n" @@ -356,7 +356,7 @@ UniValue importwallet(const JSONRPCRequest& request) if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (!reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -364,16 +364,16 @@ UniValue importwallet(const JSONRPCRequest& request) int64_t nTimeBegin = 0; bool fGood = true; { - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); nTimeBegin = chainActive.Tip()->GetBlockTime(); int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg()); file.seekg(0, file.beg); - pwalletMain->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI + pwallet->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI while (file.good()) { - pwalletMain->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100)))); + pwallet->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100)))); std::string line; std::getline(file, line); if (line.empty() || line[0] == '#') @@ -386,12 +386,12 @@ UniValue importwallet(const JSONRPCRequest& request) // Sapling keys // Let's see if the address is a valid PIVX spending key - if (pwalletMain->HasSaplingSPKM()) { + if (pwallet->HasSaplingSPKM()) { libzcash::SpendingKey spendingkey = KeyIO::DecodeSpendingKey(vstr[0]); int64_t nTime = DecodeDumpTime(vstr[1]); if (IsValidSpendingKey(spendingkey)) { libzcash::SaplingExtendedSpendingKey saplingSpendingKey = *boost::get(&spendingkey); - auto addResult = pwalletMain->GetSaplingScriptPubKeyMan()->AddSpendingKeyToWallet( + auto addResult = pwallet->GetSaplingScriptPubKeyMan()->AddSpendingKeyToWallet( Params().GetConsensus(), saplingSpendingKey, nTime); if (addResult == KeyAlreadyExists) { LogPrint(BCLog::SAPLING, "Skipping import of shielded addr (key already present)\n"); @@ -409,7 +409,7 @@ UniValue importwallet(const JSONRPCRequest& request) CPubKey pubkey = key.GetPubKey(); assert(key.VerifyPubKey(pubkey)); CKeyID keyid = pubkey.GetID(); - if (pwalletMain->HaveKey(keyid)) { + if (pwallet->HaveKey(keyid)) { LogPrintf("Skipping import of %s (key already present)\n", EncodeDestination(keyid)); continue; } @@ -432,21 +432,21 @@ UniValue importwallet(const JSONRPCRequest& request) } } LogPrintf("Importing %s...\n", EncodeDestination(keyid)); - if (!pwalletMain->AddKeyPubKey(key, pubkey)) { + if (!pwallet->AddKeyPubKey(key, pubkey)) { fGood = false; continue; } - pwalletMain->mapKeyMetadata[keyid].nCreateTime = nTime; + pwallet->mapKeyMetadata[keyid].nCreateTime = nTime; if (fLabel) // TODO: This is not entirely true.. needs to be reviewed properly. - pwalletMain->SetAddressBook(keyid, strLabel, AddressBook::AddressBookPurpose::RECEIVE); + pwallet->SetAddressBook(keyid, strLabel, AddressBook::AddressBookPurpose::RECEIVE); nTimeBegin = std::min(nTimeBegin, nTime); } file.close(); - pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI - pwalletMain->UpdateTimeFirstKey(nTimeBegin); + pwallet->ShowProgress("", 100); // hide progress dialog in GUI + pwallet->UpdateTimeFirstKey(nTimeBegin); } - pwalletMain->RescanFromTime(nTimeBegin, reserver, false /* update */); - pwalletMain->MarkDirty(); + pwallet->RescanFromTime(nTimeBegin, reserver, false /* update */); + pwallet->MarkDirty(); if (!fGood) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); @@ -456,9 +456,9 @@ UniValue importwallet(const JSONRPCRequest& request) UniValue dumpprivkey(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -466,7 +466,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request) "dumpprivkey \"pivxaddress\"\n" "\nReveals the private key corresponding to 'pivxaddress'.\n" "Then the importprivkey can be used with this output\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address for the private key\n" @@ -477,9 +477,9 @@ UniValue dumpprivkey(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("dumpprivkey", "\"myaddress\"") + HelpExampleCli("importprivkey", "\"mykey\"") + HelpExampleRpc("dumpprivkey", "\"myaddress\"")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); std::string strAddress = request.params[0].get_str(); CTxDestination dest = DecodeDestination(strAddress); @@ -489,23 +489,23 @@ UniValue dumpprivkey(const JSONRPCRequest& request) if (!keyID) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); CKey vchSecret; - if (!pwalletMain->GetKey(*keyID, vchSecret)) + if (!pwallet->GetKey(*keyID, vchSecret)) throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); return EncodeSecret(vchSecret); } UniValue dumpwallet(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "dumpwallet \"filename\"\n" "\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"filename\" (string, required) The filename\n" @@ -526,13 +526,13 @@ UniValue dumpwallet(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); - ScriptPubKeyMan* spk_man = pwalletMain->GetScriptPubKeyMan(); + ScriptPubKeyMan* spk_man = pwallet->GetScriptPubKeyMan(); fs::path filepath = request.params[0].get_str().c_str(); filepath = fs::absolute(filepath); @@ -552,7 +552,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); std::map mapKeyBirth; - pwalletMain->GetKeyBirthTimes(mapKeyBirth); + pwallet->GetKeyBirthTimes(mapKeyBirth); const std::map& mapKeyPool = spk_man->GetAllReserveKeys(); @@ -582,7 +582,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) if (!seed_id.IsNull()) { CKey seed; - if (pwalletMain->GetKey(seed_id, seed)) { + if (pwallet->GetKey(seed_id, seed)) { CExtKey masterKey; masterKey.SetSeed(seed.begin(), seed.size()); @@ -594,15 +594,15 @@ UniValue dumpwallet(const JSONRPCRequest& request) const CKeyID& keyid = it->second; std::string strTime = FormatISO8601DateTime(it->first); CKey key; - if (pwalletMain->GetKey(keyid, key)) { - const CKeyMetadata& metadata = pwalletMain->mapKeyMetadata[keyid]; + if (pwallet->GetKey(keyid, key)) { + const CKeyMetadata& metadata = pwallet->mapKeyMetadata[keyid]; std::string strAddr = EncodeDestination(keyid, (metadata.HasKeyOrigin() && IsStakingDerPath(metadata.key_origin) ? CChainParams::STAKING_ADDRESS : CChainParams::PUBKEY_ADDRESS)); file << strprintf("%s %s ", KeyIO::EncodeSecret(key), strTime); - if (pwalletMain->HasAddressBook(keyid)) { - file << strprintf("label=%s", EncodeDumpString(pwalletMain->GetNameForAddressBookEntry(keyid))); + if (pwallet->HasAddressBook(keyid)) { + file << strprintf("label=%s", EncodeDumpString(pwallet->GetNameForAddressBookEntry(keyid))); } else if (keyid == seed_id) { file << "hdseed=1"; } else if (mapKeyPool.count(keyid)) { @@ -618,13 +618,13 @@ UniValue dumpwallet(const JSONRPCRequest& request) file << "# Sapling keys\n"; file << "\n"; std::set saplingAddresses; - pwalletMain->GetSaplingPaymentAddresses(saplingAddresses); + pwallet->GetSaplingPaymentAddresses(saplingAddresses); file << "\n"; for (const auto& addr : saplingAddresses) { libzcash::SaplingExtendedSpendingKey extsk; - if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) { + if (pwallet->GetSaplingExtendedSpendingKey(addr, extsk)) { auto ivk = extsk.expsk.full_viewing_key().in_viewing_key(); - CKeyMetadata keyMeta = pwalletMain->GetSaplingScriptPubKeyMan()->mapSaplingZKeyMetadata[ivk]; + CKeyMetadata keyMeta = pwallet->GetSaplingScriptPubKeyMan()->mapSaplingZKeyMetadata[ivk]; std::string strTime = FormatISO8601DateTime(keyMeta.nCreateTime); // Keys imported with importsaplingkey do not have key origin metadata file << strprintf("%s %s # shielded_addr=%s%s\n", @@ -957,16 +957,16 @@ static int64_t GetImportTimestamp(const UniValue& data, int64_t now) UniValue importmulti(const JSONRPCRequest& mainRequest) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(mainRequest); + CWallet * const pwallet = GetWalletForJSONRPCRequest(mainRequest); - if (!EnsureWalletIsAvailable(pwalletMain, mainRequest.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, mainRequest.fHelp)) return NullUniValue; if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2) throw std::runtime_error( "importmulti \"requests\" ( \"options\" )\n" "\nImport addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. requests (array, required) Data to be imported\n" @@ -1025,7 +1025,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) } } - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (fRescan && !reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -1036,8 +1036,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) UniValue response(UniValue::VARR); { - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); // Verify all timestamps are present before importing any keys. int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; @@ -1055,7 +1055,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) for (const UniValue& data: requests.getValues()) { const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp); - const UniValue result = processImport(pwalletMain, data, timestamp); + const UniValue result = processImport(pwallet, data, timestamp); response.push_back(result); if (!fRescan) { @@ -1074,8 +1074,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) } } if (fRescan && fRunScan && requests.size()) { - int64_t scannedTime = pwalletMain->RescanFromTime(nLowestTimestamp, reserver, true /* update */); - pwalletMain->ReacceptWalletTransactions(); + int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, reserver, true /* update */); + pwallet->ReacceptWalletTransactions(); if (scannedTime > nLowestTimestamp) { std::vector results = response.getValues(); @@ -1113,16 +1113,16 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) UniValue bip38encrypt(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "bip38encrypt \"pivxaddress\" \"passphrase\"\n" "\nEncrypts a private key corresponding to 'pivxaddress'.\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address for the private key (you must hold the key already)\n" @@ -1135,9 +1135,9 @@ UniValue bip38encrypt(const JSONRPCRequest& request) HelpExampleCli("bip38encrypt", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"mypasphrase\"") + HelpExampleRpc("bip38encrypt", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"mypasphrase\"")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); std::string strAddress = request.params[0].get_str(); std::string strPassphrase = request.params[1].get_str(); @@ -1149,7 +1149,7 @@ UniValue bip38encrypt(const JSONRPCRequest& request) if (!keyID) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); CKey vchSecret; - if (!pwalletMain->GetKey(*keyID, vchSecret)) + if (!pwallet->GetKey(*keyID, vchSecret)) throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); uint256 privKey = vchSecret.GetPrivKey_256(); @@ -1164,16 +1164,16 @@ UniValue bip38encrypt(const JSONRPCRequest& request) UniValue bip38decrypt(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "bip38decrypt \"pivxaddress\" \"passphrase\"\n" "\nDecrypts and then imports password protected private key.\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"encryptedkey\" (string, required) The encrypted private key\n" @@ -1205,7 +1205,7 @@ UniValue bip38decrypt(const JSONRPCRequest& request) if (!key.IsValid()) throw JSONRPCError(RPC_WALLET_ERROR, "Private Key Not Valid"); - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (!reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -1215,23 +1215,23 @@ UniValue bip38decrypt(const JSONRPCRequest& request) result.pushKV("Address", EncodeDestination(pubkey.GetID())); CKeyID vchAddress = pubkey.GetID(); { - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); - pwalletMain->MarkDirty(); - pwalletMain->SetAddressBook(vchAddress, "", AddressBook::AddressBookPurpose::RECEIVE); + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); + pwallet->MarkDirty(); + pwallet->SetAddressBook(vchAddress, "", AddressBook::AddressBookPurpose::RECEIVE); // Don't throw error in case a key is already there - if (pwalletMain->HaveKey(vchAddress)) + if (pwallet->HaveKey(vchAddress)) throw JSONRPCError(RPC_WALLET_ERROR, "Key already held by wallet"); - pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; + pwallet->mapKeyMetadata[vchAddress].nCreateTime = 1; - if (!pwalletMain->AddKeyPubKey(key, pubkey)) + if (!pwallet->AddKeyPubKey(key, pubkey)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } // whenever a key is imported, we need to scan the whole chain - pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), nullptr, reserver, true); + pwallet->ScanForWalletTransactions(chainActive.Genesis(), nullptr, reserver, true); return result; } @@ -1240,16 +1240,16 @@ UniValue bip38decrypt(const JSONRPCRequest& request) UniValue importsaplingkey(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw std::runtime_error( "importsaplingkey \"key\" ( rescan startHeight )\n" "\nAdds a key (as returned by exportsaplingkey) to your wallet.\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"key\" (string, required) The zkey (see exportsaplingkey)\n" @@ -1292,7 +1292,7 @@ UniValue importsaplingkey(const JSONRPCRequest& request) } } - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (fRescan && !reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -1300,8 +1300,8 @@ UniValue importsaplingkey(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); CBlockIndex* pindexRescan{nullptr}; { - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); // Height to rescan from int nRescanHeight = 0; @@ -1321,11 +1321,11 @@ UniValue importsaplingkey(const JSONRPCRequest& request) result.pushKV("address", KeyIO::EncodePaymentAddress( saplingSpendingKey.DefaultAddress())); // Sapling support - auto addResult = pwalletMain->GetSaplingScriptPubKeyMan()->AddSpendingKeyToWallet(Params().GetConsensus(), saplingSpendingKey, -1); + auto addResult = pwallet->GetSaplingScriptPubKeyMan()->AddSpendingKeyToWallet(Params().GetConsensus(), saplingSpendingKey, -1); if (addResult == KeyAlreadyExists && fIgnoreExistingKey) { return result; } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); if (addResult == KeyNotAdded) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding spending key to wallet"); } @@ -1334,7 +1334,7 @@ UniValue importsaplingkey(const JSONRPCRequest& request) // We want to scan for transactions and notes if (fRescan) { - pwalletMain->ScanForWalletTransactions(pindexRescan, nullptr, reserver, true); + pwallet->ScanForWalletTransactions(pindexRescan, nullptr, reserver, true); } return result; @@ -1342,16 +1342,16 @@ UniValue importsaplingkey(const JSONRPCRequest& request) UniValue importsaplingviewingkey(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw std::runtime_error( "importsaplingviewingkey \"vkey\" ( rescan startHeight )\n" "\nAdds a viewing key (as returned by exportsaplingviewingkey) to your wallet.\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"vkey\" (string, required) The viewing key (see exportsaplingviewingkey)\n" @@ -1394,7 +1394,7 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) } } - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (fRescan && !reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -1402,8 +1402,8 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); CBlockIndex* pindexRescan{nullptr}; { - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); // Height to rescan from int nRescanHeight = 0; @@ -1422,7 +1422,7 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) libzcash::SaplingExtendedFullViewingKey efvk = *boost::get(&viewingkey); result.pushKV("address", KeyIO::EncodePaymentAddress(efvk.DefaultAddress())); - auto addResult = pwalletMain->GetSaplingScriptPubKeyMan()->AddViewingKeyToWallet(efvk); + auto addResult = pwallet->GetSaplingScriptPubKeyMan()->AddViewingKeyToWallet(efvk); if (addResult == SpendingKeyExists) { throw JSONRPCError( RPC_WALLET_ERROR, @@ -1430,7 +1430,7 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) } else if (addResult == KeyAlreadyExists && fIgnoreExistingKey) { return result; } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); if (addResult == KeyNotAdded) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding viewing key to wallet"); } @@ -1440,7 +1440,7 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) // We want to scan for transactions and notes if (fRescan) { - pwalletMain->ScanForWalletTransactions(pindexRescan, nullptr, reserver, true); + pwallet->ScanForWalletTransactions(pindexRescan, nullptr, reserver, true); } return result; @@ -1448,9 +1448,9 @@ UniValue importsaplingviewingkey(const JSONRPCRequest& request) UniValue exportsaplingviewingkey(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -1458,7 +1458,7 @@ UniValue exportsaplingviewingkey(const JSONRPCRequest& request) "exportsaplingviewingkey \"shield_addr\"\n" "\nReveals the viewing key corresponding to 'shield_addr'.\n" "Then the importsaplingviewingkey can be used with this output\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"shield_addr\" (string, required) The shield addr for the viewing key\n" @@ -1471,9 +1471,9 @@ UniValue exportsaplingviewingkey(const JSONRPCRequest& request) + HelpExampleRpc("exportsaplingviewingkey", "\"myaddress\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); std::string strAddress = request.params[0].get_str(); auto address = KeyIO::DecodePaymentAddress(strAddress); @@ -1481,7 +1481,7 @@ UniValue exportsaplingviewingkey(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid shield addr"); } const libzcash::SaplingPaymentAddress &sapAddr = *boost::get(&address); - auto vk = pwalletMain->GetSaplingScriptPubKeyMan()->GetViewingKeyForPaymentAddress(sapAddr); + auto vk = pwallet->GetSaplingScriptPubKeyMan()->GetViewingKeyForPaymentAddress(sapAddr); if (vk) { return KeyIO::EncodeViewingKey(vk.get()); } else { @@ -1491,9 +1491,9 @@ UniValue exportsaplingviewingkey(const JSONRPCRequest& request) UniValue exportsaplingkey(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -1501,7 +1501,7 @@ UniValue exportsaplingkey(const JSONRPCRequest& request) "exportsaplingkey \"shield_addr\"\n" "\nReveals the key corresponding to the 'shield_addr'.\n" "Then the importsaplingkey can be used with this output\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"addr\" (string, required) The shield addr for the private key\n" @@ -1514,9 +1514,9 @@ UniValue exportsaplingkey(const JSONRPCRequest& request) + HelpExampleRpc("exportsaplingkey", "\"myaddress\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); std::string strAddress = request.params[0].get_str(); @@ -1527,7 +1527,7 @@ UniValue exportsaplingkey(const JSONRPCRequest& request) libzcash::SaplingPaymentAddress addr = *boost::get(&address); // Sapling support - Optional sk = pwalletMain->GetSaplingScriptPubKeyMan()->GetSpendingKeyForPaymentAddress(addr); + Optional sk = pwallet->GetSaplingScriptPubKeyMan()->GetSpendingKeyForPaymentAddress(addr); if (!sk) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key for this shield addr"); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c67f60ece98c..63d3f8e04c5f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -378,9 +378,9 @@ CPubKey parseWIFKey(std::string strKey, CWallet* pwallet) UniValue upgradewallet(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -392,28 +392,28 @@ UniValue upgradewallet(const JSONRPCRequest& request) "Enabling the Sapling key manager. Sapling keys will be deterministically derived by the same HD wallet seed.\n" "Wallets that are running the latest Sapling version will not be upgraded" "\nNote that you will need to MAKE A NEW BACKUP of your wallet after upgrade it.\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" + HelpExampleCli("upgradewallet", "") + HelpExampleRpc("upgradewallet", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Do not do anything to wallets already upgraded - if (pwalletMain->CanSupportFeature(FEATURE_LATEST)) { + if (pwallet->CanSupportFeature(FEATURE_LATEST)) { throw JSONRPCError(RPC_WALLET_ERROR, "Cannot upgrade the wallet. The wallet is already running the latest version"); } - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Get version - int prev_version = pwalletMain->GetVersion(); + int prev_version = pwallet->GetVersion(); // Upgrade wallet's version - pwalletMain->SetMinVersion(FEATURE_LATEST); - pwalletMain->SetMaxVersion(FEATURE_LATEST); + pwallet->SetMinVersion(FEATURE_LATEST); + pwallet->SetMaxVersion(FEATURE_LATEST); // Upgrade to HD std::string upgradeError; - if (!pwalletMain->Upgrade(upgradeError, prev_version)) { + if (!pwallet->Upgrade(upgradeError, prev_version)) { upgradeError = strprintf("Error: Cannot upgrade wallet, %s", upgradeError); throw JSONRPCError(RPC_WALLET_ERROR, upgradeError); } @@ -489,9 +489,9 @@ UniValue sethdseed(const JSONRPCRequest& request) UniValue getnewaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -510,14 +510,14 @@ UniValue getnewaddress(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getnewaddress", "") + HelpExampleRpc("getnewaddress", "")); - return EncodeDestination(GetNewAddressFromLabel(pwalletMain, AddressBook::AddressBookPurpose::RECEIVE, request.params)); + return EncodeDestination(GetNewAddressFromLabel(pwallet, AddressBook::AddressBookPurpose::RECEIVE, request.params)); } UniValue getnewstakingaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -535,21 +535,21 @@ UniValue getnewstakingaddress(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getnewstakingaddress", "") + HelpExampleRpc("getnewstakingaddress", "")); - return EncodeDestination(GetNewAddressFromLabel(pwalletMain, "coldstaking", request.params, CChainParams::STAKING_ADDRESS), CChainParams::STAKING_ADDRESS); + return EncodeDestination(GetNewAddressFromLabel(pwallet, "coldstaking", request.params, CChainParams::STAKING_ADDRESS), CChainParams::STAKING_ADDRESS); } UniValue getnewshieldaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getnewshieldaddress\n" "\nReturns a new shield address for receiving payments.\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nResult:\n" "\"address\" (string) The new shield address.\n" @@ -559,18 +559,18 @@ UniValue getnewshieldaddress(const JSONRPCRequest& request) + HelpExampleRpc("getnewshieldaddress", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); - return KeyIO::EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey()); + return KeyIO::EncodePaymentAddress(pwallet->GenerateNewSaplingZKey()); } UniValue listshieldunspent(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 4) @@ -627,7 +627,7 @@ UniValue listshieldunspent(const JSONRPCRequest& request) std::set shieldAddrs = {}; bool fIncludeWatchonly = request.params.size() > 2 && request.params[2].get_bool(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // User has supplied shield addrs to filter on if (request.params.size() > 3) { @@ -649,7 +649,7 @@ UniValue listshieldunspent(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, address is not a valid shield address: ") + address); } libzcash::SaplingPaymentAddress paymentAddress = *boost::get(&shieldAddr); - bool hasSpendingKey = pwalletMain->HaveSpendingKeyForPaymentAddress(paymentAddress); + bool hasSpendingKey = pwallet->HaveSpendingKeyForPaymentAddress(paymentAddress); if (!fIncludeWatchonly && !hasSpendingKey) { throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, spending key for address does not belong to wallet: ") + address); } @@ -663,7 +663,7 @@ UniValue listshieldunspent(const JSONRPCRequest& request) } else { // User did not provide shield addrs, so use default i.e. all addresses std::set saplingzaddrs = {}; - pwalletMain->GetSaplingPaymentAddresses(saplingzaddrs); + pwallet->GetSaplingPaymentAddresses(saplingzaddrs); shieldAddrs.insert(saplingzaddrs.begin(), saplingzaddrs.end()); } @@ -671,23 +671,23 @@ UniValue listshieldunspent(const JSONRPCRequest& request) if (shieldAddrs.size() > 0) { std::vector saplingEntries; - pwalletMain->GetSaplingScriptPubKeyMan()->GetFilteredNotes(saplingEntries, shieldAddrs, nMinDepth, nMaxDepth, true, !fIncludeWatchonly, false); - std::set> nullifierSet = pwalletMain->GetSaplingScriptPubKeyMan()->GetNullifiersForAddresses(shieldAddrs); + pwallet->GetSaplingScriptPubKeyMan()->GetFilteredNotes(saplingEntries, shieldAddrs, nMinDepth, nMaxDepth, true, !fIncludeWatchonly, false); + std::set> nullifierSet = pwallet->GetSaplingScriptPubKeyMan()->GetNullifiersForAddresses(shieldAddrs); for (const auto& entry : saplingEntries) { UniValue obj(UniValue::VOBJ); obj.pushKV("txid", entry.op.hash.ToString()); obj.pushKV("outindex", (int)entry.op.n); obj.pushKV("confirmations", entry.confirmations); - bool hasSaplingSpendingKey = pwalletMain->HaveSpendingKeyForPaymentAddress(entry.address); + bool hasSaplingSpendingKey = pwallet->HaveSpendingKeyForPaymentAddress(entry.address); obj.pushKV("spendable", hasSaplingSpendingKey); obj.pushKV("address", KeyIO::EncodePaymentAddress(entry.address)); obj.pushKV("amount", ValueFromAmount(CAmount(entry.note.value()))); // note.value() is equivalent to plaintext.value() obj.pushKV("memo", HexStrTrimmed(entry.memo)); if (hasSaplingSpendingKey) { - obj.pushKV("change", pwalletMain->GetSaplingScriptPubKeyMan()->IsNoteSaplingChange(nullifierSet, entry.address, entry.op)); + obj.pushKV("change", pwallet->GetSaplingScriptPubKeyMan()->IsNoteSaplingChange(nullifierSet, entry.address, entry.op)); } - const auto& nd = pwalletMain->mapWallet.at(entry.op.hash).mapSaplingNoteData.at(entry.op); + const auto& nd = pwallet->mapWallet.at(entry.op.hash).mapSaplingNoteData.at(entry.op); if (nd.nullifier) { obj.pushKV("nullifier", nd.nullifier->ToString()); } @@ -700,9 +700,9 @@ UniValue listshieldunspent(const JSONRPCRequest& request) UniValue delegatoradd(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -735,14 +735,14 @@ UniValue delegatoradd(const JSONRPCRequest& request) if (!keyID) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get KeyID from PIVX address"); - return pwalletMain->SetAddressBook(*keyID, strLabel, AddressBook::AddressBookPurpose::DELEGATOR); + return pwallet->SetAddressBook(*keyID, strLabel, AddressBook::AddressBookPurpose::DELEGATOR); } UniValue delegatorremove(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -770,16 +770,16 @@ UniValue delegatorremove(const JSONRPCRequest& request) if (!keyID) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get KeyID from PIVX address"); - if (!pwalletMain->HasAddressBook(*keyID)) + if (!pwallet->HasAddressBook(*keyID)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get PIVX address from addressBook"); std::string label = ""; - auto optAdd = pwalletMain->GetAddressBookEntry(dest); + auto optAdd = pwallet->GetAddressBookEntry(dest); if (optAdd) { label = optAdd->name; } - return pwalletMain->SetAddressBook(*keyID, label, AddressBook::AddressBookPurpose::DELEGABLE); + return pwallet->SetAddressBook(*keyID, label, AddressBook::AddressBookPurpose::DELEGABLE); } static UniValue ListaddressesForPurpose(CWallet* const pwallet, const std::string strPurpose) @@ -808,9 +808,9 @@ static UniValue ListaddressesForPurpose(CWallet* const pwallet, const std::strin UniValue listdelegators(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -837,15 +837,15 @@ UniValue listdelegators(const JSONRPCRequest& request) const bool fBlacklist = (request.params.size() > 0 ? request.params[0].get_bool() : false); return (fBlacklist ? - ListaddressesForPurpose(pwalletMain, AddressBook::AddressBookPurpose::DELEGABLE) : - ListaddressesForPurpose(pwalletMain, AddressBook::AddressBookPurpose::DELEGATOR)); + ListaddressesForPurpose(pwallet, AddressBook::AddressBookPurpose::DELEGABLE) : + ListaddressesForPurpose(pwallet, AddressBook::AddressBookPurpose::DELEGATOR)); } UniValue liststakingaddresses(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -866,14 +866,14 @@ UniValue liststakingaddresses(const JSONRPCRequest& request) HelpExampleCli("liststakingaddresses" , "") + HelpExampleRpc("liststakingaddresses", "")); - return ListaddressesForPurpose(pwalletMain, AddressBook::AddressBookPurpose::COLD_STAKING); + return ListaddressesForPurpose(pwallet, AddressBook::AddressBookPurpose::COLD_STAKING); } UniValue listshieldaddresses(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -895,7 +895,7 @@ UniValue listshieldaddresses(const JSONRPCRequest& request) + HelpExampleRpc("listshieldaddresses", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); bool fIncludeWatchonly = false; if (request.params.size() > 0) { @@ -905,11 +905,11 @@ UniValue listshieldaddresses(const JSONRPCRequest& request) UniValue ret(UniValue::VARR); std::set addresses; - pwalletMain->GetSaplingPaymentAddresses(addresses); + pwallet->GetSaplingPaymentAddresses(addresses); libzcash::SaplingIncomingViewingKey ivk; libzcash::SaplingExtendedFullViewingKey extfvk; for (libzcash::SaplingPaymentAddress addr : addresses) { - if (fIncludeWatchonly || pwalletMain->HaveSpendingKeyForPaymentAddress(addr)) { + if (fIncludeWatchonly || pwallet->HaveSpendingKeyForPaymentAddress(addr)) { ret.push_back(KeyIO::EncodePaymentAddress(addr)); } } @@ -918,9 +918,9 @@ UniValue listshieldaddresses(const JSONRPCRequest& request) UniValue getrawchangeaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -935,12 +935,12 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getrawchangeaddress", "") + HelpExampleRpc("getrawchangeaddress", "")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - if (!pwalletMain->IsLocked()) - pwalletMain->TopUpKeyPool(); + if (!pwallet->IsLocked()) + pwallet->TopUpKeyPool(); - CReserveKey reservekey(pwalletMain); + CReserveKey reservekey(pwallet); CPubKey vchPubKey; if (!reservekey.GetReservedKey(vchPubKey, true)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); @@ -955,9 +955,9 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) UniValue setlabel(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) @@ -972,16 +972,16 @@ UniValue setlabel(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("setlabel", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"tabby\"") + HelpExampleRpc("setlabel", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", \"tabby\"")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CTxDestination dest = DecodeDestination(request.params[0].get_str()); if (!IsValidDestination(dest)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid PIVX address"); - std::string old_label = pwalletMain->GetNameForAddressBookEntry(dest); + std::string old_label = pwallet->GetNameForAddressBookEntry(dest); std::string label = LabelFromValue(request.params[1]); - pwalletMain->SetAddressBook(dest, label, ""); + pwallet->SetAddressBook(dest, label, ""); return NullUniValue; } @@ -1070,16 +1070,16 @@ static UniValue ShieldSendManyTo(CWallet * const pwallet, UniValue sendtoaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) throw std::runtime_error( "sendtoaddress \"pivxaddress\" amount ( \"comment\" \"comment-to\" )\n" "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address to send to.\n" @@ -1098,11 +1098,11 @@ UniValue sendtoaddress(const JSONRPCRequest& request) HelpExampleCli("sendtoaddress", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" 0.1 \"donation\" \"seans outpost\"") + HelpExampleRpc("sendtoaddress", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", 0.1, \"donation\", \"seans outpost\"")); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); bool isStaking = false, isShielded = false; const std::string addrStr = request.params[0].get_str(); @@ -1117,7 +1117,7 @@ UniValue sendtoaddress(const JSONRPCRequest& request) if (isShielded) { UniValue sendTo(UniValue::VOBJ); sendTo.pushKV(addrStr, request.params[1]); - return ShieldSendManyTo(pwalletMain, sendTo, commentStr, toStr, 1, false); + return ShieldSendManyTo(pwallet, sendTo, commentStr, toStr, 1, false); } const CTxDestination& address = *Standard::GetTransparentDestination(destination); @@ -1126,10 +1126,10 @@ UniValue sendtoaddress(const JSONRPCRequest& request) CAmount nAmount = AmountFromValue(request.params[1]); CTransactionRef tx; - SendMoney(pwalletMain, address, nAmount, tx); + SendMoney(pwallet, address, nAmount, tx); // Wallet comments - CWalletTx& wtx = pwalletMain->mapWallet.at(tx->GetHash()); + CWalletTx& wtx = pwallet->mapWallet.at(tx->GetHash()); if (!commentStr.empty()) wtx.mapValue["comment"] = commentStr; if (!toStr.empty()) @@ -1252,16 +1252,16 @@ static UniValue CreateColdStakeDelegation(CWallet* const pwallet, const UniValue UniValue delegatestake(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 7) throw std::runtime_error( "delegatestake \"stakingaddress\" amount ( \"owneraddress\" fExternalOwner fUseDelegated fFromShield fForceNotEnabled )\n" "\nDelegate an amount to a given address for cold staking. The amount is a real and is rounded to the nearest 0.00000001\n" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"stakingaddress\" (string, required) The pivx staking address to delegate.\n" @@ -1286,19 +1286,19 @@ UniValue delegatestake(const JSONRPCRequest& request) HelpExampleCli("delegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\" 1000 \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"") + HelpExampleRpc("delegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\", 1000, \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"")); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CTransactionRef wtx; - CReserveKey reservekey(pwalletMain); - UniValue ret = CreateColdStakeDelegation(pwalletMain, request.params, wtx, reservekey); + CReserveKey reservekey(pwallet); + UniValue ret = CreateColdStakeDelegation(pwallet, request.params, wtx, reservekey); - const CWallet::CommitResult& res = pwalletMain->CommitTransaction(wtx, reservekey, g_connman.get()); + const CWallet::CommitResult& res = pwallet->CommitTransaction(wtx, reservekey, g_connman.get()); if (res.status != CWallet::CommitStatus::OK) throw JSONRPCError(RPC_WALLET_ERROR, res.ToString()); @@ -1308,9 +1308,9 @@ UniValue delegatestake(const JSONRPCRequest& request) UniValue rawdelegatestake(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 7) @@ -1318,7 +1318,7 @@ UniValue rawdelegatestake(const JSONRPCRequest& request) "rawdelegatestake \"stakingaddress\" amount ( \"owneraddress\" fExternalOwner fUseDelegated fFromShield )\n" "\nDelegate an amount to a given address for cold staking. The amount is a real and is rounded to the nearest 0.00000001\n" "\nDelegate transaction is returned as json object." + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"stakingaddress\" (string, required) The pivx staking address to delegate.\n" @@ -1339,17 +1339,17 @@ UniValue rawdelegatestake(const JSONRPCRequest& request) HelpExampleCli("rawdelegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\" 1000 \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"") + HelpExampleRpc("rawdelegatestake", "\"S1t2a3kab9c8c71VA78xxxy4MxZg6vgeS6\", 1000, \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg34fk\"")); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CTransactionRef wtx; - CReserveKey reservekey(pwalletMain); - CreateColdStakeDelegation(pwalletMain, request.params, wtx, reservekey); + CReserveKey reservekey(pwallet); + CreateColdStakeDelegation(pwallet, request.params, wtx, reservekey); return EncodeHexTx(*wtx); } @@ -1359,7 +1359,7 @@ static CAmount getBalanceShieldedAddr(CWallet* const pwallet, Optional saplingEntries; LOCK2(cs_main, pwallet->cs_wallet); - pwalletMain->GetSaplingScriptPubKeyMan()->GetFilteredNotes(saplingEntries, filterAddress, minDepth, true, ignoreUnspendable); + pwallet->GetSaplingScriptPubKeyMan()->GetFilteredNotes(saplingEntries, filterAddress, minDepth, true, ignoreUnspendable); for (auto & entry : saplingEntries) { balance += CAmount(entry.note.value()); } @@ -1368,9 +1368,9 @@ static CAmount getBalanceShieldedAddr(CWallet* const pwallet, Optional 3) @@ -1400,7 +1400,7 @@ UniValue getshieldbalance(const JSONRPCRequest& request) + HelpExampleRpc("getshieldbalance", "\"*\" \"5\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); Optional address; if (request.params.size() > 0) { @@ -1419,22 +1419,22 @@ UniValue getshieldbalance(const JSONRPCRequest& request) } const bool fIncludeWatchonly = request.params.size() > 2 && request.params[2].get_bool(); - CAmount nBalance = getBalanceShieldedAddr(pwalletMain, address, nMinDepth, !fIncludeWatchonly); + CAmount nBalance = getBalanceShieldedAddr(pwallet, address, nMinDepth, !fIncludeWatchonly); return ValueFromAmount(nBalance); } UniValue viewshieldtransaction(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "viewshieldtransaction \"txid\"\n" "\nGet detailed shield information about in-wallet transaction \"txid\"\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" @@ -1472,25 +1472,25 @@ UniValue viewshieldtransaction(const JSONRPCRequest& request) + HelpExampleRpc("viewshieldtransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); - if (!pwalletMain->HasSaplingSPKM()) { + if (!pwallet->HasSaplingSPKM()) { throw JSONRPCError(RPC_WALLET_ERROR, "Sapling wallet not initialized."); } - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); uint256 hash; hash.SetHex(request.params[0].get_str()); UniValue entry(UniValue::VOBJ); - if (!pwalletMain->mapWallet.count(hash)) + if (!pwallet->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - const CWalletTx& wtx = pwalletMain->mapWallet.at(hash); + const CWalletTx& wtx = pwallet->mapWallet.at(hash); if (!wtx.tx->IsShieldedTx()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid transaction, no shield data available"); @@ -1521,7 +1521,7 @@ UniValue viewshieldtransaction(const JSONRPCRequest& request) } }; - auto sspkm = pwalletMain->GetSaplingScriptPubKeyMan(); + auto sspkm = pwallet->GetSaplingScriptPubKeyMan(); // Collect OutgoingViewingKeys for recovering output information std::set ovks; @@ -1543,8 +1543,8 @@ UniValue viewshieldtransaction(const JSONRPCRequest& request) std::string addrStr = "unknown"; UniValue amountStr = UniValue("unknown"); CAmount amount = 0; - auto wtxPrevIt = pwalletMain->mapWallet.find(op.hash); - if (wtxPrevIt != pwalletMain->mapWallet.end()) { + auto wtxPrevIt = pwallet->mapWallet.find(op.hash); + if (wtxPrevIt != pwallet->mapWallet.end()) { const auto ndIt = wtxPrevIt->second.mapSaplingNoteData.find(op); if (ndIt != wtxPrevIt->second.mapSaplingNoteData.end()) { // get cached address and amount @@ -1759,9 +1759,9 @@ static SaplingOperation CreateShieldedTransaction(CWallet* const pwallet, const UniValue shieldsendmany(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) @@ -1770,7 +1770,7 @@ UniValue shieldsendmany(const JSONRPCRequest& request) "\nSend to many recipients. Amounts are decimal numbers with at most 8 digits of precision." "\nChange generated from a transparent addr flows to a new transparent addr address, while change generated from a shield addr returns to itself." "\nWhen sending coinbase UTXOs to a shield addr, change is not allowed. The entire value of the UTXO(s) must be consumed." - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"fromaddress\" (string, required) The transparent addr or shield addr to send the funds from.\n" @@ -1797,13 +1797,13 @@ UniValue shieldsendmany(const JSONRPCRequest& request) "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", [{\"address\": \"ps1ra969yfhvhp73rw5ak2xvtcm9fkuqsnmad7qln79mphhdrst3lwu9vvv03yuyqlh42p42st47qd\" ,\"amount\": 5.0}]") ); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - SaplingOperation operation = CreateShieldedTransaction(pwalletMain, request); + SaplingOperation operation = CreateShieldedTransaction(pwallet, request); std::string txHash; auto res = operation.send(txHash); if (!res) @@ -1813,9 +1813,9 @@ UniValue shieldsendmany(const JSONRPCRequest& request) UniValue rawshieldsendmany(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) @@ -1825,7 +1825,7 @@ UniValue rawshieldsendmany(const JSONRPCRequest& request) "\nAmounts are decimal numbers with at most 8 digits of precision." "\nChange generated from a transparent addr flows to a new transparent addr address, while change generated from a shield addr returns to itself." "\nWhen sending coinbase UTXOs to a shield addr, change is not allowed. The entire value of the UTXO(s) must be consumed." - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"fromaddress\" (string, required) The transparent addr or shield addr to send the funds from.\n" @@ -1853,21 +1853,21 @@ UniValue rawshieldsendmany(const JSONRPCRequest& request) "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", [{\"address\": \"ps1ra969yfhvhp73rw5ak2xvtcm9fkuqsnmad7qln79mphhdrst3lwu9vvv03yuyqlh42p42st47qd\" ,\"amount\": 5.0}]") ); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - CTransaction tx = CreateShieldedTransaction(pwalletMain, request).getFinalTx(); + CTransaction tx = CreateShieldedTransaction(pwallet, request).getFinalTx(); return EncodeHexTx(tx); } UniValue listaddressgroupings(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp) @@ -1895,19 +1895,19 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); UniValue jsonGroupings(UniValue::VARR); - std::map balances = pwalletMain->GetAddressBalances(); - for (std::set grouping : pwalletMain->GetAddressGroupings()) { + std::map balances = pwallet->GetAddressBalances(); + for (std::set grouping : pwallet->GetAddressGroupings()) { UniValue jsonGrouping(UniValue::VARR); for (CTxDestination address : grouping) { UniValue addressInfo(UniValue::VARR); addressInfo.push_back(EncodeDestination(address)); addressInfo.push_back(ValueFromAmount(balances[address])); - auto optAdd = pwalletMain->GetAddressBookEntry(address); + auto optAdd = pwallet->GetAddressBookEntry(address); if (optAdd) { addressInfo.push_back(optAdd->name); } @@ -1920,16 +1920,16 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) UniValue signmessage(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "signmessage \"pivxaddress\" \"message\"\n" "\nSign a message with the private key of an address" + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"pivxaddress\" (string, required) The pivx address to use for the private key.\n" @@ -1948,9 +1948,9 @@ UniValue signmessage(const JSONRPCRequest& request) "\nAs json rpc\n" + HelpExampleRpc("signmessage", "\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\", \"my message\"")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); std::string strAddress = request.params[0].get_str(); std::string strMessage = request.params[1].get_str(); @@ -1964,7 +1964,7 @@ UniValue signmessage(const JSONRPCRequest& request) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); CKey key; - if (!pwalletMain->GetKey(*keyID, key)) + if (!pwallet->GetKey(*keyID, key)) throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available"); CHashWriter ss(SER_GETHASH, 0); @@ -1980,9 +1980,9 @@ UniValue signmessage(const JSONRPCRequest& request) UniValue getreceivedbyaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -2009,9 +2009,9 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nBlockHeight = chainActive.Height(); // pivx address @@ -2019,7 +2019,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid PIVX address"); CScript scriptPubKey = GetScriptForDestination(address); - if (!IsMine(*pwalletMain, scriptPubKey)) + if (!IsMine(*pwallet, scriptPubKey)) throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet"); // Minimum confirmations @@ -2029,7 +2029,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) // Tally CAmount nAmount = 0; - for (std::map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + for (std::map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (wtx.IsCoinBase() || !IsFinalTx(wtx.tx, nBlockHeight)) continue; @@ -2046,9 +2046,9 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) UniValue getreceivedbylabel(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -2075,9 +2075,9 @@ UniValue getreceivedbylabel(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nBlockHeight = chainActive.Height(); // Minimum confirmations @@ -2087,18 +2087,18 @@ UniValue getreceivedbylabel(const JSONRPCRequest& request) // Get the set of pub keys assigned to label std::string label = LabelFromValue(request.params[0]); - std::set setAddress = pwalletMain->GetLabelAddresses(label); + std::set setAddress = pwallet->GetLabelAddresses(label); // Tally CAmount nAmount = 0; - for (std::map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + for (std::map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (wtx.IsCoinBase() || !IsFinalTx(wtx.tx, nBlockHeight)) continue; for (const CTxOut& txout : wtx.tx->vout) { CTxDestination address; - if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) if (wtx.GetDepthInMainChain() >= nMinDepth) nAmount += txout.nValue; } @@ -2109,9 +2109,9 @@ UniValue getreceivedbylabel(const JSONRPCRequest& request) UniValue getbalance(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || (request.params.size() > 4 )) @@ -2140,9 +2140,9 @@ UniValue getbalance(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); const int paramsSize = request.params.size(); const int nMinDepth = paramsSize > 0 ? request.params[0].get_int() : 0; @@ -2154,14 +2154,14 @@ UniValue getbalance(const JSONRPCRequest& request) (fIncludeShielded ? ISMINE_WATCH_ONLY_ALL : ISMINE_WATCH_ONLY) : ISMINE_NO); filter |= fIncludeDelegated ? ISMINE_SPENDABLE_DELEGATED : ISMINE_NO; filter |= fIncludeShielded ? ISMINE_SPENDABLE_SHIELDED : ISMINE_NO; - return ValueFromAmount(pwalletMain->GetAvailableBalance(filter, true, nMinDepth)); + return ValueFromAmount(pwallet->GetAvailableBalance(filter, true, nMinDepth)); } UniValue getcoldstakingbalance(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || (request.params.size() != 0)) @@ -2180,18 +2180,18 @@ UniValue getcoldstakingbalance(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - return ValueFromAmount(pwalletMain->GetColdStakingBalance()); + return ValueFromAmount(pwallet->GetColdStakingBalance()); } UniValue getdelegatedbalance(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || (request.params.size() != 0)) @@ -2211,18 +2211,18 @@ UniValue getdelegatedbalance(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - return ValueFromAmount(pwalletMain->GetDelegatedBalance()); + return ValueFromAmount(pwallet->GetDelegatedBalance()); } UniValue getunconfirmedbalance(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 0) @@ -2232,11 +2232,11 @@ UniValue getunconfirmedbalance(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - return ValueFromAmount(pwalletMain->GetUnconfirmedBalance()); + return ValueFromAmount(pwallet->GetUnconfirmedBalance()); } /* @@ -2311,9 +2311,9 @@ static UniValue legacy_sendmany(CWallet* const pwallet, const UniValue& sendTo, */ UniValue sendmany(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) @@ -2321,7 +2321,7 @@ UniValue sendmany(const JSONRPCRequest& request) "sendmany \"\" {\"address\":amount,...} ( minconf \"comment\" includeDelegated )\n" "\nSend to multiple destinations. Recipients are transparent or shield PIVX addresses.\n" "\nAmounts are double-precision floating point numbers.\n" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"dummy\" (string, required) Must be set to \"\" for backwards compatibility.\n" @@ -2350,11 +2350,11 @@ UniValue sendmany(const JSONRPCRequest& request) HelpExampleRpc("sendmany", "\"\", \"{\\\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\\\":0.01,\\\"DAD3Y6ivr8nPQLT1NEPX84DxGCw9jz9Jvg\\\":0.02}\", 6, \"testing\"") ); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); // Read Params if (!request.params[0].isNull() && !request.params[0].get_str().empty()) { @@ -2378,11 +2378,11 @@ UniValue sendmany(const JSONRPCRequest& request) } if (fShieldSend) { - return ShieldSendManyTo(pwalletMain, sendTo, comment, "", nMinDepth, fIncludeDelegated); + return ShieldSendManyTo(pwallet, sendTo, comment, "", nMinDepth, fIncludeDelegated); } // All recipients are transparent: use Legacy sendmany t->t - return legacy_sendmany(pwalletMain, sendTo, nMinDepth, comment, fIncludeDelegated); + return legacy_sendmany(pwallet, sendTo, nMinDepth, comment, fIncludeDelegated); } // Defined in rpc/misc.cpp @@ -2390,9 +2390,9 @@ extern CScript _createmultisig_redeemScript(CWallet* const pwallet, const UniVal UniValue addmultisigaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) @@ -2420,18 +2420,18 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) "\nAs json rpc call\n" + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\\\",\\\"DAD3Y6ivr8nPQLT1NEPX84DxGCw9jz9Jvg\\\"]\"")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); std::string label; if (request.params.size() > 2) label = LabelFromValue(request.params[2]); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); + CScript inner = _createmultisig_redeemScript(pwallet, request.params); CScriptID innerID(inner); - pwalletMain->AddCScript(inner); + pwallet->AddCScript(inner); - pwalletMain->SetAddressBook(innerID, label, AddressBook::AddressBookPurpose::SEND); + pwallet->SetAddressBook(innerID, label, AddressBook::AddressBookPurpose::SEND); return EncodeDestination(innerID); } @@ -2593,9 +2593,9 @@ static UniValue ListReceived(CWallet* const pwallet, const UniValue& params, boo UniValue listreceivedbyaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 4) @@ -2630,18 +2630,18 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nBlockHeight = chainActive.Height(); - return ListReceived(pwalletMain, request.params, false, nBlockHeight); + return ListReceived(pwallet, request.params, false, nBlockHeight); } UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size()==0 || request.params.size() >2) @@ -2673,9 +2673,9 @@ UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nMinDepth = 1; if (request.params.size() > 1) { @@ -2694,7 +2694,7 @@ UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) } libzcash::SaplingPaymentAddress shieldAddr = *zaddr; - auto sspkm = pwalletMain->GetSaplingScriptPubKeyMan(); + auto sspkm = pwallet->GetSaplingScriptPubKeyMan(); // Visitor to support Sapling addrs if (!sspkm->PaymentAddressBelongsToWallet(shieldAddr)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, shield addr spending key or viewing key not found."); @@ -2705,7 +2705,7 @@ UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) sspkm->GetFilteredNotes(saplingEntries, zaddr, nMinDepth, false, false); std::set> nullifierSet; - bool hasSpendingKey = pwalletMain->HaveSpendingKeyForPaymentAddress(shieldAddr); + bool hasSpendingKey = pwallet->HaveSpendingKeyForPaymentAddress(shieldAddr); if (hasSpendingKey) { nullifierSet = sspkm->GetNullifiersForAddresses({*zaddr}); } @@ -2722,8 +2722,8 @@ UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) int index = -1; int64_t time = 0; - if (pwalletMain->mapWallet.count(entry.op.hash)) { - const CWalletTx& wtx = pwalletMain->mapWallet.at(entry.op.hash); + if (pwallet->mapWallet.count(entry.op.hash)) { + const CWalletTx& wtx = pwallet->mapWallet.at(entry.op.hash); if (!wtx.m_confirm.hashBlock.IsNull()) height = mapBlockIndex[wtx.m_confirm.hashBlock]->nHeight; index = wtx.m_confirm.nIndex; @@ -2744,9 +2744,9 @@ UniValue listreceivedbyshieldaddress(const JSONRPCRequest& request) UniValue listreceivedbylabel(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -2776,18 +2776,18 @@ UniValue listreceivedbylabel(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nBlockHeight = chainActive.Height(); - return ListReceived(pwalletMain, request.params, true, nBlockHeight); + return ListReceived(pwallet, request.params, true, nBlockHeight); } UniValue listcoldutxos(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -2817,9 +2817,9 @@ UniValue listcoldutxos(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); bool fExcludeWhitelisted = false; if (request.params.size() > 0) @@ -2827,7 +2827,7 @@ UniValue listcoldutxos(const JSONRPCRequest& request) UniValue results(UniValue::VARR); for (std::map::const_iterator it = - pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const uint256& wtxid = it->first; const CWalletTx* pcoin = &(*it).second; if (!CheckFinalTx(pcoin->tx) || !pcoin->IsTrusted()) @@ -2839,7 +2839,7 @@ UniValue listcoldutxos(const JSONRPCRequest& request) for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) { const CTxOut& out = pcoin->tx->vout[i]; - isminetype mine = pwalletMain->IsMine(out); + isminetype mine = pwallet->IsMine(out); if (!bool(mine & ISMINE_COLD) && !bool(mine & ISMINE_SPENDABLE_DELEGATED)) continue; txnouttype type; @@ -2847,7 +2847,7 @@ UniValue listcoldutxos(const JSONRPCRequest& request) int nRequired; if (!ExtractDestinations(out.scriptPubKey, type, addresses, nRequired)) continue; - const bool fWhitelisted = pwalletMain->HasAddressBook(addresses[1]) > 0; + const bool fWhitelisted = pwallet->HasAddressBook(addresses[1]) > 0; if (fExcludeWhitelisted && fWhitelisted) continue; UniValue entry(UniValue::VOBJ); @@ -2936,9 +2936,9 @@ static void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, int n UniValue listtransactions(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 6) throw std::runtime_error( @@ -2992,9 +2992,9 @@ UniValue listtransactions(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (!request.params[0].isNull() && request.params[0].get_str() != "*") { throw JSONRPCError(RPC_INVALID_PARAMETER, "Dummy value must be set to \"*\""); @@ -3020,12 +3020,12 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue ret(UniValue::VARR); - const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + const CWallet::TxItems & txOrdered = pwallet->wtxOrdered; // iterate backwards until we have nCount items to return: for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx* const pwtx = (*it).second; - ListTransactions(pwalletMain, *pwtx, 0, true, ret, filter); + ListTransactions(pwallet, *pwtx, 0, true, ret, filter); if ((int)ret.size() >= (nCount + nFrom)) break; } // ret is newest to oldest @@ -3056,9 +3056,9 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue listsinceblock(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp) @@ -3102,9 +3102,9 @@ UniValue listsinceblock(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CBlockIndex* pindex = NULL; int target_confirms = 1; @@ -3134,11 +3134,11 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue transactions(UniValue::VARR); - for (std::map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) { + for (std::map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); it++) { CWalletTx tx = (*it).second; if (depth == -1 || tx.GetDepthInMainChain() < depth) - ListTransactions(pwalletMain, tx, 0, true, transactions, filter); + ListTransactions(pwallet, tx, 0, true, transactions, filter); } CBlockIndex* pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; @@ -3153,9 +3153,9 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue gettransaction(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -3198,9 +3198,9 @@ UniValue gettransaction(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); uint256 hash; hash.SetHex(request.params[0].get_str()); @@ -3211,9 +3211,9 @@ UniValue gettransaction(const JSONRPCRequest& request) filter = filter | ISMINE_WATCH_ONLY; UniValue entry(UniValue::VOBJ); - if (!pwalletMain->mapWallet.count(hash)) + if (!pwallet->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - const CWalletTx& wtx = pwalletMain->mapWallet.at(hash); + const CWalletTx& wtx = pwallet->mapWallet.at(hash); CAmount nCredit = wtx.GetCredit(filter); CAmount nDebit = wtx.GetDebit(filter); @@ -3227,7 +3227,7 @@ UniValue gettransaction(const JSONRPCRequest& request) WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(pwalletMain, wtx, 0, false, details, filter); + ListTransactions(pwallet, wtx, 0, false, details, filter); entry.pushKV("details", details); std::string strHex = EncodeHexTx(*wtx.tx); @@ -3238,9 +3238,9 @@ UniValue gettransaction(const JSONRPCRequest& request) UniValue abandontransaction(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -3263,16 +3263,16 @@ UniValue abandontransaction(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); uint256 hash; hash.SetHex(request.params[0].get_str()); - if (!pwalletMain->mapWallet.count(hash)) + if (!pwallet->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - if (!pwalletMain->AbandonTransaction(hash)) + if (!pwallet->AbandonTransaction(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment"); return NullUniValue; @@ -3281,9 +3281,9 @@ UniValue abandontransaction(const JSONRPCRequest& request) UniValue backupwallet(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -3299,12 +3299,12 @@ UniValue backupwallet(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); std::string strDest = request.params[0].get_str(); - if (!BackupWallet(*pwalletMain, strDest)) + if (!BackupWallet(*pwallet, strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); return NullUniValue; @@ -3313,16 +3313,16 @@ UniValue backupwallet(const JSONRPCRequest& request) UniValue keypoolrefill(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "keypoolrefill ( newsize )\n" "\nFills the keypool." + - HelpRequiringPassphrase(pwalletMain) + "\n" + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments\n" "1. newsize (numeric, optional, default=100) The new keypool size\n" @@ -3330,7 +3330,7 @@ UniValue keypoolrefill(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("keypoolrefill", "") + HelpExampleRpc("keypoolrefill", "")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool unsigned int kpSize = 0; @@ -3340,10 +3340,10 @@ UniValue keypoolrefill(const JSONRPCRequest& request) kpSize = (unsigned int)request.params[0].get_int(); } - EnsureWalletIsUnlocked(pwalletMain); - pwalletMain->TopUpKeyPool(kpSize); + EnsureWalletIsUnlocked(pwallet); + pwallet->TopUpKeyPool(kpSize); - if (pwalletMain->GetKeyPoolSize() < kpSize) + if (pwallet->GetKeyPoolSize() < kpSize) throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); return NullUniValue; @@ -3360,12 +3360,12 @@ static void LockWallet(CWallet* pWallet) UniValue walletpassphrase(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() < 2 || request.params.size() > 3)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() < 2 || request.params.size() > 3)) throw std::runtime_error( "walletpassphrase \"passphrase\" timeout ( stakingonly )\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" @@ -3390,11 +3390,11 @@ UniValue walletpassphrase(const JSONRPCRequest& request) "\nAs json rpc call\n" + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwalletMain->IsCrypted()) + if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); // Note that the walletpassphrase is stored in params[0] which is not mlock()ed @@ -3408,7 +3408,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request) if (request.params.size() == 3) stakingOnly = request.params[2].get_bool(); - if (!pwalletMain->IsLocked() && pwalletMain->fWalletUnlockStaking && stakingOnly) + if (!pwallet->IsLocked() && pwallet->fWalletUnlockStaking && stakingOnly) throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked."); // Get the timeout @@ -3423,14 +3423,14 @@ UniValue walletpassphrase(const JSONRPCRequest& request) nSleepTime = MAX_SLEEP_TIME; } - if (!pwalletMain->Unlock(strWalletPass, stakingOnly)) + if (!pwallet->Unlock(strWalletPass, stakingOnly)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); - pwalletMain->TopUpKeyPool(); + pwallet->TopUpKeyPool(); if (nSleepTime > 0) { nWalletUnlockTime = GetTime () + nSleepTime; - RPCRunLater ("lockwallet", std::bind (LockWallet, pwalletMain), nSleepTime); + RPCRunLater ("lockwallet", std::bind (LockWallet, pwallet), nSleepTime); } return NullUniValue; @@ -3439,12 +3439,12 @@ UniValue walletpassphrase(const JSONRPCRequest& request) UniValue walletpassphrasechange(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) throw std::runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n" @@ -3456,11 +3456,11 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"") + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwalletMain->IsCrypted()) + if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) @@ -3478,7 +3478,7 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) "walletpassphrasechange \n" "Changes the wallet passphrase from to ."); - if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); return NullUniValue; @@ -3487,12 +3487,12 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) UniValue walletlock(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) throw std::runtime_error( "walletlock\n" "\nRemoves the wallet encryption key from memory, locking the wallet.\n" @@ -3511,18 +3511,18 @@ UniValue walletlock(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwalletMain->IsCrypted()) + if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); { LOCK(cs_nWalletUnlockTime); - pwalletMain->Lock(); + pwallet->Lock(); nWalletUnlockTime = 0; } @@ -3532,12 +3532,12 @@ UniValue walletlock(const JSONRPCRequest& request) UniValue encryptwallet(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1)) + if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) throw std::runtime_error( "encryptwallet \"passphrase\"\n" "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n" @@ -3562,11 +3562,11 @@ UniValue encryptwallet(const JSONRPCRequest& request) "\nAs a json rpc call\n" + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (pwalletMain->IsCrypted()) + if (pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called."); // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) @@ -3580,7 +3580,7 @@ UniValue encryptwallet(const JSONRPCRequest& request) "encryptwallet \n" "Encrypts the wallet with ."); - if (!pwalletMain->EncryptWallet(strWalletPass)) + if (!pwallet->EncryptWallet(strWalletPass)) throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); // BDB seems to have a bad habit of writing old data into @@ -3592,9 +3592,9 @@ UniValue encryptwallet(const JSONRPCRequest& request) UniValue listunspent(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 5) @@ -3649,7 +3649,7 @@ UniValue listunspent(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); int nMinDepth = 1; if (request.params.size() > 0) { @@ -3721,9 +3721,10 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue results(UniValue::VARR); std::vector vecOutputs; - LOCK2(cs_main, pwalletMain->cs_wallet); + + LOCK2(cs_main, pwallet->cs_wallet); coinFilter.fOnlyConfirmed = false; - pwalletMain->AvailableCoins(&vecOutputs, &coinControl, coinFilter); + pwallet->AvailableCoins(&vecOutputs, &coinControl, coinFilter); for (const COutput& out : vecOutputs) { if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) continue; @@ -3746,8 +3747,8 @@ UniValue listunspent(const JSONRPCRequest& request) CTxDestination address; if (ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, address)) { entry.pushKV("address", EncodeDestination(address)); - if (pwalletMain->HasAddressBook(address)) { - entry.pushKV("label", pwalletMain->GetNameForAddressBookEntry(address)); + if (pwallet->HasAddressBook(address)) { + entry.pushKV("label", pwallet->GetNameForAddressBookEntry(address)); } } entry.pushKV("scriptPubKey", HexStr(pk.begin(), pk.end())); @@ -3756,7 +3757,7 @@ UniValue listunspent(const JSONRPCRequest& request) if (ExtractDestination(pk, address)) { const CScriptID& hash = boost::get(address); CScript redeemScript; - if (pwalletMain->GetCScript(hash, redeemScript)) + if (pwallet->GetCScript(hash, redeemScript)) entry.pushKV("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())); } } @@ -3772,9 +3773,9 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue lockunspent(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -3815,9 +3816,9 @@ UniValue lockunspent(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.params.size() == 1) RPCTypeCheck(request.params, {UniValue::VBOOL}); @@ -3828,7 +3829,7 @@ UniValue lockunspent(const JSONRPCRequest& request) if (request.params.size() == 1) { if (fUnlock) - pwalletMain->UnlockAllCoins(); + pwallet->UnlockAllCoins(); return true; } @@ -3862,8 +3863,8 @@ UniValue lockunspent(const JSONRPCRequest& request) const COutPoint outpt(uint256S(txid), nOutput); - const auto it = pwalletMain->mapWallet.find(outpt.hash); - if (it == pwalletMain->mapWallet.end()) { + const auto it = pwallet->mapWallet.find(outpt.hash); + if (it == pwallet->mapWallet.end()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, unknown transaction"); } @@ -3873,11 +3874,11 @@ UniValue lockunspent(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds"); } - if (pwalletMain->IsSpent(outpt.hash, outpt.n)) { + if (pwallet->IsSpent(outpt.hash, outpt.n)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output"); } - const bool is_locked = pwalletMain->IsLockedCoin(outpt.hash, outpt.n); + const bool is_locked = pwallet->IsLockedCoin(outpt.hash, outpt.n); if (fUnlock && !is_locked) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output"); @@ -3892,8 +3893,8 @@ UniValue lockunspent(const JSONRPCRequest& request) // Atomically set (un)locked status for the outputs. for (const COutPoint& outpt : outputs) { - if (fUnlock) pwalletMain->UnlockCoin(outpt); - else pwalletMain->LockCoin(outpt); + if (fUnlock) pwallet->UnlockCoin(outpt); + else pwallet->LockCoin(outpt); } return true; @@ -3901,9 +3902,9 @@ UniValue lockunspent(const JSONRPCRequest& request) UniValue listlockunspent(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 0) @@ -3933,9 +3934,9 @@ UniValue listlockunspent(const JSONRPCRequest& request) "\nAs a json rpc call\n" + HelpExampleRpc("listlockunspent", "")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - std::set vOutpts = pwalletMain->ListLockedCoins(); + std::set vOutpts = pwallet->ListLockedCoins(); UniValue ret(UniValue::VARR); for (const COutPoint& outpt : vOutpts) { @@ -3951,9 +3952,9 @@ UniValue listlockunspent(const JSONRPCRequest& request) UniValue settxfee(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) @@ -3969,7 +3970,7 @@ UniValue settxfee(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("settxfee", "0.00001") + HelpExampleRpc("settxfee", "0.00001")); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Amount CAmount nAmount = 0; @@ -3982,9 +3983,9 @@ UniValue settxfee(const JSONRPCRequest& request) UniValue getwalletinfo(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -4020,54 +4021,54 @@ UniValue getwalletinfo(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); UniValue obj(UniValue::VOBJ); - obj.pushKV("walletversion", pwalletMain->GetVersion()); - obj.pushKV("balance", ValueFromAmount(pwalletMain->GetAvailableBalance())); - obj.pushKV("delegated_balance", ValueFromAmount(pwalletMain->GetDelegatedBalance())); - obj.pushKV("cold_staking_balance", ValueFromAmount(pwalletMain->GetColdStakingBalance())); - obj.pushKV("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())); - obj.pushKV("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance())); - obj.pushKV("immature_delegated_balance", ValueFromAmount(pwalletMain->GetImmatureDelegatedBalance())); - obj.pushKV("immature_cold_staking_balance", ValueFromAmount(pwalletMain->GetImmatureColdStakingBalance())); - obj.pushKV("txcount", (int)pwalletMain->mapWallet.size()); + obj.pushKV("walletversion", pwallet->GetVersion()); + obj.pushKV("balance", ValueFromAmount(pwallet->GetAvailableBalance())); + obj.pushKV("delegated_balance", ValueFromAmount(pwallet->GetDelegatedBalance())); + obj.pushKV("cold_staking_balance", ValueFromAmount(pwallet->GetColdStakingBalance())); + obj.pushKV("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance())); + obj.pushKV("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance())); + obj.pushKV("immature_delegated_balance", ValueFromAmount(pwallet->GetImmatureDelegatedBalance())); + obj.pushKV("immature_cold_staking_balance", ValueFromAmount(pwallet->GetImmatureColdStakingBalance())); + obj.pushKV("txcount", (int)pwallet->mapWallet.size()); // Autocombine settings - obj.pushKV("autocombine_enabled", pwalletMain->fCombineDust); - obj.pushKV("autocombine_threshold", ValueFromAmount(pwalletMain->nAutoCombineThreshold)); + obj.pushKV("autocombine_enabled", pwallet->fCombineDust); + obj.pushKV("autocombine_threshold", ValueFromAmount(pwallet->nAutoCombineThreshold)); // Keypool information - obj.pushKV("keypoololdest", pwalletMain->GetOldestKeyPoolTime()); - size_t kpExternalSize = pwalletMain->KeypoolCountExternalKeys(); + obj.pushKV("keypoololdest", pwallet->GetOldestKeyPoolTime()); + size_t kpExternalSize = pwallet->KeypoolCountExternalKeys(); obj.pushKV("keypoolsize", (int64_t)kpExternalSize); - ScriptPubKeyMan* spk_man = pwalletMain->GetScriptPubKeyMan(); + ScriptPubKeyMan* spk_man = pwallet->GetScriptPubKeyMan(); if (spk_man) { const CKeyID& seed_id = spk_man->GetHDChain().GetID(); if (!seed_id.IsNull()) { obj.pushKV("hdseedid", seed_id.GetHex()); } } - if (pwalletMain->IsHDEnabled()) { - obj.pushKV("keypoolsize_hd_internal", (int64_t)(pwalletMain->GetKeyPoolSize() - kpExternalSize)); - obj.pushKV("keypoolsize_hd_staking", (int64_t)(pwalletMain->GetStakingKeyPoolSize())); + if (pwallet->IsHDEnabled()) { + obj.pushKV("keypoolsize_hd_internal", (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize)); + obj.pushKV("keypoolsize_hd_staking", (int64_t)(pwallet->GetStakingKeyPoolSize())); } - if (pwalletMain->IsCrypted()) + if (pwallet->IsCrypted()) obj.pushKV("unlocked_until", nWalletUnlockTime); obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); - obj.pushKV("last_processed_block", pwalletMain->GetLastBlockHeight()); + obj.pushKV("last_processed_block", pwallet->GetLastBlockHeight()); return obj; } UniValue getstakingstatus(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -4097,24 +4098,24 @@ UniValue getstakingstatus(const JSONRPCRequest& request) HelpExampleCli("getstakingstatus", "") + HelpExampleRpc("getstakingstatus", "")); - if (!pwalletMain) + if (!pwallet) throw JSONRPCError(RPC_IN_WARMUP, "Try again after active chain is loaded"); { - LOCK2(cs_main, &pwalletMain->cs_wallet); + LOCK2(cs_main, &pwallet->cs_wallet); UniValue obj(UniValue::VOBJ); - obj.pushKV("staking_status", pwalletMain->pStakerStatus->IsActive()); + obj.pushKV("staking_status", pwallet->pStakerStatus->IsActive()); obj.pushKV("staking_enabled", gArgs.GetBoolArg("-staking", DEFAULT_STAKING)); bool fColdStaking = gArgs.GetBoolArg("-coldstaking", true); obj.pushKV("coldstaking_enabled", fColdStaking); obj.pushKV("haveconnections", (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) > 0)); obj.pushKV("mnsync", !masternodeSync.NotCompleted()); - obj.pushKV("walletunlocked", !pwalletMain->IsLocked()); + obj.pushKV("walletunlocked", !pwallet->IsLocked()); std::vector vCoins; - pwalletMain->StakeableCoins(&vCoins); + pwallet->StakeableCoins(&vCoins); obj.pushKV("stakeablecoins", (int)vCoins.size()); - obj.pushKV("stakingbalance", ValueFromAmount(pwalletMain->GetStakingBalance(fColdStaking))); - obj.pushKV("stakesplitthreshold", ValueFromAmount(pwalletMain->nStakeSplitThreshold)); - CStakerStatus* ss = pwalletMain->pStakerStatus; + obj.pushKV("stakingbalance", ValueFromAmount(pwallet->GetStakingBalance(fColdStaking))); + obj.pushKV("stakesplitthreshold", ValueFromAmount(pwallet->nStakeSplitThreshold)); + CStakerStatus* ss = pwallet->pStakerStatus; if (ss) { obj.pushKV("lastattempt_age", (int)(GetTime() - ss->GetLastTime())); obj.pushKV("lastattempt_depth", (chainActive.Height() - ss->GetLastHeight())); @@ -4128,9 +4129,9 @@ UniValue getstakingstatus(const JSONRPCRequest& request) UniValue setstakesplitthreshold(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -4141,7 +4142,7 @@ UniValue setstakesplitthreshold(const JSONRPCRequest& request) "higher than the threshold) as possible.\n" "E.g. If the coinstake input + the block reward is 2000, and the split threshold is 499, the corresponding\n" "coinstake transaction will have 4 outputs (of 500 PIV each)." - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. value (numeric, required) Threshold value (in PIV).\n" @@ -4164,15 +4165,15 @@ UniValue setstakesplitthreshold(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); result.pushKV("threshold", request.params[0]); - result.pushKV("saved", pwalletMain->SetStakeSplitThreshold(nStakeSplitThreshold)); + result.pushKV("saved", pwallet->SetStakeSplitThreshold(nStakeSplitThreshold)); return result; } UniValue getstakesplitthreshold(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -4186,14 +4187,14 @@ UniValue getstakesplitthreshold(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getstakesplitthreshold", "") + HelpExampleRpc("getstakesplitthreshold", "")); - return ValueFromAmount(pwalletMain->GetStakeSplitThreshold()); + return ValueFromAmount(pwallet->GetStakeSplitThreshold()); } UniValue autocombinerewards(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; bool fEnable; @@ -4214,7 +4215,7 @@ UniValue autocombinerewards(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("autocombinerewards", "true 500") + HelpExampleRpc("autocombinerewards", "true 500")); - CWalletDB walletdb(pwalletMain->GetDBHandle()); + CWalletDB walletdb(pwallet->GetDBHandle()); CAmount nThreshold = 0; if (fEnable && request.params.size() > 1) { @@ -4223,8 +4224,8 @@ UniValue autocombinerewards(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("The threshold value cannot be less than %s", FormatMoney(COIN))); } - pwalletMain->fCombineDust = fEnable; - pwalletMain->nAutoCombineThreshold = nThreshold; + pwallet->fCombineDust = fEnable; + pwallet->nAutoCombineThreshold = nThreshold; if (!walletdb.WriteAutoCombineSettings(fEnable, nThreshold)) throw std::runtime_error("Changed settings in wallet but failed to save to database\n"); @@ -4234,9 +4235,9 @@ UniValue autocombinerewards(const JSONRPCRequest& request) UniValue setautocombinethreshold(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.empty() || request.params.size() > 2) @@ -4274,16 +4275,16 @@ UniValue setautocombinethreshold(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("The threshold value cannot be less than %s", FormatMoney(COIN))); } - CWalletDB walletdb(pwalletMain->GetDBHandle()); + CWalletDB walletdb(pwallet->GetDBHandle()); { - LOCK(pwalletMain->cs_wallet); - pwalletMain->fCombineDust = fEnable; - pwalletMain->nAutoCombineThreshold = nThreshold; + LOCK(pwallet->cs_wallet); + pwallet->fCombineDust = fEnable; + pwallet->nAutoCombineThreshold = nThreshold; UniValue result(UniValue::VOBJ); result.pushKV("enabled", fEnable); - result.pushKV("threshold", ValueFromAmount(pwalletMain->nAutoCombineThreshold)); + result.pushKV("threshold", ValueFromAmount(pwallet->nAutoCombineThreshold)); if (walletdb.WriteAutoCombineSettings(fEnable, nThreshold)) { result.pushKV("saved", "true"); } else { @@ -4296,9 +4297,9 @@ UniValue setautocombinethreshold(const JSONRPCRequest& request) UniValue getautocombinethreshold(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || !request.params.empty()) @@ -4315,20 +4316,20 @@ UniValue getautocombinethreshold(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("getautocombinethreshold", "") + HelpExampleRpc("getautocombinethreshold", "")); - LOCK(pwalletMain->cs_wallet); + LOCK(pwallet->cs_wallet); UniValue result(UniValue::VOBJ); - result.pushKV("enabled", pwalletMain->fCombineDust); - result.pushKV("threshold", ValueFromAmount(pwalletMain->nAutoCombineThreshold)); + result.pushKV("enabled", pwallet->fCombineDust); + result.pushKV("threshold", ValueFromAmount(pwallet->nAutoCombineThreshold)); return result; } UniValue getsaplingnotescount(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -4349,13 +4350,13 @@ UniValue getsaplingnotescount(const JSONRPCRequest& request) // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now - pwalletMain->BlockUntilSyncedToCurrentChain(); + pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nMinDepth = !request.params.empty() ? request.params[0].get_int() : 1; int count = 0; - for (const auto& wtx : pwalletMain->mapWallet) { + for (const auto& wtx : pwallet->mapWallet) { if (wtx.second.GetDepthInMainChain() >= nMinDepth) { for (const auto& nd : wtx.second.mapSaplingNoteData) { if (nd.second.IsMyNote()) count++; @@ -4367,9 +4368,9 @@ UniValue getsaplingnotescount(const JSONRPCRequest& request) UniValue rescanblockchain(const JSONRPCRequest& request) { - CWallet * const pwalletMain = GetWalletForJSONRPCRequest(request); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 2) { @@ -4390,7 +4391,7 @@ UniValue rescanblockchain(const JSONRPCRequest& request) ); } - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwallet); if (!reserver.reserve()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } @@ -4421,9 +4422,9 @@ UniValue rescanblockchain(const JSONRPCRequest& request) } } - CBlockIndex *stopBlock = pwalletMain->ScanForWalletTransactions(pindexStart, pindexStop, reserver, true); + CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions(pindexStart, pindexStop, reserver, true); if (!stopBlock) { - if (pwalletMain->IsAbortingRescan()) { + if (pwallet->IsAbortingRescan()) { throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted."); } // if we got a nullptr returned, ScanForWalletTransactions did rescan up to the requested stopindex From cc965fe268f83b2f4b6a5e0209c85aa91c803fd4 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 9 Sep 2016 07:48:10 +0000 Subject: [PATCH 11/27] Move nWalletUnlockTime to CWallet::nRelockTime, and name timed task unique per CWallet --- src/rpc/misc.cpp | 2 +- src/rpc/server.h | 1 - src/wallet/rpcwallet.cpp | 20 ++++++++------------ src/wallet/wallet.h | 3 +++ 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index cc7c43154157..bdca9d7678a4 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -143,7 +143,7 @@ UniValue getinfo(const JSONRPCRequest& request) obj.pushKV("keypoolsize", (int64_t)kpExternalSize); } if (pwallet && pwallet->IsCrypted()) - obj.pushKV("unlocked_until", nWalletUnlockTime); + obj.pushKV("unlocked_until", pwallet->nRelockTime); obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); #endif obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); diff --git a/src/rpc/server.h b/src/rpc/server.h index d8544fbc2d23..abb69c38fa21 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -190,7 +190,6 @@ extern std::vector ParseHexO(const UniValue& o, std::string strKe extern int ParseInt(const UniValue& o, std::string strKey); extern bool ParseBool(const UniValue& o, std::string strKey); -extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const UniValue& value); extern UniValue ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 63d3f8e04c5f..b3cc943da5ef 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -34,8 +34,7 @@ #include -int64_t nWalletUnlockTime; -static RecursiveMutex cs_nWalletUnlockTime; + CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request) { @@ -3352,8 +3351,8 @@ UniValue keypoolrefill(const JSONRPCRequest& request) static void LockWallet(CWallet* pWallet) { - LOCK(cs_nWalletUnlockTime); - nWalletUnlockTime = 0; + LOCK(pWallet->cs_wallet); + pWallet->nRelockTime = 0; pWallet->fWalletUnlockStaking = false; pWallet->Lock(); } @@ -3429,7 +3428,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request) pwallet->TopUpKeyPool(); if (nSleepTime > 0) { - nWalletUnlockTime = GetTime () + nSleepTime; + pwallet->nRelockTime = GetTime () + nSleepTime; RPCRunLater ("lockwallet", std::bind (LockWallet, pwallet), nSleepTime); } @@ -3520,11 +3519,8 @@ UniValue walletlock(const JSONRPCRequest& request) if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); - { - LOCK(cs_nWalletUnlockTime); - pwallet->Lock(); - nWalletUnlockTime = 0; - } + pwallet->Lock(); + pwallet->nRelockTime = 0; return NullUniValue; } @@ -4058,8 +4054,8 @@ UniValue getwalletinfo(const JSONRPCRequest& request) } if (pwallet->IsCrypted()) - obj.pushKV("unlocked_until", nWalletUnlockTime); - obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); + obj.pushKV("unlocked_until", pwallet->nRelockTime); + obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); obj.pushKV("last_processed_block", pwallet->GetLastBlockHeight()); return obj; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 5acc189af31e..533ba8f4815f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -934,9 +934,12 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool LoadWatchOnly(const CScript& dest); //! Lock Wallet + //! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock(). + int64_t nRelockTime; bool Lock(); bool Unlock(const SecureString& strWalletPassphrase, bool anonimizeOnly = false); bool Unlock(const CKeyingMaterial& vMasterKeyIn); + bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); From 687c2fde9da92602fd0a573187a6f179750b11a4 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 29 Dec 2016 13:05:51 +0000 Subject: [PATCH 12/27] RPC: Pass on JSONRPCRequest metadata (URI/user/etc) for "help" method --- src/rpc/server.cpp | 11 +++++++---- src/rpc/server.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 51ac2adfe0da..8b688648ed08 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -188,7 +188,7 @@ bool ParseBool(const UniValue& o, std::string strKey) * Note: This interface may still be subject to change. */ -std::string CRPCTable::help(std::string strCommand) const +std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& helpreq) const { std::string strRet; std::string category; @@ -199,14 +199,17 @@ std::string CRPCTable::help(std::string strCommand) const vCommands.emplace_back(entry.second->category + entry.first, entry.second); std::sort(vCommands.begin(), vCommands.end()); + JSONRPCRequest jreq(helpreq); + jreq.fHelp = true; + jreq.params = UniValue(); + for (const std::pair& command : vCommands) { const CRPCCommand* pcmd = command.second; std::string strMethod = pcmd->name; if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand) continue; + jreq.strMethod = strMethod; try { - JSONRPCRequest jreq; - jreq.fHelp = true; rpcfn_type pfn = pcmd->actor; if (setDone.insert(pfn).second) (*pfn)(jreq); @@ -248,7 +251,7 @@ UniValue help(const JSONRPCRequest& jsonRequest) if (jsonRequest.params.size() > 0) strCommand = jsonRequest.params[0].get_str(); - return tableRPC.help(strCommand); + return tableRPC.help(strCommand, jsonRequest); } diff --git a/src/rpc/server.h b/src/rpc/server.h index abb69c38fa21..9bbeb38f0a43 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -151,7 +151,7 @@ class CRPCTable public: CRPCTable(); const CRPCCommand* operator[](const std::string& name) const; - std::string help(std::string name) const; + std::string help(const std::string& name, const JSONRPCRequest& helpreq) const; /** * Execute a method. From ca6a62d972a99a94e47b707152aca3120df21bce Mon Sep 17 00:00:00 2001 From: random-zebra Date: Fri, 23 Apr 2021 00:17:44 +0200 Subject: [PATCH 13/27] [MOVE-ONLY] Move wallet RPC declarations to rpcwallet.h based on bitcoin@a4356328e00155796cd7aa188e96c51c09562423 --- src/rest.cpp | 1 + src/rpc/budget.cpp | 3 +++ src/rpc/masternode.cpp | 3 +++ src/rpc/mining.cpp | 1 + src/rpc/misc.cpp | 1 + src/rpc/rawtransaction.cpp | 1 + src/rpc/server.h | 11 ----------- src/wallet/rpcdump.cpp | 4 +++- src/wallet/rpcwallet.cpp | 18 ++++++++---------- src/wallet/rpcwallet.h | 24 ++++++++++++++++++++---- 10 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 217a014bf2ce..3c15c7cd5704 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -16,6 +16,7 @@ #include "utilstrencodings.h" #include "validation.h" #include "version.h" +#include "wallet/wallet.h" #include diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 763b4ed0fde2..7fbdf7d4d1f9 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -15,6 +15,9 @@ #include "messagesigner.h" #include "rpc/server.h" #include "utilmoneystr.h" +#ifdef ENABLE_WALLET +#include "wallet/rpcwallet.h" +#endif #include diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index d34a96aad04a..a91bf2812b30 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -14,6 +14,9 @@ #include "netbase.h" #include "rpc/server.h" #include "utilmoneystr.h" +#ifdef ENABLE_WALLET +#include "wallet/rpcwallet.h" +#endif #include diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 177952a29cec..5944b52547ed 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -17,6 +17,7 @@ #include "rpc/server.h" #include "validationinterface.h" #ifdef ENABLE_WALLET +#include "wallet/rpcwallet.h" #include "wallet/db.h" #include "wallet/wallet.h" #endif diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index bdca9d7678a4..bd7ec3e0e73b 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -18,6 +18,7 @@ #include "timedata.h" #include "util/system.h" #ifdef ENABLE_WALLET +#include "wallet/rpcwallet.h" #include "wallet/wallet.h" #include "wallet/walletdb.h" #endif diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index ea780e5c0c48..d1d8f6212591 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -25,6 +25,7 @@ #ifdef ENABLE_WALLET #include "sapling/address.h" #include "sapling/key_io_sapling.h" +#include "wallet/rpcwallet.h" #include "wallet/wallet.h" #endif diff --git a/src/rpc/server.h b/src/rpc/server.h index 9bbeb38f0a43..89739374a4ab 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -196,17 +196,6 @@ extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpExampleCli(std::string methodname, std::string args); extern std::string HelpExampleRpc(std::string methodname, std::string args); -// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around -class CWallet; -CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request); - -#ifdef ENABLE_WALLET -// New code should accessing the wallet should be under the ../wallet/ directory -std::string HelpRequiringPassphrase(CWallet* const pwallet); -bool EnsureWalletIsAvailable(CWallet* const pwallet, bool avoidException); -void EnsureWalletIsUnlocked(CWallet *pwallet, bool fAllowAnonOnly = false); -#endif - bool StartRPC(); void InterruptRPC(); void StopRPC(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 729f94671c0e..302ab5aafafb 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -15,7 +15,9 @@ #include "util/system.h" #include "utilstrencodings.h" #include "utiltime.h" -#include "wallet/wallet.h" +#include "wallet/rpcwallet.h" +#include "wallet.h" +#include "validation.h" #include #include diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b3cc943da5ef..1209e4de7d1f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5,6 +5,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "wallet/rpcwallet.h" + #include "addressbook.h" #include "amount.h" #include "base58.h" @@ -17,21 +19,17 @@ #include "net.h" #include "policy/feerate.h" #include "rpc/server.h" -#include "timedata.h" -#include "util/system.h" -#include "utilmoneystr.h" -#include "wallet.h" -#include "walletdb.h" -#include "zpivchain.h" - #include "sapling/sapling_operation.h" #include "sapling/transaction_builder.h" #include "sapling/key_io_sapling.h" - -#include - #include "spork.h" +#include "timedata.h" +#include "utilmoneystr.h" +#include "wallet/wallet.h" +#include "wallet/walletdb.h" +#include "zpivchain.h" +#include #include diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index a5de7e2de145..6ba3bc41bf20 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -1,12 +1,28 @@ -// Copyright (c) 2016 The Bitcoin Core developers +// Copyright (c) 2016-2021 The Bitcoin Core developers +// Copyright (c) 2021 The PIVX developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef PIVX_WALLET_RPCWALLET_H +#define PIVX_WALLET_RPCWALLET_H -#ifndef BITCOIN_WALLET_RPCWALLET_H -#define BITCOIN_WALLET_RPCWALLET_H +#include class CRPCTable; +class CWallet; +class JSONRPCRequest; void RegisterWalletRPCCommands(CRPCTable &tableRPC); -#endif //BITCOIN_WALLET_RPCWALLET_H +/** + * Figures out what wallet, if any, to use for a JSONRPCRequest. + * + * @param[in] request JSONRPCRequest that wishes to access a wallet + * @return NULL if no wallet should be used, or a pointer to the CWallet + */ +CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request); + +std::string HelpRequiringPassphrase(CWallet* const pwallet); +bool EnsureWalletIsAvailable(CWallet* const pwallet, bool avoidException); +void EnsureWalletIsUnlocked(CWallet* const pwallet, bool fAllowAnonOnly = false); + +#endif //PIVX_WALLET_RPCWALLET_H From 3bfa7d8870d1b619e261939c6478d84178af3010 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 8 Jan 2017 20:33:33 +0000 Subject: [PATCH 14/27] Wallet/RPC: Use filename rather than CWallet pointer, for lockwallet RPCRunLater job name The job name is logged, and could pose as an information leak to someone attacking the process, helping them counteract ASLR protections --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1209e4de7d1f..5e20d12dc4c5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3427,7 +3427,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request) if (nSleepTime > 0) { pwallet->nRelockTime = GetTime () + nSleepTime; - RPCRunLater ("lockwallet", std::bind (LockWallet, pwallet), nSleepTime); + RPCRunLater (strprintf("lockwallet(%s)", pwallet->GetName()), std::bind (LockWallet, pwallet), nSleepTime); } return NullUniValue; From 100d67c65f07b1d40ecea2e830203d2e23ac8cb8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 8 Jan 2017 20:41:30 +0000 Subject: [PATCH 15/27] Wallet: Sanitise -wallet parameter --- src/wallet/wallet.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 401aaa5daa2d..177d687ba16e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4351,6 +4351,12 @@ bool CWallet::InitLoadWallet() std::string walletFile = gArgs.GetArg("-wallet", DEFAULT_WALLET_DAT); + if (walletFile.find_first_of("/\\") != std::string::npos) { + return UIError(_("-wallet parameter must only specify a filename (not a path)")); + } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { + return UIError(_("Invalid characters in -wallet filename")); + } + CWallet * const pwallet = CreateWalletFromFile(walletFile); if (!pwallet) { return false; From 4bbad5cf1d73771cb69cbc7b25f6c1f7467f03c1 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 12:39:06 +0200 Subject: [PATCH 16/27] [Wallet] Replace pwalletMain with a vector of wallet pointers >>> adapts bitcoin@b124cf04ea47e1eda60bbc26a9690a9715c6b23f --- src/budget/budgetmanager.cpp | 10 +++- src/init.cpp | 56 ++++++++++--------- src/masternode.cpp | 3 +- src/miner.cpp | 4 +- src/qt/pivx.cpp | 5 +- src/test/librust/sapling_rpc_wallet_tests.cpp | 2 + src/test/librust/sapling_wallet_tests.cpp | 2 + src/test/librust/wallet_zkeys_tests.cpp | 2 + src/test/miner_tests.cpp | 2 + src/test/script_P2CS_tests.cpp | 2 +- src/test/validation_tests.cpp | 2 +- src/wallet/db.cpp | 4 +- src/wallet/db.h | 13 +++-- src/wallet/rpcwallet.cpp | 3 +- ...sapling_transactions_validations_tests.cpp | 2 + .../test/wallet_shielded_balances_tests.cpp | 2 + src/wallet/test/wallet_test_fixture.cpp | 2 + src/wallet/test/wallet_tests.cpp | 13 ++--- src/wallet/wallet.cpp | 5 +- src/wallet/wallet.h | 2 +- src/wallet/walletdb.cpp | 2 + 21 files changed, 84 insertions(+), 54 deletions(-) diff --git a/src/budget/budgetmanager.cpp b/src/budget/budgetmanager.cpp index 8520533f0d8a..e7e26d2aff23 100644 --- a/src/budget/budgetmanager.cpp +++ b/src/budget/budgetmanager.cpp @@ -107,13 +107,17 @@ uint256 CBudgetManager::SubmitFinalBudget() // create the collateral tx, send it to the network and return CTransactionRef wtx; // Get our change address - CReserveKey keyChange(pwalletMain); - if (!pwalletMain->CreateBudgetFeeTX(wtx, budgetHash, keyChange, true)) { + if (vpwallets.empty() || !vpwallets[0]) { + LogPrint(BCLog::MNBUDGET,"%s: Wallet not found\n", __func__); + return UINT256_ZERO; + } + CReserveKey keyChange(vpwallets[0]); + if (!vpwallets[0]->CreateBudgetFeeTX(wtx, budgetHash, keyChange, true)) { LogPrint(BCLog::MNBUDGET,"%s: Can't make collateral transaction\n", __func__); return UINT256_ZERO; } // Send the tx to the network - const CWallet::CommitResult& res = pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get()); + const CWallet::CommitResult& res = vpwallets[0]->CommitTransaction(wtx, keyChange, g_connman.get()); if (res.status == CWallet::CommitStatus::OK) { const uint256& collateraltxid = wtx->GetHash(); mapUnconfirmedFeeTx.emplace(budgetHash, collateraltxid); diff --git a/src/init.cpp b/src/init.cpp index 80f59edd872e..6ccf6e0e9fc7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -221,8 +221,9 @@ void PrepareShutdown() StopRPC(); StopHTTPServer(); #ifdef ENABLE_WALLET - if (pwalletMain) - pwalletMain->Flush(false); + for (CWalletRef pwallet : vpwallets) { + pwallet->Flush(false); + } GenerateBitcoins(false, NULL, 0); #endif StopMapPort(); @@ -301,8 +302,9 @@ void PrepareShutdown() evoDb.reset(); } #ifdef ENABLE_WALLET - if (pwalletMain) - pwalletMain->Flush(true); + for (CWalletRef pwallet : vpwallets) { + pwallet->Flush(true); + } #endif if (pEvoNotificationInterface) { @@ -354,8 +356,10 @@ void Shutdown() PrepareShutdown(); } #ifdef ENABLE_WALLET - delete pwalletMain; - pwalletMain = NULL; + for (CWalletRef pwallet : vpwallets) { + delete pwallet; + } + vpwallets.clear(); #endif globalVerifyHandle.reset(); ECC_Stop(); @@ -1877,14 +1881,15 @@ bool AppInitMain() strBudgetMode = gArgs.GetArg("-budgetvotemode", "auto"); #ifdef ENABLE_WALLET - if (gArgs.GetBoolArg("-mnconflock", DEFAULT_MNCONFLOCK) && pwalletMain) { - LOCK(pwalletMain->cs_wallet); + // use only the first wallet here. This section can be removed after transition to DMN + if (gArgs.GetBoolArg("-mnconflock", DEFAULT_MNCONFLOCK) && !vpwallets.empty() && vpwallets[0]) { + LOCK(vpwallets[0]->cs_wallet); LogPrintf("Locking Masternodes collateral utxo:\n"); uint256 mnTxHash; for (const auto& mne : masternodeConfig.getEntries()) { mnTxHash.SetHex(mne.getTxHash()); COutPoint outpoint = COutPoint(mnTxHash, (unsigned int) std::stoul(mne.getOutputIndex())); - pwalletMain->LockCoin(outpoint); + vpwallets[0]->LockCoin(outpoint); LogPrintf("Locked collateral, MN: %s, tx hash: %s, output index: %s\n", mne.getAlias(), mne.getTxHash(), mne.getOutputIndex()); } @@ -1918,11 +1923,13 @@ bool AppInitMain() #ifdef ENABLE_WALLET { - if (pwalletMain) { - LOCK(pwalletMain->cs_wallet); - LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->GetKeyPoolSize() : 0); - LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0); - LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->GetAddressBookSize() : 0); + int idx = 0; + for (CWalletRef pwallet : vpwallets) { + LogPrintf("Wallet %d\n", idx++); + LOCK(pwallet->cs_wallet); + LogPrintf("setKeyPool.size() = %u\n", pwallet->GetKeyPoolSize()); + LogPrintf("mapWallet.size() = %u\n", pwallet->mapWallet.size()); + LogPrintf("mapAddressBook.size() = %u\n", pwallet->GetAddressBookSize()); } } #endif @@ -1953,22 +1960,21 @@ bool AppInitMain() return UIError(strNodeError); #ifdef ENABLE_WALLET - // Generate coins in the background - if (pwalletMain) - GenerateBitcoins(gArgs.GetBoolArg("-gen", DEFAULT_GENERATE), pwalletMain, gArgs.GetArg("-genproclimit", DEFAULT_GENERATE_PROCLIMIT)); + // Generate coins in the background (disabled on mainnet. use only wallet 0) + if (!vpwallets.empty()) + GenerateBitcoins(gArgs.GetBoolArg("-gen", DEFAULT_GENERATE), vpwallets[0], gArgs.GetArg("-genproclimit", DEFAULT_GENERATE_PROCLIMIT)); #endif // ********************************************************* Step 12: finished #ifdef ENABLE_WALLET - if (pwalletMain) { - uiInterface.InitMessage(_("Reaccepting wallet transactions...")); - pwalletMain->postInitProcess(scheduler); - - // StakeMiner thread disabled by default on regtest - if (gArgs.GetBoolArg("-staking", !Params().IsRegTestNet() && DEFAULT_STAKING)) { - threadGroup.create_thread(std::bind(&ThreadStakeMinter)); - } + uiInterface.InitMessage(_("Reaccepting wallet transactions...")); + for (CWalletRef pwallet : vpwallets) { + pwallet->postInitProcess(scheduler); + } + // StakeMiner thread disabled by default on regtest + if (!vpwallets.empty() && gArgs.GetBoolArg("-staking", !Params().IsRegTestNet() && DEFAULT_STAKING)) { + threadGroup.create_thread(std::bind(&ThreadStakeMinter)); } #endif diff --git a/src/masternode.cpp b/src/masternode.cpp index a4780d0635c1..a668f1008fb8 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -251,7 +251,8 @@ bool CMasternodeBroadcast::Create(const std::string& strService, } std::string strError; - if (!pwalletMain->GetMasternodeVinAndKeys(txin, pubKeyCollateralAddressNew, keyCollateralAddressNew, strTxHash, strOutputIndex, strError)) { + // Use wallet-0 here. Legacy mnb creation can be removed after transition to DMN + if (vpwallets.empty() || !vpwallets[0]->GetMasternodeVinAndKeys(txin, pubKeyCollateralAddressNew, keyCollateralAddressNew, strTxHash, strOutputIndex, strError)) { strErrorRet = strError; // GetMasternodeVinAndKeys logs this error. Only returned for GUI error notification. LogPrint(BCLog::MASTERNODE,"CMasternodeBroadcast::Create -- %s\n", strprintf("Could not allocate txin %s:%s for masternode %s", strTxHash, strOutputIndex, strService)); return false; diff --git a/src/miner.cpp b/src/miner.cpp index afeb089e7be9..6695eef856d4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -306,8 +306,8 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads) void ThreadStakeMinter() { boost::this_thread::interruption_point(); - LogPrintf("ThreadStakeMinter started\n"); - CWallet* pwallet = pwalletMain; + LogPrintf("ThreadStakeMinter started. Using wallet-0\n"); + CWallet* pwallet = vpwallets[0]; try { BitcoinMiner(pwallet, true); boost::this_thread::interruption_point(); diff --git a/src/qt/pivx.cpp b/src/qt/pivx.cpp index b96eddba4208..9608bf12cd68 100644 --- a/src/qt/pivx.cpp +++ b/src/qt/pivx.cpp @@ -487,8 +487,9 @@ void BitcoinApplication::initializeResult(int retval) window->setClientModel(clientModel); #ifdef ENABLE_WALLET - if (pwalletMain) { - walletModel = new WalletModel(pwalletMain, optionsModel); + // TODO: Expose secondary wallets + if (!vpwallets.empty()) { + walletModel = new WalletModel(vpwallets[0], optionsModel); walletModel->setClientModel(clientModel); window->addWallet(PIVXGUI::DEFAULT_WALLET, walletModel); diff --git a/src/test/librust/sapling_rpc_wallet_tests.cpp b/src/test/librust/sapling_rpc_wallet_tests.cpp index 3e17d198d231..5de83555188d 100644 --- a/src/test/librust/sapling_rpc_wallet_tests.cpp +++ b/src/test/librust/sapling_rpc_wallet_tests.cpp @@ -25,6 +25,8 @@ #include +extern CWallet* pwalletMain; + extern UniValue CallRPC(std::string args); // Implemented in rpc_tests.cpp namespace { diff --git a/src/test/librust/sapling_wallet_tests.cpp b/src/test/librust/sapling_wallet_tests.cpp index 4fac832cbbdc..ead6ad194671 100644 --- a/src/test/librust/sapling_wallet_tests.cpp +++ b/src/test/librust/sapling_wallet_tests.cpp @@ -25,6 +25,8 @@ #include +extern CWallet* pwalletMain; + void setupWallet(CWallet& wallet) { wallet.SetMinVersion(FEATURE_SAPLING); diff --git a/src/test/librust/wallet_zkeys_tests.cpp b/src/test/librust/wallet_zkeys_tests.cpp index cb06c2efbfa8..666a7fb8c3e7 100644 --- a/src/test/librust/wallet_zkeys_tests.cpp +++ b/src/test/librust/wallet_zkeys_tests.cpp @@ -12,6 +12,8 @@ #include "util/system.h" #include +extern CWallet* pwalletMain; + /** * This test covers methods on CWallet * GenerateNewZKey() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index af7814566117..cc3e23dadf29 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -17,6 +17,8 @@ #include +extern CWallet* pwalletMain; + // future: this should be MAINNET. BOOST_FIXTURE_TEST_SUITE(miner_tests, WalletRegTestingSetup) diff --git a/src/test/script_P2CS_tests.cpp b/src/test/script_P2CS_tests.cpp index 7385aac42feb..b0334d7e43fc 100644 --- a/src/test/script_P2CS_tests.cpp +++ b/src/test/script_P2CS_tests.cpp @@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(fake_script_test) { BOOST_ASSERT(!g_IsV6Active); - CWallet& wallet = *pwalletMain; + CWallet& wallet = *vpwallets[0]; LOCK(wallet.cs_wallet); setupWallet(wallet); CKey stakerKey; // dummy staker key (not in the wallet) diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp index 41b6dca855b8..a3895edf902e 100644 --- a/src/test/validation_tests.cpp +++ b/src/test/validation_tests.cpp @@ -122,7 +122,7 @@ BOOST_FIXTURE_TEST_CASE(zerocoin_rejection_tests, RegTestingSetup) std::unique_ptr pblocktemplate; CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ParseHex("8d5b4f83212214d6ef693e02e6d71969fddad976") << OP_EQUALVERIFY << OP_CHECKSIG; - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), false).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), false).CreateNewBlock(scriptPubKey, vpwallets[0], false)); pblocktemplate->block.hashPrevBlock = chainparams.GetConsensus().hashGenesisBlock; // Base tx diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 639a61b236fe..3119fb1e0d6a 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Copyright (c) 2019-2020 The PIVX developers +// Copyright (c) 2009-2021 The Bitcoin developers +// Copyright (c) 2019-2021 The PIVX developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/db.h b/src/wallet/db.h index 22c4380a8206..c57ea6b645b2 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Copyright (c) 2019-2020 The PIVX developers +// Copyright (c) 2009-2021 The Bitcoin developers +// Copyright (c) 2019-2021 The PIVX developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -96,13 +96,13 @@ class CWalletDBWrapper friend class CDB; public: /** Create dummy DB handle */ - CWalletDBWrapper(): env(nullptr) + CWalletDBWrapper() : nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(nullptr) { } /** Create DB handle to real database */ CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in): - env(env_in), strFile(strFile_in) + nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(env_in), strFile(strFile_in) { } @@ -123,13 +123,16 @@ class CWalletDBWrapper void Flush(bool shutdown); void IncrementUpdateCounter(); + std::atomic nUpdateCounter; + unsigned int nLastSeen; + unsigned int nLastFlushed; + int64_t nLastWalletUpdate; unsigned int GetUpdateCounter(); private: /** BerkeleyDB specific */ CDBEnv *env; std::string strFile; - std::atomic nUpdateCounter; /** Return whether this database handle is a dummy for testing. * Only to be used at a low level, application should ideally not care diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5e20d12dc4c5..f31dac7332b2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -36,7 +36,8 @@ CWallet* GetWalletForJSONRPCRequest(const JSONRPCRequest& request) { - return pwalletMain; + // TODO: Some way to access secondary wallets + return vpwallets.empty() ? nullptr : vpwallets[0]; } std::string HelpRequiringPassphrase(CWallet* const pwallet) diff --git a/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp b/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp index 672adc74bae1..fca7da3dda14 100644 --- a/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp +++ b/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp @@ -13,6 +13,8 @@ #include +extern CWallet* pwalletMain; + /* * A text fixture with a preloaded 100-blocks regtest chain, with sapling activating at block 101, * and a wallet containing the key used for the coinbase outputs. diff --git a/src/wallet/test/wallet_shielded_balances_tests.cpp b/src/wallet/test/wallet_shielded_balances_tests.cpp index 8ab4fe8c2306..b192c4f9768d 100644 --- a/src/wallet/test/wallet_shielded_balances_tests.cpp +++ b/src/wallet/test/wallet_shielded_balances_tests.cpp @@ -17,6 +17,8 @@ #include +extern CWallet* pwalletMain; + CAmount fee = COIN; // Hardcoded fee BOOST_FIXTURE_TEST_SUITE(wallet_shielded_balances_tests, WalletTestingSetup) diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index df083e6db1c6..e38b8400ba4e 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -10,6 +10,8 @@ #include "wallet/rpcwallet.h" #include "wallet/wallet.h" +CWallet *pwalletMain; + WalletTestingSetup::WalletTestingSetup(const std::string& chainName): SaplingTestingSetup(chainName) { diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 32397d0d106c..a12355dda283 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -22,6 +22,7 @@ extern UniValue importmulti(const JSONRPCRequest& request); extern UniValue dumpwallet(const JSONRPCRequest& request); extern UniValue importwallet(const JSONRPCRequest& request); +extern CWallet* pwalletMain; // how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles #define RUN_TESTS 100 @@ -365,8 +366,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) { CWallet wallet; WITH_LOCK(wallet.cs_wallet, wallet.SetLastBlockProcessed(newTip); ); - CWallet *backup = ::pwalletMain; - ::pwalletMain = &wallet; + vpwallets.insert(vpwallets.begin(), &wallet); UniValue keys; keys.setArray(); UniValue key; @@ -390,7 +390,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) UniValue response = importmulti(request); // !TODO: after pruning, check that the rescan for the first key fails. BOOST_CHECK_EQUAL(response.write(), "[{\"success\":true},{\"success\":true}]"); - ::pwalletMain = backup; + vpwallets.erase(vpwallets.begin()); } } @@ -400,7 +400,6 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) // than or equal to key birthday. BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) { - CWallet *pwalletMainBackup = ::pwalletMain; // Create one block const int64_t BLOCK_TIME = chainActive.Tip()->GetBlockTimeMax() + 15; SetMockTime(BLOCK_TIME); @@ -426,7 +425,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) JSONRPCRequest request; request.params.setArray(); request.params.push_back(backup_file); - ::pwalletMain = &wallet; + vpwallets.insert(vpwallets.begin(), &wallet); ::dumpwallet(request); } @@ -438,7 +437,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) JSONRPCRequest request; request.params.setArray(); request.params.push_back(backup_file); - ::pwalletMain = &wallet; + vpwallets[0] = &wallet; ::importwallet(request); LOCK(wallet.cs_wallet); @@ -452,7 +451,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) } SetMockTime(0); - ::pwalletMain = pwalletMainBackup; + vpwallets.erase(vpwallets.begin()); } void removeTxFromMempool(CWalletTx& wtx) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 177d687ba16e..e95ff932708f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -25,7 +25,7 @@ #include #include -CWallet* pwalletMain = nullptr; +std::vector vpwallets; /** * Settings */ @@ -4344,7 +4344,6 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) bool CWallet::InitLoadWallet() { if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { - pwalletMain = nullptr; LogPrintf("Wallet disabled!\n"); return true; } @@ -4361,7 +4360,7 @@ bool CWallet::InitLoadWallet() if (!pwallet) { return false; } - pwalletMain = pwallet; + vpwallets.emplace_back(pwallet); return true; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 533ba8f4815f..1ae2e0f842cf 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -45,7 +45,7 @@ #include typedef CWallet* CWalletRef; -extern CWalletRef pwalletMain; +extern std::vector vpwallets; /** * Settings diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 7022096983a4..dc43ed1ff510 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -797,6 +797,7 @@ void MaybeCompactWalletDB() return; } + /* TODO: fix me CWalletDBWrapper& dbh = pwalletMain->GetDBHandle(); static unsigned int nLastSeen = dbh.GetUpdateCounter(); @@ -813,6 +814,7 @@ void MaybeCompactWalletDB() nLastFlushed = dbh.GetUpdateCounter(); } } + */ fOneThread = false; } From d6cf6085c6805550f3ec9436c3c8138ff71b6aaa Mon Sep 17 00:00:00 2001 From: random-zebra Date: Thu, 22 Apr 2021 17:40:31 +0200 Subject: [PATCH 17/27] [Refactor] Remove CWalletDBWrapper::GetUpdateCounter() --- src/wallet/db.cpp | 5 ----- src/wallet/walletdb.cpp | 26 ++++++++++++-------------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 3119fb1e0d6a..31d16761a175 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -433,11 +433,6 @@ void CWalletDBWrapper::IncrementUpdateCounter() ++nUpdateCounter; } -unsigned int CWalletDBWrapper::GetUpdateCounter() -{ - return nUpdateCounter.load(); -} - void CDB::Close() { if (!pdb) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index dc43ed1ff510..8b9d04487f70 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -797,24 +797,22 @@ void MaybeCompactWalletDB() return; } - /* TODO: fix me - CWalletDBWrapper& dbh = pwalletMain->GetDBHandle(); + for (CWalletRef pwallet : vpwallets) { + CWalletDBWrapper& dbh = pwallet->GetDBHandle(); - static unsigned int nLastSeen = dbh.GetUpdateCounter(); - static unsigned int nLastFlushed = dbh.GetUpdateCounter(); - static int64_t nLastWalletUpdate = GetTime(); - - if (nLastSeen != dbh.GetUpdateCounter()) { - nLastSeen = dbh.GetUpdateCounter(); - nLastWalletUpdate = GetTime(); - } + unsigned int nUpdateCounter = dbh.nUpdateCounter; + if (dbh.nLastSeen != nUpdateCounter) { + dbh.nLastSeen = nUpdateCounter; + dbh.nLastWalletUpdate = GetTime(); + } - if (nLastFlushed != dbh.GetUpdateCounter() && GetTime() - nLastWalletUpdate >= 2) { - if (CDB::PeriodicFlush(dbh)) { - nLastFlushed = dbh.GetUpdateCounter(); + if (dbh.nLastFlushed != nUpdateCounter && GetTime() - dbh.nLastWalletUpdate >= 2) { + if (CDB::PeriodicFlush(dbh)) { + dbh.nLastFlushed = nUpdateCounter; + } } } - */ + fOneThread = false; } From d10acd55fd0d98ea8bcb8595bdb0f5abbea0100f Mon Sep 17 00:00:00 2001 From: random-zebra Date: Fri, 23 Apr 2021 16:06:08 +0200 Subject: [PATCH 18/27] [Tests] move pwalletMain to wallet test fixture + use smart pointer >>> inspired by bitcoin@49bd6590feb83ee422e489fd3930e8b700c5b4a7 + bitcoin@f94c2ecb48f2b3656f7412a010569eaf21fa83f5 --- src/test/librust/sapling_rpc_wallet_tests.cpp | 53 +++++++++--- src/test/librust/sapling_wallet_tests.cpp | 2 - src/test/librust/wallet_zkeys_tests.cpp | 4 +- src/test/miner_tests.cpp | 25 +++--- src/test/script_P2CS_tests.cpp | 2 +- src/test/validation_tests.cpp | 5 +- ...sapling_transactions_validations_tests.cpp | 29 +++---- .../test/wallet_shielded_balances_tests.cpp | 2 - src/wallet/test/wallet_test_fixture.cpp | 11 +-- src/wallet/test/wallet_test_fixture.h | 3 + src/wallet/test/wallet_tests.cpp | 86 ++++++++++--------- 11 files changed, 121 insertions(+), 101 deletions(-) diff --git a/src/test/librust/sapling_rpc_wallet_tests.cpp b/src/test/librust/sapling_rpc_wallet_tests.cpp index 5de83555188d..281695547d56 100644 --- a/src/test/librust/sapling_rpc_wallet_tests.cpp +++ b/src/test/librust/sapling_rpc_wallet_tests.cpp @@ -25,7 +25,6 @@ #include -extern CWallet* pwalletMain; extern UniValue CallRPC(std::string args); // Implemented in rpc_tests.cpp @@ -57,6 +56,8 @@ BOOST_FIXTURE_TEST_SUITE(sapling_rpc_wallet_tests, WalletTestingSetup) BOOST_AUTO_TEST_CASE(rpc_wallet_sapling_validateaddress) { SelectParams(CBaseChainParams::MAIN); + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); + UniValue retValue; // Check number of args @@ -83,6 +84,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_sapling_validateaddress) BOOST_CHECK_EQUAL(b, false); BOOST_CHECK_EQUAL(find_value(resultObj, "diversifier").get_str(), "e1fd627f1b9a8e4c7e6657"); BOOST_CHECK_EQUAL(find_value(resultObj, "diversifiedtransmissionkey").get_str(), "d35e0d0897edbd3cf02b3d2327622a14c685534dbd2d3f4f4fa3e0e56cc2f008"); + + vpwallets.erase(vpwallets.begin()); } BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance) @@ -92,6 +95,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance) pwalletMain->SetMinVersion(FEATURE_SAPLING); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); BOOST_CHECK_THROW(CallRPC("getshieldbalance too many args"), std::runtime_error); BOOST_CHECK_THROW(CallRPC("getshieldbalance invalidaddress"), std::runtime_error); @@ -111,6 +115,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance) BOOST_CHECK_THROW(CallRPC("listreceivedbyshieldaddress DMKU6mc52un1MThGCsnNwAtEvncaTdAuaZ 0"), std::runtime_error); // don't have the spending key BOOST_CHECK_THROW(CallRPC("listreceivedbyshieldaddress ps1u87kylcmn28yclnx2uy0psnvuhs2xn608ukm6n2nshrpg2nzyu3n62ls8j77m9cgp40dx40evej 1"), std::runtime_error); + + vpwallets.erase(vpwallets.begin()); } BOOST_AUTO_TEST_CASE(rpc_wallet_sapling_importkey_paymentaddress) @@ -120,6 +126,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_sapling_importkey_paymentaddress) pwalletMain->SetMinVersion(FEATURE_SAPLING); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); auto testAddress = [](const std::string& key) { UniValue ret; @@ -137,6 +144,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_sapling_importkey_paymentaddress) "8uqmqlx8ccxpsw7ae243quhwr0zyekrrc520gs9z0j8pm954c3cev2yvp29vrc" "0zweu7stxkwhp593p6drheps9uhz9pvkrfgvpxzte8d60uzw0qxadnsc77tcd"); + vpwallets.erase(vpwallets.begin()); } /* @@ -149,6 +157,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_sapling_importexport) pwalletMain->SetMinVersion(FEATURE_SAPLING); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); + UniValue retValue; int n1 = 1000; // number of times to import/export int n2 = 1000; // number of addresses to create and list @@ -223,15 +233,17 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_sapling_importexport) BOOST_CHECK((int) listaddrs.size() == numAddrs); BOOST_CHECK(myaddrs == listaddrs); + vpwallets.erase(vpwallets.begin()); } // Check if address is of given type and spendable from our wallet. -void CheckHaveAddr(const libzcash::PaymentAddress& addr) { +void CheckHaveAddr(std::unique_ptr& pwallet, const libzcash::PaymentAddress& addr) +{ BOOST_CHECK(IsValidPaymentAddress(addr)); auto addr_of_type = boost::get(&addr); BOOST_ASSERT(addr_of_type != nullptr); - BOOST_CHECK(pwalletMain->HaveSpendingKeyForPaymentAddress(*addr_of_type)); + BOOST_CHECK(pwallet->HaveSpendingKeyForPaymentAddress(*addr_of_type)); } BOOST_AUTO_TEST_CASE(rpc_wallet_getnewshieldaddress) @@ -241,12 +253,15 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_getnewshieldaddress) pwalletMain->SetMinVersion(FEATURE_SAPLING); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); // No parameter defaults to sapling address UniValue addr = CallRPC("getnewshieldaddress"); - CheckHaveAddr(KeyIO::DecodePaymentAddress(addr.get_str())); + CheckHaveAddr(pwalletMain, KeyIO::DecodePaymentAddress(addr.get_str())); // Too many arguments will throw with the help BOOST_CHECK_THROW(CallRPC("getnewshieldaddress many args"), std::runtime_error); + + vpwallets.erase(vpwallets.begin()); } BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_parameters) @@ -256,6 +271,7 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_parameters) pwalletMain->SetMinVersion(FEATURE_SAPLING); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); BOOST_CHECK_THROW(CallRPC("shieldsendmany"), std::runtime_error); BOOST_CHECK_THROW(CallRPC("shieldsendmany toofewargs"), std::runtime_error); @@ -308,16 +324,20 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_parameters) std::string zaddr1 = KeyIO::EncodePaymentAddress(pa); BOOST_CHECK_THROW(CallRPC(std::string("shieldsendmany DMKU6mc52un1MThGCsnNwAtEvncaTdAuaZ ") + "[{\"address\":\"" + zaddr1 + "\", \"amount\":123.456}]"), std::runtime_error); + + vpwallets.erase(vpwallets.begin()); } +// TODO: test private methods BOOST_AUTO_TEST_CASE(saplingOperationTests) { { LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->SetupSPKM(false); } - auto consensusParams = Params().GetConsensus(); + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); + UniValue retValue; // add keys manually @@ -330,7 +350,7 @@ BOOST_AUTO_TEST_CASE(saplingOperationTests) // there are no utxos to spend { std::vector recipients = { SendManyRecipient(zaddr1, COIN, "DEADBEEF") }; - SaplingOperation operation(consensusParams, 1, pwalletMain); + SaplingOperation operation(consensusParams, 1, pwalletMain.get()); operation.setFromAddress(taddr1); auto res = operation.setRecipients(recipients)->buildAndSend(ret); BOOST_CHECK(!res); @@ -340,7 +360,7 @@ BOOST_AUTO_TEST_CASE(saplingOperationTests) // minconf cannot be zero when sending from zaddr { std::vector recipients = { SendManyRecipient(zaddr1, COIN, "DEADBEEF") }; - SaplingOperation operation(consensusParams, 1, pwalletMain); + SaplingOperation operation(consensusParams, 1, pwalletMain.get()); operation.setFromAddress(zaddr1); auto res = operation.setRecipients(recipients)->setMinDepth(0)->buildAndSend(ret); BOOST_CHECK(!res); @@ -350,7 +370,7 @@ BOOST_AUTO_TEST_CASE(saplingOperationTests) // there are no unspent notes to spend { std::vector recipients = { SendManyRecipient(taddr1, COIN) }; - SaplingOperation operation(consensusParams, 1, pwalletMain); + SaplingOperation operation(consensusParams, 1, pwalletMain.get()); operation.setFromAddress(zaddr1); auto res = operation.setRecipients(recipients)->buildAndSend(ret); BOOST_CHECK(!res); @@ -385,6 +405,8 @@ BOOST_AUTO_TEST_CASE(saplingOperationTests) const std::string& errStr = res.getError(); BOOST_CHECK(errStr.find("too big") != std::string::npos); } + + vpwallets.erase(vpwallets.begin()); } @@ -394,6 +416,7 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_taddr_to_sapling) LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); UniValue retValue; @@ -411,7 +434,7 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_taddr_to_sapling) CMutableTransaction mtx; mtx.vout.emplace_back(5 * COIN, GetScriptForDestination(taddr)); // Add to wallet and get the updated wtx - CWalletTx wtxIn(pwalletMain, MakeTransactionRef(mtx)); + CWalletTx wtxIn(pwalletMain.get(), MakeTransactionRef(mtx)); pwalletMain->LoadToWallet(wtxIn); CWalletTx& wtx = pwalletMain->mapWallet.at(mtx.GetHash()); @@ -433,7 +456,7 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_taddr_to_sapling) BOOST_CHECK_MESSAGE(pwalletMain->GetAvailableBalance() > 0, "tx not confirmed"); std::vector recipients = { SendManyRecipient(zaddr1, 1 * COIN, "ABCD") }; - SaplingOperation operation(consensusParams, nextBlockHeight, pwalletMain); + SaplingOperation operation(consensusParams, nextBlockHeight, pwalletMain.get()); operation.setFromAddress(taddr); BOOST_CHECK(operation.setRecipients(recipients) ->setMinDepth(0) @@ -441,7 +464,7 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_taddr_to_sapling) // try from auto-selected transparent address std::vector recipients2 = { SendManyRecipient(zaddr1, 1 * COIN, "ABCD") }; - SaplingOperation operation2(consensusParams, nextBlockHeight, pwalletMain); + SaplingOperation operation2(consensusParams, nextBlockHeight, pwalletMain.get()); BOOST_CHECK(operation2.setSelectTransparentCoins(true) ->setRecipients(recipients2) ->setMinDepth(0) @@ -472,6 +495,7 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_taddr_to_sapling) // Tear down chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); + vpwallets.erase(vpwallets.begin()); } BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_sapzkeys) @@ -484,6 +508,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_sapzkeys) pwalletMain->SetMinVersion(FEATURE_SAPLING); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); // wallet should currently be empty std::set addrs; @@ -532,8 +557,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_sapzkeys) arr = retValue.get_array(); BOOST_CHECK((int) arr.size() == n+1); - // We can't simulate over RPC the wallet closing and being reloaded - // but there are tests for this in gtest. + vpwallets.erase(vpwallets.begin()); } BOOST_AUTO_TEST_CASE(rpc_listshieldunspent_parameters) @@ -542,6 +566,7 @@ BOOST_AUTO_TEST_CASE(rpc_listshieldunspent_parameters) LOCK(pwalletMain->cs_wallet); pwalletMain->SetupSPKM(false); } + vpwallets.insert(vpwallets.begin(), pwalletMain.get()); UniValue retValue; @@ -583,6 +608,8 @@ BOOST_AUTO_TEST_CASE(rpc_listshieldunspent_parameters) // duplicate address error BOOST_CHECK_THROW(CallRPC("listshieldunspent 1 999 false [\"" + myzaddr + "\", \"" + myzaddr + "\"]"), std::runtime_error); + + vpwallets.erase(vpwallets.begin()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/librust/sapling_wallet_tests.cpp b/src/test/librust/sapling_wallet_tests.cpp index ead6ad194671..4fac832cbbdc 100644 --- a/src/test/librust/sapling_wallet_tests.cpp +++ b/src/test/librust/sapling_wallet_tests.cpp @@ -25,8 +25,6 @@ #include -extern CWallet* pwalletMain; - void setupWallet(CWallet& wallet) { wallet.SetMinVersion(FEATURE_SAPLING); diff --git a/src/test/librust/wallet_zkeys_tests.cpp b/src/test/librust/wallet_zkeys_tests.cpp index 666a7fb8c3e7..19764a4cfd56 100644 --- a/src/test/librust/wallet_zkeys_tests.cpp +++ b/src/test/librust/wallet_zkeys_tests.cpp @@ -12,8 +12,6 @@ #include "util/system.h" #include -extern CWallet* pwalletMain; - /** * This test covers methods on CWallet * GenerateNewZKey() @@ -172,7 +170,7 @@ BOOST_AUTO_TEST_CASE(WriteCryptedSaplingZkeyDirectToDb) { BOOST_CHECK_EQUAL(DB_LOAD_OK, wallet2.LoadWallet(fFirstRun)); // Confirm it's not the same as the other wallet - BOOST_CHECK(pwalletMain != &wallet2); + BOOST_CHECK(pwalletMain.get() != &wallet2); BOOST_CHECK(wallet2.HasSaplingSPKM()); // wallet should have two keys diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index cc3e23dadf29..6f249891f760 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -17,7 +17,6 @@ #include -extern CWallet* pwalletMain; // future: this should be MAINNET. BOOST_FIXTURE_TEST_SUITE(miner_tests, WalletRegTestingSetup) @@ -91,7 +90,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) Checkpoints::fEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); // Set genesis block pblocktemplate->block.hashPrevBlock = chainparams.GetConsensus().hashGenesisBlock; @@ -117,7 +116,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) } // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); // block sigops > limit: 2000 CHECKMULTISIG + 1 tx.vin.resize(1); @@ -135,7 +134,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbaseOrCoinstake(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false), std::runtime_error, HasReason("bad-blk-sigops")); + BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false), std::runtime_error, HasReason("bad-blk-sigops")); mempool.clear(); tx.vin[0].prevout.hash = txFirst[0]->GetHash(); @@ -148,7 +147,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbaseOrCoinstake(spendsCoinbase).SigOps(20).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); mempool.clear(); // block size > limit @@ -168,13 +167,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbaseOrCoinstake(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); mempool.clear(); // orphan in mempool, template creation fails hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).FromTx(tx)); - BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); + BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); mempool.clear(); // child with higher priority than parent @@ -191,7 +190,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 5900000000LL; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(400000000LL).Time(GetTime()).SpendsCoinbaseOrCoinstake(true).FromTx(tx)); - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); mempool.clear(); // coinbase in mempool, template creation fails @@ -202,7 +201,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); // give it a fee so it'll get mined mempool.addUnchecked(hash, entry.Fee(100000).Time(GetTime()).SpendsCoinbaseOrCoinstake(false).FromTx(tx)); - BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false), std::runtime_error, HasReason("bad-cb-multiple")); + BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false), std::runtime_error, HasReason("bad-cb-multiple")); mempool.clear(); // invalid (pre-p2sh) txn in mempool, template creation fails @@ -220,7 +219,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbaseOrCoinstake(false).FromTx(tx)); // Should throw block-validation-failed - BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false), std::runtime_error, HasReason("block-validation-failed")); + BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false), std::runtime_error, HasReason("block-validation-failed")); mempool.clear(); // double spend txn pair in mempool, template creation fails @@ -233,7 +232,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbaseOrCoinstake(true).FromTx(tx)); - BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); + BOOST_CHECK_EXCEPTION(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); mempool.clear(); // non-final txs in mempool @@ -264,7 +263,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbaseOrCoinstake(true).FromTx(tx2)); { LOCK(cs_main); BOOST_CHECK(!CheckFinalTx(MakeTransactionRef(tx2), LOCKTIME_MEDIAN_TIME_PAST)); } - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); // Neither tx should have make it into the template. BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); @@ -281,7 +280,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) //BOOST_CHECK(CheckFinalTx(tx)); //BOOST_CHECK(CheckFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain, false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); WITH_LOCK(cs_main, chainActive.Tip()->nHeight--); diff --git a/src/test/script_P2CS_tests.cpp b/src/test/script_P2CS_tests.cpp index b0334d7e43fc..7385aac42feb 100644 --- a/src/test/script_P2CS_tests.cpp +++ b/src/test/script_P2CS_tests.cpp @@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(fake_script_test) { BOOST_ASSERT(!g_IsV6Active); - CWallet& wallet = *vpwallets[0]; + CWallet& wallet = *pwalletMain; LOCK(wallet.cs_wallet); setupWallet(wallet); CKey stakerKey; // dummy staker key (not in the wallet) diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp index a3895edf902e..b3d2714e99ce 100644 --- a/src/test/validation_tests.cpp +++ b/src/test/validation_tests.cpp @@ -7,6 +7,7 @@ #include "primitives/transaction.h" #include "sapling/sapling_validation.h" #include "test/librust/utiltest.h" +#include "wallet/test/wallet_test_fixture.h" #include @@ -115,14 +116,14 @@ void CheckMempoolZcRejection(CMutableTransaction& mtx) /* * Running on regtest to have v5 upgrade enforced at block 1 and test in-block zc rejection */ -BOOST_FIXTURE_TEST_CASE(zerocoin_rejection_tests, RegTestingSetup) +BOOST_FIXTURE_TEST_CASE(zerocoin_rejection_tests, WalletRegTestingSetup) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V5_0, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); const CChainParams& chainparams = Params(); std::unique_ptr pblocktemplate; CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ParseHex("8d5b4f83212214d6ef693e02e6d71969fddad976") << OP_EQUALVERIFY << OP_CHECKSIG; - BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), false).CreateNewBlock(scriptPubKey, vpwallets[0], false)); + BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), false).CreateNewBlock(scriptPubKey, pwalletMain.get(), false)); pblocktemplate->block.hashPrevBlock = chainparams.GetConsensus().hashGenesisBlock; // Base tx diff --git a/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp b/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp index fca7da3dda14..6e026fba8f28 100644 --- a/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp +++ b/src/wallet/test/wallet_sapling_transactions_validations_tests.cpp @@ -13,14 +13,14 @@ #include -extern CWallet* pwalletMain; - /* * A text fixture with a preloaded 100-blocks regtest chain, with sapling activating at block 101, * and a wallet containing the key used for the coinbase outputs. */ struct TestSaplingChainSetup: public TestChain100Setup { + std::unique_ptr pwalletMain; + TestSaplingChainSetup() : TestChain100Setup() { initZKSNARKS(); // init zk-snarks lib @@ -28,9 +28,9 @@ struct TestSaplingChainSetup: public TestChain100Setup bitdb.MakeMock(); bool fFirstRun; std::unique_ptr dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat")); - pwalletMain = new CWallet(std::move(dbw)); + pwalletMain = MakeUnique(std::move(dbw)); pwalletMain->LoadWallet(fFirstRun); - RegisterValidationInterface(pwalletMain); + RegisterValidationInterface(pwalletMain.get()); int SAPLING_ACTIVATION_HEIGHT = 101; UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V5_0, SAPLING_ACTIVATION_HEIGHT); @@ -45,16 +45,14 @@ struct TestSaplingChainSetup: public TestChain100Setup // import coinbase key used to generate the 100-blocks chain BOOST_CHECK(pwalletMain->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey())); } - WalletRescanReserver reserver(pwalletMain); + WalletRescanReserver reserver(pwalletMain.get()); BOOST_CHECK(reserver.reserve()); pwalletMain->RescanFromTime(0, reserver, true /* update */); } ~TestSaplingChainSetup() { - UnregisterValidationInterface(pwalletMain); - delete pwalletMain; - pwalletMain = nullptr; + UnregisterValidationInterface(pwalletMain.get()); bitdb.Flush(true); bitdb.Reset(); } @@ -62,12 +60,13 @@ struct TestSaplingChainSetup: public TestChain100Setup BOOST_FIXTURE_TEST_SUITE(wallet_sapling_transactions_validations_tests, TestSaplingChainSetup) -SaplingOperation createOperationAndBuildTx(std::vector recipients, - int nextBlockHeight, - bool selectTransparentCoins) +static SaplingOperation createOperationAndBuildTx(std::unique_ptr& pwallet, + std::vector recipients, + int nextBlockHeight, + bool selectTransparentCoins) { // Create the operation - SaplingOperation operation(Params().GetConsensus(), nextBlockHeight, pwalletMain); + SaplingOperation operation(Params().GetConsensus(), nextBlockHeight, pwallet.get()); auto operationResult = operation.setRecipients(recipients) ->setSelectTransparentCoins(selectTransparentCoins) ->setSelectShieldedCoins(!selectTransparentCoins) @@ -114,7 +113,7 @@ BOOST_AUTO_TEST_CASE(test_in_block_and_mempool_notes_double_spend) recipients.emplace_back(pa, CAmount(100 * COIN), ""); // Create the operation and build the transaction - SaplingOperation operation = createOperationAndBuildTx(recipients, tipHeight + 1, true); + SaplingOperation operation = createOperationAndBuildTx(pwalletMain, recipients, tipHeight + 1, true); // broadcast the tx to the network std::string retHash; BOOST_ASSERT_MSG(operation.send(retHash), "error committing and broadcasting the transaction"); @@ -137,14 +136,14 @@ BOOST_AUTO_TEST_CASE(test_in_block_and_mempool_notes_double_spend) pwalletMain->getNewAddress(tDest2, "receiveValid"); std::vector recipients2; recipients2.emplace_back(tDest2, CAmount(90 * COIN)); - SaplingOperation operation2 = createOperationAndBuildTx(recipients2, tipHeight + 1, false); + SaplingOperation operation2 = createOperationAndBuildTx(pwalletMain, recipients2, tipHeight + 1, false); // Create a second transaction that spends the same note with a different output now CTxDestination tDest3; pwalletMain->getNewAddress(tDest3, "receiveInvalid"); std::vector recipients3; recipients3.emplace_back(tDest3, CAmount(5 * COIN)); - SaplingOperation operation3 = createOperationAndBuildTx(recipients3, tipHeight + 1, false); + SaplingOperation operation3 = createOperationAndBuildTx(pwalletMain, recipients3, tipHeight + 1, false); // Now that both transactions were created, broadcast the first one std::string retTxHash2; diff --git a/src/wallet/test/wallet_shielded_balances_tests.cpp b/src/wallet/test/wallet_shielded_balances_tests.cpp index b192c4f9768d..8ab4fe8c2306 100644 --- a/src/wallet/test/wallet_shielded_balances_tests.cpp +++ b/src/wallet/test/wallet_shielded_balances_tests.cpp @@ -17,8 +17,6 @@ #include -extern CWallet* pwalletMain; - CAmount fee = COIN; // Hardcoded fee BOOST_FIXTURE_TEST_SUITE(wallet_shielded_balances_tests, WalletTestingSetup) diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index e38b8400ba4e..085f29bdf925 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -8,9 +8,6 @@ #include "rpc/server.h" #include "wallet/db.h" #include "wallet/rpcwallet.h" -#include "wallet/wallet.h" - -CWallet *pwalletMain; WalletTestingSetup::WalletTestingSetup(const std::string& chainName): SaplingTestingSetup(chainName) @@ -19,18 +16,16 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName): bool fFirstRun; std::unique_ptr dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat")); - pwalletMain = new CWallet(std::move(dbw)); + pwalletMain = MakeUnique(std::move(dbw)); pwalletMain->LoadWallet(fFirstRun); - RegisterValidationInterface(pwalletMain); + RegisterValidationInterface(pwalletMain.get()); RegisterWalletRPCCommands(tableRPC); } WalletTestingSetup::~WalletTestingSetup() { - UnregisterValidationInterface(pwalletMain); - delete pwalletMain; - pwalletMain = nullptr; + UnregisterValidationInterface(pwalletMain.get()); bitdb.Flush(true); bitdb.Reset(); diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h index 85579febf5d1..e9006ffd88f9 100644 --- a/src/wallet/test/wallet_test_fixture.h +++ b/src/wallet/test/wallet_test_fixture.h @@ -7,6 +7,7 @@ #define PIVX_WALLET_TEST_FIXTURE_H #include "test/librust/sapling_test_fixture.h" +#include "wallet/wallet.h" /** Testing setup and teardown for wallet. @@ -15,6 +16,8 @@ struct WalletTestingSetup : public SaplingTestingSetup { WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~WalletTestingSetup(); + + std::unique_ptr pwalletMain; }; struct WalletRegTestingSetup : public WalletTestingSetup diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index a12355dda283..483073906c1f 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -22,8 +22,6 @@ extern UniValue importmulti(const JSONRPCRequest& request); extern UniValue dumpwallet(const JSONRPCRequest& request); extern UniValue importwallet(const JSONRPCRequest& request); -extern CWallet* pwalletMain; - // how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles #define RUN_TESTS 100 @@ -39,7 +37,7 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) static std::vector vCoins; -static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) +static void add_coin(std::unique_ptr& pwallet, const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) { static int nextLockTime = 0; CMutableTransaction tx; @@ -51,7 +49,7 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa // so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe() tx.vin.resize(1); } - std::unique_ptr wtx(new CWalletTx(pwalletMain, MakeTransactionRef(std::move(tx)))); + std::unique_ptr wtx(new CWalletTx(pwallet.get(), MakeTransactionRef(std::move(tx)))); if (fIsFromMe) { wtx->m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1); } @@ -87,7 +85,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // with an empty wallet we can't even pay one cent BOOST_CHECK(!pwalletMain->SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); - add_coin(1*CENT, 4); // add a new 1 cent coin + add_coin(pwalletMain, 1*CENT, 4); // add a new 1 cent coin // with a new 1 cent coin, we still can't find a mature 1 cent BOOST_CHECK(!pwalletMain->SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); @@ -96,7 +94,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK(pwalletMain->SelectCoinsMinConf( 1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); - add_coin(2*CENT); // add a mature 2 cent coin + add_coin(pwalletMain, 2*CENT); // add a mature 2 cent coin // we can't make 3 cents of mature coins BOOST_CHECK(!pwalletMain->SelectCoinsMinConf( 3 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); @@ -105,9 +103,9 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK(pwalletMain->SelectCoinsMinConf( 3 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); - add_coin(5*CENT); // add a mature 5 cent coin, - add_coin(10*CENT, 3, true); // a new 10 cent coin sent from one of our own addresses - add_coin(20*CENT); // and a mature 20 cent coin + add_coin(pwalletMain, 5*CENT); // add a mature 5 cent coin, + add_coin(pwalletMain, 10*CENT, 3, true); // a new 10 cent coin sent from one of our own addresses + add_coin(pwalletMain, 20*CENT); // and a mature 20 cent coin // now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38 @@ -145,11 +143,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // now clear out the wallet and start again to test choosing between subsets of smaller coins and the next biggest coin empty_wallet(); - add_coin( 6*CENT); - add_coin( 7*CENT); - add_coin( 8*CENT); - add_coin(20*CENT); - add_coin(30*CENT); // now we have 6+7+8+20+30 = 71 cents total + add_coin(pwalletMain, 6*CENT); + add_coin(pwalletMain, 7*CENT); + add_coin(pwalletMain, 8*CENT); + add_coin(pwalletMain, 20*CENT); + add_coin(pwalletMain, 30*CENT); // now we have 6+7+8+20+30 = 71 cents total // check that we have 71 and not 72 BOOST_CHECK(pwalletMain->SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -160,14 +158,14 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); - add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total + add_coin(pwalletMain, 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total // now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20 BOOST_CHECK(pwalletMain->SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); - add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 + add_coin(pwalletMain, 18*CENT); // now we have 5+6+7+8+18+20+30 // and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18 BOOST_CHECK(pwalletMain->SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -180,10 +178,10 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // check that the smallest bigger coin is used - add_coin( 1*COIN); - add_coin( 2*COIN); - add_coin( 3*COIN); - add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents + add_coin(pwalletMain, 1*COIN); + add_coin(pwalletMain, 2*COIN); + add_coin(pwalletMain, 3*COIN); + add_coin(pwalletMain, 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents BOOST_CHECK(pwalletMain->SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -194,11 +192,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance empty_wallet(); - add_coin(0.1*CENT); - add_coin(0.2*CENT); - add_coin(0.3*CENT); - add_coin(0.4*CENT); - add_coin(0.5*CENT); + add_coin(pwalletMain, 0.1*CENT); + add_coin(pwalletMain, 0.2*CENT); + add_coin(pwalletMain, 0.3*CENT); + add_coin(pwalletMain, 0.4*CENT); + add_coin(pwalletMain, 0.5*CENT); // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents // we'll get sub-cent change whatever happens, so can expect 1.0 exactly @@ -206,15 +204,15 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // but if we add a bigger coin, making it possible to avoid sub-cent change, things change: - add_coin(1111*CENT); + add_coin(pwalletMain, 1111*CENT); // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents BOOST_CHECK(pwalletMain->SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount // if we add more sub-cent coins: - add_coin(0.6*CENT); - add_coin(0.7*CENT); + add_coin(pwalletMain, 0.6*CENT); + add_coin(pwalletMain, 0.7*CENT); // and try again to make 1.0 cents, we can still make 1.0 cents BOOST_CHECK(pwalletMain->SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -224,7 +222,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change empty_wallet(); for (int j = 0; j < 20; j++) - add_coin(50000 * COIN); + add_coin(pwalletMain, 50000 * COIN); BOOST_CHECK(pwalletMain->SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount @@ -235,29 +233,29 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(0.5 * CENT); - add_coin(0.6 * CENT); - add_coin(0.7 * CENT); - add_coin(1111 * CENT); + add_coin(pwalletMain, 0.5 * CENT); + add_coin(pwalletMain, 0.6 * CENT); + add_coin(pwalletMain, 0.7 * CENT); + add_coin(pwalletMain, 1111 * CENT); BOOST_CHECK(pwalletMain->SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); - add_coin(0.4 * CENT); - add_coin(0.6 * CENT); - add_coin(0.8 * CENT); - add_coin(1111 * CENT); + add_coin(pwalletMain, 0.4 * CENT); + add_coin(pwalletMain, 0.6 * CENT); + add_coin(pwalletMain, 0.8 * CENT); + add_coin(pwalletMain, 1111 * CENT); BOOST_CHECK(pwalletMain->SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6 // test avoiding sub-cent change empty_wallet(); - add_coin(0.0005 * COIN); - add_coin(0.01 * COIN); - add_coin(1 * COIN); + add_coin(pwalletMain, 0.0005 * COIN); + add_coin(pwalletMain, 0.01 * COIN); + add_coin(pwalletMain, 1 * COIN); // trying to make 1.0001 from these three coins BOOST_CHECK(pwalletMain->SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -273,7 +271,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) { empty_wallet(); for (int i2 = 0; i2 < 100; i2++) - add_coin(COIN); + add_coin(pwalletMain, COIN); // picking 50 from 100 coins doesn't depend on the shuffle, // but does depend on randomness in the stochastic approximation code @@ -296,7 +294,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // add 75 cents in small change. not enough to make 90 cents, // then try making 90 cents. there are multiple competing "smallest bigger" coins, // one of which should be picked at random - add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT); + add_coin(pwalletMain, 5*CENT); + add_coin(pwalletMain, 10*CENT); + add_coin(pwalletMain, 15*CENT); + add_coin(pwalletMain, 20*CENT); + add_coin(pwalletMain, 25*CENT); fails = 0; for (int j = 0; j < RANDOM_REPEATS; j++) From b27dcfe5e3dc75cc1c9a3f73d631f92b1bd2bf9a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 9 Sep 2016 08:50:09 +0000 Subject: [PATCH 19/27] Wallet: Support loading multiple wallets if -wallet used more than once --- src/init.cpp | 7 ++----- src/wallet/wallet.cpp | 46 +++++++++++++++++++------------------------ src/wallet/wallet.h | 3 --- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 6ccf6e0e9fc7..f427a3856a9a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1337,11 +1337,8 @@ bool AppInitMain() } } -// ********************************************************* Step 5: Backup wallet and verify wallet database integrity +// ********************************************************* Step 5: Verify wallet database integrity #ifdef ENABLE_WALLET - if (!InitAutoBackupWallet()) { - return false; - } if (!CWallet::Verify()) { return false; } @@ -1729,7 +1726,7 @@ bool AppInitMain() mempool.ReadFeeEstimates(est_filein); fFeeEstimatesInitialized = true; -// ********************************************************* Step 8: load wallet +// ********************************************************* Step 8: Backup and Load wallet #ifdef ENABLE_WALLET if (!CWallet::InitLoadWallet()) return false; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e95ff932708f..36417bf8ffd4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4348,19 +4348,29 @@ bool CWallet::InitLoadWallet() return true; } - std::string walletFile = gArgs.GetArg("-wallet", DEFAULT_WALLET_DAT); + gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); - if (walletFile.find_first_of("/\\") != std::string::npos) { - return UIError(_("-wallet parameter must only specify a filename (not a path)")); - } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { - return UIError(_("Invalid characters in -wallet filename")); - } + for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { + if (fs::path(walletFile).filename() != walletFile) { + return UIError(_("-wallet parameter must only specify a filename (not a path)")); + } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { + return UIError(_("Invalid characters in -wallet filename")); + } - CWallet * const pwallet = CreateWalletFromFile(walletFile); - if (!pwallet) { - return false; + // automatic backups + std::string strWarning, strError; + if(!AutoBackupWallet(walletFile, strWarning, strError)) { + if (!strWarning.empty()) UIWarning(strWarning); + if (!strError.empty()) return UIError(strError); + } + + CWallet * const pwallet = CreateWalletFromFile(walletFile); + if (!pwallet) { + return false; + } + vpwallets.emplace_back(pwallet); } - vpwallets.emplace_back(pwallet); + return true; } @@ -4885,19 +4895,3 @@ CStakeableOutput::CStakeableOutput(const CWalletTx* txIn, int iIn, int nDepthIn, const CBlockIndex*& _pindex) : COutput(txIn, iIn, nDepthIn, fSpendableIn, fSolvableIn), pindex(_pindex) {} -bool InitAutoBackupWallet() -{ - if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { - return true; - } - - std::string strWalletFile = gArgs.GetArg("-wallet", DEFAULT_WALLET_DAT); - - std::string strWarning, strError; - if(!AutoBackupWallet(strWalletFile, strWarning, strError)) { - if (!strWarning.empty()) UIWarning(strWarning); - if (!strError.empty()) return UIError(strError); - } - - return true; -} diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1ae2e0f842cf..5b4a7e6e0365 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1276,7 +1276,4 @@ class WalletRescanReserver } }; -// !TODO: move to wallet/init.* -bool InitAutoBackupWallet(); - #endif // PIVX_WALLET_H From 647fbc9b8ec9422b97d749dd4c568ffa41f405cb Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 9 Mar 2017 23:45:58 +0000 Subject: [PATCH 20/27] Wallet: Move multiwallet sanity checks to CWallet::Verify, and do other checks on all wallets --- src/wallet/wallet.cpp | 70 ++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 36417bf8ffd4..6eed62cbc96e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2080,40 +2080,44 @@ bool CWallet::Verify() return true; } - uiInterface.InitMessage(_("Verifying wallet...")); - std::string walletFile = gArgs.GetArg("-wallet", DEFAULT_WALLET_DAT); - std::string strDataDir = GetDataDir().string(); - - std::string strError; - if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) - return UIError(strError); - - if (gArgs.GetBoolArg("-salvagewallet", false)) { - // Recover readable keypairs: - CWallet dummyWallet; - // Even if we don't use this lock in this function, we want to preserve - // lock order in LoadToWallet if query of chain state is needed to know - // tx status. If lock can't be taken, tx confirmation status may be not - // reliable. - LOCK(cs_main); - if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter)) - return false; - } + gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); + uiInterface.InitMessage(_("Verifying wallet(s)...")); - std::string strWarning; - bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); - if (!strWarning.empty()) { - UIWarning(strWarning); - } - if (!dbV) { - UIError(strError); - return false; + for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { + if (fs::path(walletFile).filename() != walletFile) { + return UIError(_("-wallet parameter must only specify a filename (not a path)")); + } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { + return UIError(_("Invalid characters in -wallet filename")); + } + + std::string strError; + if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) + return UIError(strError); + + if (gArgs.GetBoolArg("-salvagewallet", false)) { + // Recover readable keypairs: + CWallet dummyWallet; + // Even if we don't use this lock in this function, we want to preserve + // lock order in LoadToWallet if query of chain state is needed to know + // tx status. If lock can't be taken, tx confirmation status may be not + // reliable. + LOCK(cs_main); + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter)) + return false; + } + + std::string strWarning; + bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); + if (!strWarning.empty()) + UIWarning(strWarning); + if (!dbV) { + return UIError(strError); + } } + return true; } - - void CWallet::ResendWalletTransactions(CConnman* connman) { // Do this infrequently and randomly to avoid giving away @@ -4348,15 +4352,7 @@ bool CWallet::InitLoadWallet() return true; } - gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); - for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { - if (fs::path(walletFile).filename() != walletFile) { - return UIError(_("-wallet parameter must only specify a filename (not a path)")); - } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { - return UIError(_("Invalid characters in -wallet filename")); - } - // automatic backups std::string strWarning, strError; if(!AutoBackupWallet(walletFile, strWarning, strError)) { From e6efa6ba1c9d4a6b06223490b13927e322f3c1d0 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 5 Jun 2017 22:01:48 +0000 Subject: [PATCH 21/27] wallet: Include actual backup filename in recovery warning message --- src/wallet/db.cpp | 17 +++++++++-------- src/wallet/db.h | 12 +++++++----- src/wallet/wallet.cpp | 3 ++- src/wallet/walletdb.cpp | 8 ++++---- src/wallet/walletdb.h | 6 +++--- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 31d16761a175..b6eb52eaf226 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -146,7 +146,7 @@ void CDBEnv::MakeMock() fMockDb = true; } -CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFunc)(const std::string& strFile)) +CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename) { LOCK(cs_db); assert(mapFileUseCount.count(strFile) == 0); @@ -159,11 +159,11 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFu return RECOVER_FAIL; // Try to recover: - bool fRecovered = (*recoverFunc)(strFile); + bool fRecovered = (*recoverFunc)(strFile, out_backup_filename); return (fRecovered ? RECOVER_OK : RECOVER_FAIL); } -bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)) +bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename) { // Recovery procedure: // move wallet file to wallet.timestamp.bak @@ -173,7 +173,7 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco // Set -rescan so any missing transactions will be // found. int64_t now = GetTime(); - std::string newFilename = strprintf("wallet.%d.bak", now); + newFilename = strprintf("wallet.%d.bak", now); int result = bitdb.dbenv->dbrename(NULL, filename.c_str(), NULL, newFilename.c_str(), DB_AUTO_COMMIT); @@ -257,16 +257,17 @@ bool CDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataD return true; } -bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, bool (*recoverFunc)(const std::string& strFile)) +bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc) { if (fs::exists(dataDir / walletFile)) { - CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc); + std::string backup_filename; + CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc, backup_filename); if (r == CDBEnv::RECOVER_OK) { - warningStr = strprintf(("Warning: Wallet file corrupt, data salvaged!" + warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!" " Original %s saved as %s in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), - walletFile, "wallet.{timestamp}.bak", dataDir); + walletFile, backup_filename, dataDir); } if (r == CDBEnv::RECOVER_FAIL) { errorStr = strprintf(("%s corrupt, salvage failed"), walletFile); diff --git a/src/wallet/db.h b/src/wallet/db.h index c57ea6b645b2..1c76d58c91e8 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -55,9 +55,11 @@ class CDBEnv * Returns true if strFile is OK. */ enum VerifyResult { VERIFY_OK, - RECOVER_OK, - RECOVER_FAIL }; - VerifyResult Verify(const std::string& strFile, bool (*recoverFunc)(const std::string& strFile)); + RECOVER_OK, + RECOVER_FAIL }; + typedef bool (*recoverFunc_type)(const std::string& strFile, std::string& out_backup_filename); + VerifyResult Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename); + /** * Salvage data from a file that Verify says is bad. * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation). @@ -159,7 +161,7 @@ class CDB void Flush(); void Close(); - static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)); + static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename); /* flush the wallet passively (TRY_LOCK) ideal to be called periodically */ @@ -167,7 +169,7 @@ class CDB /* verifies the database environment */ static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr); /* verifies the database file */ - static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, bool (*recoverFunc)(const std::string& strFile)); + static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc); private: CDB(const CDB&); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6eed62cbc96e..8ddf6f75adce 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2097,12 +2097,13 @@ bool CWallet::Verify() if (gArgs.GetBoolArg("-salvagewallet", false)) { // Recover readable keypairs: CWallet dummyWallet; + std::string backup_filename; // Even if we don't use this lock in this function, we want to preserve // lock order in LoadToWallet if query of chain state is needed to know // tx status. If lock can't be taken, tx confirmation status may be not // reliable. LOCK(cs_main); - if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter)) + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) return false; } diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 8b9d04487f70..0b9d38297c9e 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1063,16 +1063,16 @@ bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const f // // Try to (very carefully!) recover wallet file if there is a problem. // -bool CWalletDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)) +bool CWalletDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename) { - return CDB::Recover(filename, callbackDataIn, recoverKVcallback); + return CDB::Recover(filename, callbackDataIn, recoverKVcallback, out_backup_filename); } -bool CWalletDB::Recover(const std::string& filename) +bool CWalletDB::Recover(const std::string& filename, std::string& out_backup_filename) { // recover without a key filter callback // results in recovering all record types - return CWalletDB::Recover(filename, NULL, NULL); + return CWalletDB::Recover(filename, NULL, NULL, out_backup_filename); } bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index ea9fca79a35b..28ac7efdb1b0 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -207,9 +207,9 @@ class CWalletDB DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); /* Try to (very carefully!) recover wallet database (with a possible key type filter) */ - static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)); - /* Recover convenience-function to bypass the key filter callback, called when verify failes, recoveres everything */ - static bool Recover(const std::string& filename); + static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename); + /* Recover convenience-function to bypass the key filter callback, called when verify fails, recovers everything */ + static bool Recover(const std::string& filename, std::string& out_backup_filename); /* Recover filter (used as callback), will only let keys (cryptographical keys) as KV/key-type pass through */ static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue); /* Function to determin if a certain KV/key-type is a key (cryptographical key) type */ From 60f9b4bc468ada8b3fa3400277fa8efcfc077bbf Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 5 Jun 2017 22:02:32 +0000 Subject: [PATCH 22/27] wallet: Base backup filenames on original wallet filename --- src/wallet/db.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index b6eb52eaf226..b6cf8dfc8cdf 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -166,14 +166,14 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename) { // Recovery procedure: - // move wallet file to wallet.timestamp.bak + // move wallet file to walletfilename.timestamp.bak // Call Salvage with fAggressive=true to // get as much data as possible. // Rewrite salvaged data to fresh wallet file // Set -rescan so any missing transactions will be // found. int64_t now = GetTime(); - newFilename = strprintf("wallet.%d.bak", now); + newFilename = strprintf("%s.%d.bak", filename, now); int result = bitdb.dbenv->dbrename(NULL, filename.c_str(), NULL, newFilename.c_str(), DB_AUTO_COMMIT); From b6dbbf3a5ce237321ccbbb6b0b836bd70dca913d Mon Sep 17 00:00:00 2001 From: random-zebra Date: Fri, 23 Apr 2021 17:30:58 +0200 Subject: [PATCH 23/27] wallet: Forbid -salvagewallet, -zapwallettxes, and -upgradewallet with multiple wallets >>> backports bitcoin@9cbe8c80bad1b55557a91db65a06b66ec4743f18 --- src/init.cpp | 18 ------------------ src/wallet/wallet.cpp | 32 +++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index f427a3856a9a..6c748bd99973 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -936,24 +936,6 @@ void InitParameterInteraction() if (gArgs.SoftSetBoolArg("-discover", false)) LogPrintf("%s : parameter interaction: -externalip set -> setting -discover=0\n", __func__); } - - if (gArgs.GetBoolArg("-salvagewallet", false)) { - // Rewrite just private keys: rescan to find transactions - if (gArgs.SoftSetBoolArg("-rescan", true)) - LogPrintf("%s : parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); - } - - int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0); - // -zapwallettxes implies dropping the mempool on startup - if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) { - LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes); - } - - // -zapwallettxes implies a rescan - if (zapwallettxes != 0) { - if (gArgs.SoftSetBoolArg("-rescan", true)) - LogPrintf("%s : parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes); - } } bool InitNUParams() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8ddf6f75adce..2d562c1881a2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -654,6 +654,37 @@ bool CWallet::ParameterInteraction() return UIError("-sysperms is not allowed in combination with enabled wallet functionality"); } + gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); + const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; + + if (gArgs.GetBoolArg("-salvagewallet", false) && gArgs.SoftSetBoolArg("-rescan", true)) { + if (is_multiwallet) { + return UIError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet")); + } + // Rewrite just private keys: rescan to find transactions + LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); + } + + int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0); + // -zapwallettxes implies dropping the mempool on startup + if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) { + LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes); + } + + // -zapwallettxes implies a rescan + if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-rescan", true)) { + if (is_multiwallet) { + return UIError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes")); + } + LogPrintf("%s: parameter interaction: -zapwallettxes= -> setting -rescan=1\n", __func__); + } + + if (is_multiwallet) { + if (gArgs.GetBoolArg("-upgradewallet", false)) { + return UIError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet")); + } + } + if (gArgs.IsArgSet("-mintxfee")) { CAmount n = 0; if (ParseMoney(gArgs.GetArg("-mintxfee", ""), n) && n > 0) @@ -2080,7 +2111,6 @@ bool CWallet::Verify() return true; } - gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); uiInterface.InitMessage(_("Verifying wallet(s)...")); for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { From 36796f2a0ceff04b3f0561eb5d83f62d9f19032e Mon Sep 17 00:00:00 2001 From: random-zebra Date: Fri, 23 Apr 2021 17:48:20 +0200 Subject: [PATCH 24/27] [Cleanup] Fix formatting in wallet and walletdb --- src/wallet/wallet.cpp | 24 +++++++---- src/wallet/walletdb.cpp | 91 +++++++++++++++++++++++------------------ src/wallet/walletdb.h | 10 ++--- 3 files changed, 72 insertions(+), 53 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2d562c1881a2..1338e677e8fd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2121,8 +2121,9 @@ bool CWallet::Verify() } std::string strError; - if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) + if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) { return UIError(strError); + } if (gArgs.GetBoolArg("-salvagewallet", false)) { // Recover readable keypairs: @@ -2133,14 +2134,16 @@ bool CWallet::Verify() // tx status. If lock can't be taken, tx confirmation status may be not // reliable. LOCK(cs_main); - if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) { return false; + } } std::string strWarning; bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); - if (!strWarning.empty()) + if (!strWarning.empty()) { UIWarning(strWarning); + } if (!dbV) { return UIError(strError); } @@ -2153,16 +2156,19 @@ void CWallet::ResendWalletTransactions(CConnman* connman) { // Do this infrequently and randomly to avoid giving away // that these are our transactions. - if (GetTime() < nNextResend) + if (GetTime() < nNextResend) { return; + } bool fFirst = (nNextResend == 0); nNextResend = GetTime() + GetRand(30 * 60); - if (fFirst) + if (fFirst) { return; + } // Only do it if there's been a new block since last time - if (nTimeBestReceived < nLastResend) + if (nTimeBestReceived < nLastResend) { return; + } nLastResend = GetTime(); // Rebroadcast any of our txes that aren't in a block yet @@ -2175,8 +2181,9 @@ void CWallet::ResendWalletTransactions(CConnman* connman) CWalletTx& wtx = item.second; // Don't rebroadcast until it's had plenty of time that // it should have gotten in already by now. - if (nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60) + if (nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60) { mapSorted.emplace(wtx.nTimeReceived, &wtx); + } } for (std::pair & item : mapSorted) { CWalletTx& wtx = *item.second; @@ -4256,8 +4263,9 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); nMaxVersion = FEATURE_LATEST; walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately - } else + } else { LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); + } if (nMaxVersion < walletInstance->GetVersion()) { UIError("Cannot downgrade wallet\n"); return nullptr; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 0b9d38297c9e..c164b5b81fb8 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2021 The Bitcoin developers // Copyright (c) 2014-2015 The Dash developers -// Copyright (c) 2015-2020 The PIVX developers +// Copyright (c) 2015-2021 The PIVX developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -100,8 +100,9 @@ bool CWalletDB::EraseTx(uint256 hash) bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta) { - if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta, false)) + if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta, false)) { return false; + } // hash pubkey/privkey to accelerate wallet load std::vector vchKey; @@ -113,16 +114,18 @@ bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, c } bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, - const std::vector& vchCryptedSecret, - const CKeyMetadata& keyMeta) + const std::vector& vchCryptedSecret, + const CKeyMetadata& keyMeta) { const bool fEraseUnencryptedKey = true; - if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta)) + if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta)) { return false; + } - if (!WriteIC(std::make_pair(std::string(DBKeys::CRYPTED_KEY), vchPubKey), vchCryptedSecret, false)) + if (!WriteIC(std::make_pair(std::string(DBKeys::CRYPTED_KEY), vchPubKey), vchCryptedSecret, false)) { return false; + } if (fEraseUnencryptedKey) { EraseIC(std::make_pair(std::string(DBKeys::KEY), vchPubKey)); } @@ -134,32 +137,34 @@ bool CWalletDB::WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta) { - if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) + if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) { return false; + } return WriteIC(std::make_pair(std::string(DBKeys::SAP_KEY), ivk), key, false); } -bool CWalletDB::WriteSaplingPaymentAddress( - const libzcash::SaplingPaymentAddress &addr, - const libzcash::SaplingIncomingViewingKey &ivk) +bool CWalletDB::WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, + const libzcash::SaplingIncomingViewingKey &ivk) { return WriteIC(std::make_pair(std::string(DBKeys::SAP_ADDR), addr), ivk, false); } -bool CWalletDB::WriteCryptedSaplingZKey( - const libzcash::SaplingExtendedFullViewingKey &extfvk, - const std::vector& vchCryptedSecret, - const CKeyMetadata &keyMeta) +bool CWalletDB::WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, + const std::vector& vchCryptedSecret, + const CKeyMetadata &keyMeta) { const bool fEraseUnencryptedKey = true; auto ivk = extfvk.fvk.in_viewing_key(); - if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) + if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) { return false; + } - if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEY_CRIPTED), ivk), std::make_pair(extfvk, vchCryptedSecret), false)) + if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEY_CRIPTED), ivk), + std::make_pair(extfvk, vchCryptedSecret), false)) { return false; + } if (fEraseUnencryptedKey) { EraseIC(std::make_pair(std::string(DBKeys::SAP_KEY), ivk)); @@ -210,7 +215,9 @@ bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) bool CWalletDB::ReadBestBlock(CBlockLocator& locator) { - if (batch.Read(std::string(DBKeys::BESTBLOCK), locator) && !locator.vHave.empty()) return true; + if (batch.Read(std::string(DBKeys::BESTBLOCK), locator) && !locator.vHave.empty()) { + return true; + } return batch.Read(std::string(DBKeys::BESTBLOCK_NOMERKLE), locator); } @@ -279,7 +286,7 @@ DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) typedef std::multimap TxItems; TxItems txByTime; - for (std::map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { + for (auto it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { CWalletTx* wtx = &((*it).second); txByTime.insert(std::make_pair(wtx->nTimeReceived, wtx)); } @@ -295,8 +302,8 @@ DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) nOrderPos = nOrderPosNext++; nOrderPosOffsets.push_back(nOrderPos); - if (!WriteTx(*pwtx)) - return DB_LOAD_FAIL; + if (!WriteTx(*pwtx)) return DB_LOAD_FAIL; + } else { int64_t nOrderPosOff = 0; for (const int64_t& nOffsetStart : nOrderPosOffsets) { @@ -306,12 +313,10 @@ DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) nOrderPos += nOrderPosOff; nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); - if (!nOrderPosOff) - continue; + if (!nOrderPosOff) continue; // Since we're changing the order, write it back - if (!WriteTx(*pwtx)) - return DB_LOAD_FAIL; + if (!WriteTx(*pwtx)) return DB_LOAD_FAIL; } } WriteOrderPosNext(nOrderPosNext); @@ -626,8 +631,9 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) try { int nMinVersion = 0; if (batch.Read((std::string) DBKeys::MINVERSION, nMinVersion)) { - if (nMinVersion > CLIENT_VERSION) + if (nMinVersion > CLIENT_VERSION) { return DB_TOO_NEW; + } pwallet->LoadMinVersion(nMinVersion); } @@ -643,9 +649,9 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue); - if (ret == DB_NOTFOUND) + if (ret == DB_NOTFOUND) { break; - else if (ret != 0) { + } else if (ret != 0) { LogPrintf("Error reading next record from wallet database\n"); return DB_CORRUPT; } @@ -655,9 +661,9 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr)) { // losing keys is considered a catastrophic error, anything else // we assume the user can live with: - if (IsKeyType(strType) || strType == DBKeys::DEFAULTKEY) + if (IsKeyType(strType) || strType == DBKeys::DEFAULTKEY) { result = DB_CORRUPT; - else { + } else { // Leave other errors alone, if we try to fix them we might make things worse. fNoncriticalErrors = true; // ... but do warn the user there is something wrong. if (strType == DBKeys::TX) @@ -695,18 +701,22 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) if ((wss.nKeys + wss.nCKeys) != wss.nKeyMeta) pwallet->nTimeFirstKey = 1; // 0 would be considered 'no value' - for (const uint256& hash : wss.vWalletUpgrade) + for (const uint256& hash : wss.vWalletUpgrade) { WriteTx(pwallet->mapWallet.at(hash)); + } // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: - if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000)) + if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000)) { return DB_NEED_REWRITE; + } - if (wss.nFileVersion < CLIENT_VERSION) // Update + if (wss.nFileVersion < CLIENT_VERSION) { // Update WriteVersion(CLIENT_VERSION); + } - if (wss.fAnyUnordered) + if (wss.fAnyUnordered) { result = ReorderTransactions(pwallet); + } return result; } @@ -720,8 +730,9 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, std::vector& vTxHash LOCK(pwallet->cs_wallet); int nMinVersion = 0; if (batch.Read((std::string) DBKeys::MINVERSION, nMinVersion)) { - if (nMinVersion > CLIENT_VERSION) + if (nMinVersion > CLIENT_VERSION) { return DB_TOO_NEW; + } pwallet->LoadMinVersion(nMinVersion); } @@ -737,9 +748,9 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, std::vector& vTxHash CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue); - if (ret == DB_NOTFOUND) + if (ret == DB_NOTFOUND) { break; - else if (ret != 0) { + } else if (ret != 0) { LogPrintf("Error reading next record from wallet database\n"); return DB_CORRUPT; } @@ -775,13 +786,13 @@ DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, std::vector& vWtx) // build list of wallet TXs std::vector vTxHash; DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); - if (err != DB_LOAD_OK) + if (err != DB_LOAD_OK) { return err; + } // erase each wallet TX for (uint256& hash : vTxHash) { - if (!EraseTx(hash)) - return DB_CORRUPT; + if (!EraseTx(hash)) return DB_CORRUPT; } return DB_LOAD_OK; diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 28ac7efdb1b0..281bba204508 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,11 +1,11 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Copyright (c) 2016-2020 The PIVX developers +// Copyright (c) 2009-2021 The Bitcoin developers +// Copyright (c) 2016-2021 The PIVX developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_WALLETDB_H -#define BITCOIN_WALLETDB_H +#ifndef PIVX_WALLETDB_H +#define PIVX_WALLETDB_H #include "amount.h" #include "wallet/db.h" @@ -247,4 +247,4 @@ bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWa //! Compacts BDB state so that wallet.dat is self-contained (if there are changes) void MaybeCompactWalletDB(); -#endif // BITCOIN_WALLETDB_H +#endif // PIVX_WALLETDB_H From dc596f33e9295cff44c1e3a36e295eb0a40fc3e4 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Fri, 23 Apr 2021 21:31:53 +0200 Subject: [PATCH 25/27] [Doc] Add multiwallet section to release notes --- doc/release-notes.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 026cb3cd37a8..bac5fd8589db 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -49,7 +49,7 @@ Cold-Staking Re-Activation PIVX Core v6.0.0 includes a fix for the vulnerability identified within the cold-staking protocol (see PR [#2258](https://github.com/PIVX-Project/PIVX/pull/2258)). Therefore the feature will be re-enabled on the network, via `SPORK_19`, shortly after the upgrade enforcement. -#### Protocol changes +### Protocol changes A new opcode (`0xd2`) is introduced (see PR [#2275](https://github.com/PIVX-Project/PIVX/pull/2275)). It enforces the same rules as the legacy cold-staking opcode, but without allowing a "free" script for the last output of the transaction. This is in accord with the consensus change introduced with the "Deterministic Masternodes" update, as masternode/budget payments are now outputs of the *coinbase* transaction (rather than the *coinstake*), therefore a "free" output for the coinstake is no longer needed. @@ -57,6 +57,18 @@ The new opcode takes the name of `OP_CHECKCOLDSTAKEVERIFY`, and the legacy opcod Scripts with the old opcode are still accepted on the network (the restriction on the last-output is enforced after the script validation in this case), but the client creates new delegations with the new opcode, by default, after the upgrade enforcement. +Multi-wallet support +-------------------- + +PIVX Core now supports loading multiple, separate wallets (See [PR 2337](https://github.com/PIVX-Project/PIVX/pull/2337)). The wallets are completely separated, with individual balances, keys and received transactions. + +Multi-wallet is enabled by using more than one `-wallet` argument when starting PIVX client, either on the command line or in the pivx.conf config file. + +**In pivx-qt, only the first wallet will be displayed and accessible for creating and signing transactions.** GUI selectable multiple wallets will be supported in a future version. However, even in 6.0 other loaded wallets will remain synchronized to the node's current tip in the background. + +!TODO: update after endpoint support and multi-wallet RPC support + + GUI changes ----------- @@ -101,6 +113,7 @@ Low-level RPC changes - `maximumCount` - a number specifying the minimum number of UTXOs - `minimumSumAmount` - a number specifying the minimum sum value of all UTXOs + #### Show wallet's auto-combine settings in getwalletinfo `getwalletinfo` now has two additional return fields. `autocombine_enabled` (boolean) and `autocombine_threshold` (numeric) that will show the auto-combine threshold and whether or not it is currently enabled. From ff4cee0ecbcdbe4923ac1631804833556617be90 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Wed, 5 May 2021 00:53:39 +0200 Subject: [PATCH 26/27] [Trivial] Add wallet filename to backup errors/warning --- src/wallet/wallet.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1338e677e8fd..71a509eb0be7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4395,8 +4395,12 @@ bool CWallet::InitLoadWallet() // automatic backups std::string strWarning, strError; if(!AutoBackupWallet(walletFile, strWarning, strError)) { - if (!strWarning.empty()) UIWarning(strWarning); - if (!strError.empty()) return UIError(strError); + if (!strWarning.empty()) { + UIWarning(strprintf("%s: %s", walletFile, strWarning)); + } + if (!strError.empty()) { + return UIError(strprintf("%s: %s", walletFile, strError)); + } } CWallet * const pwallet = CreateWalletFromFile(walletFile); From 4734a8465ec5e83b52998452a66774cee1b2e6e8 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Mon, 17 May 2021 14:53:59 +0200 Subject: [PATCH 27/27] [Cleanup][Tests] Fix chainparams-change in librust tests --- src/test/librust/sapling_test_fixture.cpp | 5 + src/test/librust/sapling_test_fixture.h | 8 ++ src/test/librust/sapling_wallet_tests.cpp | 109 ++++++++---------- .../librust/transaction_builder_tests.cpp | 46 ++------ src/test/librust/utiltest.cpp | 10 -- src/test/librust/utiltest.h | 3 - .../test/wallet_shielded_balances_tests.cpp | 12 +- 7 files changed, 72 insertions(+), 121 deletions(-) diff --git a/src/test/librust/sapling_test_fixture.cpp b/src/test/librust/sapling_test_fixture.cpp index 740c70341fee..ea03ff84c863 100644 --- a/src/test/librust/sapling_test_fixture.cpp +++ b/src/test/librust/sapling_test_fixture.cpp @@ -13,3 +13,8 @@ SaplingTestingSetup::SaplingTestingSetup(const std::string& chainName) : Testing SaplingTestingSetup::~SaplingTestingSetup() { } + +SaplingRegTestingSetup::SaplingRegTestingSetup() : SaplingTestingSetup(CBaseChainParams::REGTEST) +{ + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V5_0, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); +} diff --git a/src/test/librust/sapling_test_fixture.h b/src/test/librust/sapling_test_fixture.h index 59ae6927b46d..962d479ce279 100644 --- a/src/test/librust/sapling_test_fixture.h +++ b/src/test/librust/sapling_test_fixture.h @@ -16,5 +16,13 @@ struct SaplingTestingSetup : public TestingSetup ~SaplingTestingSetup(); }; +/** + * Regtest setup with sapling always active + */ +struct SaplingRegTestingSetup : public SaplingTestingSetup +{ + SaplingRegTestingSetup(); +}; + #endif //PIVX_SAPLING_TEST_FIXTURE_H diff --git a/src/test/librust/sapling_wallet_tests.cpp b/src/test/librust/sapling_wallet_tests.cpp index 4fac832cbbdc..36c8681a94bf 100644 --- a/src/test/librust/sapling_wallet_tests.cpp +++ b/src/test/librust/sapling_wallet_tests.cpp @@ -70,10 +70,10 @@ uint256 GetWitnessesAndAnchors(CWallet& wallet, return saplingAnchor; } -BOOST_FIXTURE_TEST_SUITE(sapling_wallet_tests, WalletTestingSetup) +BOOST_FIXTURE_TEST_SUITE(sapling_wallet_tests, WalletRegTestingSetup) BOOST_AUTO_TEST_CASE(SetSaplingNoteAddrsInCWalletTx) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; LOCK(wallet.cs_wallet); @@ -124,9 +124,6 @@ BOOST_AUTO_TEST_CASE(SetSaplingNoteAddrsInCWalletTx) { BOOST_CHECK(nullifier == wtx.mapSaplingNoteData[op].nullifier); BOOST_CHECK(nd.witnessHeight == wtx.mapSaplingNoteData[op].witnessHeight); BOOST_CHECK(witness == wtx.mapSaplingNoteData[op].witnesses.front()); - - // Revert to default - RegtestDeactivateSapling(); } // Cannot add note data for an index which does not exist in tx.vShieldedOutput @@ -142,8 +139,9 @@ BOOST_AUTO_TEST_CASE(SetInvalidSaplingNoteDataInCWalletTx) { BOOST_CHECK_THROW(wtx.SetSaplingNoteData(noteData), std::logic_error); } -BOOST_AUTO_TEST_CASE(FindMySaplingNotes) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(FindMySaplingNotes) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; LOCK(wallet.cs_wallet); @@ -175,14 +173,12 @@ BOOST_AUTO_TEST_CASE(FindMySaplingNotes) { BOOST_CHECK(wallet.HaveSaplingSpendingKey(extfvk)); noteMap = wallet.GetSaplingScriptPubKeyMan()->FindMySaplingNotes(*wtx.tx).first; BOOST_CHECK_EQUAL(2, noteMap.size()); - - // Revert to default - RegtestDeactivateSapling(); } // Generate note A and spend to create note B, from which we spend to create two conflicting transactions -BOOST_AUTO_TEST_CASE(GetConflictedSaplingNotes) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(GetConflictedSaplingNotes) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; LOCK2(cs_main, wallet.cs_wallet); @@ -296,15 +292,13 @@ BOOST_AUTO_TEST_CASE(GetConflictedSaplingNotes) { BOOST_CHECK(std::set({hash2, hash3}) == c3); // Tear down - chainActive.SetTip(NULL); + chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); - - // Revert to default - RegtestDeactivateSapling(); } -BOOST_AUTO_TEST_CASE(SaplingNullifierIsSpent) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(SaplingNullifierIsSpent) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; LOCK2(cs_main, wallet.cs_wallet); @@ -357,15 +351,13 @@ BOOST_AUTO_TEST_CASE(SaplingNullifierIsSpent) { BOOST_CHECK(wallet.GetSaplingScriptPubKeyMan()->IsSaplingSpent(nullifier)); // Tear down - chainActive.SetTip(NULL); + chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); - - // Revert to default - RegtestDeactivateSapling(); } -BOOST_AUTO_TEST_CASE(NavigateFromSaplingNullifierToNote) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(NavigateFromSaplingNullifierToNote) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; LOCK2(cs_main, wallet.cs_wallet); @@ -454,16 +446,14 @@ BOOST_AUTO_TEST_CASE(NavigateFromSaplingNullifierToNote) { } // Tear down - chainActive.SetTip(NULL); + chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); - - // Revert to default - RegtestDeactivateSapling(); } // Create note A, spend A to create note B, spend and verify note B is from me. -BOOST_AUTO_TEST_CASE(SpentSaplingNoteIsFromMe) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(SpentSaplingNoteIsFromMe) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; LOCK2(cs_main, wallet.cs_wallet); @@ -601,16 +591,14 @@ BOOST_AUTO_TEST_CASE(SpentSaplingNoteIsFromMe) { BOOST_CHECK(wallet.GetSaplingScriptPubKeyMan()->mapSaplingNullifiersToNotes.count(nullifier2)); // Tear down - chainActive.SetTip(NULL); + chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); mapBlockIndex.erase(blockHash2); - - // Revert to default - RegtestDeactivateSapling(); } -BOOST_AUTO_TEST_CASE(CachedWitnessesEmptyChain) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(CachedWitnessesEmptyChain) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; { @@ -646,13 +634,11 @@ BOOST_AUTO_TEST_CASE(CachedWitnessesEmptyChain) { // Until zcash#1302 is implemented, this should triggger an assertion BOOST_CHECK_THROW(wallet.DecrementNoteWitnesses(&index), std::runtime_error); - - // Revert to default - RegtestDeactivateSapling(); } -BOOST_AUTO_TEST_CASE(CachedWitnessesChainTip) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(CachedWitnessesChainTip) +{ + auto consensusParams = Params().GetConsensus(); libzcash::SaplingExtendedSpendingKey sk = GetTestMasterSaplingSpendingKey(); CWallet& wallet = *pwalletMain; @@ -730,9 +716,9 @@ BOOST_AUTO_TEST_CASE(CachedWitnessesChainTip) { } } -BOOST_AUTO_TEST_CASE(CachedWitnessesDecrementFirst) { - auto consensusParams = RegtestActivateSapling(); - +BOOST_AUTO_TEST_CASE(CachedWitnessesDecrementFirst) +{ + auto consensusParams = Params().GetConsensus(); libzcash::SaplingExtendedSpendingKey sk = GetTestMasterSaplingSpendingKey(); CWallet& wallet = *pwalletMain; { @@ -798,8 +784,9 @@ BOOST_AUTO_TEST_CASE(CachedWitnessesDecrementFirst) { } } -BOOST_AUTO_TEST_CASE(CachedWitnessesCleanIndex) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(CachedWitnessesCleanIndex) +{ + auto consensusParams = Params().GetConsensus(); libzcash::SaplingExtendedSpendingKey sk = GetTestMasterSaplingSpendingKey(); CWallet& wallet = *pwalletMain; @@ -874,8 +861,9 @@ BOOST_AUTO_TEST_CASE(CachedWitnessesCleanIndex) { } } -BOOST_AUTO_TEST_CASE(ClearNoteWitnessCache) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(ClearNoteWitnessCache) +{ + auto consensusParams = Params().GetConsensus(); libzcash::SaplingExtendedSpendingKey sk = GetTestMasterSaplingSpendingKey(); CWallet& wallet = *pwalletMain; @@ -922,8 +910,9 @@ BOOST_AUTO_TEST_CASE(ClearNoteWitnessCache) { BOOST_CHECK_EQUAL(0, wallet.GetSaplingScriptPubKeyMan()->nWitnessCacheSize); } -BOOST_AUTO_TEST_CASE(UpdatedSaplingNoteData) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(UpdatedSaplingNoteData) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; // Need to lock cs_main for now due the lock ordering. future: revamp all of this function to only lock where is needed. @@ -1028,15 +1017,13 @@ BOOST_AUTO_TEST_CASE(UpdatedSaplingNoteData) { BOOST_CHECK(wtx.mapSaplingNoteData[sop1].witnesses.front() == testNote.tree.witness()); // Tear down - chainActive.SetTip(NULL); + chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); - - // Revert to default - RegtestDeactivateSapling(); } -BOOST_AUTO_TEST_CASE(MarkAffectedSaplingTransactionsDirty) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(MarkAffectedSaplingTransactionsDirty) +{ + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; LOCK2(cs_main, wallet.cs_wallet); @@ -1140,16 +1127,13 @@ BOOST_AUTO_TEST_CASE(MarkAffectedSaplingTransactionsDirty) { BOOST_CHECK(!wallet.mapWallet.at(hash).IsAmountCached(CWalletTx::AmountType::DEBIT, ISMINE_SPENDABLE)); // Tear down - chainActive.SetTip(NULL); + chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); - - // Revert to default - RegtestDeactivateSapling(); } BOOST_AUTO_TEST_CASE(GetNotes) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); CWallet& wallet = *pwalletMain; libzcash::SaplingPaymentAddress pk; @@ -1238,9 +1222,6 @@ BOOST_AUTO_TEST_CASE(GetNotes) LOCK(cs_main); chainActive.SetTip(nullptr); mapBlockIndex.erase(blockHash); - - // Revert to default - RegtestDeactivateSapling(); } // TODO: Back port WriteWitnessCache & SetBestChainIgnoresTxsWithoutShieldedData test cases. diff --git a/src/test/librust/transaction_builder_tests.cpp b/src/test/librust/transaction_builder_tests.cpp index 17aed96c8058..55c5180c6066 100644 --- a/src/test/librust/transaction_builder_tests.cpp +++ b/src/test/librust/transaction_builder_tests.cpp @@ -13,11 +13,11 @@ #include #include -BOOST_FIXTURE_TEST_SUITE(sapling_transaction_builder_tests, SaplingTestingSetup) +BOOST_FIXTURE_TEST_SUITE(sapling_transaction_builder_tests, SaplingRegTestingSetup) BOOST_AUTO_TEST_CASE(TransparentToSapling) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); CBasicKeyStore keystore; CKey tsk = AddTestCKeyToKeyStore(keystore); @@ -49,13 +49,11 @@ BOOST_AUTO_TEST_CASE(TransparentToSapling) CValidationState state; BOOST_CHECK(SaplingValidation::ContextualCheckTransaction(tx, state, Params(), 2, true, false)); BOOST_CHECK_EQUAL(state.GetRejectReason(), ""); - - // Revert to default - RegtestDeactivateSapling(); } -BOOST_AUTO_TEST_CASE(SaplingToSapling) { - auto consensusParams = RegtestActivateSapling(); +BOOST_AUTO_TEST_CASE(SaplingToSapling) +{ + auto consensusParams = Params().GetConsensus(); auto sk = libzcash::SaplingSpendingKey::random(); auto expsk = sk.expanded_spending_key(); @@ -101,45 +99,33 @@ BOOST_AUTO_TEST_CASE(SaplingToSapling) { BOOST_CHECK_EQUAL(tx2.sapData->valueBalance, 10000000); BOOST_CHECK(SaplingValidation::ContextualCheckTransaction(tx2, state, Params(), 3, true, false)); BOOST_CHECK_EQUAL(state.GetRejectReason(), ""); - - // Revert to default - RegtestDeactivateSapling(); } BOOST_AUTO_TEST_CASE(ThrowsOnTransparentInputWithoutKeyStore) { - SelectParams(CBaseChainParams::REGTEST); - auto consensusParams = Params().GetConsensus(); - - auto builder = TransactionBuilder(consensusParams, 1); + auto builder = TransactionBuilder(Params().GetConsensus(), 1); BOOST_CHECK_THROW(builder.AddTransparentInput(COutPoint(), CScript(), 1), std::runtime_error); } BOOST_AUTO_TEST_CASE(RejectsInvalidTransparentOutput) { - SelectParams(CBaseChainParams::REGTEST); - auto consensusParams = Params().GetConsensus(); - // Default CTxDestination type is an invalid address CTxDestination taddr; - auto builder = TransactionBuilder(consensusParams, 1); + auto builder = TransactionBuilder(Params().GetConsensus(), 1); BOOST_CHECK_THROW(builder.AddTransparentOutput(taddr, 50), std::runtime_error); } BOOST_AUTO_TEST_CASE(RejectsInvalidTransparentChangeAddress) { - SelectParams(CBaseChainParams::REGTEST); - auto consensusParams = Params().GetConsensus(); - // Default CTxDestination type is an invalid address CTxDestination taddr; - auto builder = TransactionBuilder(consensusParams, 1); + auto builder = TransactionBuilder(Params().GetConsensus(), 1); BOOST_CHECK_THROW(builder.SendChangeTo(taddr), std::runtime_error); } BOOST_AUTO_TEST_CASE(FailsWithNegativeChange) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); // Generate dummy Sapling address auto sk = libzcash::SaplingSpendingKey::random(); @@ -179,14 +165,11 @@ BOOST_AUTO_TEST_CASE(FailsWithNegativeChange) // Succeeds if there is sufficient input builder.AddTransparentInput(COutPoint(), scriptPubKey, 10000); BOOST_CHECK(builder.Build().IsTx()); - - // Revert to default - RegtestDeactivateSapling(); } BOOST_AUTO_TEST_CASE(ChangeOutput) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); // Generate dummy Sapling address auto sk = libzcash::SaplingSpendingKey::random(); @@ -260,14 +243,11 @@ BOOST_AUTO_TEST_CASE(ChangeOutput) BOOST_CHECK_EQUAL(tx.sapData->valueBalance, 0); BOOST_CHECK_EQUAL(tx.vout[0].nValue, 15000000); } - - // Revert to default - RegtestDeactivateSapling(); } BOOST_AUTO_TEST_CASE(SetFee) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); // Generate dummy Sapling address auto sk = libzcash::SaplingSpendingKey::random(); @@ -292,14 +272,10 @@ BOOST_AUTO_TEST_CASE(SetFee) BOOST_CHECK_EQUAL(tx.sapData->vShieldedOutput.size(), 2); BOOST_CHECK_EQUAL(tx.sapData->valueBalance, COIN); } - - // Revert to default - RegtestDeactivateSapling(); } BOOST_AUTO_TEST_CASE(CheckSaplingTxVersion) { - SelectParams(CBaseChainParams::REGTEST); auto consensusParams = Params().GetConsensus(); auto sk = libzcash::SaplingSpendingKey::random(); diff --git a/src/test/librust/utiltest.cpp b/src/test/librust/utiltest.cpp index caf2511daf1b..5864fea63bcb 100644 --- a/src/test/librust/utiltest.cpp +++ b/src/test/librust/utiltest.cpp @@ -13,16 +13,6 @@ static const std::string T_SECRET_REGTEST = "cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN"; -const Consensus::Params& RegtestActivateSapling() { - SelectParams(CBaseChainParams::REGTEST); - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V5_0, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); - return Params().GetConsensus(); -} - -void RegtestDeactivateSapling() { - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V5_0, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); -} - libzcash::SaplingExtendedSpendingKey GetTestMasterSaplingSpendingKey() { std::vector> rawSeed(32); HDSeed seed(rawSeed); diff --git a/src/test/librust/utiltest.h b/src/test/librust/utiltest.h index 4f6e8412015f..f58f806275d5 100644 --- a/src/test/librust/utiltest.h +++ b/src/test/librust/utiltest.h @@ -28,9 +28,6 @@ struct TransparentInput { CAmount amount; }; -const Consensus::Params& RegtestActivateSapling(); - -void RegtestDeactivateSapling(); libzcash::SaplingExtendedSpendingKey GetTestMasterSaplingSpendingKey(); diff --git a/src/wallet/test/wallet_shielded_balances_tests.cpp b/src/wallet/test/wallet_shielded_balances_tests.cpp index 8ab4fe8c2306..237663b3ced9 100644 --- a/src/wallet/test/wallet_shielded_balances_tests.cpp +++ b/src/wallet/test/wallet_shielded_balances_tests.cpp @@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(GetShieldedSimpleCachedCreditAndDebit) //////// Credit //////// /////////////////////// - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); // Main wallet CWallet &wallet = *pwalletMain; @@ -191,9 +191,6 @@ BOOST_AUTO_TEST_CASE(GetShieldedSimpleCachedCreditAndDebit) // Checks that the only shielded output of this tx is change. BOOST_CHECK(wallet.GetSaplingScriptPubKeyMan()->IsNoteSaplingChange( SaplingOutPoint(wtxDebitUpdated.GetHash(), 0), pa)); - - // Revert to default - RegtestDeactivateSapling(); } libzcash::SaplingPaymentAddress getNewDummyShieldedAddress() @@ -237,7 +234,7 @@ CWalletTx& buildTxAndLoadToWallet(CWallet& wallet, const libzcash::SaplingExtend */ BOOST_AUTO_TEST_CASE(VerifyShieldedToRemoteShieldedCachedBalance) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); // Main wallet CWallet &wallet = *pwalletMain; @@ -280,9 +277,6 @@ BOOST_AUTO_TEST_CASE(VerifyShieldedToRemoteShieldedCachedBalance) // Plus, change should be same and be cached as well BOOST_CHECK_EQUAL(wtxDebitUpdated.GetShieldedChange(), expectedShieldedChange); BOOST_CHECK(wtxDebitUpdated.fShieldedChangeCached); - - // Revert to default - RegtestDeactivateSapling(); } struct FakeBlock @@ -320,7 +314,7 @@ FakeBlock SimpleFakeMine(CWalletTx& wtx, SaplingMerkleTree& currentTree, CWallet */ BOOST_AUTO_TEST_CASE(GetShieldedAvailableCredit) { - auto consensusParams = RegtestActivateSapling(); + auto consensusParams = Params().GetConsensus(); // Main wallet CWallet &wallet = *pwalletMain;