Skip to content

Commit c527893

Browse files
committed
Allow locked UTXOs to be store in the wallet database
1 parent 51c7d88 commit c527893

File tree

6 files changed

+58
-18
lines changed

6 files changed

+58
-18
lines changed

src/interfaces/wallet.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ class Wallet
122122
virtual bool displayAddress(const CTxDestination& dest) = 0;
123123

124124
//! Lock coin.
125-
virtual void lockCoin(const COutPoint& output) = 0;
125+
virtual bool lockCoin(const COutPoint& output) = 0;
126126

127127
//! Unlock coin.
128-
virtual void unlockCoin(const COutPoint& output) = 0;
128+
virtual bool unlockCoin(const COutPoint& output) = 0;
129129

130130
//! Return whether coin is locked.
131131
virtual bool isLockedCoin(const COutPoint& output) = 0;

src/wallet/interfaces.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,12 @@ class WalletImpl : public Wallet
214214
LOCK(m_wallet->cs_wallet);
215215
return m_wallet->DisplayAddress(dest);
216216
}
217-
void lockCoin(const COutPoint& output) override
217+
bool lockCoin(const COutPoint& output) override
218218
{
219219
LOCK(m_wallet->cs_wallet);
220220
return m_wallet->LockCoin(output);
221221
}
222-
void unlockCoin(const COutPoint& output) override
222+
bool unlockCoin(const COutPoint& output) override
223223
{
224224
LOCK(m_wallet->cs_wallet);
225225
return m_wallet->UnlockCoin(output);

src/wallet/wallet.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -589,19 +589,24 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
589589
return false;
590590
}
591591

592-
void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
592+
void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch)
593593
{
594594
mapTxSpends.insert(std::make_pair(outpoint, wtxid));
595595

596-
setLockedCoins.erase(outpoint);
596+
if (batch) {
597+
UnlockCoin(outpoint, batch);
598+
} else {
599+
WalletBatch temp_batch(GetDatabase());
600+
UnlockCoin(outpoint, &temp_batch);
601+
}
597602

598603
std::pair<TxSpends::iterator, TxSpends::iterator> range;
599604
range = mapTxSpends.equal_range(outpoint);
600605
SyncMetaData(range);
601606
}
602607

603608

604-
void CWallet::AddToSpends(const uint256& wtxid)
609+
void CWallet::AddToSpends(const uint256& wtxid, WalletBatch* batch)
605610
{
606611
auto it = mapWallet.find(wtxid);
607612
assert(it != mapWallet.end());
@@ -610,7 +615,7 @@ void CWallet::AddToSpends(const uint256& wtxid)
610615
return;
611616

612617
for (const CTxIn& txin : thisTx.tx->vin)
613-
AddToSpends(txin.prevout, wtxid);
618+
AddToSpends(txin.prevout, wtxid, batch);
614619
}
615620

616621
bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
@@ -910,7 +915,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
910915
wtx.nOrderPos = IncOrderPosNext(&batch);
911916
wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
912917
wtx.nTimeSmart = ComputeTimeSmart(wtx);
913-
AddToSpends(hash);
918+
AddToSpends(hash, &batch);
914919
}
915920

916921
if (!fInsertedNew)
@@ -2260,22 +2265,36 @@ bool CWallet::DisplayAddress(const CTxDestination& dest)
22602265
return signer_spk_man->DisplayAddress(scriptPubKey, signer);
22612266
}
22622267

2263-
void CWallet::LockCoin(const COutPoint& output)
2268+
bool CWallet::LockCoin(const COutPoint& output, WalletBatch* batch)
22642269
{
22652270
AssertLockHeld(cs_wallet);
22662271
setLockedCoins.insert(output);
2272+
if (batch) {
2273+
return batch->WriteLockedUTXO(output);
2274+
}
2275+
return true;
22672276
}
22682277

2269-
void CWallet::UnlockCoin(const COutPoint& output)
2278+
bool CWallet::UnlockCoin(const COutPoint& output, WalletBatch* batch)
22702279
{
22712280
AssertLockHeld(cs_wallet);
2272-
setLockedCoins.erase(output);
2281+
bool was_locked = setLockedCoins.erase(output);
2282+
if (batch && was_locked) {
2283+
return batch->EraseLockedUTXO(output);
2284+
}
2285+
return true;
22732286
}
22742287

2275-
void CWallet::UnlockAllCoins()
2288+
bool CWallet::UnlockAllCoins()
22762289
{
22772290
AssertLockHeld(cs_wallet);
2291+
bool success = true;
2292+
WalletBatch batch(GetDatabase());
2293+
for (auto it = setLockedCoins.begin(); it != setLockedCoins.end(); ++it) {
2294+
success &= batch.EraseLockedUTXO(*it);
2295+
}
22782296
setLockedCoins.clear();
2297+
return success;
22792298
}
22802299

22812300
bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const

src/wallet/wallet.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
256256
*/
257257
typedef std::multimap<COutPoint, uint256> TxSpends;
258258
TxSpends mapTxSpends GUARDED_BY(cs_wallet);
259-
void AddToSpends(const COutPoint& outpoint, const uint256& wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
260-
void AddToSpends(const uint256& wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
259+
void AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
260+
void AddToSpends(const uint256& wtxid, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
261261

262262
/**
263263
* Add a transaction to the wallet, or update it. pIndex and posInBlock should
@@ -449,9 +449,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
449449
bool DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
450450

451451
bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
452-
void LockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
453-
void UnlockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
454-
void UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
452+
bool LockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
453+
bool UnlockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
454+
bool UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
455455
void ListLockedCoins(std::vector<COutPoint>& vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
456456

457457
/*

src/wallet/walletdb.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const std::string FLAGS{"flags"};
4040
const std::string HDCHAIN{"hdchain"};
4141
const std::string KEYMETA{"keymeta"};
4242
const std::string KEY{"key"};
43+
const std::string LOCKED_UTXO{"lockedutxo"};
4344
const std::string MASTER_KEY{"mkey"};
4445
const std::string MINVERSION{"minversion"};
4546
const std::string NAME{"name"};
@@ -284,6 +285,16 @@ bool WalletBatch::WriteDescriptorCacheItems(const uint256& desc_id, const Descri
284285
return true;
285286
}
286287

288+
bool WalletBatch::WriteLockedUTXO(const COutPoint& output)
289+
{
290+
return WriteIC(std::make_pair(DBKeys::LOCKED_UTXO, std::make_pair(output.hash, output.n)), uint8_t{'1'});
291+
}
292+
293+
bool WalletBatch::EraseLockedUTXO(const COutPoint& output)
294+
{
295+
return EraseIC(std::make_pair(DBKeys::LOCKED_UTXO, std::make_pair(output.hash, output.n)));
296+
}
297+
287298
class CWalletScanState {
288299
public:
289300
unsigned int nKeys{0};
@@ -701,6 +712,12 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
701712

702713
wss.m_descriptor_crypt_keys.insert(std::make_pair(std::make_pair(desc_id, pubkey.GetID()), std::make_pair(pubkey, privkey)));
703714
wss.fIsEncrypted = true;
715+
} else if (strType == DBKeys::LOCKED_UTXO) {
716+
uint256 hash;
717+
uint32_t n;
718+
ssKey >> hash;
719+
ssKey >> n;
720+
pwallet->LockCoin(COutPoint(hash, n));
704721
} else if (strType != DBKeys::BESTBLOCK && strType != DBKeys::BESTBLOCK_NOMERKLE &&
705722
strType != DBKeys::MINVERSION && strType != DBKeys::ACENTRY &&
706723
strType != DBKeys::VERSION && strType != DBKeys::SETTINGS &&

src/wallet/walletdb.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ extern const std::string FLAGS;
6565
extern const std::string HDCHAIN;
6666
extern const std::string KEY;
6767
extern const std::string KEYMETA;
68+
extern const std::string LOCKED_UTXO;
6869
extern const std::string MASTER_KEY;
6970
extern const std::string MINVERSION;
7071
extern const std::string NAME;
@@ -250,6 +251,9 @@ class WalletBatch
250251
bool WriteDescriptorLastHardenedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
251252
bool WriteDescriptorCacheItems(const uint256& desc_id, const DescriptorCache& cache);
252253

254+
bool WriteLockedUTXO(const COutPoint& output);
255+
bool EraseLockedUTXO(const COutPoint& output);
256+
253257
/// Write destination data key,value tuple to database
254258
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);
255259
/// Erase destination data tuple from wallet database

0 commit comments

Comments
 (0)