aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xci/test/01_base_install.sh3
-rwxr-xr-xci/test/06_script_b.sh2
-rw-r--r--src/common/settings.cpp2
-rw-r--r--src/kernel/mempool_entry.h10
-rw-r--r--src/rpc/client.cpp4
-rw-r--r--src/rpc/mempool.cpp4
-rw-r--r--src/rpc/server.cpp2
-rw-r--r--src/support/allocators/secure.h4
-rw-r--r--src/support/allocators/zeroafterfree.h4
-rw-r--r--src/test/fuzz/transaction.cpp13
-rw-r--r--src/test/settings_tests.cpp2
-rw-r--r--src/txmempool.cpp8
-rw-r--r--src/txorphanage.cpp12
-rw-r--r--src/txorphanage.h2
-rw-r--r--src/univalue/include/univalue.h2
-rw-r--r--src/univalue/lib/univalue.cpp6
-rw-r--r--src/univalue/test/object.cpp4
-rw-r--r--src/validation.cpp1
-rw-r--r--src/wallet/rpc/addresses.cpp4
-rw-r--r--src/wallet/wallet.cpp7
-rwxr-xr-xtest/functional/feature_assumevalid.py11
-rwxr-xr-xtest/functional/feature_block.py6
-rwxr-xr-xtest/functional/feature_nulldummy.py12
-rwxr-xr-xtest/functional/feature_taproot.py8
-rwxr-xr-xtest/functional/mempool_accept.py6
-rwxr-xr-xtest/functional/mempool_dust.py9
-rwxr-xr-xtest/functional/p2p_segwit.py12
-rwxr-xr-xtest/functional/rpc_createmultisig.py11
-rwxr-xr-xtest/functional/rpc_psbt.py22
-rwxr-xr-xtest/functional/rpc_signrawtransactionwithkey.py21
-rw-r--r--test/functional/test_framework/wallet.py7
-rwxr-xr-xtest/functional/test_framework/wallet_util.py23
-rwxr-xr-xtest/functional/wallet_blank.py14
-rwxr-xr-xtest/functional/wallet_createwallet.py12
-rwxr-xr-xtest/functional/wallet_fundrawtransaction.py9
-rwxr-xr-xtest/functional/wallet_importprunedfunds.py9
-rwxr-xr-xtest/functional/wallet_listsinceblock.py9
-rwxr-xr-xtest/functional/wallet_migration.py37
-rwxr-xr-xtest/functional/wallet_send.py8
-rwxr-xr-xtest/fuzz/test_runner.py22
-rw-r--r--test/sanitizer_suppressions/ubsan1
41 files changed, 188 insertions, 177 deletions
diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh
index 230288bc6c..76cde42161 100755
--- a/ci/test/01_base_install.sh
+++ b/ci/test/01_base_install.sh
@@ -42,7 +42,7 @@ if [ -n "$PIP_PACKAGES" ]; then
fi
if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then
- git clone --depth=1 https://github.com/llvm/llvm-project -b llvmorg-16.0.5 "${BASE_SCRATCH_DIR}"/msan/llvm-project
+ git clone --depth=1 https://github.com/llvm/llvm-project -b llvmorg-16.0.6 "${BASE_SCRATCH_DIR}"/msan/llvm-project
cmake -G Ninja -B "${BASE_SCRATCH_DIR}"/msan/clang_build/ -DLLVM_ENABLE_PROJECTS="clang" \
-DCMAKE_BUILD_TYPE=Release \
@@ -55,6 +55,7 @@ if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then
update-alternatives --install /usr/bin/clang++ clang++ "${BASE_SCRATCH_DIR}"/msan/clang_build/bin/clang++ 100
update-alternatives --install /usr/bin/clang clang "${BASE_SCRATCH_DIR}"/msan/clang_build/bin/clang 100
+ update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer "${BASE_SCRATCH_DIR}"/msan/clang_build/bin/llvm-symbolizer 100
cmake -G Ninja -B "${BASE_SCRATCH_DIR}"/msan/cxx_build/ -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' \
-DCMAKE_BUILD_TYPE=Release \
diff --git a/ci/test/06_script_b.sh b/ci/test/06_script_b.sh
index 1e086a9f13..0b10ebd44b 100755
--- a/ci/test/06_script_b.sh
+++ b/ci/test/06_script_b.sh
@@ -170,5 +170,5 @@ if [ "${RUN_TIDY}" = "true" ]; then
fi
if [ "$RUN_FUZZ_TESTS" = "true" ]; then
- bash -c "LD_LIBRARY_PATH=${DEPENDS_DIR}/${HOST}/lib test/fuzz/test_runner.py ${FUZZ_TESTS_CONFIG} $MAKEJOBS -l DEBUG ${DIR_FUZZ_IN}"
+ bash -c "LD_LIBRARY_PATH=${DEPENDS_DIR}/${HOST}/lib test/fuzz/test_runner.py ${FUZZ_TESTS_CONFIG} $MAKEJOBS -l DEBUG ${DIR_FUZZ_IN} --empty_min_time=60"
fi
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 9187f242eb..5761e8b321 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -115,7 +115,7 @@ bool WriteSettings(const fs::path& path,
{
SettingsValue out(SettingsValue::VOBJ);
for (const auto& value : values) {
- out.__pushKV(value.first, value.second);
+ out.pushKVEnd(value.first, value.second);
}
std::ofstream file;
file.open(path);
diff --git a/src/kernel/mempool_entry.h b/src/kernel/mempool_entry.h
index 969ddcd1ce..886e1e1b3a 100644
--- a/src/kernel/mempool_entry.h
+++ b/src/kernel/mempool_entry.h
@@ -57,7 +57,7 @@ struct CompareIteratorByHash {
* ("descendant" transactions).
*
* When a new entry is added to the mempool, we update the descendant state
- * (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for
+ * (m_count_with_descendants, nSizeWithDescendants, and nModFeesWithDescendants) for
* all ancestors of the newly added transaction.
*
*/
@@ -87,13 +87,13 @@ private:
// Information about descendants of this transaction that are in the
// mempool; if we remove this transaction we must remove all of these
// descendants as well.
- uint64_t nCountWithDescendants{1}; //!< number of descendant transactions
+ int64_t m_count_with_descendants{1}; //!< number of descendant transactions
// Using int64_t instead of int32_t to avoid signed integer overflow issues.
int64_t nSizeWithDescendants; //!< ... and size
CAmount nModFeesWithDescendants; //!< ... and total fees (all including us)
// Analogous statistics for ancestor transactions
- uint64_t nCountWithAncestors{1};
+ int64_t m_count_with_ancestors{1};
// Using int64_t instead of int32_t to avoid signed integer overflow issues.
int64_t nSizeWithAncestors;
CAmount nModFeesWithAncestors;
@@ -153,13 +153,13 @@ public:
lockPoints = lp;
}
- uint64_t GetCountWithDescendants() const { return nCountWithDescendants; }
+ uint64_t GetCountWithDescendants() const { return m_count_with_descendants; }
int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
bool GetSpendsCoinbase() const { return spendsCoinbase; }
- uint64_t GetCountWithAncestors() const { return nCountWithAncestors; }
+ uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; }
int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; }
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index edc0fb05d7..5f58eef1db 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -371,10 +371,10 @@ UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<s
}
if (!positional_args.empty()) {
- // Use __pushKV instead of pushKV to avoid overwriting an explicit
+ // Use pushKVEnd instead of pushKV to avoid overwriting an explicit
// "args" value with an implicit one. Let the RPC server handle the
// request as given.
- params.__pushKV("args", positional_args);
+ params.pushKVEnd("args", positional_args);
}
return params;
diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
index 89c403b6f5..11d2874961 100644
--- a/src/rpc/mempool.cpp
+++ b/src/rpc/mempool.cpp
@@ -351,8 +351,8 @@ UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempoo
entryToJSON(pool, info, e);
// Mempool has unique entries so there is no advantage in using
// UniValue::pushKV, which checks if the key already exists in O(N).
- // UniValue::__pushKV is used instead which currently is O(1).
- o.__pushKV(hash.ToString(), info);
+ // UniValue::pushKVEnd is used instead which currently is O(1).
+ o.pushKVEnd(hash.ToString(), info);
}
return o;
} else {
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index d39efcb245..daf751111f 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -437,7 +437,7 @@ static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, c
if (options.exists(fr->first)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter " + fr->first + " specified multiple times");
}
- options.__pushKV(fr->first, *fr->second);
+ options.pushKVEnd(fr->first, *fr->second);
argsIn.erase(fr);
}
continue;
diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h
index a0918bf463..b2076bea07 100644
--- a/src/support/allocators/secure.h
+++ b/src/support/allocators/secure.h
@@ -32,9 +32,9 @@ struct secure_allocator : public std::allocator<T> {
{
}
~secure_allocator() noexcept {}
- template <typename _Other>
+ template <typename Other>
struct rebind {
- typedef secure_allocator<_Other> other;
+ typedef secure_allocator<Other> other;
};
T* allocate(std::size_t n, const void* hint = nullptr)
diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h
index 795eea3bc0..2dc644c242 100644
--- a/src/support/allocators/zeroafterfree.h
+++ b/src/support/allocators/zeroafterfree.h
@@ -27,9 +27,9 @@ struct zero_after_free_allocator : public std::allocator<T> {
{
}
~zero_after_free_allocator() noexcept {}
- template <typename _Other>
+ template <typename Other>
struct rebind {
- typedef zero_after_free_allocator<_Other> other;
+ typedef zero_after_free_allocator<Other> other;
};
void deallocate(T* p, std::size_t n)
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index 7035c53d13..c561675d1a 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -101,7 +101,14 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction)
(void)AreInputsStandard(tx, coins_view_cache);
(void)IsWitnessStandard(tx, coins_view_cache);
- UniValue u(UniValue::VOBJ);
- TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u);
- TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u);
+ if (tx.GetTotalSize() < 250'000) { // Avoid high memory usage (with msan) due to json encoding
+ {
+ UniValue u{UniValue::VOBJ};
+ TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u);
+ }
+ {
+ UniValue u{UniValue::VOBJ};
+ TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u);
+ }
+ }
}
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index c24921bf9b..eb11df0497 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -35,7 +35,7 @@ inline std::ostream& operator<<(std::ostream& os, const common::SettingsValue& v
inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, common::SettingsValue>& kv)
{
common::SettingsValue out(common::SettingsValue::VOBJ);
- out.__pushKV(kv.first, kv.second);
+ out.pushKVEnd(kv.first, kv.second);
os << out.write();
return os;
}
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 1286eba035..845fbdb66e 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -370,8 +370,8 @@ void CTxMemPoolEntry::UpdateDescendantState(int32_t modifySize, CAmount modifyFe
nSizeWithDescendants += modifySize;
assert(nSizeWithDescendants > 0);
nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, modifyFee);
- nCountWithDescendants += uint64_t(modifyCount);
- assert(int64_t(nCountWithDescendants) > 0);
+ m_count_with_descendants += modifyCount;
+ assert(m_count_with_descendants > 0);
}
void CTxMemPoolEntry::UpdateAncestorState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
@@ -379,8 +379,8 @@ void CTxMemPoolEntry::UpdateAncestorState(int32_t modifySize, CAmount modifyFee,
nSizeWithAncestors += modifySize;
assert(nSizeWithAncestors > 0);
nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, modifyFee);
- nCountWithAncestors += uint64_t(modifyCount);
- assert(int64_t(nCountWithAncestors) > 0);
+ m_count_with_ancestors += modifyCount;
+ assert(m_count_with_ancestors > 0);
nSigOpCostWithAncestors += modifySigOps;
assert(int(nSigOpCostWithAncestors) >= 0);
}
diff --git a/src/txorphanage.cpp b/src/txorphanage.cpp
index 19f9fae998..af86baa8ac 100644
--- a/src/txorphanage.cpp
+++ b/src/txorphanage.cpp
@@ -55,10 +55,10 @@ bool TxOrphanage::AddTx(const CTransactionRef& tx, NodeId peer)
int TxOrphanage::EraseTx(const uint256& txid)
{
LOCK(m_mutex);
- return _EraseTx(txid);
+ return EraseTxNoLock(txid);
}
-int TxOrphanage::_EraseTx(const uint256& txid)
+int TxOrphanage::EraseTxNoLock(const uint256& txid)
{
AssertLockHeld(m_mutex);
std::map<uint256, OrphanTx>::iterator it = m_orphans.find(txid);
@@ -103,7 +103,7 @@ void TxOrphanage::EraseForPeer(NodeId peer)
std::map<uint256, OrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
if (maybeErase->second.fromPeer == peer)
{
- nErased += _EraseTx(maybeErase->second.tx->GetHash());
+ nErased += EraseTxNoLock(maybeErase->second.tx->GetHash());
}
}
if (nErased > 0) LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx from peer=%d\n", nErased, peer);
@@ -125,7 +125,7 @@ void TxOrphanage::LimitOrphans(unsigned int max_orphans)
{
std::map<uint256, OrphanTx>::iterator maybeErase = iter++;
if (maybeErase->second.nTimeExpire <= nNow) {
- nErased += _EraseTx(maybeErase->second.tx->GetHash());
+ nErased += EraseTxNoLock(maybeErase->second.tx->GetHash());
} else {
nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
}
@@ -139,7 +139,7 @@ void TxOrphanage::LimitOrphans(unsigned int max_orphans)
{
// Evict a random orphan:
size_t randompos = rng.randrange(m_orphan_list.size());
- _EraseTx(m_orphan_list[randompos]->first);
+ EraseTxNoLock(m_orphan_list[randompos]->first);
++nEvicted;
}
if (nEvicted > 0) LogPrint(BCLog::MEMPOOL, "orphanage overflow, removed %u tx\n", nEvicted);
@@ -231,7 +231,7 @@ void TxOrphanage::EraseForBlock(const CBlock& block)
if (vOrphanErase.size()) {
int nErased = 0;
for (const uint256& orphanHash : vOrphanErase) {
- nErased += _EraseTx(orphanHash);
+ nErased += EraseTxNoLock(orphanHash);
}
LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx included or conflicted by block\n", nErased);
}
diff --git a/src/txorphanage.h b/src/txorphanage.h
index 45276c6c98..a4705bf382 100644
--- a/src/txorphanage.h
+++ b/src/txorphanage.h
@@ -99,7 +99,7 @@ protected:
std::map<uint256, OrphanMap::iterator> m_wtxid_to_orphan_it GUARDED_BY(m_mutex);
/** Erase an orphan by txid */
- int _EraseTx(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex);
+ int EraseTxNoLock(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex);
};
#endif // BITCOIN_TXORPHANAGE_H
diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h
index 004135ef97..94f80f9c27 100644
--- a/src/univalue/include/univalue.h
+++ b/src/univalue/include/univalue.h
@@ -87,7 +87,7 @@ public:
template <class It>
void push_backV(It first, It last);
- void __pushKV(std::string key, UniValue val);
+ void pushKVEnd(std::string key, UniValue val);
void pushKV(std::string key, UniValue val);
void pushKVs(UniValue obj);
diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp
index c3d19caae0..656d2e8203 100644
--- a/src/univalue/lib/univalue.cpp
+++ b/src/univalue/lib/univalue.cpp
@@ -115,7 +115,7 @@ void UniValue::push_backV(const std::vector<UniValue>& vec)
values.insert(values.end(), vec.begin(), vec.end());
}
-void UniValue::__pushKV(std::string key, UniValue val)
+void UniValue::pushKVEnd(std::string key, UniValue val)
{
checkType(VOBJ);
@@ -131,7 +131,7 @@ void UniValue::pushKV(std::string key, UniValue val)
if (findKey(key, idx))
values[idx] = std::move(val);
else
- __pushKV(std::move(key), std::move(val));
+ pushKVEnd(std::move(key), std::move(val));
}
void UniValue::pushKVs(UniValue obj)
@@ -140,7 +140,7 @@ void UniValue::pushKVs(UniValue obj)
obj.checkType(VOBJ);
for (size_t i = 0; i < obj.keys.size(); i++)
- __pushKV(std::move(obj.keys.at(i)), std::move(obj.values.at(i)));
+ pushKVEnd(std::move(obj.keys.at(i)), std::move(obj.values.at(i)));
}
void UniValue::getObjMap(std::map<std::string,UniValue>& kv) const
diff --git a/src/univalue/test/object.cpp b/src/univalue/test/object.cpp
index 5fb973c67b..8b90448b36 100644
--- a/src/univalue/test/object.cpp
+++ b/src/univalue/test/object.cpp
@@ -86,7 +86,7 @@ void univalue_push_throw()
UniValue j;
BOOST_CHECK_THROW(j.push_back(1), std::runtime_error);
BOOST_CHECK_THROW(j.push_backV({1}), std::runtime_error);
- BOOST_CHECK_THROW(j.__pushKV("k", 1), std::runtime_error);
+ BOOST_CHECK_THROW(j.pushKVEnd("k", 1), std::runtime_error);
BOOST_CHECK_THROW(j.pushKV("k", 1), std::runtime_error);
BOOST_CHECK_THROW(j.pushKVs({}), std::runtime_error);
}
@@ -364,7 +364,7 @@ void univalue_object()
obj.setObject();
UniValue uv;
uv.setInt(42);
- obj.__pushKV("age", uv);
+ obj.pushKVEnd("age", uv);
BOOST_CHECK_EQUAL(obj.size(), 1);
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "42");
diff --git a/src/validation.cpp b/src/validation.cpp
index d9a0fce34f..542c1060a9 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2914,6 +2914,7 @@ CBlockIndex* Chainstate::FindMostWorkChain()
while (pindexTest != pindexFailed) {
if (fFailedChain) {
pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
+ m_blockman.m_dirty_blockindex.insert(pindexFailed);
} else if (fMissingData) {
// If we're missing data, then add back to m_blocks_unlinked,
// so that if the block arrives in the future we can try adding
diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp
index 0bd6a9670c..a8ef0a5731 100644
--- a/src/wallet/rpc/addresses.cpp
+++ b/src/wallet/rpc/addresses.cpp
@@ -677,11 +677,11 @@ RPCHelpMan getaddressesbylabel()
CHECK_NONFATAL(unique);
// UniValue::pushKV checks if the key exists in O(N)
// and since duplicate addresses are unexpected (checked with
- // std::set in O(log(N))), UniValue::__pushKV is used instead,
+ // std::set in O(log(N))), UniValue::pushKVEnd is used instead,
// which currently is O(1).
UniValue value(UniValue::VOBJ);
value.pushKV("purpose", _purpose ? PurposeToString(*_purpose) : "unknown");
- ret.__pushKV(address, value);
+ ret.pushKVEnd(address, value);
}
});
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 62f0f53b01..ba11933b91 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3856,16 +3856,19 @@ bool CWallet::MigrateToSQLite(bilingual_str& error)
// Close this database and delete the file
fs::path db_path = fs::PathFromString(m_database->Filename());
- fs::path db_dir = db_path.parent_path();
m_database->Close();
fs::remove(db_path);
+ // Generate the path for the location of the migrated wallet
+ // Wallets that are plain files rather than wallet directories will be migrated to be wallet directories.
+ const fs::path wallet_path = fsbridge::AbsPathJoin(GetWalletDir(), fs::PathFromString(m_name));
+
// Make new DB
DatabaseOptions opts;
opts.require_create = true;
opts.require_format = DatabaseFormat::SQLITE;
DatabaseStatus db_status;
- std::unique_ptr<WalletDatabase> new_db = MakeDatabase(db_dir, opts, db_status, error);
+ std::unique_ptr<WalletDatabase> new_db = MakeDatabase(wallet_path, opts, db_status, error);
assert(new_db); // This is to prevent doing anything further with this wallet. The original file was deleted, but a backup exists.
m_database.reset();
m_database = std::move(new_db);
diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py
index 36ee79dab9..613d2eab14 100755
--- a/test/functional/feature_assumevalid.py
+++ b/test/functional/feature_assumevalid.py
@@ -35,7 +35,6 @@ from test_framework.blocktools import (
create_block,
create_coinbase,
)
-from test_framework.key import ECKey
from test_framework.messages import (
CBlockHeader,
COutPoint,
@@ -46,9 +45,13 @@ from test_framework.messages import (
msg_headers,
)
from test_framework.p2p import P2PInterface
-from test_framework.script import (CScript, OP_TRUE)
+from test_framework.script import (
+ CScript,
+ OP_TRUE,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
+from test_framework.wallet_util import generate_keypair
class BaseNode(P2PInterface):
@@ -90,9 +93,7 @@ class AssumeValidTest(BitcoinTestFramework):
self.blocks = []
# Get a pubkey for the coinbase TXO
- coinbase_key = ECKey()
- coinbase_key.generate()
- coinbase_pubkey = coinbase_key.get_pubkey().get_bytes()
+ _, coinbase_pubkey = generate_keypair()
# Create the first block with a coinbase output to our key
height = 1
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 1080e77c40..765db97445 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -14,7 +14,6 @@ from test_framework.blocktools import (
get_legacy_sigopcount_block,
MAX_BLOCK_SIGOPS,
)
-from test_framework.key import ECKey
from test_framework.messages import (
CBlock,
COIN,
@@ -55,6 +54,7 @@ from test_framework.util import (
assert_equal,
assert_greater_than,
)
+from test_framework.wallet_util import generate_keypair
from data import invalid_txs
@@ -98,9 +98,7 @@ class FullBlockTest(BitcoinTestFramework):
self.bootstrap_p2p() # Add one p2p connection to the node
self.block_heights = {}
- self.coinbase_key = ECKey()
- self.coinbase_key.generate()
- self.coinbase_pubkey = self.coinbase_key.get_pubkey().get_bytes()
+ self.coinbase_key, self.coinbase_pubkey = generate_keypair()
self.tip = None
self.blocks = {}
self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16)
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index c95657dbbb..7b2a29bdb4 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -35,8 +35,7 @@ from test_framework.util import (
assert_raises_rpc_error,
)
from test_framework.wallet import getnewdestination
-from test_framework.key import ECKey
-from test_framework.wallet_util import bytes_to_wif
+from test_framework.wallet_util import generate_keypair
NULLDUMMY_ERROR = "non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)"
@@ -71,12 +70,9 @@ class NULLDUMMYTest(BitcoinTestFramework):
return tx_from_hex(signedtx["hex"])
def run_test(self):
- eckey = ECKey()
- eckey.generate()
- self.privkey = bytes_to_wif(eckey.get_bytes())
- self.pubkey = eckey.get_pubkey().get_bytes().hex()
- cms = self.nodes[0].createmultisig(1, [self.pubkey])
- wms = self.nodes[0].createmultisig(1, [self.pubkey], 'p2sh-segwit')
+ self.privkey, self.pubkey = generate_keypair(wif=True)
+ cms = self.nodes[0].createmultisig(1, [self.pubkey.hex()])
+ wms = self.nodes[0].createmultisig(1, [self.pubkey.hex()], 'p2sh-segwit')
self.ms_address = cms["address"]
ms_unlock_details = {"scriptPubKey": address_to_scriptpubkey(self.ms_address).hex(),
"redeemScript": cms["redeemScript"]}
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index 8be2040d91..b37bfd28ae 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -97,6 +97,7 @@ from test_framework.util import (
assert_equal,
random_bytes,
)
+from test_framework.wallet_util import generate_keypair
from test_framework.key import (
generate_privkey,
compute_xonly_pubkey,
@@ -1186,11 +1187,8 @@ def spenders_taproot_active():
# Also add a few legacy spends into the mix, so that transactions which combine taproot and pre-taproot spends get tested too.
for compressed in [False, True]:
- eckey1 = ECKey()
- eckey1.set(generate_privkey(), compressed)
- pubkey1 = eckey1.get_pubkey().get_bytes()
- eckey2 = ECKey()
- eckey2.set(generate_privkey(), compressed)
+ eckey1, pubkey1 = generate_keypair(compressed=compressed)
+ eckey2, _ = generate_keypair(compressed=compressed)
for p2sh in [False, True]:
for witv0 in [False, True]:
for hashtype in VALID_SIGHASHES_ECDSA + [random.randrange(0x04, 0x80), random.randrange(0x84, 0x100)]:
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index 737a8d0a2e..8f3aec96a7 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -9,7 +9,6 @@ from decimal import Decimal
import math
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.key import ECKey
from test_framework.messages import (
MAX_BIP125_RBF_SEQUENCE,
COIN,
@@ -44,6 +43,7 @@ from test_framework.util import (
assert_raises_rpc_error,
)
from test_framework.wallet import MiniWallet
+from test_framework.wallet_util import generate_keypair
class MempoolAcceptanceTest(BitcoinTestFramework):
@@ -283,9 +283,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
rawtxs=[tx.serialize().hex()],
)
tx = tx_from_hex(raw_tx_reference)
- key = ECKey()
- key.generate()
- pubkey = key.get_pubkey().get_bytes()
+ _, pubkey = generate_keypair()
tx.vout[0].scriptPubKey = keys_to_multisig_script([pubkey] * 3, k=2) # Some bare multisig script (2-of-3)
self.check_mempool_result(
result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bare-multisig'}],
diff --git a/test/functional/mempool_dust.py b/test/functional/mempool_dust.py
index 41a26e82da..f4e385a112 100755
--- a/test/functional/mempool_dust.py
+++ b/test/functional/mempool_dust.py
@@ -5,7 +5,6 @@
"""Test dust limit mempool policy (`-dustrelayfee` parameter)"""
from decimal import Decimal
-from test_framework.key import ECKey
from test_framework.messages import (
COIN,
CTxOut,
@@ -32,6 +31,7 @@ from test_framework.util import (
get_fee,
)
from test_framework.wallet import MiniWallet
+from test_framework.wallet_util import generate_keypair
DUST_RELAY_TX_FEE = 3000 # default setting [sat/kvB]
@@ -74,11 +74,8 @@ class DustRelayFeeTest(BitcoinTestFramework):
self.wallet = MiniWallet(self.nodes[0])
# prepare output scripts of each standard type
- key = ECKey()
- key.generate(compressed=False)
- uncompressed_pubkey = key.get_pubkey().get_bytes()
- key.generate(compressed=True)
- pubkey = key.get_pubkey().get_bytes()
+ _, uncompressed_pubkey = generate_keypair(compressed=False)
+ _, pubkey = generate_keypair(compressed=True)
output_scripts = (
(key_to_p2pk_script(uncompressed_pubkey), "P2PK (uncompressed)"),
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index b0900e49b8..bfae190c66 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -14,7 +14,6 @@ from test_framework.blocktools import (
create_block,
create_coinbase,
)
-from test_framework.key import ECKey
from test_framework.messages import (
MAX_BIP125_RBF_SEQUENCE,
CBlockHeader,
@@ -89,6 +88,7 @@ from test_framework.util import (
assert_raises_rpc_error,
)
from test_framework.wallet import MiniWallet
+from test_framework.wallet_util import generate_keypair
MAX_SIGOP_COST = 80000
@@ -1448,9 +1448,7 @@ class SegWitTest(BitcoinTestFramework):
# Segwit transactions using uncompressed pubkeys are not accepted
# under default policy, but should still pass consensus.
- key = ECKey()
- key.generate(False)
- pubkey = key.get_pubkey().get_bytes()
+ key, pubkey = generate_keypair(compressed=False)
assert_equal(len(pubkey), 65) # This should be an uncompressed pubkey
utxo = self.utxo.pop(0)
@@ -1544,11 +1542,7 @@ class SegWitTest(BitcoinTestFramework):
@subtest
def test_signature_version_1(self):
-
- key = ECKey()
- key.generate()
- pubkey = key.get_pubkey().get_bytes()
-
+ key, pubkey = generate_keypair()
witness_script = key_to_p2pk_script(pubkey)
script_pubkey = script_to_p2wsh_script(witness_script)
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index 279fb01a57..34e60d70f0 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -12,13 +12,13 @@ from test_framework.address import address_to_scriptpubkey
from test_framework.blocktools import COINBASE_MATURITY
from test_framework.authproxy import JSONRPCException
from test_framework.descriptors import descsum_create, drop_origins
-from test_framework.key import ECPubKey, ECKey
+from test_framework.key import ECPubKey
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_raises_rpc_error,
assert_equal,
)
-from test_framework.wallet_util import bytes_to_wif
+from test_framework.wallet_util import generate_keypair
from test_framework.wallet import (
MiniWallet,
getnewdestination,
@@ -38,10 +38,9 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
self.priv = []
node0, node1, node2 = self.nodes
for _ in range(self.nkeys):
- k = ECKey()
- k.generate()
- self.pub.append(k.get_pubkey().get_bytes().hex())
- self.priv.append(bytes_to_wif(k.get_bytes(), k.is_compressed))
+ privkey, pubkey = generate_keypair(wif=True)
+ self.pub.append(pubkey.hex())
+ self.priv.append(privkey)
if self.is_bdb_compiled():
self.final = node2.getnewaddress()
else:
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index e2fb4673ea..c4ed4da0f2 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -8,7 +8,7 @@ from decimal import Decimal
from itertools import product
from test_framework.descriptors import descsum_create
-from test_framework.key import ECKey, H_POINT
+from test_framework.key import H_POINT
from test_framework.messages import (
COutPoint,
CTransaction,
@@ -43,8 +43,8 @@ from test_framework.util import (
random_bytes,
)
from test_framework.wallet_util import (
- bytes_to_wif,
- get_generate_key
+ generate_keypair,
+ get_generate_key,
)
import json
@@ -710,9 +710,7 @@ class PSBTTest(BitcoinTestFramework):
self.log.info("Test that we can fund psbts with external inputs specified")
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
+ privkey, _ = generate_keypair(wif=True)
self.nodes[1].createwallet("extfund")
wallet = self.nodes[1].get_wallet_rpc("extfund")
@@ -825,11 +823,9 @@ class PSBTTest(BitcoinTestFramework):
self.nodes[1].createwallet(wallet_name="scriptwatchonly", disable_private_keys=True)
watchonly = self.nodes[1].get_wallet_rpc("scriptwatchonly")
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
+ privkey, pubkey = generate_keypair(wif=True)
- desc = descsum_create("wsh(pkh({}))".format(eckey.get_pubkey().get_bytes().hex()))
+ desc = descsum_create("wsh(pkh({}))".format(pubkey.hex()))
if self.options.descriptors:
res = watchonly.importdescriptors([{"desc": desc, "timestamp": "now"}])
else:
@@ -846,11 +842,9 @@ class PSBTTest(BitcoinTestFramework):
# Same test but for taproot
if self.options.descriptors:
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
+ privkey, pubkey = generate_keypair(wif=True)
- desc = descsum_create("tr({},pk({}))".format(H_POINT, eckey.get_pubkey().get_bytes().hex()))
+ desc = descsum_create("tr({},pk({}))".format(H_POINT, pubkey.hex()))
res = watchonly.importdescriptors([{"desc": desc, "timestamp": "now"}])
assert res[0]["success"]
addr = self.nodes[0].deriveaddresses(desc)[0]
diff --git a/test/functional/rpc_signrawtransactionwithkey.py b/test/functional/rpc_signrawtransactionwithkey.py
index 580f63063d..ac7a86704f 100755
--- a/test/functional/rpc_signrawtransactionwithkey.py
+++ b/test/functional/rpc_signrawtransactionwithkey.py
@@ -11,7 +11,6 @@ from test_framework.address import (
address_to_scriptpubkey,
script_to_p2sh,
)
-from test_framework.key import ECKey
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
@@ -23,16 +22,16 @@ from test_framework.script_util import (
script_to_p2sh_p2wsh_script,
script_to_p2wsh_script,
)
+from test_framework.wallet import (
+ getnewdestination,
+)
from test_framework.wallet_util import (
- bytes_to_wif,
+ generate_keypair,
)
from decimal import (
Decimal,
)
-from test_framework.wallet import (
- getnewdestination,
-)
class SignRawTransactionWithKeyTest(BitcoinTestFramework):
@@ -80,11 +79,8 @@ class SignRawTransactionWithKeyTest(BitcoinTestFramework):
def witness_script_test(self):
self.log.info("Test signing transaction to P2SH-P2WSH addresses without wallet")
# Create a new P2SH-P2WSH 1-of-1 multisig address:
- eckey = ECKey()
- eckey.generate()
- embedded_privkey = bytes_to_wif(eckey.get_bytes())
- embedded_pubkey = eckey.get_pubkey().get_bytes().hex()
- p2sh_p2wsh_address = self.nodes[1].createmultisig(1, [embedded_pubkey], "p2sh-segwit")
+ embedded_privkey, embedded_pubkey = generate_keypair(wif=True)
+ p2sh_p2wsh_address = self.nodes[1].createmultisig(1, [embedded_pubkey.hex()], "p2sh-segwit")
# send transaction to P2SH-P2WSH 1-of-1 multisig address
self.block_hash = self.generate(self.nodes[0], COINBASE_MATURITY + 1)
self.blk_idx = 0
@@ -109,10 +105,7 @@ class SignRawTransactionWithKeyTest(BitcoinTestFramework):
def verify_txn_with_witness_script(self, tx_type):
self.log.info("Test with a {} script as the witnessScript".format(tx_type))
- eckey = ECKey()
- eckey.generate()
- embedded_privkey = bytes_to_wif(eckey.get_bytes())
- embedded_pubkey = eckey.get_pubkey().get_bytes().hex()
+ embedded_privkey, embedded_pubkey = generate_keypair(wif=True)
witness_script = {
'P2PKH': key_to_p2pkh_script(embedded_pubkey).hex(),
'P2PK': key_to_p2pk_script(embedded_pubkey).hex()
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index 1d546e12bd..271095ea21 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -20,6 +20,7 @@ from test_framework.address import (
key_to_p2wpkh,
output_key_to_p2tr,
)
+from test_framework.blocktools import COINBASE_MATURITY
from test_framework.descriptors import descsum_create
from test_framework.key import (
ECKey,
@@ -53,7 +54,7 @@ from test_framework.util import (
assert_equal,
assert_greater_than_or_equal,
)
-from test_framework.blocktools import COINBASE_MATURITY
+from test_framework.wallet_util import generate_keypair
DEFAULT_FEE = Decimal("0.0001")
@@ -395,9 +396,7 @@ def getnewdestination(address_type='bech32m'):
'legacy', 'p2sh-segwit', 'bech32' and 'bech32m'. Can be used when a random
destination is needed, but no compiled wallet is available (e.g. as
replacement to the getnewaddress/getaddressinfo RPCs)."""
- key = ECKey()
- key.generate()
- pubkey = key.get_pubkey().get_bytes()
+ key, pubkey = generate_keypair()
if address_type == 'legacy':
scriptpubkey = key_to_p2pkh_script(pubkey)
address = key_to_p2pkh(pubkey)
diff --git a/test/functional/test_framework/wallet_util.py b/test/functional/test_framework/wallet_util.py
index 410d85cd8c..319f120297 100755
--- a/test/functional/test_framework/wallet_util.py
+++ b/test/functional/test_framework/wallet_util.py
@@ -63,12 +63,9 @@ def get_generate_key():
"""Generate a fresh key
Returns a named tuple of privkey, pubkey and all address and scripts."""
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
- pubkey = eckey.get_pubkey().get_bytes().hex()
+ privkey, pubkey = generate_keypair(wif=True)
return Key(privkey=privkey,
- pubkey=pubkey,
+ pubkey=pubkey.hex(),
p2pkh_script=key_to_p2pkh_script(pubkey).hex(),
p2pkh_addr=key_to_p2pkh(pubkey),
p2wpkh_script=key_to_p2wpkh_script(pubkey).hex(),
@@ -114,8 +111,14 @@ def bytes_to_wif(b, compressed=True):
b += b'\x01'
return byte_to_base58(b, 239)
-def generate_wif_key():
- # Makes a WIF privkey for imports
- k = ECKey()
- k.generate()
- return bytes_to_wif(k.get_bytes(), k.is_compressed)
+def generate_keypair(compressed=True, wif=False):
+ """Generate a new random keypair and return the corresponding ECKey /
+ bytes objects. The private key can also be provided as WIF (wallet
+ import format) string instead, which is often useful for wallet RPC
+ interaction."""
+ privkey = ECKey()
+ privkey.generate(compressed)
+ pubkey = privkey.get_pubkey().get_bytes()
+ if wif:
+ privkey = bytes_to_wif(privkey.get_bytes(), compressed)
+ return privkey, pubkey
diff --git a/test/functional/wallet_blank.py b/test/functional/wallet_blank.py
index eda3fda35b..4836eba3b2 100755
--- a/test/functional/wallet_blank.py
+++ b/test/functional/wallet_blank.py
@@ -10,11 +10,10 @@ from test_framework.address import (
ADDRESS_BCRT1_UNSPENDABLE,
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR,
)
-from test_framework.key import ECKey
from test_framework.util import (
assert_equal,
)
-from test_framework.wallet_util import bytes_to_wif
+from test_framework.wallet_util import generate_keypair
class WalletBlankTest(BitcoinTestFramework):
@@ -50,10 +49,8 @@ class WalletBlankTest(BitcoinTestFramework):
assert_equal(info["descriptors"], False)
assert_equal(info["blank"], True)
- eckey = ECKey()
- eckey.generate(compressed=comp)
-
- wallet.importpubkey(eckey.get_pubkey().get_bytes().hex())
+ _, pubkey = generate_keypair(compressed=comp)
+ wallet.importpubkey(pubkey.hex())
assert_equal(wallet.getwalletinfo()["blank"], False)
def test_importprivkey(self):
@@ -67,10 +64,7 @@ class WalletBlankTest(BitcoinTestFramework):
assert_equal(info["descriptors"], False)
assert_equal(info["blank"], True)
- eckey = ECKey()
- eckey.generate(compressed=comp)
- wif = bytes_to_wif(eckey.get_bytes(), eckey.is_compressed)
-
+ wif, _ = generate_keypair(compressed=comp, wif=True)
wallet.importprivkey(wif)
assert_equal(wallet.getwalletinfo()["blank"], False)
diff --git a/test/functional/wallet_createwallet.py b/test/functional/wallet_createwallet.py
index a4e6f96cce..75b507c387 100755
--- a/test/functional/wallet_createwallet.py
+++ b/test/functional/wallet_createwallet.py
@@ -7,13 +7,13 @@
from test_framework.address import key_to_p2wpkh
from test_framework.descriptors import descsum_create
-from test_framework.key import ECKey
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
)
-from test_framework.wallet_util import bytes_to_wif, generate_wif_key
+from test_framework.wallet_util import generate_keypair
+
EMPTY_PASSPHRASE_MSG = "Empty string given as passphrase, wallet will not be encrypted."
LEGACY_WALLET_MSG = "Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future."
@@ -50,14 +50,12 @@ class CreateWalletTest(BitcoinTestFramework):
w1.importpubkey(w0.getaddressinfo(address1)['pubkey'])
self.log.info('Test that private keys cannot be imported')
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
+ privkey, pubkey = generate_keypair(wif=True)
assert_raises_rpc_error(-4, 'Cannot import private keys to a wallet with private keys disabled', w1.importprivkey, privkey)
if self.options.descriptors:
result = w1.importdescriptors([{'desc': descsum_create('wpkh(' + privkey + ')'), 'timestamp': 'now'}])
else:
- result = w1.importmulti([{'scriptPubKey': {'address': key_to_p2wpkh(eckey.get_pubkey().get_bytes())}, 'timestamp': 'now', 'keys': [privkey]}])
+ result = w1.importmulti([{'scriptPubKey': {'address': key_to_p2wpkh(pubkey)}, 'timestamp': 'now', 'keys': [privkey]}])
assert not result[0]['success']
assert 'warnings' not in result[0]
assert_equal(result[0]['error']['code'], -4)
@@ -77,7 +75,7 @@ class CreateWalletTest(BitcoinTestFramework):
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w3.getnewaddress)
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w3.getrawchangeaddress)
# Import private key
- w3.importprivkey(generate_wif_key())
+ w3.importprivkey(generate_keypair(wif=True)[0])
# Imported private keys are currently ignored by the keypool
assert_equal(w3.getwalletinfo()['keypoolsize'], 0)
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w3.getnewaddress)
diff --git a/test/functional/wallet_fundrawtransaction.py b/test/functional/wallet_fundrawtransaction.py
index c88e0b3f6e..46706d6ad2 100755
--- a/test/functional/wallet_fundrawtransaction.py
+++ b/test/functional/wallet_fundrawtransaction.py
@@ -10,7 +10,6 @@ from itertools import product
from math import ceil
from test_framework.descriptors import descsum_create
-from test_framework.key import ECKey
from test_framework.messages import (
COIN,
)
@@ -25,7 +24,7 @@ from test_framework.util import (
count_bytes,
find_vout_for_address,
)
-from test_framework.wallet_util import bytes_to_wif
+from test_framework.wallet_util import generate_keypair
ERR_NOT_ENOUGH_PRESET_INPUTS = "The preselected coins total amount does not cover the transaction target. " \
"Please allow other inputs to be automatically selected or include more coins manually"
@@ -999,11 +998,7 @@ class RawTransactionsTest(BitcoinTestFramework):
def test_external_inputs(self):
self.log.info("Test funding with external inputs")
-
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
-
+ privkey, _ = generate_keypair(wif=True)
self.nodes[2].createwallet("extfund")
wallet = self.nodes[2].get_wallet_rpc("extfund")
diff --git a/test/functional/wallet_importprunedfunds.py b/test/functional/wallet_importprunedfunds.py
index 77b407579f..5fe7c4b591 100755
--- a/test/functional/wallet_importprunedfunds.py
+++ b/test/functional/wallet_importprunedfunds.py
@@ -7,7 +7,6 @@ from decimal import Decimal
from test_framework.address import key_to_p2wpkh
from test_framework.blocktools import COINBASE_MATURITY
-from test_framework.key import ECKey
from test_framework.messages import (
CMerkleBlock,
from_hex,
@@ -17,7 +16,7 @@ from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
)
-from test_framework.wallet_util import bytes_to_wif
+from test_framework.wallet_util import generate_keypair
class ImportPrunedFundsTest(BitcoinTestFramework):
@@ -40,10 +39,8 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
# pubkey
address2 = self.nodes[0].getnewaddress()
# privkey
- eckey = ECKey()
- eckey.generate()
- address3_privkey = bytes_to_wif(eckey.get_bytes())
- address3 = key_to_p2wpkh(eckey.get_pubkey().get_bytes())
+ address3_privkey, address3_pubkey = generate_keypair(wif=True)
+ address3 = key_to_p2wpkh(address3_pubkey)
self.nodes[0].importprivkey(address3_privkey)
# Check only one address
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
index bfca344fd1..a19a3ac2cb 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -7,7 +7,6 @@
from test_framework.address import key_to_p2wpkh
from test_framework.blocktools import COINBASE_MATURITY
from test_framework.descriptors import descsum_create
-from test_framework.key import ECKey
from test_framework.test_framework import BitcoinTestFramework
from test_framework.messages import MAX_BIP125_RBF_SEQUENCE
from test_framework.util import (
@@ -15,7 +14,7 @@ from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
)
-from test_framework.wallet_util import bytes_to_wif
+from test_framework.wallet_util import generate_keypair
from decimal import Decimal
@@ -202,10 +201,8 @@ class ListSinceBlockTest(BitcoinTestFramework):
self.sync_all()
# share utxo between nodes[1] and nodes[2]
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
- address = key_to_p2wpkh(eckey.get_pubkey().get_bytes())
+ privkey, pubkey = generate_keypair(wif=True)
+ address = key_to_p2wpkh(pubkey)
self.nodes[2].sendtoaddress(address, 10)
self.generate(self.nodes[2], 6)
self.nodes[2].importprivkey(privkey)
diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py
index c6c2af10b1..320f5dd9df 100755
--- a/test/functional/wallet_migration.py
+++ b/test/functional/wallet_migration.py
@@ -6,6 +6,7 @@
import os
import random
+import shutil
from test_framework.descriptors import descsum_create
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
@@ -470,6 +471,40 @@ class WalletMigrationTest(BitcoinTestFramework):
assert_equal(bals, wallet.getbalances())
+ def test_default_wallet(self):
+ self.log.info("Test migration of the wallet named as the empty string")
+ wallet = self.create_legacy_wallet("")
+
+ wallet.migratewallet()
+ info = wallet.getwalletinfo()
+ assert_equal(info["descriptors"], True)
+ assert_equal(info["format"], "sqlite")
+
+ def test_direct_file(self):
+ self.log.info("Test migration of a wallet that is not in a wallet directory")
+ wallet = self.create_legacy_wallet("plainfile")
+ wallet.unloadwallet()
+
+ wallets_dir = os.path.join(self.nodes[0].datadir, "regtest", "wallets")
+ wallet_path = os.path.join(wallets_dir, "plainfile")
+ wallet_dat_path = os.path.join(wallet_path, "wallet.dat")
+ shutil.copyfile(wallet_dat_path, os.path.join(wallets_dir, "plainfile.bak"))
+ shutil.rmtree(wallet_path)
+ shutil.move(os.path.join(wallets_dir, "plainfile.bak"), wallet_path)
+
+ self.nodes[0].loadwallet("plainfile")
+ info = wallet.getwalletinfo()
+ assert_equal(info["descriptors"], False)
+ assert_equal(info["format"], "bdb")
+
+ wallet.migratewallet()
+ info = wallet.getwalletinfo()
+ assert_equal(info["descriptors"], True)
+ assert_equal(info["format"], "sqlite")
+
+ assert os.path.isdir(wallet_path)
+ assert os.path.isfile(wallet_dat_path)
+
def run_test(self):
self.generate(self.nodes[0], 101)
@@ -482,6 +517,8 @@ class WalletMigrationTest(BitcoinTestFramework):
self.test_encrypted()
self.test_unloaded()
self.test_unloaded_by_path()
+ self.test_default_wallet()
+ self.test_direct_file()
if __name__ == '__main__':
WalletMigrationTest().main()
diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py
index ac3ec06eec..d7bb6ab1e7 100755
--- a/test/functional/wallet_send.py
+++ b/test/functional/wallet_send.py
@@ -9,7 +9,6 @@ from itertools import product
from test_framework.authproxy import JSONRPCException
from test_framework.descriptors import descsum_create
-from test_framework.key import ECKey
from test_framework.messages import (
ser_compact_size,
WITNESS_SCALE_FACTOR,
@@ -22,7 +21,8 @@ from test_framework.util import (
assert_raises_rpc_error,
count_bytes,
)
-from test_framework.wallet_util import bytes_to_wif
+from test_framework.wallet_util import generate_keypair
+
class WalletSendTest(BitcoinTestFramework):
def add_options(self, parser):
@@ -500,9 +500,7 @@ class WalletSendTest(BitcoinTestFramework):
assert res["complete"]
self.log.info("External outputs")
- eckey = ECKey()
- eckey.generate()
- privkey = bytes_to_wif(eckey.get_bytes())
+ privkey, _ = generate_keypair(wif=True)
self.nodes[1].createwallet("extsend")
ext_wallet = self.nodes[1].get_wallet_rpc("extsend")
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index af21e7b956..d953f48584 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -6,6 +6,7 @@
"""
from concurrent.futures import ThreadPoolExecutor, as_completed
+from pathlib import Path
import argparse
import configparser
import logging
@@ -42,6 +43,11 @@ def main():
help='If true, run fuzzing binaries under the valgrind memory error detector',
)
parser.add_argument(
+ "--empty_min_time",
+ type=int,
+ help="If set, run at least this long, if the existing fuzz inputs directory is empty.",
+ )
+ parser.add_argument(
'-x',
'--exclude',
help="A comma-separated list of targets to exclude",
@@ -76,6 +82,7 @@ def main():
)
args = parser.parse_args()
+ args.corpus_dir = Path(args.corpus_dir)
# Set up logging
logging.basicConfig(
@@ -180,6 +187,7 @@ def main():
src_dir=config['environment']['SRCDIR'],
build_dir=config["environment"]["BUILDDIR"],
use_valgrind=args.valgrind,
+ empty_min_time=args.empty_min_time,
)
@@ -251,16 +259,22 @@ def merge_inputs(*, fuzz_pool, corpus, test_list, src_dir, build_dir, merge_dir)
future.result()
-def run_once(*, fuzz_pool, corpus, test_list, src_dir, build_dir, use_valgrind):
+def run_once(*, fuzz_pool, corpus, test_list, src_dir, build_dir, use_valgrind, empty_min_time):
jobs = []
for t in test_list:
- corpus_path = os.path.join(corpus, t)
+ corpus_path = corpus / t
os.makedirs(corpus_path, exist_ok=True)
args = [
os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
- '-runs=1',
- corpus_path,
]
+ empty_dir = not any(corpus_path.iterdir())
+ if empty_min_time and empty_dir:
+ args += [f"-max_total_time={empty_min_time}"]
+ else:
+ args += [
+ "-runs=1",
+ corpus_path,
+ ]
if use_valgrind:
args = ['valgrind', '--quiet', '--error-exitcode=1'] + args
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index ae70fb49d4..8808a83e32 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -46,7 +46,6 @@ unsigned-integer-overflow:hash.cpp
unsigned-integer-overflow:policy/fees.cpp
unsigned-integer-overflow:prevector.h
unsigned-integer-overflow:script/interpreter.cpp
-unsigned-integer-overflow:txmempool.cpp
unsigned-integer-overflow:xoroshiro128plusplus.h
implicit-integer-sign-change:compat/stdin.cpp
implicit-integer-sign-change:compressor.h