wallet, refactor: Convert uint256 to Txid in wallet

Switch all instances of transactions from uint256 to Txid in the
wallet and relevant tests. Also remove the added implicit conversion
line in transaction_identifier.h
This commit is contained in:
marcofleon 2025-03-28 17:45:13 +00:00
parent ff88abdaa7
commit 641165fdd1
19 changed files with 102 additions and 104 deletions

View file

@ -75,7 +75,7 @@ void ConfirmSend(QString* text = nullptr, QMessageBox::StandardButton confirm_ty
}
//! Send coins to address and return txid.
uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDestination& address, CAmount amount, bool rbf,
Txid SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDestination& address, CAmount amount, bool rbf,
QMessageBox::StandardButton confirm_type = QMessageBox::Yes)
{
QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
@ -86,8 +86,8 @@ uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDe
->findChild<QFrame*>("frameFeeSelection")
->findChild<QCheckBox*>("optInRBF")
->setCheckState(rbf ? Qt::Checked : Qt::Unchecked);
uint256 txid;
boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](const uint256& hash, ChangeType status) {
Txid txid;
boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](const Txid& hash, ChangeType status) {
if (status == CT_NEW) txid = hash;
}));
ConfirmSend(/*text=*/nullptr, confirm_type);
@ -97,7 +97,7 @@ uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDe
}
//! Find index of txid in transaction list.
QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid)
QModelIndex FindTx(const QAbstractItemModel& model, const Txid& txid)
{
QString hash = QString::fromStdString(txid.ToString());
int rows = model.rowCount({});
@ -111,7 +111,7 @@ QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid)
}
//! Invoke bumpfee on txid and check results.
void BumpFee(TransactionView& view, const uint256& txid, bool expectDisabled, std::string expectError, bool cancel)
void BumpFee(TransactionView& view, const Txid& txid, bool expectDisabled, std::string expectError, bool cancel)
{
QTableView* table = view.findChild<QTableView*>("transactionView");
QModelIndex index = FindTx(*table->selectionModel()->model(), txid);
@ -292,8 +292,8 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
// Send two transactions, and verify they are added to transaction list.
TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
QCOMPARE(transactionTableModel->rowCount({}), 105);
uint256 txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false);
uint256 txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true);
Txid txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false);
Txid txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true);
// Transaction table model updates on a QueuedConnection, so process events to ensure it's updated.
qApp->processEvents();
QCOMPARE(transactionTableModel->rowCount({}), 107);

View file

@ -65,10 +65,6 @@ public:
* to using the Txid and Wtxid types. Until then it makes for a smoother
* transition to allow this conversion. */
operator const uint256&() const LIFETIMEBOUND { return m_wrapped; }
// TODO: This should never go into master. It's only used for intermediate
// commits so that each conceptual chunk can be built.
operator uint256&() LIFETIMEBOUND { return m_wrapped; }
};
/** Txid commits to all transaction fields except the witness. */

View file

@ -151,7 +151,7 @@ static CFeeRate EstimateFeeRate(const CWallet& wallet, const CWalletTx& wtx, con
namespace feebumper {
bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid)
bool TransactionCanBeBumped(const CWallet& wallet, const Txid& txid)
{
LOCK(wallet.cs_wallet);
const CWalletTx* wtx = wallet.GetWalletTx(txid);
@ -162,7 +162,7 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid)
return res == feebumper::Result::OK;
}
Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<bilingual_str>& errors,
Result CreateRateBumpTransaction(CWallet& wallet, const Txid& txid, const CCoinControl& coin_control, std::vector<bilingual_str>& errors,
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx, bool require_mine, const std::vector<CTxOut>& outputs, std::optional<uint32_t> original_change_index)
{
// For now, cannot specify both new outputs to use and an output index to send change
@ -353,7 +353,7 @@ bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx) {
}
}
Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<bilingual_str>& errors, uint256& bumped_txid)
Result CommitTransaction(CWallet& wallet, const Txid& txid, CMutableTransaction&& mtx, std::vector<bilingual_str>& errors, Txid& bumped_txid)
{
LOCK(wallet.cs_wallet);
if (!errors.empty()) {

View file

@ -31,7 +31,7 @@ enum class Result
};
//! Return whether transaction can be bumped.
bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid);
bool TransactionCanBeBumped(const CWallet& wallet, const Txid& txid);
/** Create bumpfee transaction based on feerate estimates.
*
@ -47,7 +47,7 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid);
* @param[in] original_change_index The position of the change output to deduct the fee from in the transaction being bumped
*/
Result CreateRateBumpTransaction(CWallet& wallet,
const uint256& txid,
const Txid& txid,
const CCoinControl& coin_control,
std::vector<bilingual_str>& errors,
CAmount& old_fee,
@ -67,10 +67,10 @@ bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx);
//! but sets errors if the tx could not be added to the mempool (will try later)
//! or if the old transaction could not be marked as replaced.
Result CommitTransaction(CWallet& wallet,
const uint256& txid,
const Txid& txid,
CMutableTransaction&& mtx,
std::vector<bilingual_str>& errors,
uint256& bumped_txid);
Txid& bumped_txid);
struct SignatureWeights
{

View file

@ -548,7 +548,7 @@ public:
std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override
{
return MakeSignalHandler(m_wallet->NotifyTransactionChanged.connect(
[fn](const uint256& txid, ChangeType status) { fn(Txid::FromUint256(txid), status); }));
[fn](const Txid& txid, ChangeType status) { fn(txid, status); }));
}
std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override
{

View file

@ -254,7 +254,7 @@ bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminef
}
// NOLINTNEXTLINE(misc-no-recursion)
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<uint256>& trusted_parents)
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<Txid>& trusted_parents)
{
AssertLockHeld(wallet.cs_wallet);
if (wtx.isConfirmed()) return true;
@ -285,7 +285,7 @@ bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<uin
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx)
{
std::set<uint256> trusted_parents;
std::set<Txid> trusted_parents;
LOCK(wallet.cs_wallet);
return CachedTxIsTrusted(wallet, wtx, trusted_parents);
}
@ -296,7 +296,7 @@ Balance GetBalance(const CWallet& wallet, const int min_depth, bool avoid_reuse)
isminefilter reuse_filter = avoid_reuse ? ISMINE_NO : ISMINE_USED;
{
LOCK(wallet.cs_wallet);
std::set<uint256> trusted_parents;
std::set<Txid> trusted_parents;
for (const auto& entry : wallet.mapWallet)
{
const CWalletTx& wtx = entry.second;
@ -325,7 +325,7 @@ std::map<CTxDestination, CAmount> GetAddressBalances(const CWallet& wallet)
{
LOCK(wallet.cs_wallet);
std::set<uint256> trusted_parents;
std::set<Txid> trusted_parents;
for (const auto& walletEntry : wallet.mapWallet)
{
const CWalletTx& wtx = walletEntry.second;
@ -348,7 +348,7 @@ std::map<CTxDestination, CAmount> GetAddressBalances(const CWallet& wallet)
if(!ExtractDestination(output.scriptPubKey, addr))
continue;
CAmount n = wallet.IsSpent(COutPoint(Txid::FromUint256(walletEntry.first), i)) ? 0 : output.nValue;
CAmount n = wallet.IsSpent(COutPoint(walletEntry.first, i)) ? 0 : output.nValue;
balances[addr] += n;
}
}

View file

@ -45,7 +45,7 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx,
CAmount& nFee, const isminefilter& filter,
bool include_change);
bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter);
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<uint256>& trusted_parents) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<Txid>& trusted_parents) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx);
struct Balance {

View file

@ -337,7 +337,7 @@ RPCHelpMan importprunedfunds()
if (!DecodeHexTx(tx, request.params[0].get_str())) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
}
uint256 hashTx = tx.GetHash();
Txid hashTx = tx.GetHash();
DataStream ssMB{ParseHexV(request.params[1], "proof")};
CMerkleBlock merkleBlock;
@ -357,7 +357,7 @@ RPCHelpMan importprunedfunds()
}
std::vector<uint256>::const_iterator it;
if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx)) == vMatch.end()) {
if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx.ToUint256())) == vMatch.end()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof");
}
@ -394,8 +394,8 @@ RPCHelpMan removeprunedfunds()
LOCK(pwallet->cs_wallet);
uint256 hash(ParseHashV(request.params[0], "txid"));
std::vector<uint256> vHash;
Txid hash = Txid::FromUint256((ParseHashV(request.params[0], "txid")));
std::vector<Txid> vHash;
vHash.push_back(hash);
if (auto res = pwallet->RemoveTxs(vHash); !res) {
throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(res).original);

View file

@ -56,7 +56,7 @@ static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool b
// Tally
CAmount amount = 0;
for (const std::pair<const uint256, CWalletTx>& wtx_pair : wallet.mapWallet) {
for (const std::pair<const Txid, CWalletTx>& wtx_pair : wallet.mapWallet) {
const CWalletTx& wtx = wtx_pair.second;
int depth{wallet.GetTxDepthInMainChain(wtx)};
if (depth < min_depth

View file

@ -1067,7 +1067,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name)
throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
}
uint256 hash(ParseHashV(request.params[0], "txid"));
Txid hash = Txid::FromUint256((ParseHashV(request.params[0], "txid")));
CCoinControl coin_control;
coin_control.fAllowWatchOnly = pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
@ -1165,7 +1165,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name)
throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
}
uint256 txid;
Txid txid;
if (feebumper::CommitTransaction(*pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) {
throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original);
}

View file

@ -7,6 +7,7 @@
#include <policy/rbf.h>
#include <rpc/util.h>
#include <rpc/blockchain.h>
#include <util/transaction_identifier.h>
#include <util/vector.h>
#include <wallet/receive.h>
#include <wallet/rpc/util.h>
@ -34,11 +35,11 @@ static void WalletTxToJSON(const CWallet& wallet, const CWalletTx& wtx, UniValue
} else {
entry.pushKV("trusted", CachedTxIsTrusted(wallet, wtx));
}
uint256 hash = wtx.GetHash();
Txid hash = wtx.GetHash();
entry.pushKV("txid", hash.GetHex());
entry.pushKV("wtxid", wtx.GetWitnessHash().GetHex());
UniValue conflicts(UniValue::VARR);
for (const uint256& conflict : wallet.GetTxConflicts(wtx))
for (const Txid& conflict : wallet.GetTxConflicts(wtx))
conflicts.push_back(conflict.GetHex());
entry.pushKV("walletconflicts", std::move(conflicts));
UniValue mempool_conflicts(UniValue::VARR);
@ -67,7 +68,7 @@ struct tallyitem
{
CAmount nAmount{0};
int nConf{std::numeric_limits<int>::max()};
std::vector<uint256> txids;
std::vector<Txid> txids;
bool fIsWatchonly{false};
tallyitem() = default;
};
@ -100,7 +101,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons
// Tally
std::map<CTxDestination, tallyitem> mapTally;
for (const std::pair<const uint256, CWalletTx>& pairWtx : wallet.mapWallet) {
for (const std::pair<const Txid, CWalletTx>& pairWtx : wallet.mapWallet) {
const CWalletTx& wtx = pairWtx.second;
int nDepth = wallet.GetTxDepthInMainChain(wtx);
@ -169,7 +170,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons
obj.pushKV("label", label);
UniValue transactions(UniValue::VARR);
if (it != mapTally.end()) {
for (const uint256& _item : (*it).second.txids) {
for (const Txid& _item : (*it).second.txids) {
transactions.push_back(_item.GetHex());
}
}
@ -650,7 +651,7 @@ RPCHelpMan listsinceblock()
UniValue transactions(UniValue::VARR);
for (const std::pair<const uint256, CWalletTx>& pairWtx : wallet.mapWallet) {
for (const std::pair<const Txid, CWalletTx>& pairWtx : wallet.mapWallet) {
const CWalletTx& tx = pairWtx.second;
if (depth == -1 || abs(wallet.GetTxDepthInMainChain(tx)) < depth) {
@ -760,7 +761,7 @@ RPCHelpMan gettransaction()
LOCK(pwallet->cs_wallet);
uint256 hash(ParseHashV(request.params[0], "txid"));
Txid hash = Txid::FromUint256((ParseHashV(request.params[0], "txid")));
isminefilter filter = ISMINE_SPENDABLE;
@ -833,7 +834,7 @@ RPCHelpMan abandontransaction()
LOCK(pwallet->cs_wallet);
uint256 hash(ParseHashV(request.params[0], "txid"));
Txid hash = Txid::FromUint256((ParseHashV(request.params[0], "txid")));
if (!pwallet->mapWallet.count(hash)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");

View file

@ -328,10 +328,10 @@ CoinsResult AvailableCoins(const CWallet& wallet,
const bool can_grind_r = wallet.CanGrindR();
std::vector<COutPoint> outpoints;
std::set<uint256> trusted_parents;
std::set<Txid> trusted_parents;
for (const auto& entry : wallet.mapWallet)
{
const uint256& txid = entry.first;
const Txid& txid = entry.first;
const CWalletTx& wtx = entry.second;
if (wallet.IsTxImmatureCoinBase(wtx) && !params.include_immature_coinbase)
@ -391,7 +391,7 @@ CoinsResult AvailableCoins(const CWallet& wallet,
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
const CTxOut& output = wtx.tx->vout[i];
const COutPoint outpoint(Txid::FromUint256(txid), i);
const COutPoint outpoint(txid, i);
if (output.nValue < params.min_amount || output.nValue > params.max_amount)
continue;

View file

@ -80,7 +80,7 @@ static void add_coin(CoinsResult& available_coins, CWallet& wallet, const CAmoun
if (spendable) {
tx.vout[nInput].scriptPubKey = GetScriptForDestination(*Assert(wallet.GetNewDestination(OutputType::BECH32, "")));
}
uint256 txid = tx.GetHash();
Txid txid = tx.GetHash();
LOCK(wallet.cs_wallet);
auto ret = wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid), std::forward_as_tuple(MakeTransactionRef(std::move(tx)), TxStateInactive{}));

View file

@ -40,7 +40,7 @@ static void addCoin(CoinsResult& coins,
tx.vout[0].nValue = nValue;
tx.vout[0].scriptPubKey = GetScriptForDestination(dest);
const auto txid{tx.GetHash().ToUint256()};
const auto txid{tx.GetHash()};
LOCK(wallet.cs_wallet);
auto ret = wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid), std::forward_as_tuple(MakeTransactionRef(std::move(tx)), TxStateInactive{}));
assert(ret.second);

View file

@ -951,7 +951,7 @@ BOOST_FIXTURE_TEST_CASE(RemoveTxs, TestChain100Setup)
BOOST_CHECK(wallet->HasWalletSpend(prev_tx));
BOOST_CHECK_EQUAL(wallet->mapWallet.count(block_hash), 1u);
std::vector<uint256> vHashIn{ block_hash };
std::vector<Txid> vHashIn{ block_hash };
BOOST_CHECK(wallet->RemoveTxs(vHashIn));
BOOST_CHECK(!wallet->HasWalletSpend(prev_tx));
@ -1001,7 +1001,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_sync_tx_invalid_state_test, TestingSetup)
{
// Verify balance update for the new tx and the old one
LOCK(wallet.cs_wallet);
const CWalletTx* new_wtx = wallet.GetWalletTx(good_tx_id.ToUint256());
const CWalletTx* new_wtx = wallet.GetWalletTx(good_tx_id);
BOOST_CHECK_EQUAL(CachedTxGetAvailableCredit(wallet, *new_wtx), 1 * COIN);
// Now the old wtx

View file

@ -539,7 +539,7 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& b
* @{
*/
const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
const CWalletTx* CWallet::GetWalletTx(const Txid& hash) const
{
AssertLockHeld(cs_wallet);
const auto it = mapWallet.find(hash);
@ -676,9 +676,9 @@ void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in)
}
}
std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
std::set<Txid> CWallet::GetConflicts(const Txid& txid) const
{
std::set<uint256> result;
std::set<Txid> result;
AssertLockHeld(cs_wallet);
const auto it = mapWallet.find(txid);
@ -744,7 +744,7 @@ void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> ran
// Now copy data from copyFrom to rest:
for (TxSpends::iterator it = range.first; it != range.second; ++it)
{
const uint256& hash = it->second;
const Txid& hash = it->second;
CWalletTx* copyTo = &mapWallet.at(hash);
if (copyFrom == copyTo) continue;
assert(copyFrom && "Oldest wallet transaction in range assumed to have been found.");
@ -770,7 +770,7 @@ bool CWallet::IsSpent(const COutPoint& outpoint) const
range = mapTxSpends.equal_range(outpoint);
for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
const uint256& wtxid = it->second;
const Txid& wtxid = it->second;
const auto mit = mapWallet.find(wtxid);
if (mit != mapWallet.end()) {
const auto& wtx = mit->second;
@ -781,7 +781,7 @@ bool CWallet::IsSpent(const COutPoint& outpoint) const
return false;
}
void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch)
void CWallet::AddToSpends(const COutPoint& outpoint, const Txid& wtxid, WalletBatch* batch)
{
mapTxSpends.insert(std::make_pair(outpoint, wtxid));
@ -983,12 +983,12 @@ void CWallet::MarkDirty()
{
{
LOCK(cs_wallet);
for (std::pair<const uint256, CWalletTx>& item : mapWallet)
for (std::pair<const Txid, CWalletTx>& item : mapWallet)
item.second.MarkDirty();
}
}
bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
bool CWallet::MarkReplaced(const Txid& originalHash, const Txid& newHash)
{
LOCK(cs_wallet);
@ -1020,7 +1020,7 @@ bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
return success;
}
void CWallet::SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations)
void CWallet::SetSpentKeyState(WalletBatch& batch, const Txid& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations)
{
AssertLockHeld(cs_wallet);
const CWalletTx* srctx = GetWalletTx(hash);
@ -1075,7 +1075,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const
WalletBatch batch(GetDatabase(), fFlushOnClose);
uint256 hash = tx->GetHash();
Txid hash = tx->GetHash();
if (IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) {
// Mark used destinations
@ -1197,7 +1197,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const
return &wtx;
}
bool CWallet::LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx)
bool CWallet::LoadToWallet(const Txid& hash, const UpdateWalletTxFn& fill_wtx)
{
const auto& ins = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(nullptr, TxStateInactive{}));
CWalletTx& wtx = ins.first->second;
@ -1295,7 +1295,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const SyncTxS
return false;
}
bool CWallet::TransactionCanBeAbandoned(const uint256& hashTx) const
bool CWallet::TransactionCanBeAbandoned(const Txid& hashTx) const
{
LOCK(cs_wallet);
const CWalletTx* wtx = GetWalletTx(hashTx);
@ -1312,7 +1312,7 @@ void CWallet::MarkInputsDirty(const CTransactionRef& tx)
}
}
bool CWallet::AbandonTransaction(const uint256& hashTx)
bool CWallet::AbandonTransaction(const Txid& hashTx)
{
LOCK(cs_wallet);
auto it = mapWallet.find(hashTx);
@ -1350,7 +1350,7 @@ bool CWallet::AbandonTransaction(CWalletTx& tx)
return true;
}
void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, const uint256& hashTx)
void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, const Txid& hashTx)
{
LOCK(cs_wallet);
@ -1380,20 +1380,20 @@ void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, c
}
void CWallet::RecursiveUpdateTxState(const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) {
void CWallet::RecursiveUpdateTxState(const Txid& tx_hash, const TryUpdatingStateFn& try_updating_state) {
// Do not flush the wallet here for performance reasons
WalletBatch batch(GetDatabase(), false);
RecursiveUpdateTxState(&batch, tx_hash, try_updating_state);
}
void CWallet::RecursiveUpdateTxState(WalletBatch* batch, const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) {
std::set<uint256> todo;
std::set<uint256> done;
void CWallet::RecursiveUpdateTxState(WalletBatch* batch, const Txid& tx_hash, const TryUpdatingStateFn& try_updating_state) {
std::set<Txid> todo;
std::set<Txid> done;
todo.insert(tx_hash);
while (!todo.empty()) {
uint256 now = *todo.begin();
Txid now = *todo.begin();
todo.erase(now);
done.insert(now);
auto it = mapWallet.find(now);
@ -1406,7 +1406,7 @@ void CWallet::RecursiveUpdateTxState(WalletBatch* batch, const uint256& tx_hash,
if (batch) batch->WriteTx(wtx);
// Iterate over all its outputs, and update those tx states as well (if applicable)
for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(COutPoint(Txid::FromUint256(now), i));
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(COutPoint(now, i));
for (TxSpends::const_iterator iter = range.first; iter != range.second; ++iter) {
if (!done.count(iter->second)) {
todo.insert(iter->second);
@ -1450,7 +1450,7 @@ void CWallet::transactionAddedToMempool(const CTransactionRef& tx) {
for (const CTxIn& tx_in : tx->vin) {
// For each wallet transaction spending this prevout..
for (auto range = mapTxSpends.equal_range(tx_in.prevout); range.first != range.second; range.first++) {
const uint256& spent_id = range.first->second;
const Txid& spent_id = range.first->second;
// Skip the recently added tx
if (spent_id == txid) continue;
RecursiveUpdateTxState(/*batch=*/nullptr, spent_id, [&txid](CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) {
@ -1503,7 +1503,7 @@ void CWallet::transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRe
// and recursively mark them as no longer conflicting with
// txid
for (auto range = mapTxSpends.equal_range(tx_in.prevout); range.first != range.second; range.first++) {
const uint256& spent_id = range.first->second;
const Txid& spent_id = range.first->second;
RecursiveUpdateTxState(/*batch=*/nullptr, spent_id, [&txid](CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) {
return wtx.mempool_conflicts.erase(txid) ? TxUpdate::CHANGED : TxUpdate::UNCHANGED;
@ -2072,12 +2072,12 @@ bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string
return ret;
}
std::set<uint256> CWallet::GetTxConflicts(const CWalletTx& wtx) const
std::set<Txid> CWallet::GetTxConflicts(const CWalletTx& wtx) const
{
AssertLockHeld(cs_wallet);
const uint256 myHash{wtx.GetHash()};
std::set<uint256> result{GetConflicts(myHash)};
const Txid myHash{wtx.GetHash()};
std::set<Txid> result{GetConflicts(myHash)};
result.erase(myHash);
return result;
}
@ -2228,7 +2228,7 @@ std::optional<PSBTError> CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bo
// If we have no utxo, grab it from the wallet.
if (!input.non_witness_utxo) {
const uint256& txhash = txin.prevout.hash;
const Txid& txhash = txin.prevout.hash;
const auto it = mapWallet.find(txhash);
if (it != mapWallet.end()) {
const CWalletTx& wtx = it->second;
@ -2405,7 +2405,7 @@ DBErrors CWallet::LoadWallet()
return nLoadWalletRet;
}
util::Result<void> CWallet::RemoveTxs(std::vector<uint256>& txs_to_remove)
util::Result<void> CWallet::RemoveTxs(std::vector<Txid>& txs_to_remove)
{
AssertLockHeld(cs_wallet);
bilingual_str str_err; // future: make RunWithinTxn return a util::Result
@ -2419,16 +2419,16 @@ util::Result<void> CWallet::RemoveTxs(std::vector<uint256>& txs_to_remove)
return {}; // all good
}
util::Result<void> CWallet::RemoveTxs(WalletBatch& batch, std::vector<uint256>& txs_to_remove)
util::Result<void> CWallet::RemoveTxs(WalletBatch& batch, std::vector<Txid>& txs_to_remove)
{
AssertLockHeld(cs_wallet);
if (!batch.HasActiveTxn()) return util::Error{strprintf(_("The transactions removal process can only be executed within a db txn"))};
// Check for transaction existence and remove entries from disk
using TxIterator = std::unordered_map<uint256, CWalletTx, SaltedTxidHasher>::const_iterator;
using TxIterator = std::unordered_map<Txid, CWalletTx, SaltedTxidHasher>::const_iterator;
std::vector<TxIterator> erased_txs;
bilingual_str str_err;
for (const uint256& hash : txs_to_remove) {
for (const Txid& hash : txs_to_remove) {
auto it_wtx = mapWallet.find(hash);
if (it_wtx == mapWallet.end()) {
return util::Error{strprintf(_("Transaction %s does not belong to this wallet"), hash.GetHex())};
@ -2443,7 +2443,7 @@ util::Result<void> CWallet::RemoveTxs(WalletBatch& batch, std::vector<uint256>&
batch.RegisterTxnListener({.on_commit=[&, erased_txs]() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) {
// Update the in-memory state and notify upper layers about the removals
for (const auto& it : erased_txs) {
const uint256 hash{it->first};
const Txid hash{it->first};
wtxOrdered.erase(it->second.m_it_wtxOrdered);
for (const auto& txin : it->second.tx->vin)
mapTxSpends.erase(txin.prevout);
@ -4159,7 +4159,7 @@ util::Result<void> CWallet::ApplyMigrationData(WalletBatch& local_wallet_batch,
// Check if the transactions in the wallet are still ours. Either they belong here, or they belong in the watchonly wallet.
// We need to go through these in the tx insertion order so that lookups to spends works.
std::vector<uint256> txids_to_delete;
std::vector<Txid> txids_to_delete;
std::unique_ptr<WalletBatch> watchonly_batch;
if (data.watchonly_wallet) {
watchonly_batch = std::make_unique<WalletBatch>(data.watchonly_wallet->GetDatabase());
@ -4190,7 +4190,7 @@ util::Result<void> CWallet::ApplyMigrationData(WalletBatch& local_wallet_batch,
LOCK(data.watchonly_wallet->cs_wallet);
if (data.watchonly_wallet->IsMine(*wtx->tx) || data.watchonly_wallet->IsFromMe(*wtx->tx)) {
// Add to watchonly wallet
const uint256& hash = wtx->GetHash();
const Txid& hash = wtx->GetHash();
const CWalletTx& to_copy_wtx = *wtx;
if (!data.watchonly_wallet->LoadToWallet(hash, [&](CWalletTx& ins_wtx, bool new_tx) EXCLUSIVE_LOCKS_REQUIRED(data.watchonly_wallet->cs_wallet) {
if (!new_tx) return false;

View file

@ -331,9 +331,9 @@ private:
* detect and report conflicts (double-spends or
* mutated transactions where the mutant gets mined).
*/
typedef std::unordered_multimap<COutPoint, uint256, SaltedOutpointHasher> TxSpends;
typedef std::unordered_multimap<COutPoint, Txid, SaltedOutpointHasher> TxSpends;
TxSpends mapTxSpends GUARDED_BY(cs_wallet);
void AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void AddToSpends(const COutPoint& outpoint, const Txid& wtxid, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void AddToSpends(const CWalletTx& wtx, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
@ -355,15 +355,15 @@ private:
bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, const SyncTxState& state, bool fUpdate, bool rescanning_old_block) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/** Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
void MarkConflicted(const uint256& hashBlock, int conflicting_height, const uint256& hashTx);
void MarkConflicted(const uint256& hashBlock, int conflicting_height, const Txid& hashTx);
enum class TxUpdate { UNCHANGED, CHANGED, NOTIFY_CHANGED };
using TryUpdatingStateFn = std::function<TxUpdate(CWalletTx& wtx)>;
/** Mark a transaction (and its in-wallet descendants) as a particular tx state. */
void RecursiveUpdateTxState(const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void RecursiveUpdateTxState(WalletBatch* batch, const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void RecursiveUpdateTxState(const Txid& tx_hash, const TryUpdatingStateFn& try_updating_state) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void RecursiveUpdateTxState(WalletBatch* batch, const Txid& tx_hash, const TryUpdatingStateFn& try_updating_state) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/** Mark a transaction's inputs dirty, thus forcing the outputs to be recomputed */
void MarkInputsDirty(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
@ -481,7 +481,7 @@ public:
/** Map from txid to CWalletTx for all transactions this wallet is
* interested in, including received and sent transactions. */
std::unordered_map<uint256, CWalletTx, SaltedTxidHasher> mapWallet GUARDED_BY(cs_wallet);
std::unordered_map<Txid, CWalletTx, SaltedTxidHasher> mapWallet GUARDED_BY(cs_wallet);
typedef std::multimap<int64_t, CWalletTx*> TxItems;
TxItems wtxOrdered;
@ -503,9 +503,9 @@ public:
/** Interface for accessing chain state. */
interfaces::Chain& chain() const { assert(m_chain); return *m_chain; }
const CWalletTx* GetWalletTx(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
const CWalletTx* GetWalletTx(const Txid& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::set<uint256> GetTxConflicts(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::set<Txid> GetTxConflicts(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
* Return depth of transaction in blockchain:
@ -537,7 +537,7 @@ public:
// Whether this or any known scriptPubKey with the same single key has been spent.
bool IsSpentKey(const CScript& scriptPubKey) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void SetSpentKeyState(WalletBatch& batch, const Txid& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/** Display address on an external signer. */
util::Result<void> DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
@ -608,7 +608,7 @@ public:
* @return the recently added wtx pointer or nullptr if there was a db write error.
*/
CWalletTx* AddToWallet(CTransactionRef tx, const TxState& state, const UpdateWalletTxFn& update_wtx=nullptr, bool fFlushOnClose=true, bool rescanning_old_block = false);
bool LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool LoadToWallet(const Txid& hash, const UpdateWalletTxFn& fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void transactionAddedToMempool(const CTransactionRef& tx) override;
void blockConnected(ChainstateRole role, const interfaces::BlockInfo& block) override;
void blockDisconnected(const interfaces::BlockInfo& block) override;
@ -793,8 +793,8 @@ public:
DBErrors LoadWallet();
/** Erases the provided transactions from the wallet. */
util::Result<void> RemoveTxs(std::vector<uint256>& txs_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
util::Result<void> RemoveTxs(WalletBatch& batch, std::vector<uint256>& txs_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
util::Result<void> RemoveTxs(std::vector<Txid>& txs_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
util::Result<void> RemoveTxs(WalletBatch& batch, std::vector<Txid>& txs_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& purpose);
@ -817,7 +817,7 @@ public:
int GetVersion() const { LOCK(cs_wallet); return nWalletVersion; }
//! Get wallet transactions that conflict with given transaction (spend same outputs)
std::set<uint256> GetConflicts(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::set<Txid> GetConflicts(const Txid& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
//! Check if a given transaction has any of its outputs spent by another transaction in the wallet
bool HasWalletSpend(const CTransactionRef& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
@ -844,7 +844,7 @@ public:
* Wallet transaction added, removed or updated.
* @note called with lock cs_wallet held.
*/
boost::signals2::signal<void(const uint256& hashTx, ChangeType status)> NotifyTransactionChanged;
boost::signals2::signal<void(const Txid& hashTx, ChangeType status)> NotifyTransactionChanged;
/** Show progress e.g. for rescan */
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
@ -867,14 +867,14 @@ public:
void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; }
/** Return whether transaction can be abandoned */
bool TransactionCanBeAbandoned(const uint256& hashTx) const;
bool TransactionCanBeAbandoned(const Txid& hashTx) const;
/* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */
bool AbandonTransaction(const uint256& hashTx);
bool AbandonTransaction(const Txid& hashTx);
bool AbandonTransaction(CWalletTx& tx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/** Mark a transaction as replaced by another transaction. */
bool MarkReplaced(const uint256& originalHash, const uint256& newHash);
bool MarkReplaced(const Txid& originalHash, const Txid& newHash);
/* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
static std::shared_ptr<CWallet> Create(WalletContext& context, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings);

View file

@ -16,6 +16,7 @@
#include <util/bip32.h>
#include <util/check.h>
#include <util/fs.h>
#include <util/transaction_identifier.h>
#include <util/time.h>
#include <util/translation.h>
#ifdef USE_BDB
@ -96,9 +97,9 @@ bool WalletBatch::WriteTx(const CWalletTx& wtx)
return WriteIC(std::make_pair(DBKeys::TX, wtx.GetHash()), wtx);
}
bool WalletBatch::EraseTx(uint256 hash)
bool WalletBatch::EraseTx(Txid hash)
{
return EraseIC(std::make_pair(DBKeys::TX, hash));
return EraseIC(std::make_pair(DBKeys::TX, hash.ToUint256()));
}
bool WalletBatch::WriteKeyMetadata(const CKeyMetadata& meta, const CPubKey& pubkey, const bool overwrite)
@ -1043,7 +1044,7 @@ static DBErrors LoadAddressBookRecords(CWallet* pwallet, DatabaseBatch& batch) E
return result;
}
static DBErrors LoadTxRecords(CWallet* pwallet, DatabaseBatch& batch, std::vector<uint256>& upgraded_txs, bool& any_unordered) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
static DBErrors LoadTxRecords(CWallet* pwallet, DatabaseBatch& batch, std::vector<Txid>& upgraded_txs, bool& any_unordered) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
{
AssertLockHeld(pwallet->cs_wallet);
DBErrors result = DBErrors::LOAD_OK;
@ -1053,7 +1054,7 @@ static DBErrors LoadTxRecords(CWallet* pwallet, DatabaseBatch& batch, std::vecto
LoadResult tx_res = LoadRecords(pwallet, batch, DBKeys::TX,
[&any_unordered, &upgraded_txs] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
DBErrors result = DBErrors::LOAD_OK;
uint256 hash;
Txid hash;
key >> hash;
// LoadToWallet call below creates a new CWalletTx that fill_wtx
// callback fills with transaction metadata.
@ -1187,7 +1188,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
{
DBErrors result = DBErrors::LOAD_OK;
bool any_unordered = false;
std::vector<uint256> upgraded_txs;
std::vector<Txid> upgraded_txs;
LOCK(pwallet->cs_wallet);
@ -1242,7 +1243,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
if (result != DBErrors::LOAD_OK)
return result;
for (const uint256& hash : upgraded_txs)
for (const Txid& hash : upgraded_txs)
WriteTx(pwallet->mapWallet.at(hash));
if (!has_last_client || last_client != CLIENT_VERSION) // Update

View file

@ -237,7 +237,7 @@ public:
bool ErasePurpose(const std::string& strAddress);
bool WriteTx(const CWalletTx& wtx);
bool EraseTx(uint256 hash);
bool EraseTx(Txid hash);
bool WriteKeyMetadata(const CKeyMetadata& meta, const CPubKey& pubkey, const bool overwrite);
bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta);