diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index 1fef7400f5042..122c8dc22df1e 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -194,7 +194,7 @@ fi if ! getent services http https ftp > /dev/null 2>&1; then cat << EOF -ERR: Your system's C library can not find service database entries for at least +ERR: Your system's C library cannot find service database entries for at least one of the following services: http, https, ftp. Hint: Most likely, /etc/services does not exist yet (common for docker images diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 1f3aef04a6839..04013dfcb690e 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -445,7 +445,7 @@ other input. failure, it will throw an exception, which can be caught to recover from the error. - For example, a nullptr dereference or any other logic bug in RPC code - means that the RPC code is faulty and can not be executed. However, the + means that the RPC code is faulty and cannot be executed. However, the logic bug can be shown to the user and the program can continue to run. * `Assume` should be used to document assumptions when program execution can safely continue even if the assumption is violated. In debug builds it @@ -1352,7 +1352,7 @@ A few guidelines for introducing and reviewing new RPC interfaces: - Don't forget to fill in the argument names correctly in the RPC command table. - - *Rationale*: If not, the call can not be used with name-based arguments. + - *Rationale*: If not, the call cannot be used with name-based arguments. - Add every non-string RPC argument `(method, idx, name)` to the table `vRPCConvertParams` in `rpc/client.cpp`. diff --git a/doc/release-process.md b/doc/release-process.md index 355ca16159fc6..f9b01fae20371 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -178,7 +178,7 @@ Commit your signature for the signed macOS/Windows binaries: ```sh pushd ./guix.sigs git add "${VERSION}/${SIGNER}"/all.SHA256SUMS{,.asc} -git commit -m "Add ${SIGNER} ${VERSION} signed binaries signatures" +git commit -m "Add attestations by ${SIGNER} for ${VERSION} codesigned" git push # Assuming you can push to the guix.sigs tree popd ``` diff --git a/src/net.cpp b/src/net.cpp index 5b07e5f9bfb1f..de9a5f74cca47 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -5189,7 +5189,7 @@ void CaptureMessageToFile(const CAddress& addr, // layer (processing) perspective. auto now = GetTime(); - // Windows folder names can not include a colon + // Windows folder names cannot include a colon std::string clean_addr = addr.ToStringAddrPort(); std::replace(clean_addr.begin(), clean_addr.end(), ':', '_'); diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 46518ae8ef109..a6e76e3ccd012 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -336,7 +336,7 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) bool fPrintPriority = gArgs.GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); if (fPrintPriority) { - LogPrintf("fee %s txid %s\n", + LogPrintf("fee rate %s txid %s\n", CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(), iter->GetTx().GetHash().ToString()); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 41f0fbe804e77..e6e75ae37f19c 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -510,7 +510,7 @@ int GuiMain(int argc, char* argv[]) InitError(strprintf(Untranslated("Error parsing command line arguments: %s\n"), error)); // Create a message box, because the gui has neither been created nor has subscribed to core signals QMessageBox::critical(nullptr, PACKAGE_NAME, - // message can not be translated because translations have not been initialized + // message cannot be translated because translations have not been initialized QString::fromStdString("Error parsing command line arguments: %1.").arg(QString::fromStdString(error))); return EXIT_FAILURE; } diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index a90535acbc4c0..581ede260433c 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -304,7 +304,7 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable void Intro::UpdateFreeSpaceLabel() { - QString freeString = tr("%1 GB of free space available").arg(m_bytes_available / GB_BYTES); + QString freeString = tr("%1 GB of space available").arg(m_bytes_available / GB_BYTES); if (m_bytes_available < m_required_space_gb * GB_BYTES) { freeString += " " + tr("(of %1 GB needed)").arg(m_required_space_gb); ui->freeSpace->setStyleSheet(GUIUtil::getThemedStyleQString(GUIUtil::ThemedStyle::TS_ERROR)); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index a26fa7c5f4265..38f3398d66f3b 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -499,7 +499,7 @@ static RPCHelpMan setmocktime() RPCTypeCheck(request.params, {UniValue::VNUM}); const int64_t time{request.params[0].get_int64()}; if (time < 0) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Mocktime can not be negative: %s.", time)); + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Mocktime cannot be negative: %s.", time)); } SetMockTime(time); if (auto* node_context = GetContext(request.context)) { diff --git a/src/rpc/txoutproof.cpp b/src/rpc/txoutproof.cpp index 5173e162fd996..a8469485b3857 100644 --- a/src/rpc/txoutproof.cpp +++ b/src/rpc/txoutproof.cpp @@ -133,7 +133,7 @@ static RPCHelpMan verifytxoutproof() RPCResult{ RPCResult::Type::ARR, "", "", { - {RPCResult::Type::STR_HEX, "txid", "The txid(s) which the proof commits to, or empty array if the proof can not be validated."}, + {RPCResult::Type::STR_HEX, "txid", "The txid(s) which the proof commits to, or empty array if the proof cannot be validated."}, } }, RPCExamples{ diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index fbdb851ae19d8..1b9ea354093f5 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1375,7 +1375,7 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney) BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000); BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000); - // Parsing amount that can not be represented should fail + // Parsing amount that cannot be represented should fail BOOST_CHECK(!ParseMoney("100000000.00")); BOOST_CHECK(!ParseMoney("0.000000001")); diff --git a/src/txdb.cpp b/src/txdb.cpp index f780b56b44088..90a5a20bba129 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -40,7 +40,7 @@ std::optional CheckLegacyTxindex(CBlockTreeDB& block_tree_db) { CBlockLocator ignored{}; if (block_tree_db.Read(DB_TXINDEX_BLOCK, ignored)) { - return _("The -txindex upgrade started by a previous version can not be completed. Restart with the previous version or run a full -reindex."); + return _("The -txindex upgrade started by a previous version cannot be completed. Restart with the previous version or run a full -reindex."); } bool txindex_legacy_flag{false}; block_tree_db.ReadFlag("txindex", txindex_legacy_flag); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d4adf717ce344..1416dc3b573fa 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -124,10 +124,9 @@ size_t CTxMemPoolEntry::GetTxSize() const return GetVirtualTransactionSize(nTxSize, sigOpCount); } -// Update the given tx for any in-mempool descendants. -// Assumes that CTxMemPool::m_children is correct for the given tx and all -// descendants. -void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, const std::set &setExclude) +void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants, + const std::set& setExclude, std::set& descendants_to_remove, + uint64_t ancestor_size_limit, uint64_t ancestor_count_limit) { CTxMemPoolEntry::Children stageEntries, descendants; stageEntries = updateIt->GetMemPoolChildrenConst(); @@ -164,17 +163,18 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendan cachedDescendants[updateIt].insert(mapTx.iterator_to(descendant)); // Update ancestor state for each descendant mapTx.modify(mapTx.iterator_to(descendant), update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCount())); + // Don't directly remove the transaction here -- doing so would + // invalidate iterators in cachedDescendants. Mark it for removal + // by inserting into descendants_to_remove. + if (descendant.GetCountWithAncestors() > ancestor_count_limit || descendant.GetSizeWithAncestors() > ancestor_size_limit) { + descendants_to_remove.insert(descendant.GetTx().GetHash()); + } } } mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount)); } -// vHashesToUpdate is the set of transaction hashes from a disconnected block -// which has been re-added to the mempool. -// for each entry, look for descendants that are outside vHashesToUpdate, and -// add fee/size information for such descendants to the parent. -// for each such descendant, also update the ancestor state to include the parent. -void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashesToUpdate) +void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashesToUpdate, uint64_t ancestor_size_limit, uint64_t ancestor_count_limit) { AssertLockHeld(cs); // For each entry in vHashesToUpdate, store the set of in-mempool, but not @@ -186,6 +186,8 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes // accounted for in the state of their ancestors) std::set setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); + std::set descendants_to_remove; + // Iterate in reverse, so that whenever we are looking at a transaction // we are sure that all in-mempool descendants have already been processed. // This maximizes the benefit of the descendant cache and guarantees that @@ -215,7 +217,15 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes } } } // release epoch guard for UpdateForDescendants - UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded); + UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded, descendants_to_remove, ancestor_size_limit, ancestor_count_limit); + } + + for (const auto& txid : descendants_to_remove) { + // This txid may have been removed already in a prior call to removeRecursive. + // Therefore we ensure it is not yet removed already. + if (const std::optional txiter = GetIter(txid)) { + removeRecursive((*txiter)->GetTx(), MemPoolRemovalReason::SIZELIMIT); + } } } @@ -1470,7 +1480,7 @@ void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeD ++nTransactionsUpdated; } } - LogPrint(BCLog::MEMPOOL, "PrioritiseTransaction: %s feerate += %s\n", hash.ToString(), FormatMoney(nFeeDelta)); + LogPrint(BCLog::MEMPOOL, "PrioritiseTransaction: %s fee += %s\n", hash.ToString(), FormatMoney(nFeeDelta)); } void CTxMemPool::ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const diff --git a/src/txmempool.h b/src/txmempool.h index 80e12f4e7df58..f1f93c8a7d5a8 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -680,16 +680,25 @@ class CTxMemPool */ void RemoveStaged(setEntries& stage, bool updateDescendants, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs); - /** When adding transactions from a disconnected block back to the mempool, - * new mempool entries may have children in the mempool (which is generally - * not the case when otherwise adding transactions). - * UpdateTransactionsFromBlock() will find child transactions and update the - * descendant state for each transaction in vHashesToUpdate (excluding any - * child transactions present in vHashesToUpdate, which are already accounted - * for). Note: vHashesToUpdate should be the set of transactions from the - * disconnected block that have been accepted back into the mempool. + /** UpdateTransactionsFromBlock is called when adding transactions from a + * disconnected block back to the mempool, new mempool entries may have + * children in the mempool (which is generally not the case when otherwise + * adding transactions). + * @post updated descendant state for descendants of each transaction in + * vHashesToUpdate (excluding any child transactions present in + * vHashesToUpdate, which are already accounted for). Updated state + * includes add fee/size information for such descendants to the + * parent and updated ancestor state to include the parent. + * + * @param[in] vHashesToUpdate The set of txids from the + * disconnected block that have been accepted back into the mempool. + * @param[in] ancestor_size_limit The maximum allowed size in virtual + * bytes of an entry and its ancestors + * @param[in] ancestor_count_limit The maximum allowed number of + * transactions including the entry and its ancestors. */ - void UpdateTransactionsFromBlock(const std::vector& vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main) LOCKS_EXCLUDED(m_epoch); + void UpdateTransactionsFromBlock(const std::vector& vHashesToUpdate, + uint64_t ancestor_size_limit, uint64_t ancestor_count_limit) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main) LOCKS_EXCLUDED(m_epoch); /** Try to calculate all in-mempool ancestors of entry. * (these are all calculated including the tx itself) @@ -836,19 +845,38 @@ class CTxMemPool /** UpdateForDescendants is used by UpdateTransactionsFromBlock to update * the descendants for a single transaction that has been added to the * mempool but may have child transactions in the mempool, eg during a - * chain reorg. setExclude is the set of descendant transactions in the - * mempool that must not be accounted for (because any descendants in - * setExclude were added to the mempool after the transaction being - * updated and hence their state is already reflected in the parent - * state). + * chain reorg. + * + * @pre CTxMemPool::m_children is correct for the given tx and all + * descendants. + * @pre cachedDescendants is an accurate cache where each entry has all + * descendants of the corresponding key, including those that should + * be removed for violation of ancestor limits. + * @post if updateIt has any non-excluded descendants, cachedDescendants has + * a new cache line for updateIt. + * @post descendants_to_remove has a new entry for any descendant which exceeded + * ancestor limits relative to updateIt. * - * cachedDescendants will be updated with the descendants of the transaction - * being updated, so that future invocations don't need to walk the - * same transaction again, if encountered in another transaction chain. + * @param[in] updateIt the entry to update for its descendants + * @param[in,out] cachedDescendants a cache where each line corresponds to all + * descendants. It will be updated with the descendants of the transaction + * being updated, so that future invocations don't need to walk the same + * transaction again, if encountered in another transaction chain. + * @param[in] setExclude the set of descendant transactions in the mempool + * that must not be accounted for (because any descendants in setExclude + * were added to the mempool after the transaction being updated and hence + * their state is already reflected in the parent state). + * @param[out] descendants_to_remove Populated with the txids of entries that + * exceed ancestor limits. It's the responsibility of the caller to + * removeRecursive them. + * @param[in] ancestor_size_limit the max number of ancestral bytes allowed + * for any descendant + * @param[in] ancestor_count_limit the max number of ancestor transactions + * allowed for any descendant */ - void UpdateForDescendants(txiter updateIt, - cacheMap &cachedDescendants, - const std::set &setExclude) EXCLUSIVE_LOCKS_REQUIRED(cs); + void UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants, + const std::set& setExclude, std::set& descendants_to_remove, + uint64_t ancestor_size_limit, uint64_t ancestor_count_limit) EXCLUSIVE_LOCKS_REQUIRED(cs); /** Update ancestors of hash to add/remove it as a descendant transaction. */ void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs); /** Set ancestor state for an entry */ diff --git a/src/validation.cpp b/src/validation.cpp index 2fabcc6e45b80..d7e5625f87025 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -357,7 +357,9 @@ void CChainState::MaybeUpdateMempoolForReorg( // previously-confirmed transactions back to the mempool. // UpdateTransactionsFromBlock finds descendants of any transactions in // the disconnectpool that were added back and cleans up the mempool state. - m_mempool->UpdateTransactionsFromBlock(vHashUpdate); + const uint64_t ancestor_count_limit = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); + const uint64_t ancestor_size_limit = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000; + m_mempool->UpdateTransactionsFromBlock(vHashUpdate, ancestor_size_limit, ancestor_count_limit); // Predicate to use for filtering transactions in removeForReorg. // Checks whether the transaction is still final and, if it spends a coinbase output, mature. diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b4ca6de160730..c79507214d7b9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2015,7 +2015,7 @@ static RPCHelpMan walletpassphrase() } if (strWalletPass.empty()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "passphrase can not be empty"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "passphrase cannot be empty"); } if (!pwallet->Unlock(strWalletPass, fForMixingOnly)) { @@ -2087,7 +2087,7 @@ static RPCHelpMan walletpassphrasechange() strNewWalletPass = request.params[1].get_str().c_str(); if (strOldWalletPass.empty() || strNewWalletPass.empty()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "passphrase can not be empty"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "passphrase cannot be empty"); } if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) { @@ -2184,7 +2184,7 @@ static RPCHelpMan encryptwallet() strWalletPass = request.params[0].get_str().c_str(); if (strWalletPass.empty()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "passphrase can not be empty"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "passphrase cannot be empty"); } if (!pwallet->EncryptWallet(strWalletPass)) { diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index f8b74ee920e57..7fa30ec727d52 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -715,7 +715,7 @@ class CreateTransactionTestSetup : public TestChain100Setup const std::string strUnableToLocateCoinJoin1 = "Unable to locate enough non-denominated funds for this transaction."; const std::string strUnableToLocateCoinJoin2 = "Unable to locate enough mixed funds for this transaction. CoinJoin uses exact denominated amounts to send funds, you might simply need to mix some more coins."; const std::string strTransactionTooLarge = "Transaction too large"; - const std::string strChangeIndexOutOfRange = "Change index out of range"; + const std::string strChangeIndexOutOfRange = "Transaction change output index out of range"; const std::string strExceededMaxTries = "Exceeded max tries."; const std::string strMaxFeeExceeded = "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 869af8d63b53a..0d15f415b4c01 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3783,7 +3783,7 @@ bool CWallet::CreateTransactionInternal( } else if ((unsigned int)nChangePosRequest > txNew.vout.size()) { - error = _("Change index out of range"); + error = _("Transaction change output index out of range"); return false; } else { nChangePosInOut = nChangePosRequest; diff --git a/test/functional/feature_txindex_compatibility.py b/test/functional/feature_txindex_compatibility.py index f4a8e7cf55372..ed913f51372ff 100755 --- a/test/functional/feature_txindex_compatibility.py +++ b/test/functional/feature_txindex_compatibility.py @@ -83,7 +83,7 @@ def run_test(self): self.stop_nodes() - self.log.info("Check migrated txindex can not be read by legacy node") + self.log.info("Check migrated txindex cannot be read by legacy node") err_msg = f": You need to rebuild the database using -reindex to change -txindex.{os.linesep}Please restart with -reindex or -reindex-chainstate to recover." shutil.rmtree(legacy_chain_dir) shutil.copytree(migrate_chain_dir, legacy_chain_dir) diff --git a/test/functional/mempool_updatefromblock.py b/test/functional/mempool_updatefromblock.py index 22f136d1a5c33..f2e5aa1a8985a 100755 --- a/test/functional/mempool_updatefromblock.py +++ b/test/functional/mempool_updatefromblock.py @@ -17,7 +17,7 @@ class MempoolUpdateFromBlockTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [['-limitdescendantsize=1000', '-limitancestorsize=1000']] + self.extra_args = [['-limitdescendantsize=1000', '-limitancestorsize=1000', '-limitancestorcount=100']] def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/rpc_decodescript.py b/test/functional/rpc_decodescript.py index 438f246af51c5..6df7d1b63ba51 100755 --- a/test/functional/rpc_decodescript.py +++ b/test/functional/rpc_decodescript.py @@ -48,7 +48,7 @@ def decodescript_script_sig(self): rpc_result = self.nodes[0].decodescript('5100') assert_equal('1 0', rpc_result['asm']) - # 5) null data scriptSig - no such thing because null data scripts can not be spent. + # 5) null data scriptSig - no such thing because null data scripts cannot be spent. # thus, no test case for that standard transaction type is here. def decodescript_script_pub_key(self): diff --git a/test/functional/rpc_uptime.py b/test/functional/rpc_uptime.py index 645d76cdfaa90..853c13f13504a 100755 --- a/test/functional/rpc_uptime.py +++ b/test/functional/rpc_uptime.py @@ -23,7 +23,7 @@ def run_test(self): self._test_uptime() def _test_negative_time(self): - assert_raises_rpc_error(-8, "Mocktime can not be negative: -1.", self.nodes[0].setmocktime, -1) + assert_raises_rpc_error(-8, "Mocktime cannot be negative: -1.", self.nodes[0].setmocktime, -1) def _test_uptime(self): wait_time = 10 diff --git a/test/functional/wallet_encryption.py b/test/functional/wallet_encryption.py index 25f19baf8e3c8..126cb9c4f9869 100755 --- a/test/functional/wallet_encryption.py +++ b/test/functional/wallet_encryption.py @@ -35,14 +35,14 @@ def run_test(self): assert_raises_rpc_error(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.", self.nodes[0].walletpassphrasechange, 'ff', 'ff') # Encrypt the wallet - assert_raises_rpc_error(-8, "passphrase can not be empty", self.nodes[0].encryptwallet, '') + assert_raises_rpc_error(-8, "passphrase cannot be empty", self.nodes[0].encryptwallet, '') self.nodes[0].encryptwallet(passphrase) # Test that the wallet is encrypted assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", self.nodes[0].signmessage, address, msg) assert_raises_rpc_error(-15, "Error: running with an encrypted wallet, but encryptwallet was called.", self.nodes[0].encryptwallet, 'ff') - assert_raises_rpc_error(-8, "passphrase can not be empty", self.nodes[0].walletpassphrase, '', 1) - assert_raises_rpc_error(-8, "passphrase can not be empty", self.nodes[0].walletpassphrasechange, '', 'ff') + assert_raises_rpc_error(-8, "passphrase cannot be empty", self.nodes[0].walletpassphrase, '', 1) + assert_raises_rpc_error(-8, "passphrase cannot be empty", self.nodes[0].walletpassphrasechange, '', 'ff') # Check that walletpassphrase works self.nodes[0].walletpassphrase(passphrase, 2) diff --git a/test/util/test_runner.py b/test/util/test_runner.py index 1f7c09439dafb..576c2d3de06c2 100755 --- a/test/util/test_runner.py +++ b/test/util/test_runner.py @@ -93,7 +93,7 @@ def bctest(testDir, testObj, buildenv): try: outputData = open(os.path.join(testDir, outputFn), encoding="utf8").read() except: - logging.error("Output file " + outputFn + " can not be opened") + logging.error("Output file " + outputFn + " cannot be opened") raise if not outputData: logging.error("Output data missing for " + outputFn)