Bitcoin Core 31.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
8#include <interfaces/chain.h>
9
11
12namespace wallet {
14{
15 CMutableTransaction tx1 {*this->GetTx()};
16 CMutableTransaction tx2 {*_tx.GetTx()};
17 for (auto& txin : tx1.vin) {
18 txin.scriptSig = CScript();
19 txin.scriptWitness.SetNull();
20 }
21 for (auto& txin : tx2.vin) {
22 txin.scriptSig = CScript();
23 txin.scriptWitness.SetNull();
24 }
25 return CTransaction(tx1) == CTransaction(tx2);
26}
27
29{
30 return state<TxStateInMempool>();
31}
32
33int64_t CWalletTx::GetTxTime() const
34{
35 int64_t n = nTimeSmart;
36 return n ? n : nTimeReceived;
37}
38
40{
41 bool active;
42 auto lookup_block = [&](const uint256& hash, int& height, TxState& state) {
43 // If tx block (or conflicting block) was reorged out of chain
44 // while the wallet was shutdown, change tx status to UNCONFIRMED
45 // and reset block height, hash, and index. ABANDONED tx don't have
46 // associated blocks and don't need to be updated. The case where a
47 // transaction was reorged out while online and then reconfirmed
48 // while offline is covered by the rescan logic.
49 if (!chain.findBlock(hash, FoundBlock().inActiveChain(active).height(height)) || !active) {
51 }
52 };
53 if (auto* conf = state<TxStateConfirmed>()) {
54 lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, m_state);
55 } else if (auto* conf = state<TxStateBlockConflicted>()) {
56 lookup_block(conf->conflicting_block_hash, conf->conflicting_block_height, m_state);
57 }
58
59 // If the above downgraded a previously-confirmed witness variant back to unconfirmed,
60 // the canonical choice is no longer pinned by confirmation. Re-apply the least-weight rule.
62}
63
64bool CWalletTx::Update(CTransactionRef new_tx, const TxState& new_state)
65{
66 Assert(new_tx);
67 if (!Assume(GetHash() == new_tx->GetHash())) {
68 return false;
69 }
70 bool ret = false;
71 const auto& [tx_pair, inserted] = m_txs.emplace(new_tx->GetWitnessHash(), std::move(new_tx));
72 if (inserted) {
73 ret = true;
74 }
75 const auto& [wtxid, tx] = *tx_pair;
76
77 if (new_state.index() != m_state.index()) {
78 m_state = new_state;
79 if (state<TxStateConfirmed>()) {
80 m_canonical_wtxid = wtxid;
81 }
82 ret = true;
83 } else {
86 }
87
88 // While unconfirmed, derive the canonical variant from all known variants
89 if (!isConfirmed()) {
90 const Wtxid prev_canonical = m_canonical_wtxid;
92 if (m_canonical_wtxid != prev_canonical) {
93 ret = true;
94 }
95 }
96
97 return ret;
98}
99
101{
102 // Recompute the canonical variant among the witness variants. They share
103 // the txid but differ in the wtxid. Prefer variant with witness data and
104 // the least weight.
105 Assert(!m_txs.empty());
106
107 m_canonical_wtxid = std::ranges::min_element(m_txs, std::less{}, [](const auto& entry) {
108 return std::make_pair(!entry.second->HasWitness(), GetTransactionWeight(*entry.second));
109 })->first;
110}
111} // namespace wallet
int ret
#define Assert(val)
Identity function.
Definition: check.h:116
#define Assume(val)
Assume is the identity function.
Definition: check.h:128
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:281
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:119
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:54
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:192
bool isConfirmed() const
Definition: transaction.h:386
const Txid & GetHash() const LIFETIMEBOUND
Definition: transaction.h:387
const T * state() const
Definition: transaction.h:374
bool IsEquivalentTo(const CWalletTx &tx) const
True if only scriptSigs are different.
Definition: transaction.cpp:13
std::map< Wtxid, CTransactionRef > m_txs
Definition: transaction.h:420
void updateState(interfaces::Chain &chain)
Update transaction state when attaching to a chain, filling in heights of conflicted and confirmed bl...
Definition: transaction.cpp:39
unsigned int nTimeReceived
time received by this node
Definition: transaction.h:208
bool Update(CTransactionRef tx, const TxState &new_state)
Definition: transaction.cpp:64
bool InMempool() const
Definition: transaction.cpp:28
int64_t GetTxTime() const
Definition: transaction.cpp:33
CTransactionRef GetTx() const
Definition: transaction.h:349
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.
Definition: transaction.h:218
static int32_t GetTransactionWeight(const CTransaction &tx)
Definition: validation.h:140
std::variant< TxStateConfirmed, TxStateInMempool, TxStateBlockConflicted, TxStateInactive, TxStateUnrecognized > TxState
All possible CWalletTx states.
Definition: transaction.h:79
static int TxStateSerializedIndex(const TxState &state)
Get TxState serialized block index. Inverse of TxStateInterpretSerialized.
Definition: transaction.h:112
static uint256 TxStateSerializedBlockHash(const TxState &state)
Get TxState serialized block hash. Inverse of TxStateInterpretSerialized.
Definition: transaction.h:100
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:403
A mutable version of CTransaction.
Definition: transaction.h:358
State of transaction not confirmed or conflicting with a known block and not in the mempool.
Definition: transaction.h:59
assert(!tx.IsCoinBase())