Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
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 {
15{
16 return GetTx()->Equals(*_tx.GetTx(), {.include_script_sig = false, .include_witness_data = false});
17}
18
20{
22}
23
25{
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
56{
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()) {
73 }
74 metadata_changed = true;
75 } else {
78 }
79
80 // While unconfirmed, derive the canonical variant from all known variants
81 if (!isConfirmed()) {
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
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:119
#define Assume(val)
Assume is the identity function.
Definition check.h:131
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.
bool Update(CTransactionRef tx, const TxState &new_state, WalletBatch &batch, bool metadata_changed)
bool isConfirmed() const
const Txid & GetHash() const LIFETIMEBOUND
const T * state() const
std::map< Wtxid, CTransactionRef > m_txs
void updateState(interfaces::Chain &chain)
Update transaction state when attaching to a chain, filling in heights of conflicted and confirmed bl...
unsigned int nTimeReceived
time received by this node
bool InMempool() const
int64_t GetTxTime() const
CTransactionRef GetTx() const
bool IsMalleation(const CWalletTx &tx) const
True if tx is a malleation of this, i.e.
void RecomputeCanonical()
Set m_canonical_wtxid to the best variant under the unconfirmed rule (witnessed preferred,...
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet.
Access to the wallet database.
Definition walletdb.h:199
bool WriteTxMetadata(const CWalletTx &wtx)
Definition walletdb.cpp:123
bool WriteWtxVariant(const Txid &txid, const CTransactionRef &tx)
Definition walletdb.cpp:118
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.
static uint256 TxStateSerializedBlockHash(const TxState &state)
Get TxState serialized block hash. Inverse of TxStateInterpretSerialized.
std::shared_ptr< const CTransaction > CTransactionRef
State of transaction not confirmed or conflicting with a known block and not in the mempool.
Definition transaction.h:61
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82
assert(!tx.IsCoinBase())