Branch data Line data Source code
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 : :
5 : : #include <wallet/transaction.h>
6 : :
7 : : #include <consensus/validation.h>
8 : : #include <interfaces/chain.h>
9 : :
10 : : using interfaces::FoundBlock;
11 : :
12 : : namespace wallet {
13 : 2862 : bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
14 : : {
15 [ + - ]: 2862 : CMutableTransaction tx1 {*this->GetTx()};
16 [ + - + - ]: 2862 : CMutableTransaction tx2 {*_tx.GetTx()};
17 [ + + ]: 5768 : for (auto& txin : tx1.vin) {
18 : 2906 : txin.scriptSig = CScript();
19 : 2906 : txin.scriptWitness.SetNull();
20 : : }
21 [ + + ]: 5774 : for (auto& txin : tx2.vin) {
22 : 2912 : txin.scriptSig = CScript();
23 : 2912 : txin.scriptWitness.SetNull();
24 : : }
25 [ + - + - ]: 11448 : return CTransaction(tx1) == CTransaction(tx2);
26 : 5724 : }
27 : :
28 : 150171 : bool CWalletTx::InMempool() const
29 : : {
30 [ + + ]: 150171 : return state<TxStateInMempool>();
31 : : }
32 : :
33 : 299660 : int64_t CWalletTx::GetTxTime() const
34 : : {
35 : 299660 : int64_t n = nTimeSmart;
36 [ + + ]: 299660 : return n ? n : nTimeReceived;
37 : : }
38 : :
39 : 8665 : void CWalletTx::updateState(interfaces::Chain& chain)
40 : : {
41 : 8665 : bool active;
42 : 17140 : 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 [ + + - + ]: 8475 : if (!chain.findBlock(hash, FoundBlock().inActiveChain(active).height(height)) || !active) {
50 [ - + ]: 362 : state = TxStateInactive{};
51 : : }
52 : 17140 : };
53 [ + + ]: 8665 : if (auto* conf = state<TxStateConfirmed>()) {
54 : 8423 : lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, m_state);
55 [ + + ]: 242 : } else if (auto* conf = state<TxStateBlockConflicted>()) {
56 : 52 : 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.
61 [ + + ]: 8665 : if (!isConfirmed()) RecomputeCanonical();
62 : 8665 : }
63 : :
64 : 8500 : bool CWalletTx::Update(CTransactionRef new_tx, const TxState& new_state)
65 : : {
66 [ - + ]: 8500 : Assert(new_tx);
67 [ - + + - ]: 8500 : if (!Assume(GetHash() == new_tx->GetHash())) {
68 : : return false;
69 : : }
70 : 8500 : bool ret = false;
71 [ + + ]: 8500 : const auto& [tx_pair, inserted] = m_txs.emplace(new_tx->GetWitnessHash(), std::move(new_tx));
72 [ + + ]: 8500 : if (inserted) {
73 : 3 : ret = true;
74 : : }
75 [ + + ]: 8500 : const auto& [wtxid, tx] = *tx_pair;
76 : :
77 [ + + ]: 8500 : if (new_state.index() != m_state.index()) {
78 : 4368 : m_state = new_state;
79 [ + + ]: 4368 : if (state<TxStateConfirmed>()) {
80 : 3754 : m_canonical_wtxid = wtxid;
81 : : }
82 : : ret = true;
83 : : } else {
84 [ - + ]: 4132 : assert(TxStateSerializedIndex(m_state) == TxStateSerializedIndex(new_state));
85 [ - + ]: 4132 : assert(TxStateSerializedBlockHash(m_state) == TxStateSerializedBlockHash(new_state));
86 : : }
87 : :
88 : : // While unconfirmed, derive the canonical variant from all known variants
89 [ + + ]: 8500 : if (!isConfirmed()) {
90 : 2300 : const Wtxid prev_canonical = m_canonical_wtxid;
91 : 2300 : RecomputeCanonical();
92 [ + + ]: 2300 : if (m_canonical_wtxid != prev_canonical) {
93 : : ret = true;
94 : : }
95 : : }
96 : :
97 : : return ret;
98 : : }
99 : :
100 : 2903 : void CWalletTx::RecomputeCanonical()
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 [ - + ]: 2903 : Assert(!m_txs.empty());
106 : :
107 : : // Returns true if 'a' should be preferred over 'b'
108 : 2915 : auto is_better = [](const CTransactionRef& a, const CTransactionRef& b) {
109 : : // A witnessed variant always beats a witnessless one
110 [ + - ]: 12 : if (a->HasWitness() != b->HasWitness()) return a->HasWitness();
111 : : // Otherwise the lighter one wins
112 : 12 : return GetTransactionWeight(*a) < GetTransactionWeight(*b);
113 : : };
114 : :
115 : 2903 : auto it = m_txs.begin();
116 : 2903 : auto best_wtxid = it->first;
117 : 2903 : const CTransactionRef* best = &it->second;
118 : 2903 : it = std::next(it);
119 [ + + ]: 2915 : for (; it != m_txs.end(); it = std::next(it)) {
120 [ - + ]: 12 : if (is_better(it->second, *best)) {
121 : 0 : best = &it->second;
122 : 0 : best_wtxid = it->first;
123 : : }
124 : : }
125 : 2903 : m_canonical_wtxid = best_wtxid;
126 : 2903 : }
127 : : } // namespace wallet
|