aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Dobson <dobsonsa68@gmail.com>2021-09-23 00:17:55 +1200
committerSamuel Dobson <dobsonsa68@gmail.com>2021-09-25 23:50:06 +1200
commitc52789365e5dbcb25aa5f1775de4d318da79e5a7 (patch)
tree084875ba97e0bb82e4a34d5b1f2448af999dfbe3
parent51c7d88e6790d857b9920bb8b51422320dde662d (diff)
Allow locked UTXOs to be store in the wallet database
-rw-r--r--src/interfaces/wallet.h4
-rw-r--r--src/wallet/interfaces.cpp4
-rw-r--r--src/wallet/wallet.cpp37
-rw-r--r--src/wallet/wallet.h10
-rw-r--r--src/wallet/walletdb.cpp17
-rw-r--r--src/wallet/walletdb.h4
6 files changed, 58 insertions, 18 deletions
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index a85db04b8b..f92d100ef5 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -122,10 +122,10 @@ public:
virtual bool displayAddress(const CTxDestination& dest) = 0;
//! Lock coin.
- virtual void lockCoin(const COutPoint& output) = 0;
+ virtual bool lockCoin(const COutPoint& output) = 0;
//! Unlock coin.
- virtual void unlockCoin(const COutPoint& output) = 0;
+ virtual bool unlockCoin(const COutPoint& output) = 0;
//! Return whether coin is locked.
virtual bool isLockedCoin(const COutPoint& output) = 0;
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index 9a8c1e3c02..809569cfaa 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -214,12 +214,12 @@ public:
LOCK(m_wallet->cs_wallet);
return m_wallet->DisplayAddress(dest);
}
- void lockCoin(const COutPoint& output) override
+ bool lockCoin(const COutPoint& output) override
{
LOCK(m_wallet->cs_wallet);
return m_wallet->LockCoin(output);
}
- void unlockCoin(const COutPoint& output) override
+ bool unlockCoin(const COutPoint& output) override
{
LOCK(m_wallet->cs_wallet);
return m_wallet->UnlockCoin(output);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 70349b2455..a9610d05a4 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -589,11 +589,16 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
return false;
}
-void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
+void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch)
{
mapTxSpends.insert(std::make_pair(outpoint, wtxid));
- setLockedCoins.erase(outpoint);
+ if (batch) {
+ UnlockCoin(outpoint, batch);
+ } else {
+ WalletBatch temp_batch(GetDatabase());
+ UnlockCoin(outpoint, &temp_batch);
+ }
std::pair<TxSpends::iterator, TxSpends::iterator> range;
range = mapTxSpends.equal_range(outpoint);
@@ -601,7 +606,7 @@ void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
}
-void CWallet::AddToSpends(const uint256& wtxid)
+void CWallet::AddToSpends(const uint256& wtxid, WalletBatch* batch)
{
auto it = mapWallet.find(wtxid);
assert(it != mapWallet.end());
@@ -610,7 +615,7 @@ void CWallet::AddToSpends(const uint256& wtxid)
return;
for (const CTxIn& txin : thisTx.tx->vin)
- AddToSpends(txin.prevout, wtxid);
+ AddToSpends(txin.prevout, wtxid, batch);
}
bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
@@ -910,7 +915,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
wtx.nOrderPos = IncOrderPosNext(&batch);
wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
wtx.nTimeSmart = ComputeTimeSmart(wtx);
- AddToSpends(hash);
+ AddToSpends(hash, &batch);
}
if (!fInsertedNew)
@@ -2260,22 +2265,36 @@ bool CWallet::DisplayAddress(const CTxDestination& dest)
return signer_spk_man->DisplayAddress(scriptPubKey, signer);
}
-void CWallet::LockCoin(const COutPoint& output)
+bool CWallet::LockCoin(const COutPoint& output, WalletBatch* batch)
{
AssertLockHeld(cs_wallet);
setLockedCoins.insert(output);
+ if (batch) {
+ return batch->WriteLockedUTXO(output);
+ }
+ return true;
}
-void CWallet::UnlockCoin(const COutPoint& output)
+bool CWallet::UnlockCoin(const COutPoint& output, WalletBatch* batch)
{
AssertLockHeld(cs_wallet);
- setLockedCoins.erase(output);
+ bool was_locked = setLockedCoins.erase(output);
+ if (batch && was_locked) {
+ return batch->EraseLockedUTXO(output);
+ }
+ return true;
}
-void CWallet::UnlockAllCoins()
+bool CWallet::UnlockAllCoins()
{
AssertLockHeld(cs_wallet);
+ bool success = true;
+ WalletBatch batch(GetDatabase());
+ for (auto it = setLockedCoins.begin(); it != setLockedCoins.end(); ++it) {
+ success &= batch.EraseLockedUTXO(*it);
+ }
setLockedCoins.clear();
+ return success;
}
bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 2dc9eff712..6b4bcf31c4 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -256,8 +256,8 @@ private:
*/
typedef std::multimap<COutPoint, uint256> TxSpends;
TxSpends mapTxSpends GUARDED_BY(cs_wallet);
- void AddToSpends(const COutPoint& outpoint, const uint256& wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- void AddToSpends(const uint256& wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void AddToSpends(const uint256& wtxid, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/**
* Add a transaction to the wallet, or update it. pIndex and posInBlock should
@@ -449,9 +449,9 @@ public:
bool DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- void LockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- void UnlockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- void UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool LockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool UnlockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void ListLockedCoins(std::vector<COutPoint>& vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/*
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 03464cd2c8..c697534c06 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -40,6 +40,7 @@ const std::string FLAGS{"flags"};
const std::string HDCHAIN{"hdchain"};
const std::string KEYMETA{"keymeta"};
const std::string KEY{"key"};
+const std::string LOCKED_UTXO{"lockedutxo"};
const std::string MASTER_KEY{"mkey"};
const std::string MINVERSION{"minversion"};
const std::string NAME{"name"};
@@ -284,6 +285,16 @@ bool WalletBatch::WriteDescriptorCacheItems(const uint256& desc_id, const Descri
return true;
}
+bool WalletBatch::WriteLockedUTXO(const COutPoint& output)
+{
+ return WriteIC(std::make_pair(DBKeys::LOCKED_UTXO, std::make_pair(output.hash, output.n)), uint8_t{'1'});
+}
+
+bool WalletBatch::EraseLockedUTXO(const COutPoint& output)
+{
+ return EraseIC(std::make_pair(DBKeys::LOCKED_UTXO, std::make_pair(output.hash, output.n)));
+}
+
class CWalletScanState {
public:
unsigned int nKeys{0};
@@ -701,6 +712,12 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
wss.m_descriptor_crypt_keys.insert(std::make_pair(std::make_pair(desc_id, pubkey.GetID()), std::make_pair(pubkey, privkey)));
wss.fIsEncrypted = true;
+ } else if (strType == DBKeys::LOCKED_UTXO) {
+ uint256 hash;
+ uint32_t n;
+ ssKey >> hash;
+ ssKey >> n;
+ pwallet->LockCoin(COutPoint(hash, n));
} else if (strType != DBKeys::BESTBLOCK && strType != DBKeys::BESTBLOCK_NOMERKLE &&
strType != DBKeys::MINVERSION && strType != DBKeys::ACENTRY &&
strType != DBKeys::VERSION && strType != DBKeys::SETTINGS &&
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index 25c2ec5909..a549c8039c 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -65,6 +65,7 @@ extern const std::string FLAGS;
extern const std::string HDCHAIN;
extern const std::string KEY;
extern const std::string KEYMETA;
+extern const std::string LOCKED_UTXO;
extern const std::string MASTER_KEY;
extern const std::string MINVERSION;
extern const std::string NAME;
@@ -250,6 +251,9 @@ public:
bool WriteDescriptorLastHardenedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
bool WriteDescriptorCacheItems(const uint256& desc_id, const DescriptorCache& cache);
+ bool WriteLockedUTXO(const COutPoint& output);
+ bool EraseLockedUTXO(const COutPoint& output);
+
/// Write destination data key,value tuple to database
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);
/// Erase destination data tuple from wallet database