diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fs.cpp | 2 | ||||
-rw-r--r-- | src/init.cpp | 49 | ||||
-rw-r--r-- | src/interfaces/wallet.cpp | 255 | ||||
-rw-r--r-- | src/node/transaction.cpp | 40 | ||||
-rw-r--r-- | src/node/transaction.h | 20 | ||||
-rw-r--r-- | src/psbt.cpp | 10 | ||||
-rw-r--r-- | src/psbt.h | 7 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 2 | ||||
-rw-r--r-- | src/qt/walletcontroller.cpp | 1 | ||||
-rw-r--r-- | src/rpc/blockchain.cpp | 25 | ||||
-rw-r--r-- | src/rpc/client.cpp | 5 | ||||
-rw-r--r-- | src/rpc/misc.cpp | 34 | ||||
-rw-r--r-- | src/rpc/net.cpp | 16 | ||||
-rw-r--r-- | src/rpc/rawtransaction.cpp | 24 | ||||
-rw-r--r-- | src/rpc/util.cpp | 52 | ||||
-rw-r--r-- | src/rpc/util.h | 13 | ||||
-rw-r--r-- | src/util/system.cpp | 18 | ||||
-rw-r--r-- | src/util/system.h | 5 | ||||
-rw-r--r-- | src/validation.cpp | 6 | ||||
-rw-r--r-- | src/wallet/psbtwallet.cpp | 10 | ||||
-rw-r--r-- | src/wallet/psbtwallet.h | 8 | ||||
-rw-r--r-- | src/wallet/rpcdump.cpp | 18 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 66 | ||||
-rw-r--r-- | src/wallet/test/psbt_wallet_tests.cpp | 3 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 11 | ||||
-rw-r--r-- | src/wallet/wallet.h | 2 | ||||
-rw-r--r-- | src/wallet/walletutil.cpp | 2 |
27 files changed, 322 insertions, 382 deletions
diff --git a/src/fs.cpp b/src/fs.cpp index 3c8f4c0247..f937f64e04 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -160,6 +160,7 @@ static std::string openmodeToStr(std::ios_base::openmode mode) void ifstream::open(const fs::path& p, std::ios_base::openmode mode) { close(); + mode |= std::ios_base::in; m_file = fsbridge::fopen(p, openmodeToStr(mode).c_str()); if (m_file == nullptr) { return; @@ -183,6 +184,7 @@ void ifstream::close() void ofstream::open(const fs::path& p, std::ios_base::openmode mode) { close(); + mode |= std::ios_base::out; m_file = fsbridge::fopen(p, openmodeToStr(mode).c_str()); if (m_file == nullptr) { return; diff --git a/src/init.cpp b/src/init.cpp index f85a0da37e..e0da962030 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -53,6 +53,8 @@ #include <stdio.h> #ifndef WIN32 +#include <attributes.h> +#include <cerrno> #include <signal.h> #include <sys/stat.h> #endif @@ -92,6 +94,32 @@ std::unique_ptr<BanMan> g_banman; static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; +/** + * The PID file facilities. + */ +static const char* BITCOIN_PID_FILENAME = "bitcoind.pid"; + +static fs::path GetPidFile() +{ + return AbsPathForConfigVal(fs::path(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME))); +} + +NODISCARD static bool CreatePidFile() +{ + FILE* file = fsbridge::fopen(GetPidFile(), "w"); + if (file) { +#ifdef WIN32 + fprintf(file, "%d\n", GetCurrentProcessId()); +#else + fprintf(file, "%d\n", getpid()); +#endif + fclose(file); + return true; + } else { + return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile().string(), std::strerror(errno))); + } +} + ////////////////////////////////////////////////////////////////////////////// // // Shutdown @@ -260,13 +288,13 @@ void Shutdown(InitInterfaces& interfaces) } #endif -#ifndef WIN32 try { - fs::remove(GetPidFile()); + if (!fs::remove(GetPidFile())) { + LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__); + } } catch (const fs::filesystem_error& e) { - LogPrintf("%s: Unable to remove pidfile: %s\n", __func__, e.what()); + LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); } -#endif interfaces.chain_clients.clear(); UnregisterAllValidationInterfaces(); GetMainSignals().UnregisterBackgroundSignalScheduler(); @@ -352,7 +380,7 @@ void SetupServerArgs() gArgs.AddArg("-conf=<file>", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), false, OptionsCategory::OPTIONS); gArgs.AddArg("-datadir=<dir>", "Specify data directory", false, OptionsCategory::OPTIONS); gArgs.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), true, OptionsCategory::OPTIONS); - gArgs.AddArg("-dbcache=<n>", strprintf("Set database cache size in MiB (%d to %d, default: %d)", nMinDbCache, nMaxDbCache, nDefaultDbCache), false, OptionsCategory::OPTIONS); + gArgs.AddArg("-dbcache=<n>", strprintf("Maximum database cache size <n> MiB (%d to %d, default: %d). In addition, unused mempool memory is shared for this cache (see -maxmempool).", nMinDbCache, nMaxDbCache, nDefaultDbCache), false, OptionsCategory::OPTIONS); gArgs.AddArg("-debuglogfile=<file>", strprintf("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (-nodebuglogfile to disable; default: %s)", DEFAULT_DEBUGLOGFILE), false, OptionsCategory::OPTIONS); gArgs.AddArg("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER), true, OptionsCategory::OPTIONS); gArgs.AddArg("-includeconf=<file>", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", false, OptionsCategory::OPTIONS); @@ -364,11 +392,7 @@ void SetupServerArgs() gArgs.AddArg("-par=<n>", strprintf("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)", -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS), false, OptionsCategory::OPTIONS); gArgs.AddArg("-persistmempool", strprintf("Whether to save the mempool on shutdown and load on restart (default: %u)", DEFAULT_PERSIST_MEMPOOL), false, OptionsCategory::OPTIONS); -#ifndef WIN32 gArgs.AddArg("-pid=<file>", strprintf("Specify pid file. Relative paths will be prefixed by a net-specific datadir location. (default: %s)", BITCOIN_PID_FILENAME), false, OptionsCategory::OPTIONS); -#else - hidden_args.emplace_back("-pid"); -#endif gArgs.AddArg("-prune=<n>", strprintf("Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >=%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), false, OptionsCategory::OPTIONS); @@ -1200,9 +1224,10 @@ bool AppInitMain(InitInterfaces& interfaces) { const CChainParams& chainparams = Params(); // ********************************************************* Step 4a: application initialization -#ifndef WIN32 - CreatePidFile(GetPidFile(), getpid()); -#endif + if (!CreatePidFile()) { + // Detailed error printed inside CreatePidFile(). + return false; + } if (LogInstance().m_print_to_file) { if (gArgs.GetBoolArg("-shrinkdebugfile", LogInstance().DefaultShrinkDebugFile())) { // Do this first since it both loads a bunch of debug.log into memory, diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 5b5430037c..0dac75834e 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -135,55 +135,55 @@ WalletTxOut MakeWalletTxOut(interfaces::Chain::Lock& locked_chain, class WalletImpl : public Wallet { public: - explicit WalletImpl(const std::shared_ptr<CWallet>& wallet) : m_shared_wallet(wallet), m_wallet(*wallet.get()) {} + explicit WalletImpl(const std::shared_ptr<CWallet>& wallet) : m_wallet(wallet) {} bool encryptWallet(const SecureString& wallet_passphrase) override { - return m_wallet.EncryptWallet(wallet_passphrase); + return m_wallet->EncryptWallet(wallet_passphrase); } - bool isCrypted() override { return m_wallet.IsCrypted(); } - bool lock() override { return m_wallet.Lock(); } - bool unlock(const SecureString& wallet_passphrase) override { return m_wallet.Unlock(wallet_passphrase); } - bool isLocked() override { return m_wallet.IsLocked(); } + bool isCrypted() override { return m_wallet->IsCrypted(); } + bool lock() override { return m_wallet->Lock(); } + bool unlock(const SecureString& wallet_passphrase) override { return m_wallet->Unlock(wallet_passphrase); } + bool isLocked() override { return m_wallet->IsLocked(); } bool changeWalletPassphrase(const SecureString& old_wallet_passphrase, const SecureString& new_wallet_passphrase) override { - return m_wallet.ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase); + return m_wallet->ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase); } - void abortRescan() override { m_wallet.AbortRescan(); } - bool backupWallet(const std::string& filename) override { return m_wallet.BackupWallet(filename); } - std::string getWalletName() override { return m_wallet.GetName(); } + void abortRescan() override { m_wallet->AbortRescan(); } + bool backupWallet(const std::string& filename) override { return m_wallet->BackupWallet(filename); } + std::string getWalletName() override { return m_wallet->GetName(); } bool getKeyFromPool(bool internal, CPubKey& pub_key) override { - return m_wallet.GetKeyFromPool(pub_key, internal); + return m_wallet->GetKeyFromPool(pub_key, internal); } - bool getPubKey(const CKeyID& address, CPubKey& pub_key) override { return m_wallet.GetPubKey(address, pub_key); } - bool getPrivKey(const CKeyID& address, CKey& key) override { return m_wallet.GetKey(address, key); } - bool isSpendable(const CTxDestination& dest) override { return IsMine(m_wallet, dest) & ISMINE_SPENDABLE; } - bool haveWatchOnly() override { return m_wallet.HaveWatchOnly(); }; + bool getPubKey(const CKeyID& address, CPubKey& pub_key) override { return m_wallet->GetPubKey(address, pub_key); } + bool getPrivKey(const CKeyID& address, CKey& key) override { return m_wallet->GetKey(address, key); } + bool isSpendable(const CTxDestination& dest) override { return IsMine(*m_wallet, dest) & ISMINE_SPENDABLE; } + bool haveWatchOnly() override { return m_wallet->HaveWatchOnly(); }; bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) override { - return m_wallet.SetAddressBook(dest, name, purpose); + return m_wallet->SetAddressBook(dest, name, purpose); } bool delAddressBook(const CTxDestination& dest) override { - return m_wallet.DelAddressBook(dest); + return m_wallet->DelAddressBook(dest); } bool getAddress(const CTxDestination& dest, std::string* name, isminetype* is_mine, std::string* purpose) override { - LOCK(m_wallet.cs_wallet); - auto it = m_wallet.mapAddressBook.find(dest); - if (it == m_wallet.mapAddressBook.end()) { + LOCK(m_wallet->cs_wallet); + auto it = m_wallet->mapAddressBook.find(dest); + if (it == m_wallet->mapAddressBook.end()) { return false; } if (name) { *name = it->second.name; } if (is_mine) { - *is_mine = IsMine(m_wallet, dest); + *is_mine = IsMine(*m_wallet, dest); } if (purpose) { *purpose = it->second.purpose; @@ -192,52 +192,52 @@ public: } std::vector<WalletAddress> getAddresses() override { - LOCK(m_wallet.cs_wallet); + LOCK(m_wallet->cs_wallet); std::vector<WalletAddress> result; - for (const auto& item : m_wallet.mapAddressBook) { - result.emplace_back(item.first, IsMine(m_wallet, item.first), item.second.name, item.second.purpose); + for (const auto& item : m_wallet->mapAddressBook) { + result.emplace_back(item.first, IsMine(*m_wallet, item.first), item.second.name, item.second.purpose); } return result; } - void learnRelatedScripts(const CPubKey& key, OutputType type) override { m_wallet.LearnRelatedScripts(key, type); } + void learnRelatedScripts(const CPubKey& key, OutputType type) override { m_wallet->LearnRelatedScripts(key, type); } bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) override { - LOCK(m_wallet.cs_wallet); - return m_wallet.AddDestData(dest, key, value); + LOCK(m_wallet->cs_wallet); + return m_wallet->AddDestData(dest, key, value); } bool eraseDestData(const CTxDestination& dest, const std::string& key) override { - LOCK(m_wallet.cs_wallet); - return m_wallet.EraseDestData(dest, key); + LOCK(m_wallet->cs_wallet); + return m_wallet->EraseDestData(dest, key); } std::vector<std::string> getDestValues(const std::string& prefix) override { - LOCK(m_wallet.cs_wallet); - return m_wallet.GetDestValues(prefix); + LOCK(m_wallet->cs_wallet); + return m_wallet->GetDestValues(prefix); } void lockCoin(const COutPoint& output) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.LockCoin(output); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->LockCoin(output); } void unlockCoin(const COutPoint& output) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.UnlockCoin(output); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->UnlockCoin(output); } bool isLockedCoin(const COutPoint& output) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.IsLockedCoin(output.hash, output.n); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->IsLockedCoin(output.hash, output.n); } void listLockedCoins(std::vector<COutPoint>& outputs) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.ListLockedCoins(outputs); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->ListLockedCoins(outputs); } std::unique_ptr<PendingWalletTx> createTransaction(const std::vector<CRecipient>& recipients, const CCoinControl& coin_control, @@ -246,25 +246,25 @@ public: CAmount& fee, std::string& fail_reason) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - auto pending = MakeUnique<PendingWalletTxImpl>(m_wallet); - if (!m_wallet.CreateTransaction(*locked_chain, recipients, pending->m_tx, pending->m_key, fee, change_pos, + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + auto pending = MakeUnique<PendingWalletTxImpl>(*m_wallet); + if (!m_wallet->CreateTransaction(*locked_chain, recipients, pending->m_tx, pending->m_key, fee, change_pos, fail_reason, coin_control, sign)) { return {}; } return std::move(pending); } - bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet.TransactionCanBeAbandoned(txid); } + bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet->TransactionCanBeAbandoned(txid); } bool abandonTransaction(const uint256& txid) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.AbandonTransaction(*locked_chain, txid); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->AbandonTransaction(*locked_chain, txid); } bool transactionCanBeBumped(const uint256& txid) override { - return feebumper::TransactionCanBeBumped(&m_wallet, txid); + return feebumper::TransactionCanBeBumped(m_wallet.get(), txid); } bool createBumpTransaction(const uint256& txid, const CCoinControl& coin_control, @@ -274,46 +274,46 @@ public: CAmount& new_fee, CMutableTransaction& mtx) override { - return feebumper::CreateTransaction(&m_wallet, txid, coin_control, total_fee, errors, old_fee, new_fee, mtx) == + return feebumper::CreateTransaction(m_wallet.get(), txid, coin_control, total_fee, errors, old_fee, new_fee, mtx) == feebumper::Result::OK; } - bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(&m_wallet, mtx); } + bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(m_wallet.get(), mtx); } bool commitBumpTransaction(const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid) override { - return feebumper::CommitTransaction(&m_wallet, txid, std::move(mtx), errors, bumped_txid) == + return feebumper::CommitTransaction(m_wallet.get(), txid, std::move(mtx), errors, bumped_txid) == feebumper::Result::OK; } CTransactionRef getTx(const uint256& txid) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - auto mi = m_wallet.mapWallet.find(txid); - if (mi != m_wallet.mapWallet.end()) { + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + auto mi = m_wallet->mapWallet.find(txid); + if (mi != m_wallet->mapWallet.end()) { return mi->second.tx; } return {}; } WalletTx getWalletTx(const uint256& txid) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - auto mi = m_wallet.mapWallet.find(txid); - if (mi != m_wallet.mapWallet.end()) { - return MakeWalletTx(*locked_chain, m_wallet, mi->second); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + auto mi = m_wallet->mapWallet.find(txid); + if (mi != m_wallet->mapWallet.end()) { + return MakeWalletTx(*locked_chain, *m_wallet, mi->second); } return {}; } std::vector<WalletTx> getWalletTxs() override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); std::vector<WalletTx> result; - result.reserve(m_wallet.mapWallet.size()); - for (const auto& entry : m_wallet.mapWallet) { - result.emplace_back(MakeWalletTx(*locked_chain, m_wallet, entry.second)); + result.reserve(m_wallet->mapWallet.size()); + for (const auto& entry : m_wallet->mapWallet) { + result.emplace_back(MakeWalletTx(*locked_chain, *m_wallet, entry.second)); } return result; } @@ -322,16 +322,16 @@ public: int& num_blocks, int64_t& block_time) override { - auto locked_chain = m_wallet.chain().lock(true /* try_lock */); + auto locked_chain = m_wallet->chain().lock(true /* try_lock */); if (!locked_chain) { return false; } - TRY_LOCK(m_wallet.cs_wallet, locked_wallet); + TRY_LOCK(m_wallet->cs_wallet, locked_wallet); if (!locked_wallet) { return false; } - auto mi = m_wallet.mapWallet.find(txid); - if (mi == m_wallet.mapWallet.end()) { + auto mi = m_wallet->mapWallet.find(txid); + if (mi == m_wallet->mapWallet.end()) { return false; } if (Optional<int> height = locked_chain->getHeight()) { @@ -350,37 +350,37 @@ public: bool& in_mempool, int& num_blocks) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - auto mi = m_wallet.mapWallet.find(txid); - if (mi != m_wallet.mapWallet.end()) { + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + auto mi = m_wallet->mapWallet.find(txid); + if (mi != m_wallet->mapWallet.end()) { num_blocks = locked_chain->getHeight().get_value_or(-1); in_mempool = mi->second.InMempool(); order_form = mi->second.vOrderForm; tx_status = MakeWalletTxStatus(*locked_chain, mi->second); - return MakeWalletTx(*locked_chain, m_wallet, mi->second); + return MakeWalletTx(*locked_chain, *m_wallet, mi->second); } return {}; } WalletBalances getBalances() override { WalletBalances result; - result.balance = m_wallet.GetBalance(); - result.unconfirmed_balance = m_wallet.GetUnconfirmedBalance(); - result.immature_balance = m_wallet.GetImmatureBalance(); - result.have_watch_only = m_wallet.HaveWatchOnly(); + result.balance = m_wallet->GetBalance(); + result.unconfirmed_balance = m_wallet->GetUnconfirmedBalance(); + result.immature_balance = m_wallet->GetImmatureBalance(); + result.have_watch_only = m_wallet->HaveWatchOnly(); if (result.have_watch_only) { - result.watch_only_balance = m_wallet.GetBalance(ISMINE_WATCH_ONLY); - result.unconfirmed_watch_only_balance = m_wallet.GetUnconfirmedWatchOnlyBalance(); - result.immature_watch_only_balance = m_wallet.GetImmatureWatchOnlyBalance(); + result.watch_only_balance = m_wallet->GetBalance(ISMINE_WATCH_ONLY); + result.unconfirmed_watch_only_balance = m_wallet->GetUnconfirmedWatchOnlyBalance(); + result.immature_watch_only_balance = m_wallet->GetImmatureWatchOnlyBalance(); } return result; } bool tryGetBalances(WalletBalances& balances, int& num_blocks) override { - auto locked_chain = m_wallet.chain().lock(true /* try_lock */); + auto locked_chain = m_wallet->chain().lock(true /* try_lock */); if (!locked_chain) return false; - TRY_LOCK(m_wallet.cs_wallet, locked_wallet); + TRY_LOCK(m_wallet->cs_wallet, locked_wallet); if (!locked_wallet) { return false; } @@ -388,68 +388,68 @@ public: num_blocks = locked_chain->getHeight().get_value_or(-1); return true; } - CAmount getBalance() override { return m_wallet.GetBalance(); } + CAmount getBalance() override { return m_wallet->GetBalance(); } CAmount getAvailableBalance(const CCoinControl& coin_control) override { - return m_wallet.GetAvailableBalance(&coin_control); + return m_wallet->GetAvailableBalance(&coin_control); } isminetype txinIsMine(const CTxIn& txin) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.IsMine(txin); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->IsMine(txin); } isminetype txoutIsMine(const CTxOut& txout) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.IsMine(txout); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->IsMine(txout); } CAmount getDebit(const CTxIn& txin, isminefilter filter) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.GetDebit(txin, filter); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->GetDebit(txin, filter); } CAmount getCredit(const CTxOut& txout, isminefilter filter) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); - return m_wallet.GetCredit(txout, filter); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); + return m_wallet->GetCredit(txout, filter); } CoinsList listCoins() override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); CoinsList result; - for (const auto& entry : m_wallet.ListCoins(*locked_chain)) { + for (const auto& entry : m_wallet->ListCoins(*locked_chain)) { auto& group = result[entry.first]; for (const auto& coin : entry.second) { group.emplace_back(COutPoint(coin.tx->GetHash(), coin.i), - MakeWalletTxOut(*locked_chain, m_wallet, *coin.tx, coin.i, coin.nDepth)); + MakeWalletTxOut(*locked_chain, *m_wallet, *coin.tx, coin.i, coin.nDepth)); } } return result; } std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) override { - auto locked_chain = m_wallet.chain().lock(); - LOCK(m_wallet.cs_wallet); + auto locked_chain = m_wallet->chain().lock(); + LOCK(m_wallet->cs_wallet); std::vector<WalletTxOut> result; result.reserve(outputs.size()); for (const auto& output : outputs) { result.emplace_back(); - auto it = m_wallet.mapWallet.find(output.hash); - if (it != m_wallet.mapWallet.end()) { + auto it = m_wallet->mapWallet.find(output.hash); + if (it != m_wallet->mapWallet.end()) { int depth = it->second.GetDepthInMainChain(*locked_chain); if (depth >= 0) { - result.back() = MakeWalletTxOut(*locked_chain, m_wallet, it->second, output.n, depth); + result.back() = MakeWalletTxOut(*locked_chain, *m_wallet, it->second, output.n, depth); } } } return result; } - CAmount getRequiredFee(unsigned int tx_bytes) override { return GetRequiredFee(m_wallet, tx_bytes); } + CAmount getRequiredFee(unsigned int tx_bytes) override { return GetRequiredFee(*m_wallet, tx_bytes); } CAmount getMinimumFee(unsigned int tx_bytes, const CCoinControl& coin_control, int* returned_target, @@ -457,55 +457,54 @@ public: { FeeCalculation fee_calc; CAmount result; - result = GetMinimumFee(m_wallet, tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc); + result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc); if (returned_target) *returned_target = fee_calc.returnedTarget; if (reason) *reason = fee_calc.reason; return result; } - unsigned int getConfirmTarget() override { return m_wallet.m_confirm_target; } - bool hdEnabled() override { return m_wallet.IsHDEnabled(); } - bool canGetAddresses() override { return m_wallet.CanGetAddresses(); } - bool IsWalletFlagSet(uint64_t flag) override { return m_wallet.IsWalletFlagSet(flag); } - OutputType getDefaultAddressType() override { return m_wallet.m_default_address_type; } - OutputType getDefaultChangeType() override { return m_wallet.m_default_change_type; } + unsigned int getConfirmTarget() override { return m_wallet->m_confirm_target; } + bool hdEnabled() override { return m_wallet->IsHDEnabled(); } + bool canGetAddresses() override { return m_wallet->CanGetAddresses(); } + bool IsWalletFlagSet(uint64_t flag) override { return m_wallet->IsWalletFlagSet(flag); } + OutputType getDefaultAddressType() override { return m_wallet->m_default_address_type; } + OutputType getDefaultChangeType() override { return m_wallet->m_default_change_type; } void remove() override { - RemoveWallet(m_shared_wallet); + RemoveWallet(m_wallet); } std::unique_ptr<Handler> handleUnload(UnloadFn fn) override { - return MakeHandler(m_wallet.NotifyUnload.connect(fn)); + return MakeHandler(m_wallet->NotifyUnload.connect(fn)); } std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override { - return MakeHandler(m_wallet.ShowProgress.connect(fn)); + return MakeHandler(m_wallet->ShowProgress.connect(fn)); } std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn) override { - return MakeHandler(m_wallet.NotifyStatusChanged.connect([fn](CCryptoKeyStore*) { fn(); })); + return MakeHandler(m_wallet->NotifyStatusChanged.connect([fn](CCryptoKeyStore*) { fn(); })); } std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) override { - return MakeHandler(m_wallet.NotifyAddressBookChanged.connect( + return MakeHandler(m_wallet->NotifyAddressBookChanged.connect( [fn](CWallet*, const CTxDestination& address, const std::string& label, bool is_mine, const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); })); } std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override { - return MakeHandler(m_wallet.NotifyTransactionChanged.connect( + return MakeHandler(m_wallet->NotifyTransactionChanged.connect( [fn](CWallet*, const uint256& txid, ChangeType status) { fn(txid, status); })); } std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override { - return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn)); + return MakeHandler(m_wallet->NotifyWatchonlyChanged.connect(fn)); } std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) override { - return MakeHandler(m_wallet.NotifyCanGetAddressesChanged.connect(fn)); + return MakeHandler(m_wallet->NotifyCanGetAddressesChanged.connect(fn)); } - std::shared_ptr<CWallet> m_shared_wallet; - CWallet& m_wallet; + std::shared_ptr<CWallet> m_wallet; }; class WalletClientImpl : public ChainClient diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp index c9cdd0d1cd..7b9b4310e7 100644 --- a/src/node/transaction.cpp +++ b/src/node/transaction.cpp @@ -12,7 +12,7 @@ #include <future> -const char* TransactionErrorString(const TransactionError err) +std::string TransactionErrorString(const TransactionError err) { switch (err) { case TransactionError::OK: @@ -33,22 +33,16 @@ const char* TransactionErrorString(const TransactionError err) return "PSBTs not compatible (different transactions)"; case TransactionError::SIGHASH_MISMATCH: return "Specified sighash value does not match existing value"; - - case TransactionError::UNKNOWN_ERROR: - default: break; + // no default case, so the compiler can warn about missing cases } - return "Unknown error"; + assert(false); } -bool BroadcastTransaction(const CTransactionRef tx, uint256& hashTx, TransactionError& error, std::string& err_string, const bool allowhighfees) +TransactionError BroadcastTransaction(const CTransactionRef tx, uint256& hashTx, std::string& err_string, const CAmount& highfee) { std::promise<void> promise; hashTx = tx->GetHash(); - CAmount nMaxRawTxFee = maxTxFee; - if (allowhighfees) - nMaxRawTxFee = 0; - { // cs_main scope LOCK(cs_main); CCoinsViewCache &view = *pcoinsTip; @@ -63,19 +57,16 @@ bool BroadcastTransaction(const CTransactionRef tx, uint256& hashTx, Transaction CValidationState state; bool fMissingInputs; if (!AcceptToMemoryPool(mempool, state, std::move(tx), &fMissingInputs, - nullptr /* plTxnReplaced */, false /* bypass_limits */, nMaxRawTxFee)) { + nullptr /* plTxnReplaced */, false /* bypass_limits */, highfee)) { if (state.IsInvalid()) { err_string = FormatStateMessage(state); - error = TransactionError::MEMPOOL_REJECTED; - return false; + return TransactionError::MEMPOOL_REJECTED; } else { if (fMissingInputs) { - error = TransactionError::MISSING_INPUTS; - return false; + return TransactionError::MISSING_INPUTS; } err_string = FormatStateMessage(state); - error = TransactionError::MEMPOOL_ERROR; - return false; + return TransactionError::MEMPOOL_ERROR; } } else { // If wallet is enabled, ensure that the wallet has been made aware @@ -88,8 +79,7 @@ bool BroadcastTransaction(const CTransactionRef tx, uint256& hashTx, Transaction }); } } else if (fHaveChain) { - error = TransactionError::ALREADY_IN_CHAIN; - return false; + return TransactionError::ALREADY_IN_CHAIN; } else { // Make sure we don't block forever if re-sending // a transaction already in mempool. @@ -100,16 +90,14 @@ bool BroadcastTransaction(const CTransactionRef tx, uint256& hashTx, Transaction promise.get_future().wait(); - if(!g_connman) { - error = TransactionError::P2P_DISABLED; - return false; + if (!g_connman) { + return TransactionError::P2P_DISABLED; } CInv inv(MSG_TX, hashTx); - g_connman->ForEachNode([&inv](CNode* pnode) - { + g_connman->ForEachNode([&inv](CNode* pnode) { pnode->PushInventory(inv); }); - return true; - } + return TransactionError::OK; +} diff --git a/src/node/transaction.h b/src/node/transaction.h index 3b0cbba98b..3457ececa4 100644 --- a/src/node/transaction.h +++ b/src/node/transaction.h @@ -1,17 +1,16 @@ -// Copyright (c) 2017-2018 The Bitcoin Core developers +// Copyright (c) 2017-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NODE_TRANSACTION_H #define BITCOIN_NODE_TRANSACTION_H +#include <attributes.h> #include <primitives/transaction.h> #include <uint256.h> enum class TransactionError { - OK = 0, - UNKNOWN_ERROR, - + OK, //!< No error MISSING_INPUTS, ALREADY_IN_CHAIN, P2P_DISABLED, @@ -20,24 +19,19 @@ enum class TransactionError { INVALID_PSBT, PSBT_MISMATCH, SIGHASH_MISMATCH, - - ERROR_COUNT }; -#define TRANSACTION_ERR_LAST TransactionError::ERROR_COUNT - -const char* TransactionErrorString(const TransactionError error); +std::string TransactionErrorString(const TransactionError error); /** * Broadcast a transaction * * @param[in] tx the transaction to broadcast * @param[out] &txid the txid of the transaction, if successfully broadcast - * @param[out] &error reference to UniValue to fill with error info on failure * @param[out] &err_string reference to std::string to fill with error string if available - * @param[in] allowhighfees whether to allow fees exceeding maxTxFee - * return true on success, false on error (and fills in `error`) + * @param[in] highfee Reject txs with fees higher than this (if 0, accept any fee) + * return error */ -bool BroadcastTransaction(CTransactionRef tx, uint256& txid, TransactionError& error, std::string& err_string, bool allowhighfees = false); +NODISCARD TransactionError BroadcastTransaction(CTransactionRef tx, uint256& txid, std::string& err_string, const CAmount& highfee); #endif // BITCOIN_NODE_TRANSACTION_H diff --git a/src/psbt.cpp b/src/psbt.cpp index 32fb459dec..0fb7d49d7d 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -309,21 +309,19 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti return true; } -bool CombinePSBTs(PartiallySignedTransaction& out, TransactionError& error, const std::vector<PartiallySignedTransaction>& psbtxs) +TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs) { out = psbtxs[0]; // Copy the first one // Merge for (auto it = std::next(psbtxs.begin()); it != psbtxs.end(); ++it) { if (!out.Merge(*it)) { - error = TransactionError::PSBT_MISMATCH; - return false; + return TransactionError::PSBT_MISMATCH; } } if (!out.IsSane()) { - error = TransactionError::INVALID_PSBT; - return false; + return TransactionError::INVALID_PSBT; } - return true; + return TransactionError::OK; } diff --git a/src/psbt.h b/src/psbt.h index 27b0aedd05..c889dad361 100644 --- a/src/psbt.h +++ b/src/psbt.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -575,10 +575,9 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti * Combines PSBTs with the same underlying transaction, resulting in a single PSBT with all partial signatures from each input. * * @param[out] &out the combined PSBT, if successful - * @param[out] &error reference to TransactionError to fill with error info on failure * @param[in] psbtxs the PSBTs to combine - * @return True if we successfully combined the transactions, false if they were not compatible + * @return error (OK if we successfully combined the transactions, other error if they were not compatible) */ -bool CombinePSBTs(PartiallySignedTransaction& out, TransactionError& error, const std::vector<PartiallySignedTransaction>& psbtxs); +NODISCARD TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs); #endif // BITCOIN_PSBT_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index bc88dd5e0a..abf9136eee 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -396,6 +396,8 @@ void BitcoinGUI::createActions() connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet); connect(activity, &OpenWalletActivity::finished, activity, &QObject::deleteLater); connect(activity, &OpenWalletActivity::finished, dialog, &QObject::deleteLater); + bool invoked = QMetaObject::invokeMethod(activity, "open"); + assert(invoked); }); } }); diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index c532ffbbfe..fab86a7912 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -59,7 +59,6 @@ OpenWalletActivity* WalletController::openWallet(const std::string& name, QWidge { OpenWalletActivity* activity = new OpenWalletActivity(this, name); activity->moveToThread(&m_activity_thread); - QMetaObject::invokeMethod(activity, "open", Qt::QueuedConnection); return activity; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 7fb9ff2eaf..7e8e5e07d0 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1778,9 +1778,7 @@ static constexpr size_t PER_UTXO_OVERHEAD = sizeof(COutPoint) + sizeof(uint32_t) static UniValue getblockstats(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) { - throw std::runtime_error( - RPCHelpMan{"getblockstats", + const RPCHelpMan help{"getblockstats", "\nCompute per block statistics for a given window. All amounts are in satoshis.\n" "It won't work for some heights with pruning.\n" "It won't work without -txindex for utxo_size_inc, *fee or *feerate stats.\n", @@ -1836,7 +1834,9 @@ static UniValue getblockstats(const JSONRPCRequest& request) HelpExampleCli("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'") + HelpExampleRpc("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'") }, - }.ToString()); + }; + if (request.fHelp || !help.IsValidNumArgs(request.params.size())) { + throw std::runtime_error(help.ToString()); } LOCK(cs_main); @@ -2159,7 +2159,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with output descriptor and metadata", { {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, - {"range", RPCArg::Type::NUM, /* default */ "1000", "Up to what child index HD chains should be explored"}, + {"range", RPCArg::Type::RANGE, /* default */ "1000", "The range of HD chain indexes to explore (either end or [begin,end])"}, }, }, }, @@ -2216,7 +2216,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) // loop through the scan objects for (const UniValue& scanobject : request.params[1].get_array().getValues()) { std::string desc_str; - int range = 1000; + std::pair<int64_t, int64_t> range = {0, 1000}; if (scanobject.isStr()) { desc_str = scanobject.get_str(); } else if (scanobject.isObject()) { @@ -2225,8 +2225,8 @@ UniValue scantxoutset(const JSONRPCRequest& request) desc_str = desc_uni.get_str(); UniValue range_uni = find_value(scanobject, "range"); if (!range_uni.isNull()) { - range = range_uni.get_int(); - if (range < 0 || range > 1000000) throw JSONRPCError(RPC_INVALID_PARAMETER, "range out of range"); + range = ParseRange(range_uni); + if (range.first < 0 || (range.second >> 31) != 0 || range.second >= range.first + 1000000) throw JSONRPCError(RPC_INVALID_PARAMETER, "range out of range"); } } else { throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan object needs to be either a string or an object"); @@ -2237,8 +2237,11 @@ UniValue scantxoutset(const JSONRPCRequest& request) if (!desc) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid descriptor '%s'", desc_str)); } - if (!desc->IsRange()) range = 0; - for (int i = 0; i <= range; ++i) { + if (!desc->IsRange()) { + range.first = 0; + range.second = 0; + } + for (int i = range.first; i <= range.second; ++i) { std::vector<CScript> scripts; if (!desc->Expand(i, provider, scripts, provider)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys: '%s'", desc_str)); diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 1cdc9f87a7..a266580b3d 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -28,8 +28,6 @@ public: static const CRPCConvertParam vRPCConvertParams[] = { { "setmocktime", 0, "timestamp" }, - { "generate", 0, "nblocks" }, - { "generate", 1, "maxtries" }, { "generatetoaddress", 0, "nblocks" }, { "generatetoaddress", 2, "maxtries" }, { "getnetworkhashps", 0, "nblocks" }, @@ -68,8 +66,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "sendmany", 4, "subtractfeefrom" }, { "sendmany", 5 , "replaceable" }, { "sendmany", 6 , "conf_target" }, - { "deriveaddresses", 1, "begin" }, - { "deriveaddresses", 2, "end" }, + { "deriveaddresses", 1, "range" }, { "scantxoutset", 1, "scanobjects" }, { "addmultisigaddress", 0, "nrequired" }, { "addmultisigaddress", 1, "keys" }, diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 999a307e2b..822a0beef9 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -185,7 +185,7 @@ UniValue getdescriptorinfo(const JSONRPCRequest& request) UniValue deriveaddresses(const JSONRPCRequest& request) { - if (request.fHelp || request.params.empty() || request.params.size() > 3) { + if (request.fHelp || request.params.empty() || request.params.size() > 2) { throw std::runtime_error( RPCHelpMan{"deriveaddresses", {"\nDerives one or more addresses corresponding to an output descriptor.\n" @@ -199,37 +199,37 @@ UniValue deriveaddresses(const JSONRPCRequest& request) "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n"}, { {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor."}, - {"begin", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the beginning of the range to import."}, - {"end", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end of the range to import."} + {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."}, }, RPCResult{ "[ address ] (array) the derived addresses\n" }, RPCExamples{ "First three native segwit receive addresses\n" + - HelpExampleCli("deriveaddresses", "\"wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#trd0mf0l\" 0 2") + HelpExampleCli("deriveaddresses", "\"wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#trd0mf0l\" \"[0,2]\"") }}.ToString() ); } - RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VNUM, UniValue::VNUM}); + RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType()}); // Range argument is checked later const std::string desc_str = request.params[0].get_str(); - int range_begin = 0; - int range_end = 0; + int64_t range_begin = 0; + int64_t range_end = 0; - if (request.params.size() >= 2) { - if (request.params.size() == 2) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing range end parameter"); - } - range_begin = request.params[1].get_int(); - range_end = request.params[2].get_int(); - if (range_begin < 0) { + if (request.params.size() >= 2 && !request.params[1].isNull()) { + auto range = ParseRange(request.params[1]); + if (range.first < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should be greater or equal than 0"); } - if (range_begin > range_end) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Range end should be equal to or greater than begin"); + if ((range.second >> 31) != 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "End of range is too high"); + } + if (range.second >= range.first + 1000000) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Range is too large"); } + range_begin = range.first; + range_end = range.second; } FlatSigningProvider provider; @@ -603,7 +603,7 @@ static const CRPCCommand commands[] = { "control", "logging", &logging, {"include", "exclude"}}, { "util", "validateaddress", &validateaddress, {"address"} }, { "util", "createmultisig", &createmultisig, {"nrequired","keys","address_type"} }, - { "util", "deriveaddresses", &deriveaddresses, {"descriptor", "begin", "end"} }, + { "util", "deriveaddresses", &deriveaddresses, {"descriptor", "range"} }, { "util", "getdescriptorinfo", &getdescriptorinfo, {"descriptor"} }, { "util", "verifymessage", &verifymessage, {"address","signature","message"} }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} }, diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 6bbbbc9876..c7b3478f44 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -523,13 +523,7 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request) static UniValue setban(const JSONRPCRequest& request) { - std::string strCommand; - if (!request.params[1].isNull()) - strCommand = request.params[1].get_str(); - if (request.fHelp || request.params.size() < 2 || - (strCommand != "add" && strCommand != "remove")) - throw std::runtime_error( - RPCHelpMan{"setban", + const RPCHelpMan help{"setban", "\nAttempts to add or remove an IP/Subnet from the banned list.\n", { {"subnet", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP)"}, @@ -543,7 +537,13 @@ static UniValue setban(const JSONRPCRequest& request) + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400") }, - }.ToString()); + }; + std::string strCommand; + if (!request.params[1].isNull()) + strCommand = request.params[1].get_str(); + if (request.fHelp || !help.IsValidNumArgs(request.params.size()) || (strCommand != "add" && strCommand != "remove")) { + throw std::runtime_error(help.ToString()); + } if (!g_banman) { throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded"); } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 38e2dc237e..d19afaa8a1 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -6,8 +6,8 @@ #include <chain.h> #include <coins.h> #include <compat/byteswap.h> -#include <consensus/validation.h> #include <consensus/tx_verify.h> +#include <consensus/validation.h> #include <core_io.h> #include <index/txindex.h> #include <init.h> @@ -67,9 +67,7 @@ static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& static UniValue getrawtransaction(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) - throw std::runtime_error( - RPCHelpMan{ + const RPCHelpMan help{ "getrawtransaction", "\nReturn the raw transaction data.\n" @@ -79,8 +77,7 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) "will return the transaction if it is in the mempool, or if -txindex is enabled and the transaction\n" "is in a block in the blockchain.\n" - "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n" - "Or use gettransaction for wallet transactions.\n" + "\nHint: Use gettransaction for wallet transactions.\n" "\nIf verbose is 'true', returns an Object with information about 'txid'.\n" "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n", @@ -148,7 +145,11 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) + HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"") + HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"") }, - }.ToString()); + }; + + if (request.fHelp || !help.IsValidNumArgs(request.params.size())) { + throw std::runtime_error(help.ToString()); + } bool in_active_chain = true; uint256 hash = ParseHashV(request.params[0], "parameter 1"); @@ -1065,10 +1066,11 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) bool allowhighfees = false; if (!request.params[1].isNull()) allowhighfees = request.params[1].get_bool(); + const CAmount highfee{allowhighfees ? 0 : ::maxTxFee}; uint256 txid; - TransactionError err; std::string err_string; - if (!BroadcastTransaction(tx, txid, err, err_string, allowhighfees)) { + const TransactionError err = BroadcastTransaction(tx, txid, err_string, highfee); + if (TransactionError::OK != err) { throw JSONRPCTransactionError(err, err_string); } @@ -1493,8 +1495,8 @@ UniValue combinepsbt(const JSONRPCRequest& request) } PartiallySignedTransaction merged_psbt; - TransactionError error; - if (!CombinePSBTs(merged_psbt, error, psbtxs)) { + const TransactionError error = CombinePSBTs(merged_psbt, psbtxs); + if (error != TransactionError::OK) { throw JSONRPCTransactionError(error); } diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 023b4b6746..40ac133186 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -1,11 +1,10 @@ -// Copyright (c) 2017-2018 The Bitcoin Core developers +// Copyright (c) 2017-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <key_io.h> #include <keystore.h> #include <policy/fees.h> -#include <rpc/protocol.h> #include <rpc/util.h> #include <tinyformat.h> #include <util/strencodings.h> @@ -201,6 +200,7 @@ struct Sections { case RPCArg::Type::STR: case RPCArg::Type::NUM: case RPCArg::Type::AMOUNT: + case RPCArg::Type::RANGE: case RPCArg::Type::BOOL: { if (outer_type == OuterType::NAMED_ARG) return; // Nothing more to do for non-recursive types on first recursion auto left = indent; @@ -315,6 +315,17 @@ std::string RPCExamples::ToDescriptionString() const return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples; } +bool RPCHelpMan::IsValidNumArgs(size_t num_args) const +{ + size_t num_required_args = 0; + for (size_t n = m_args.size(); n > 0; --n) { + if (!m_args.at(n - 1).IsOptional()) { + num_required_args = n; + break; + } + } + return num_required_args <= num_args && num_args <= m_args.size(); +} std::string RPCHelpMan::ToString() const { std::string ret; @@ -323,12 +334,7 @@ std::string RPCHelpMan::ToString() const ret += m_name; bool was_optional{false}; for (const auto& arg : m_args) { - bool optional; - if (arg.m_fallback.which() == 1) { - optional = true; - } else { - optional = RPCArg::Optional::NO != boost::get<RPCArg::Optional>(arg.m_fallback); - } + const bool optional = arg.IsOptional(); ret += " "; if (optional) { if (!was_optional) ret += "( "; @@ -370,6 +376,15 @@ std::string RPCHelpMan::ToString() const return ret; } +bool RPCArg::IsOptional() const +{ + if (m_fallback.which() == 1) { + return true; + } else { + return RPCArg::Optional::NO != boost::get<RPCArg::Optional>(m_fallback); + } +} + std::string RPCArg::ToDescriptionString() const { std::string ret; @@ -391,6 +406,10 @@ std::string RPCArg::ToDescriptionString() const ret += "numeric or string"; break; } + case Type::RANGE: { + ret += "numeric or array"; + break; + } case Type::BOOL: { ret += "boolean"; break; @@ -450,6 +469,8 @@ std::string RPCArg::ToStringObj(const bool oneline) const return res + "\"hex\""; case Type::NUM: return res + "n"; + case Type::RANGE: + return res + "n or [n,n]"; case Type::AMOUNT: return res + "amount"; case Type::BOOL: @@ -480,6 +501,7 @@ std::string RPCArg::ToString(const bool oneline) const return "\"" + m_name + "\""; } case Type::NUM: + case Type::RANGE: case Type::AMOUNT: case Type::BOOL: { return m_name; @@ -509,3 +531,17 @@ std::string RPCArg::ToString(const bool oneline) const } assert(false); } + +std::pair<int64_t, int64_t> ParseRange(const UniValue& value) +{ + if (value.isNum()) { + return {0, value.get_int64()}; + } + if (value.isArray() && value.size() == 2 && value[0].isNum() && value[1].isNum()) { + int64_t low = value[0].get_int64(); + int64_t high = value[1].get_int64(); + if (low > high) throw JSONRPCError(RPC_INVALID_PARAMETER, "Range specified as [begin,end] must not have begin after end"); + return {low, high}; + } + throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified as end or as [begin,end]"); +} diff --git a/src/rpc/util.h b/src/rpc/util.h index 1c9ddcdf44..f1bd2c89df 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 The Bitcoin Core developers +// Copyright (c) 2017-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,7 @@ #include <node/transaction.h> #include <pubkey.h> +#include <rpc/protocol.h> #include <script/standard.h> #include <univalue.h> @@ -37,6 +38,9 @@ unsigned int ParseConfirmTarget(const UniValue& value); RPCErrorCode RPCErrorFromTransactionError(TransactionError terr); UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = ""); +//! Parse a JSON range specified as int64, or [int64, int64] +std::pair<int64_t, int64_t> ParseRange(const UniValue& value); + struct RPCArg { enum class Type { OBJ, @@ -47,13 +51,14 @@ struct RPCArg { OBJ_USER_KEYS, //!< Special type where the user must set the keys e.g. to define multiple addresses; as opposed to e.g. an options object where the keys are predefined AMOUNT, //!< Special type representing a floating point amount (can be either NUM or STR) STR_HEX, //!< Special type that is a STR with only hex chars + RANGE, //!< Special type that is a NUM or [NUM,NUM] }; enum class Optional { /** Required arg */ NO, /** - * Optinal arg that is a named argument and has a default value of + * Optional arg that is a named argument and has a default value of * `null`. When possible, the default value should be specified. */ OMITTED_NAMED_ARG, @@ -110,6 +115,8 @@ struct RPCArg { assert(type == Type::ARR || type == Type::OBJ); } + bool IsOptional() const; + /** * Return the type string of the argument. * Set oneline to allow it to be overridden by a custom oneline type string (m_oneline_description). @@ -185,6 +192,8 @@ public: RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples); std::string ToString() const; + /** If the supplied number of args is neither too small nor too high */ + bool IsValidNumArgs(size_t num_args) const; private: const std::string m_name; diff --git a/src/util/system.cpp b/src/util/system.cpp index 9e02a227cb..5ae0604894 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -74,7 +74,6 @@ const int64_t nStartupTime = GetTime(); const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; -const char * const BITCOIN_PID_FILENAME = "bitcoind.pid"; ArgsManager gArgs; @@ -961,23 +960,6 @@ std::string ArgsManager::GetChainName() const return CBaseChainParams::MAIN; } -#ifndef WIN32 -fs::path GetPidFile() -{ - return AbsPathForConfigVal(fs::path(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME))); -} - -void CreatePidFile(const fs::path &path, pid_t pid) -{ - FILE* file = fsbridge::fopen(path, "w"); - if (file) - { - fprintf(file, "%d\n", pid); - fclose(file); - } -} -#endif - bool RenameOver(fs::path src, fs::path dest) { #ifdef WIN32 diff --git a/src/util/system.h b/src/util/system.h index cb66c470a6..6899e38c9e 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -40,7 +40,6 @@ int64_t GetStartupTime(); extern const char * const BITCOIN_CONF_FILENAME; -extern const char * const BITCOIN_PID_FILENAME; /** Translate a message to the native language of the user. */ const extern std::function<std::string(const char*)> G_TRANSLATION_FUN; @@ -86,10 +85,6 @@ const fs::path &GetBlocksDir(); const fs::path &GetDataDir(bool fNetSpecific = true); void ClearDatadirCache(); fs::path GetConfigFile(const std::string& confPath); -#ifndef WIN32 -fs::path GetPidFile(); -void CreatePidFile(const fs::path &path, pid_t pid); -#endif #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif diff --git a/src/validation.cpp b/src/validation.cpp index 1806bc1268..f3d34dca70 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2259,12 +2259,6 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar } if (nUpgraded > 0) AppendWarning(warningMessages, strprintf(_("%d of last 100 blocks have unexpected version"), nUpgraded)); - if (nUpgraded > 100/2) - { - std::string strWarning = _("Warning: Unknown block versions being mined! It's possible unknown rules are in effect"); - // notify GetWarnings(), called by Qt and the JSON-RPC code to warn the user: - DoWarning(strWarning); - } } LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)", __func__, /* Continued */ pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion, diff --git a/src/wallet/psbtwallet.cpp b/src/wallet/psbtwallet.cpp index 761e7b7dd7..1b17b09763 100644 --- a/src/wallet/psbtwallet.cpp +++ b/src/wallet/psbtwallet.cpp @@ -4,7 +4,7 @@ #include <wallet/psbtwallet.h> -bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, TransactionError& error, bool& complete, int sighash_type, bool sign, bool bip32derivs) +TransactionError FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs) { LOCK(pwallet->cs_wallet); // Get all of the previous transactions @@ -19,8 +19,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, Transac // Verify input looks sane. This will check that we have at most one uxto, witness or non-witness. if (!input.IsSane()) { - error = TransactionError::INVALID_PSBT; - return false; + return TransactionError::INVALID_PSBT; } // If we have no utxo, grab it from the wallet. @@ -37,8 +36,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, Transac // Get the Sighash type if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) { - error = TransactionError::SIGHASH_MISMATCH; - return false; + return TransactionError::SIGHASH_MISMATCH; } complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), psbtx, i, sighash_type); @@ -58,5 +56,5 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, Transac psbt_out.FromSignatureData(sigdata); } - return true; + return TransactionError::OK; } diff --git a/src/wallet/psbtwallet.h b/src/wallet/psbtwallet.h index b679f5c6ba..a24a0967d2 100644 --- a/src/wallet/psbtwallet.h +++ b/src/wallet/psbtwallet.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,16 +18,14 @@ * * @param[in] pwallet pointer to a wallet * @param[in] &psbtx reference to PartiallySignedTransaction to fill in - * @param[out] &error reference to UniValue to fill with error info on failure * @param[out] &complete indicates whether the PSBT is now complete * @param[in] sighash_type the sighash type to use when signing (if PSBT does not specify) * @param[in] sign whether to sign or not * @param[in] bip32derivs whether to fill in bip32 derivation information if available - * return true on success, false on error (and fills in `error`) + * return error */ -bool FillPSBT(const CWallet* pwallet, +NODISCARD TransactionError FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, - TransactionError& error, bool& complete, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index f38202a2b8..5b0592e06d 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1132,13 +1132,10 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID if (!data.exists("range")) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor is ranged, please specify the range"); } - const UniValue& range = data["range"]; - range_start = range.exists("start") ? range["start"].get_int64() : 0; - if (!range.exists("end")) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "End of range for descriptor must be specified"); - } - range_end = range["end"].get_int64(); - if (range_end < range_start || range_start < 0) { + auto range = ParseRange(data["range"]); + range_start = range.first; + range_end = range.second; + if (range_start < 0 || (range_end >> 31) != 0 || range_end - range_start >= 1000000) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid descriptor range specified"); } } @@ -1373,12 +1370,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) {"key", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""}, } }, - {"range", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "If a ranged descriptor is used, this specifies the start and end of the range to import", - { - {"start", RPCArg::Type::NUM, /* default */ "0", "Start of the range to import"}, - {"end", RPCArg::Type::NUM, RPCArg::Optional::NO, "End of the range to import (inclusive)"}, - } - }, + {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED, "If a ranged descriptor is used, this specifies the end or the range (in the form [begin,end]) to import"}, {"internal", RPCArg::Type::BOOL, /* default */ "false", "Stating whether matching outputs should be treated as not incoming payments (also known as change)"}, {"watchonly", RPCArg::Type::BOOL, /* default */ "false", "Stating whether matching outputs should be considered watchonly."}, {"label", RPCArg::Type::STR, /* default */ "''", "Label to assign to the address, only allowed with internal=false"}, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 37fc88dfd5..47790fbf92 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -19,7 +19,6 @@ #include <policy/fees.h> #include <policy/policy.h> #include <policy/rbf.h> -#include <rpc/mining.h> #include <rpc/rawtransaction.h> #include <rpc/server.h> #include <rpc/util.h> @@ -3358,62 +3357,6 @@ static UniValue bumpfee(const JSONRPCRequest& request) return result; } -UniValue generate(const JSONRPCRequest& request) -{ - std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); - CWallet* const pwallet = wallet.get(); - - - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { - return NullUniValue; - } - - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { - throw std::runtime_error( - RPCHelpMan{"generate", - "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n", - { - {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."}, - {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."}, - }, - RPCResult{ - "[ blockhashes ] (array) hashes of blocks generated\n" - }, - RPCExamples{ - "\nGenerate 11 blocks\n" - + HelpExampleCli("generate", "11") - }, - }.ToString()); - } - - if (!IsDeprecatedRPCEnabled("generate")) { - throw JSONRPCError(RPC_METHOD_DEPRECATED, "The wallet generate rpc method is deprecated and will be fully removed in v0.19. " - "To use generate in v0.18, restart bitcoind with -deprecatedrpc=generate.\n" - "Clients should transition to using the node rpc method generatetoaddress\n"); - } - - int num_generate = request.params[0].get_int(); - uint64_t max_tries = 1000000; - if (!request.params[1].isNull()) { - max_tries = request.params[1].get_int(); - } - - std::shared_ptr<CReserveScript> coinbase_script; - pwallet->GetScriptForMining(coinbase_script); - - // If the keypool is exhausted, no script is returned at all. Catch this. - if (!coinbase_script) { - throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - } - - //throw an error if no script was provided - if (coinbase_script->reserveScript.empty()) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available"); - } - - return generateBlocks(coinbase_script, num_generate, max_tries, true); -} - UniValue rescanblockchain(const JSONRPCRequest& request) { std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); @@ -4007,8 +3950,8 @@ UniValue walletprocesspsbt(const JSONRPCRequest& request) bool sign = request.params[1].isNull() ? true : request.params[1].get_bool(); bool bip32derivs = request.params[3].isNull() ? false : request.params[3].get_bool(); bool complete = true; - TransactionError err; - if (!FillPSBT(pwallet, psbtx, err, complete, nHashType, sign, bip32derivs)) { + const TransactionError err = FillPSBT(pwallet, psbtx, complete, nHashType, sign, bip32derivs); + if (err != TransactionError::OK) { throw JSONRPCTransactionError(err); } @@ -4125,8 +4068,8 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) // Fill transaction with out data but don't sign bool bip32derivs = request.params[4].isNull() ? false : request.params[4].get_bool(); bool complete = true; - TransactionError err; - if (!FillPSBT(pwallet, psbtx, err, complete, 1, false, bip32derivs)) { + const TransactionError err = FillPSBT(pwallet, psbtx, complete, 1, false, bip32derivs); + if (err != TransactionError::OK) { throw JSONRPCTransactionError(err); } @@ -4156,7 +4099,6 @@ UniValue importmulti(const JSONRPCRequest& request); static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- - { "generating", "generate", &generate, {"nblocks","maxtries"} }, { "hidden", "resendwallettransactions", &resendwallettransactions, {} }, { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options","iswitness"} }, { "wallet", "abandontransaction", &abandontransaction, {"txid"} }, diff --git a/src/wallet/test/psbt_wallet_tests.cpp b/src/wallet/test/psbt_wallet_tests.cpp index 2a3149de46..789e86e21b 100644 --- a/src/wallet/test/psbt_wallet_tests.cpp +++ b/src/wallet/test/psbt_wallet_tests.cpp @@ -62,9 +62,8 @@ BOOST_AUTO_TEST_CASE(psbt_updater_test) ssData >> psbtx; // Fill transaction with our data - TransactionError err; bool complete = true; - FillPSBT(&m_wallet, psbtx, err, complete, SIGHASH_ALL, false, true); + BOOST_REQUIRE_EQUAL(TransactionError::OK, FillPSBT(&m_wallet, psbtx, complete, SIGHASH_ALL, false, true)); // Get the final tx CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 388422bec8..cee31d5ac2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3819,17 +3819,6 @@ void CWallet::MarkReserveKeysAsUsed(int64_t keypool_id) } } -void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script) -{ - std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this); - CPubKey pubkey; - if (!rKey->GetReservedKey(pubkey)) - return; - - script = rKey; - script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; -} - void CWallet::LockCoin(const COutPoint& output) { AssertLockHeld(cs_wallet); // setLockedCoins diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 2a5d6caaf8..5173f957c7 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1065,8 +1065,6 @@ public: const std::string& GetLabelName(const CScript& scriptPubKey) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); - void GetScriptForMining(std::shared_ptr<CReserveScript> &script); - unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); // set{Ex,In}ternalKeyPool diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp index 6db4c63acb..d779251d56 100644 --- a/src/wallet/walletutil.cpp +++ b/src/wallet/walletutil.cpp @@ -35,7 +35,7 @@ static bool IsBerkeleyBtree(const fs::path& path) boost::system::error_code ec; if (fs::file_size(path, ec) < 4096) return false; - fs::ifstream file(path.string(), std::ios::binary); + fsbridge::ifstream file(path, std::ios::binary); if (!file.is_open()) return false; file.seekg(12, std::ios::beg); // Magic bytes start at offset 12 |