Bitcoin Core
32.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
wallet
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
5
#include <
wallet/transaction.h
>
6
#include <
wallet/walletdb.h
>
7
8
#include <
consensus/validation.h
>
9
#include <
interfaces/chain.h
>
10
11
using
interfaces::FoundBlock
;
12
13
namespace
wallet
{
14
bool
CWalletTx::IsMalleation
(
const
CWalletTx
& _tx)
const
15
{
16
return
GetTx
()->Equals(*_tx.
GetTx
(), {.include_script_sig = false, .include_witness_data = false});
17
}
18
19
bool
CWalletTx::InMempool
()
const
20
{
21
return
state<TxStateInMempool>
();
22
}
23
24
int64_t
CWalletTx::GetTxTime
()
const
25
{
26
int64_t n =
nTimeSmart
;
27
return
n ? n :
nTimeReceived
;
28
}
29
30
void
CWalletTx::updateState
(
interfaces::Chain
& chain)
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) {
41
state
=
TxStateInactive
{};
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.
52
if
(!
isConfirmed
())
RecomputeCanonical
();
53
}
54
55
bool
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
{
76
assert
(TxStateSerializedIndex(
m_state
) == TxStateSerializedIndex(new_state));
77
assert
(TxStateSerializedBlockHash(
m_state
) == TxStateSerializedBlockHash(new_state));
78
}
79
80
// While unconfirmed, derive the canonical variant from all known variants
81
if
(!
isConfirmed
()) {
82
const
Wtxid
prev_canonical =
m_canonical_wtxid
;
83
RecomputeCanonical
();
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
98
void
CWalletTx::RecomputeCanonical
()
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
Assert
#define Assert(val)
Identity function.
Definition
check.h:116
Assume
#define Assume(val)
Assume is the identity function.
Definition
check.h:128
interfaces::Chain
Definition
chain.h:117
interfaces::Chain::findBlock
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
interfaces::FoundBlock
Definition
chain.h:52
uint256
256-bit opaque blob.
Definition
uint256.h:196
wallet::CWalletTx::m_state
TxState m_state
Definition
transaction.h:260
wallet::CWalletTx::Update
bool Update(CTransactionRef tx, const TxState &new_state, WalletBatch &batch, bool metadata_changed)
Definition
transaction.cpp:55
wallet::CWalletTx::isConfirmed
bool isConfirmed() const
Definition
transaction.h:389
wallet::CWalletTx::GetHash
const Txid & GetHash() const LIFETIMEBOUND
Definition
transaction.h:390
wallet::CWalletTx::state
const T * state() const
Definition
transaction.h:377
wallet::CWalletTx::m_txs
std::map< Wtxid, CTransactionRef > m_txs
Definition
transaction.h:423
wallet::CWalletTx::updateState
void updateState(interfaces::Chain &chain)
Definition
transaction.cpp:30
wallet::CWalletTx::nTimeReceived
unsigned int nTimeReceived
time received by this node
Definition
transaction.h:210
wallet::CWalletTx::m_canonical_wtxid
Wtxid m_canonical_wtxid
Definition
transaction.h:422
wallet::CWalletTx::InMempool
bool InMempool() const
Definition
transaction.cpp:19
wallet::CWalletTx::GetTxTime
int64_t GetTxTime() const
Definition
transaction.cpp:24
wallet::CWalletTx::GetTx
CTransactionRef GetTx() const
Definition
transaction.h:351
wallet::CWalletTx::CWalletTx
CWalletTx(CTransactionRef tx, const TxState &state)
Definition
transaction.h:239
wallet::CWalletTx::IsMalleation
bool IsMalleation(const CWalletTx &tx) const
True if tx is a malleation of this, i.e.
Definition
transaction.cpp:14
wallet::CWalletTx::RecomputeCanonical
void RecomputeCanonical()
Definition
transaction.cpp:98
wallet::CWalletTx::nTimeSmart
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet.
Definition
transaction.h:220
wallet::WalletBatch
Access to the wallet database.
Definition
walletdb.h:197
wallet::WalletBatch::WriteTxMetadata
bool WriteTxMetadata(const CWalletTx &wtx)
Definition
walletdb.cpp:121
wallet::WalletBatch::WriteWtxVariant
bool WriteWtxVariant(const Txid &txid, const CTransactionRef &tx)
Definition
walletdb.cpp:116
validation.h
chain.h
wallet
Definition
coin_selection.cpp:31
wallet::TxState
std::variant< TxStateConfirmed, TxStateInMempool, TxStateBlockConflicted, TxStateInactive, TxStateUnrecognized > TxState
All possible CWalletTx states.
Definition
transaction.h:81
CTransactionRef
std::shared_ptr< const CTransaction > CTransactionRef
Definition
transaction.h:417
wallet::TxStateInactive
Definition
transaction.h:61
Wtxid
transaction_identifier< true > Wtxid
Wtxid commits to all transaction fields including the witness.
Definition
transaction_identifier.h:62
assert
assert(!tx.IsCoinBase())
transaction.h
walletdb.h
Generated on
for Bitcoin Core by
1.18.0