@@ -276,7 +276,7 @@ std::string COutput::ToString() const
276
276
277
277
const CWalletTx* CWallet::GetWalletTx (const uint256& hash) const
278
278
{
279
- LOCK (cs_wallet);
279
+ AssertLockHeld (cs_wallet);
280
280
std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find (hash);
281
281
if (it == mapWallet.end ())
282
282
return nullptr ;
@@ -1210,15 +1210,13 @@ void CWallet::BlockUntilSyncedToCurrentChain() const {
1210
1210
1211
1211
isminetype CWallet::IsMine (const CTxIn &txin) const
1212
1212
{
1213
+ AssertLockHeld (cs_wallet);
1214
+ std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find (txin.prevout .hash );
1215
+ if (mi != mapWallet.end ())
1213
1216
{
1214
- LOCK (cs_wallet);
1215
- std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find (txin.prevout .hash );
1216
- if (mi != mapWallet.end ())
1217
- {
1218
- const CWalletTx& prev = (*mi).second ;
1219
- if (txin.prevout .n < prev.tx ->vout .size ())
1220
- return IsMine (prev.tx ->vout [txin.prevout .n ]);
1221
- }
1217
+ const CWalletTx& prev = (*mi).second ;
1218
+ if (txin.prevout .n < prev.tx ->vout .size ())
1219
+ return IsMine (prev.tx ->vout [txin.prevout .n ]);
1222
1220
}
1223
1221
return ISMINE_NO;
1224
1222
}
@@ -1243,16 +1241,19 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
1243
1241
1244
1242
isminetype CWallet::IsMine (const CTxOut& txout) const
1245
1243
{
1244
+ AssertLockHeld (cs_wallet);
1246
1245
return IsMine (txout.scriptPubKey );
1247
1246
}
1248
1247
1249
1248
isminetype CWallet::IsMine (const CTxDestination& dest) const
1250
1249
{
1250
+ AssertLockHeld (cs_wallet);
1251
1251
return IsMine (GetScriptForDestination (dest));
1252
1252
}
1253
1253
1254
1254
isminetype CWallet::IsMine (const CScript& script) const
1255
1255
{
1256
+ AssertLockHeld (cs_wallet);
1256
1257
isminetype result = ISMINE_NO;
1257
1258
for (const auto & spk_man_pair : m_spk_managers) {
1258
1259
result = std::max (result, spk_man_pair.second ->IsMine (script));
@@ -1264,6 +1265,7 @@ CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) cons
1264
1265
{
1265
1266
if (!MoneyRange (txout.nValue ))
1266
1267
throw std::runtime_error (std::string (__func__) + " : value out of range" );
1268
+ LOCK (cs_wallet);
1267
1269
return ((IsMine (txout) & filter) ? txout.nValue : 0 );
1268
1270
}
1269
1271
@@ -1281,13 +1283,12 @@ bool CWallet::IsChange(const CScript& script) const
1281
1283
// a better way of identifying which outputs are 'the send' and which are
1282
1284
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
1283
1285
// which output, if any, was change).
1286
+ AssertLockHeld (cs_wallet);
1284
1287
if (IsMine (script))
1285
1288
{
1286
1289
CTxDestination address;
1287
1290
if (!ExtractDestination (script, address))
1288
1291
return true ;
1289
-
1290
- LOCK (cs_wallet);
1291
1292
if (!FindAddressBookEntry (address)) {
1292
1293
return true ;
1293
1294
}
@@ -1297,13 +1298,15 @@ bool CWallet::IsChange(const CScript& script) const
1297
1298
1298
1299
CAmount CWallet::GetChange (const CTxOut& txout) const
1299
1300
{
1301
+ AssertLockHeld (cs_wallet);
1300
1302
if (!MoneyRange (txout.nValue ))
1301
1303
throw std::runtime_error (std::string (__func__) + " : value out of range" );
1302
1304
return (IsChange (txout) ? txout.nValue : 0 );
1303
1305
}
1304
1306
1305
1307
bool CWallet::IsMine (const CTransaction& tx) const
1306
1308
{
1309
+ AssertLockHeld (cs_wallet);
1307
1310
for (const CTxOut& txout : tx.vout )
1308
1311
if (IsMine (txout))
1309
1312
return true ;
@@ -1362,6 +1365,7 @@ CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) c
1362
1365
1363
1366
CAmount CWallet::GetChange (const CTransaction& tx) const
1364
1367
{
1368
+ LOCK (cs_wallet);
1365
1369
CAmount nChange = 0 ;
1366
1370
for (const CTxOut& txout : tx.vout )
1367
1371
{
@@ -1597,6 +1601,7 @@ void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
1597
1601
nFee = nDebit - nValueOut;
1598
1602
}
1599
1603
1604
+ LOCK (pwallet->cs_wallet );
1600
1605
// Sent/received.
1601
1606
for (unsigned int i = 0 ; i < tx->vout .size (); ++i)
1602
1607
{
@@ -1983,6 +1988,7 @@ bool CWalletTx::IsTrusted(std::set<uint256>& trusted_parents) const
1983
1988
if (!InMempool ()) return false ;
1984
1989
1985
1990
// Trusted if all inputs are from us and are in the mempool:
1991
+ LOCK (pwallet->cs_wallet );
1986
1992
for (const CTxIn& txin : tx->vin )
1987
1993
{
1988
1994
// Transactions not sent by us: not trusted
@@ -3194,15 +3200,17 @@ DBErrors CWallet::ZapWalletTx(std::list<CWalletTx>& vWtx)
3194
3200
bool CWallet::SetAddressBookWithDB (WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3195
3201
{
3196
3202
bool fUpdated = false ;
3203
+ bool is_mine;
3197
3204
{
3198
3205
LOCK (cs_wallet);
3199
3206
std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find (address);
3200
3207
fUpdated = (mi != m_address_book.end () && !mi->second .IsChange ());
3201
3208
m_address_book[address].SetLabel (strName);
3202
3209
if (!strPurpose.empty ()) /* update purpose only if requested */
3203
3210
m_address_book[address].purpose = strPurpose;
3211
+ is_mine = IsMine (address) != ISMINE_NO;
3204
3212
}
3205
- NotifyAddressBookChanged (this , address, strName, IsMine (address) != ISMINE_NO ,
3213
+ NotifyAddressBookChanged (this , address, strName, is_mine ,
3206
3214
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
3207
3215
if (!strPurpose.empty () && !batch.WritePurpose (EncodeDestination (address), strPurpose))
3208
3216
return false ;
@@ -3217,27 +3225,27 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& s
3217
3225
3218
3226
bool CWallet::DelAddressBook (const CTxDestination& address)
3219
3227
{
3220
- // If we want to delete receiving addresses, we need to take care that DestData "used" (and possibly newer DestData) gets preserved (and the "deleted" address transformed into a change entry instead of actually being deleted)
3221
- // NOTE: This isn't a problem for sending addresses because they never have any DestData yet!
3222
- // When adding new DestData, it should be considered here whether to retain or delete it (or move it?).
3223
- if (IsMine (address)) {
3224
- WalletLogPrintf (" %s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n " , __func__, PACKAGE_BUGREPORT);
3225
- return false ;
3226
- }
3227
-
3228
+ bool is_mine;
3228
3229
{
3229
3230
LOCK (cs_wallet);
3230
-
3231
+ // If we want to delete receiving addresses, we need to take care that DestData "used" (and possibly newer DestData) gets preserved (and the "deleted" address transformed into a change entry instead of actually being deleted)
3232
+ // NOTE: This isn't a problem for sending addresses because they never have any DestData yet!
3233
+ // When adding new DestData, it should be considered here whether to retain or delete it (or move it?).
3234
+ if (IsMine (address)) {
3235
+ WalletLogPrintf (" %s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n " , __func__, PACKAGE_BUGREPORT);
3236
+ return false ;
3237
+ }
3231
3238
// Delete destdata tuples associated with address
3232
3239
std::string strAddress = EncodeDestination (address);
3233
3240
for (const std::pair<const std::string, std::string> &item : m_address_book[address].destdata )
3234
3241
{
3235
3242
WalletBatch (*database).EraseDestData (strAddress, item.first );
3236
3243
}
3237
3244
m_address_book.erase (address);
3245
+ is_mine = IsMine (address) != ISMINE_NO;
3238
3246
}
3239
3247
3240
- NotifyAddressBookChanged (this , address, " " , IsMine (address) != ISMINE_NO , " " , CT_DELETED);
3248
+ NotifyAddressBookChanged (this , address, " " , is_mine , " " , CT_DELETED);
3241
3249
3242
3250
WalletBatch (*database).ErasePurpose (EncodeDestination (address));
3243
3251
return WalletBatch (*database).EraseName (EncodeDestination (address));
0 commit comments