diff options
author | Russell Yanofsky <russ@yanofsky.org> | 2021-02-16 22:36:26 -0500 |
---|---|---|
committer | Russell Yanofsky <russ@yanofsky.org> | 2021-11-15 09:11:44 -0500 |
commit | d8ee8f3cd32bbfefec931724f5798cbb088ceb6f (patch) | |
tree | 09bea6475822b6b37ca0050d03a4394946af35a3 /src/wallet/interfaces.cpp | |
parent | 2efc8c0999a4b99cfe3076f7312806e83e778261 (diff) | |
download | bitcoin-d8ee8f3cd32bbfefec931724f5798cbb088ceb6f.tar.xz |
refactor: Make CWalletTx sync state type-safe
Current CWalletTx state representation makes it possible to set
inconsistent states that won't be handled correctly by wallet sync code
or serialized & deserialized back into the same form.
For example, it is possible to call setConflicted without setting a
conflicting block hash, or setConfirmed with no transaction index. And
it's possible update individual m_confirm and fInMempool data fields
without setting an overall consistent state that can be serialized and
handled correctly.
Fix this without changing behavior by using std::variant, instead of an
enum and collection of fields, to represent sync state, so state
tracking code is safer and more legible.
This is a first step to fixing state tracking bugs
https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Wallet-Transaction-Conflict-Tracking,
by adding an extra margin of safety that can prevent new bugs from being
introduced as existing bugs are fixed.
Diffstat (limited to 'src/wallet/interfaces.cpp')
-rw-r--r-- | src/wallet/interfaces.cpp | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index 57f1a6a67a..6489e2a5fc 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -82,7 +82,10 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) WalletTxStatus MakeWalletTxStatus(const CWallet& wallet, const CWalletTx& wtx) { WalletTxStatus result; - result.block_height = wtx.m_confirm.block_height > 0 ? wtx.m_confirm.block_height : std::numeric_limits<int>::max(); + result.block_height = + wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height : + wtx.state<TxStateConflicted>() ? wtx.state<TxStateConflicted>()->conflicting_block_height : + std::numeric_limits<int>::max(); result.blocks_to_maturity = wallet.GetTxBlocksToMaturity(wtx); result.depth_in_main_chain = wallet.GetTxDepthInMainChain(wtx); result.time_received = wtx.nTimeReceived; |