See also: Bitcoin DevWiki Page
- TxStateConfirmed: Contains corresponding block information
- TxStateInMempool
- TxStateConflicted: Contains corresponding conflicting block information
- TxStateInactive: Can be
abandon
ed or not - TxStateUnrecognized: Treated as inactive
Note: all of the conditions described must be true
- An output is considered for spending by
AvailableCoins
when:- Not an immature coinbase
- Not conflicted
- Mined in a block OR in the mempool in a tx where all of the inputs come from us
- Not replacing a transaction or being replaced by a transaction
- Not spent
- An output's value is added to the balance when:
- The output has been mined in a block OR is in the mempool
- Not an immature coinbase
- Not spent
- An output is considered spent:
- There exists a transaction spending that output that has been mined in a block OR (is not conflicted AND has not been abandoned)
Transactions and their respective transaction states are written to the database and read when a wallet is loaded. These transaction states are then checked after adding them to mapWallet
just in case their state has changed while the wallet was unloaded.
- It starts at
WalletBatch::LoadWallet
:LoadWallet
callsReadKeyValue
, which is used to load information from the database into the wallet.- Because the transaction state is serialized as part of the transaction record in the database,
ReadKeyValue
just unserializes the transaction into aCWalletTx
. - Then,
LoadToWallet
is called, which then checks whether the transaction state is either confirmed or conflicted, and if it can't be found in the blockchain, the tx state is updated toTxStateInactive
. - It is important to note here that a wallet's
m_spk_managers
map is not updated until after transactions are deserialized from the database and added tomapWallet
. This is important to note because when a UTXO pool is being constructed,IsMine
will always return asfalse
, since it has no way of identifying outputs that belong to the wallet without SPKMans. This means that it is important to iterate throughmapWallet
and update a UTXO pool accordingly at the end ofCWallet::LoadWallet
.
SubmitTxMemoryPoolAndRelay
: if broadcast is successful, the state is changed toTxStateInMempool{}
. This is called by:CommitTransaction
: Usually called after callingCreateTransaction
ResubmitWalletTransactions
: resubmits wallet transactions to the mempool, primarily to ensure that our own mempool is aware of our transactions. called periodically to relay unconfirmed transactions.
MarkConflicted
: Marks a transaction and its in-wallet descendants as conflicting with a particular block. The state is changed toTxStateConflicted
.AbandonTransaction
: Just the RPCabandontransaction
. Marks a transaction and its in-wallet descendants as abandoned. The state is changed toTxStateInactive
.AddToWallet
: This only changes the state when the wallet already knows about the given transaction, but the state just needs to be updated. This is called by:AddToWalletIfInvolvingMe
: Only add if the tx is related- Called by
SyncTransaction
:transactionAddedToMempool
: changes state toTxStateInMempool
if it is in the mempool, if not but it was marked as being in the mempool, change toTxStateInactive
. (Learn more about this by looking atRefreshMempoolStatus
)transactionRemovedFromMempool
: if the transaction is actually in the mempool, make itTxStateInMempool
, if it was not in the mempool but markedTxStateInMempool
, mark it asTxStateInactive
. Additionally, if the reason why the transaction was removed is a conflict, then mark it asTxStateInactive
. (as a side note: I think that there might be some redundancy here)blockConnected
: Marks all txs in block asTxStateConfirmed
. also callstransactionRemovedFromMempool
for reasons that are beyond me.blockDisconnected
: Marks all txs in block asTxStateInactive
. If a previously conflicted transaction is no longer conflicted, then mark that tx asTxStateInactive
instead ofTxStateConflicted
(see #27145)ScanForWalletTransactions
: Marks txs found in blocks asTxStateConfirmed
- Called by
CommitTransaction
: This just adds a transaction to the wallet asTxStateInactive
as transaction history. The state is later changed whenSubmitTxMemoryPoolAndRelay
is called [see above]
- #27307: wallet: track mempool conflicts with wallet transactions