aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/init.cpp6
-rw-r--r--src/wallet/scriptpubkeyman.cpp4
-rw-r--r--src/wallet/transaction.cpp25
-rw-r--r--src/wallet/transaction.h8
-rw-r--r--src/wallet/wallet.cpp20
-rw-r--r--src/wallet/wallet.h7
-rw-r--r--src/wallet/walletutil.h4
7 files changed, 48 insertions, 26 deletions
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 0d0a8650ac..088343458c 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -95,8 +95,6 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
argsman.AddArg("-walletrejectlongchains", strprintf("Wallet will not create transactions that violate mempool chain limits (default: %u)", DEFAULT_WALLET_REJECT_LONG_CHAINS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
argsman.AddArg("-walletcrosschain", strprintf("Allow reusing wallet files across chains (default: %u)", DEFAULT_WALLETCROSSCHAIN), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
-
- argsman.AddHiddenArgs({"-zapwallettxes"});
}
bool WalletInit::ParameterInteraction() const
@@ -118,10 +116,6 @@ bool WalletInit::ParameterInteraction() const
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
}
- if (gArgs.IsArgSet("-zapwallettxes")) {
- return InitError(Untranslated("-zapwallettxes has been removed. If you are attempting to remove a stuck transaction from your wallet, please use abandontransaction instead."));
- }
-
return true;
}
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index bc3327cdb2..d2b2801aa8 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -2601,7 +2601,7 @@ std::unique_ptr<CKeyMetadata> DescriptorScriptPubKeyMan::GetMetadata(const CTxDe
uint256 DescriptorScriptPubKeyMan::GetID() const
{
LOCK(cs_desc_man);
- return DescriptorID(*m_wallet_descriptor.descriptor);
+ return m_wallet_descriptor.id;
}
void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
@@ -2655,7 +2655,7 @@ bool DescriptorScriptPubKeyMan::AddCryptedKey(const CKeyID& key_id, const CPubKe
bool DescriptorScriptPubKeyMan::HasWalletDescriptor(const WalletDescriptor& desc) const
{
LOCK(cs_desc_man);
- return m_wallet_descriptor.descriptor != nullptr && desc.descriptor != nullptr && m_wallet_descriptor.descriptor->ToString() == desc.descriptor->ToString();
+ return !m_wallet_descriptor.id.IsNull() && !desc.id.IsNull() && m_wallet_descriptor.id == desc.id;
}
void DescriptorScriptPubKeyMan::WriteDescriptor()
diff --git a/src/wallet/transaction.cpp b/src/wallet/transaction.cpp
index 4f78fe7520..6777257e53 100644
--- a/src/wallet/transaction.cpp
+++ b/src/wallet/transaction.cpp
@@ -4,6 +4,10 @@
#include <wallet/transaction.h>
+#include <interfaces/chain.h>
+
+using interfaces::FoundBlock;
+
namespace wallet {
bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
{
@@ -25,6 +29,27 @@ int64_t CWalletTx::GetTxTime() const
return n ? n : nTimeReceived;
}
+void CWalletTx::updateState(interfaces::Chain& chain)
+{
+ bool active;
+ auto lookup_block = [&](const uint256& hash, int& height, TxState& state) {
+ // If tx block (or conflicting block) was reorged out of chain
+ // while the wallet was shutdown, change tx status to UNCONFIRMED
+ // and reset block height, hash, and index. ABANDONED tx don't have
+ // associated blocks and don't need to be updated. The case where a
+ // transaction was reorged out while online and then reconfirmed
+ // while offline is covered by the rescan logic.
+ if (!chain.findBlock(hash, FoundBlock().inActiveChain(active).height(height)) || !active) {
+ state = TxStateInactive{};
+ }
+ };
+ if (auto* conf = state<TxStateConfirmed>()) {
+ lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, m_state);
+ } else if (auto* conf = state<TxStateConflicted>()) {
+ lookup_block(conf->conflicting_block_hash, conf->conflicting_block_height, m_state);
+ }
+}
+
void CWalletTx::CopyFrom(const CWalletTx& _tx)
{
*this = _tx;
diff --git a/src/wallet/transaction.h b/src/wallet/transaction.h
index db858fa5ba..0c28628915 100644
--- a/src/wallet/transaction.h
+++ b/src/wallet/transaction.h
@@ -22,6 +22,10 @@
#include <variant>
#include <vector>
+namespace interfaces {
+class Chain;
+} // namespace interfaces
+
namespace wallet {
//! State of transaction confirmed in a block.
struct TxStateConfirmed {
@@ -326,6 +330,10 @@ public:
template<typename T> const T* state() const { return std::get_if<T>(&m_state); }
template<typename T> T* state() { return std::get_if<T>(&m_state); }
+ //! Update transaction state when attaching to a chain, filling in heights
+ //! of conflicted and confirmed blocks
+ void updateState(interfaces::Chain& chain);
+
bool isAbandoned() const { return state<TxStateInactive>() && state<TxStateInactive>()->abandoned; }
bool isConflicted() const { return state<TxStateConflicted>(); }
bool isInactive() const { return state<TxStateInactive>(); }
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 162d7f9ec7..ecf18fbe78 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1184,23 +1184,7 @@ bool CWallet::LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx
// If wallet doesn't have a chain (e.g when using bitcoin-wallet tool),
// don't bother to update txn.
if (HaveChain()) {
- bool active;
- auto lookup_block = [&](const uint256& hash, int& height, TxState& state) {
- // If tx block (or conflicting block) was reorged out of chain
- // while the wallet was shutdown, change tx status to UNCONFIRMED
- // and reset block height, hash, and index. ABANDONED tx don't have
- // associated blocks and don't need to be updated. The case where a
- // transaction was reorged out while online and then reconfirmed
- // while offline is covered by the rescan logic.
- if (!chain().findBlock(hash, FoundBlock().inActiveChain(active).height(height)) || !active) {
- state = TxStateInactive{};
- }
- };
- if (auto* conf = wtx.state<TxStateConfirmed>()) {
- lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, wtx.m_state);
- } else if (auto* conf = wtx.state<TxStateConflicted>()) {
- lookup_block(conf->conflicting_block_hash, conf->conflicting_block_height, wtx.m_state);
- }
+ wtx.updateState(chain());
}
if (/* insertion took place */ ins.second) {
wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
@@ -3319,8 +3303,10 @@ int CWallet::GetTxDepthInMainChain(const CWalletTx& wtx) const
{
AssertLockHeld(cs_wallet);
if (auto* conf = wtx.state<TxStateConfirmed>()) {
+ assert(conf->confirmed_block_height >= 0);
return GetLastBlockHeight() - conf->confirmed_block_height + 1;
} else if (auto* conf = wtx.state<TxStateConflicted>()) {
+ assert(conf->conflicting_block_height >= 0);
return -1 * (GetLastBlockHeight() - conf->conflicting_block_height + 1);
} else {
return 0;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 9333493a6e..0832887159 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -503,6 +503,13 @@ public:
* <0 : conflicts with a transaction this deep in the blockchain
* 0 : in memory pool, waiting to be included in a block
* >=1 : this many blocks deep in the main chain
+ *
+ * Preconditions: it is only valid to call this function when the wallet is
+ * online and the block index is loaded. So this cannot be called by
+ * bitcoin-wallet tool code or by wallet migration code. If this is called
+ * without the wallet being online, it won't be able able to determine the
+ * the height of the last block processed, or the heights of blocks
+ * referenced in transaction, and might cause assert failures.
*/
int GetTxDepthInMainChain(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool IsTxInMainChain(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
index c5975144c1..7ad3ffe9e4 100644
--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -85,6 +85,7 @@ class WalletDescriptor
{
public:
std::shared_ptr<Descriptor> descriptor;
+ uint256 id; // Descriptor ID (calculated once at descriptor initialization/deserialization)
uint64_t creation_time = 0;
int32_t range_start = 0; // First item in range; start of range, inclusive, i.e. [range_start, range_end). This never changes.
int32_t range_end = 0; // Item after the last; end of range, exclusive, i.e. [range_start, range_end). This will increment with each TopUp()
@@ -99,6 +100,7 @@ public:
if (!descriptor) {
throw std::ios_base::failure("Invalid descriptor: " + error);
}
+ id = DescriptorID(*descriptor);
}
SERIALIZE_METHODS(WalletDescriptor, obj)
@@ -110,7 +112,7 @@ public:
}
WalletDescriptor() {}
- WalletDescriptor(std::shared_ptr<Descriptor> descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index) : descriptor(descriptor), creation_time(creation_time), range_start(range_start), range_end(range_end), next_index(next_index) {}
+ WalletDescriptor(std::shared_ptr<Descriptor> descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index) : descriptor(descriptor), id(DescriptorID(*descriptor)), creation_time(creation_time), range_start(range_start), range_end(range_end), next_index(next_index) { }
};
} // namespace wallet