Bitcoin Core 32.99.0
P2P Digital Currency
transaction.cpp
Go to the documentation of this file.
1// Copyright (c) 2021-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6#include <wallet/walletdb.h>
7
9#include <interfaces/chain.h>
10
12
13namespace wallet {
14bool CWalletTx::IsMalleation(const CWalletTx& _tx) const
15{
16 return GetTx()->Equals(*_tx.GetTx(), {.include_script_sig = false, .include_witness_data = false});
17}
18
20{
21 return state<TxStateInMempool>();
22}
23
24int64_t CWalletTx::GetTxTime() const
25{
26 int64_t n = nTimeSmart;
27 return n ? n : nTimeReceived;
28}
29
31{
32 bool active;
33 auto lookup_block = [&](const uint256& hash, int& height, TxState& state) {
34 // If tx block (or conflicting block) was reorged out of chain
35 // while the wallet was shutdown, change tx status to UNCONFIRMED
36 // and reset block height, hash, and index. ABANDONED tx don't have
37 // associated blocks and don't need to be updated. The case where a
38 // transaction was reorged out while online and then reconfirmed
39 // while offline is covered by the rescan logic.
40 if (!chain.findBlock(hash, FoundBlock().inActiveChain(active).height(height)) || !active) {
42 }
43 };
44 if (auto* conf = state<TxStateConfirmed>()) {
45 lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, m_state);
46 } else if (auto* conf = state<TxStateBlockConflicted>()) {
47 lookup_block(conf->conflicting_block_hash, conf->conflicting_block_height, m_state);
48 }
49
50 // If the above downgraded a previously-confirmed witness variant back to unconfirmed,
51 // the canonical choice is no longer pinned by confirmation. Re-apply the least-weight rule.
53}
54
55bool CWalletTx::Update(CTransactionRef new_tx, const TxState& new_state, WalletBatch& batch, bool metadata_changed)
56{
57 Assert(new_tx);
58 if (!Assume(GetHash() == new_tx->GetHash())) {
59 return false;
60 }
61 const auto& [tx_pair, new_variant] = m_txs.emplace(new_tx->GetWitnessHash(), std::move(new_tx));
62 if (new_variant) {
63 if (!batch.WriteWtxVariant(GetHash(), tx_pair->second)) {
64 throw std::ios_base::failure("Unable to write wtxvariant record");
65 }
66 }
67 const auto& [wtxid, tx] = *tx_pair;
68
69 if (new_state.index() != m_state.index()) {
70 m_state = new_state;
71 if (state<TxStateConfirmed>()) {
72 m_canonical_wtxid = wtxid;
73 }
74 metadata_changed = true;
75 } else {
78 }
79
80 // While unconfirmed, derive the canonical variant from all known variants
81 if (!isConfirmed()) {
82 const Wtxid prev_canonical = m_canonical_wtxid;
84 if (m_canonical_wtxid != prev_canonical) {
85 metadata_changed = true;
86 }
87 }
88
89 if (metadata_changed) {
90 if (!batch.WriteTxMetadata(*this)) {
91 throw std::ios_base::failure("Unable to write tx record");
92 }
93 }
94
95 return new_variant || metadata_changed;
96}
97
99{
100 // Recompute the canonical variant among the witness variants. They share
101 // the txid but differ in the wtxid. Prefer variant with witness data and
102 // the least weight.
103 Assert(!m_txs.empty());
104
105 m_canonical_wtxid = std::ranges::min_element(m_txs, std::less{}, [](const auto& entry) {
106 return std::make_pair(!entry.second->HasWitness(), GetTransactionWeight(*entry.second));
107 })->first;
108}
109} // namespace wallet
#define Assert(val)
Identity function.
Definition: check.h:116
#define Assume(val)
Assume is the identity function.
Definition: check.h:128
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:117
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:52
256-bit opaque blob.
Definition: uint256.h:196
A transaction with a bunch of additional info that only the owner cares about.
Definition: transaction.h:194
bool Update(CTransactionRef tx, const TxState &new_state, WalletBatch &batch, bool metadata_changed)
Definition: transaction.cpp:55
bool isConfirmed() const
Definition: transaction.h:389
const Txid & GetHash() const LIFETIMEBOUND
Definition: transaction.h:390
const T * state() const
Definition: transaction.h:377
std::map< Wtxid, CTransactionRef > m_txs
Definition: transaction.h:423
void updateState(interfaces::Chain &chain)
Update transaction state when attaching to a chain, filling in heights of conflicted and confirmed bl...
Definition: transaction.cpp:30
unsigned int nTimeReceived
time received by this node
Definition: transaction.h:210
bool InMempool() const
Definition: transaction.cpp:19
int64_t GetTxTime() const
Definition: transaction.cpp:24
CTransactionRef GetTx() const
Definition: transaction.h:351
bool IsMalleation(const CWalletTx &tx) const
True if tx is a malleation of this, i.e.
Definition: transaction.cpp:14
void RecomputeCanonical()
Set m_canonical_wtxid to the best variant under the unconfirmed rule (witnessed preferred,...
Definition: transaction.cpp:98
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet.
Definition: transaction.h:220
Access to the wallet database.
Definition: walletdb.h:197
bool WriteTxMetadata(const CWalletTx &wtx)
Definition: walletdb.cpp:121
bool WriteWtxVariant(const Txid &txid, const CTransactionRef &tx)
Definition: walletdb.cpp:116
static int32_t GetTransactionWeight(const CTransaction &tx)
Definition: validation.h:139
std::variant< TxStateConfirmed, TxStateInMempool, TxStateBlockConflicted, TxStateInactive, TxStateUnrecognized > TxState
All possible CWalletTx states.
Definition: transaction.h:81
static int TxStateSerializedIndex(const TxState &state)
Get TxState serialized block index. Inverse of TxStateInterpretSerialized.
Definition: transaction.h:114
static uint256 TxStateSerializedBlockHash(const TxState &state)
Get TxState serialized block hash. Inverse of TxStateInterpretSerialized.
Definition: transaction.h:102
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:417
State of transaction not confirmed or conflicting with a known block and not in the mempool.
Definition: transaction.h:61
assert(!tx.IsCoinBase())