@@ -320,7 +320,7 @@ bool CWallet::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& secret, const C
320
320
secret.GetPrivKey (),
321
321
mapKeyMetadata[pubkey.GetID ()]);
322
322
}
323
- UnsetWalletFlag ( WALLET_FLAG_BLANK_WALLET);
323
+ UnsetWalletFlagWithDB (batch, WALLET_FLAG_BLANK_WALLET);
324
324
return true ;
325
325
}
326
326
@@ -362,12 +362,6 @@ void CWallet::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata&
362
362
m_script_metadata[script_id] = meta;
363
363
}
364
364
365
- // Writes a keymetadata for a public key. overwrite specifies whether to overwrite an existing metadata for that key if there exists one.
366
- bool CWallet::WriteKeyMetadata (const CKeyMetadata& meta, const CPubKey& pubkey, const bool overwrite)
367
- {
368
- return WalletBatch (*database).WriteKeyMetadata (meta, pubkey, overwrite);
369
- }
370
-
371
365
void CWallet::UpgradeKeyMetadata ()
372
366
{
373
367
AssertLockHeld (cs_wallet);
@@ -376,7 +370,6 @@ void CWallet::UpgradeKeyMetadata()
376
370
}
377
371
378
372
std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(*database);
379
- size_t cnt = 0 ;
380
373
for (auto & meta_pair : mapKeyMetadata) {
381
374
CKeyMetadata& meta = meta_pair.second ;
382
375
if (!meta.hd_seed_id .IsNull () && !meta.has_key_origin && meta.hdKeypath != " s" ) { // If the hdKeypath is "s", that's the seed and it doesn't have a key origin
@@ -399,10 +392,6 @@ void CWallet::UpgradeKeyMetadata()
399
392
CPubKey pubkey;
400
393
if (GetPubKey (meta_pair.first , pubkey)) {
401
394
batch->WriteKeyMetadata (meta, pubkey, true );
402
- if (++cnt % 1000 == 0 ) {
403
- // avoid creating overlarge in-memory batches in case the wallet contains large amounts of keys
404
- batch.reset (new WalletBatch (*database));
405
- }
406
395
}
407
396
}
408
397
}
@@ -432,11 +421,17 @@ void CWallet::UpdateTimeFirstKey(int64_t nCreateTime)
432
421
}
433
422
434
423
bool CWallet::AddCScript (const CScript& redeemScript)
424
+ {
425
+ WalletBatch batch (*database);
426
+ return AddCScriptWithDB (batch, redeemScript);
427
+ }
428
+
429
+ bool CWallet::AddCScriptWithDB (WalletBatch& batch, const CScript& redeemScript)
435
430
{
436
431
if (!CCryptoKeyStore::AddCScript (redeemScript))
437
432
return false ;
438
- if (WalletBatch (*database) .WriteCScript (Hash160 (redeemScript), redeemScript)) {
439
- UnsetWalletFlag ( WALLET_FLAG_BLANK_WALLET);
433
+ if (batch .WriteCScript (Hash160 (redeemScript), redeemScript)) {
434
+ UnsetWalletFlagWithDB (batch, WALLET_FLAG_BLANK_WALLET);
440
435
return true ;
441
436
}
442
437
return false ;
@@ -457,20 +452,32 @@ bool CWallet::LoadCScript(const CScript& redeemScript)
457
452
return CCryptoKeyStore::AddCScript (redeemScript);
458
453
}
459
454
460
- bool CWallet::AddWatchOnly ( const CScript& dest)
455
+ bool CWallet::AddWatchOnlyWithDB (WalletBatch &batch, const CScript& dest)
461
456
{
462
457
if (!CCryptoKeyStore::AddWatchOnly (dest))
463
458
return false ;
464
459
const CKeyMetadata& meta = m_script_metadata[CScriptID (dest)];
465
460
UpdateTimeFirstKey (meta.nCreateTime );
466
461
NotifyWatchonlyChanged (true );
467
- if (WalletBatch (*database) .WriteWatchOnly (dest, meta)) {
468
- UnsetWalletFlag ( WALLET_FLAG_BLANK_WALLET);
462
+ if (batch .WriteWatchOnly (dest, meta)) {
463
+ UnsetWalletFlagWithDB (batch, WALLET_FLAG_BLANK_WALLET);
469
464
return true ;
470
465
}
471
466
return false ;
472
467
}
473
468
469
+ bool CWallet::AddWatchOnlyWithDB (WalletBatch &batch, const CScript& dest, int64_t create_time)
470
+ {
471
+ m_script_metadata[CScriptID (dest)].nCreateTime = create_time;
472
+ return AddWatchOnlyWithDB (batch, dest);
473
+ }
474
+
475
+ bool CWallet::AddWatchOnly (const CScript& dest)
476
+ {
477
+ WalletBatch batch (*database);
478
+ return AddWatchOnlyWithDB (batch, dest);
479
+ }
480
+
474
481
bool CWallet::AddWatchOnly (const CScript& dest, int64_t nCreateTime)
475
482
{
476
483
m_script_metadata[CScriptID (dest)].nCreateTime = nCreateTime;
@@ -1542,10 +1549,16 @@ void CWallet::SetWalletFlag(uint64_t flags)
1542
1549
}
1543
1550
1544
1551
void CWallet::UnsetWalletFlag (uint64_t flag)
1552
+ {
1553
+ WalletBatch batch (*database);
1554
+ UnsetWalletFlagWithDB (batch, flag);
1555
+ }
1556
+
1557
+ void CWallet::UnsetWalletFlagWithDB (WalletBatch& batch, uint64_t flag)
1545
1558
{
1546
1559
LOCK (cs_wallet);
1547
1560
m_wallet_flags &= ~flag;
1548
- if (!WalletBatch (*database) .WriteWalletFlags (m_wallet_flags))
1561
+ if (!batch .WriteWalletFlags (m_wallet_flags))
1549
1562
throw std::runtime_error (std::string (__func__) + " : writing wallet flags failed" );
1550
1563
}
1551
1564
@@ -1606,6 +1619,80 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut>
1606
1619
return true ;
1607
1620
}
1608
1621
1622
+ bool CWallet::ImportScripts (const std::set<CScript> scripts)
1623
+ {
1624
+ WalletBatch batch (*database);
1625
+ for (const auto & entry : scripts) {
1626
+ if (!HaveCScript (CScriptID (entry)) && !AddCScriptWithDB (batch, entry)) {
1627
+ return false ;
1628
+ }
1629
+ }
1630
+ return true ;
1631
+ }
1632
+
1633
+ bool CWallet::ImportPrivKeys (const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1634
+ {
1635
+ WalletBatch batch (*database);
1636
+ for (const auto & entry : privkey_map) {
1637
+ const CKey& key = entry.second ;
1638
+ CPubKey pubkey = key.GetPubKey ();
1639
+ const CKeyID& id = entry.first ;
1640
+ assert (key.VerifyPubKey (pubkey));
1641
+ mapKeyMetadata[id].nCreateTime = timestamp;
1642
+ // If the private key is not present in the wallet, insert it.
1643
+ if (!HaveKey (id) && !AddKeyPubKeyWithDB (batch, key, pubkey)) {
1644
+ return false ;
1645
+ }
1646
+ UpdateTimeFirstKey (timestamp);
1647
+ }
1648
+ return true ;
1649
+ }
1650
+
1651
+ bool CWallet::ImportPubKeys (const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp)
1652
+ {
1653
+ WalletBatch batch (*database);
1654
+ for (const auto & entry : key_origins) {
1655
+ AddKeyOriginWithDB (batch, entry.second .first , entry.second .second );
1656
+ }
1657
+ for (const CKeyID& id : ordered_pubkeys) {
1658
+ auto entry = pubkey_map.find (id);
1659
+ if (entry == pubkey_map.end ()) {
1660
+ continue ;
1661
+ }
1662
+ const CPubKey& pubkey = entry->second ;
1663
+ CPubKey temp;
1664
+ if (!GetPubKey (id, temp) && !AddWatchOnlyWithDB (batch, GetScriptForRawPubKey (pubkey), timestamp)) {
1665
+ return false ;
1666
+ }
1667
+ mapKeyMetadata[id].nCreateTime = timestamp;
1668
+
1669
+ // Add to keypool only works with pubkeys
1670
+ if (add_keypool) {
1671
+ AddKeypoolPubkeyWithDB (pubkey, internal, batch);
1672
+ NotifyCanGetAddressesChanged ();
1673
+ }
1674
+ }
1675
+ return true ;
1676
+ }
1677
+
1678
+ bool CWallet::ImportScriptPubKeys (const std::string& label, const std::set<CScript>& script_pub_keys, const bool have_solving_data, const bool internal, const int64_t timestamp)
1679
+ {
1680
+ WalletBatch batch (*database);
1681
+ for (const CScript& script : script_pub_keys) {
1682
+ if (!have_solving_data || !::IsMine (*this , script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1683
+ if (!AddWatchOnlyWithDB (batch, script, timestamp)) {
1684
+ return false ;
1685
+ }
1686
+ }
1687
+ CTxDestination dest;
1688
+ ExtractDestination (script, dest);
1689
+ if (!internal && IsValidDestination (dest)) {
1690
+ SetAddressBookWithDB (batch, dest, label, " receive" );
1691
+ }
1692
+ }
1693
+ return true ;
1694
+ }
1695
+
1609
1696
int64_t CalculateMaximumSignedTxSize (const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
1610
1697
{
1611
1698
std::vector<CTxOut> txouts;
@@ -3149,8 +3236,7 @@ DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
3149
3236
return DBErrors::LOAD_OK;
3150
3237
}
3151
3238
3152
-
3153
- bool CWallet::SetAddressBook (const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3239
+ bool CWallet::SetAddressBookWithDB (WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3154
3240
{
3155
3241
bool fUpdated = false ;
3156
3242
{
@@ -3163,9 +3249,15 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& s
3163
3249
}
3164
3250
NotifyAddressBookChanged (this , address, strName, ::IsMine (*this , address) != ISMINE_NO,
3165
3251
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
3166
- if (!strPurpose.empty () && !WalletBatch (*database) .WritePurpose (EncodeDestination (address), strPurpose))
3252
+ if (!strPurpose.empty () && !batch .WritePurpose (EncodeDestination (address), strPurpose))
3167
3253
return false ;
3168
- return WalletBatch (*database).WriteName (EncodeDestination (address), strName);
3254
+ return batch.WriteName (EncodeDestination (address), strName);
3255
+ }
3256
+
3257
+ bool CWallet::SetAddressBook (const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3258
+ {
3259
+ WalletBatch batch (*database);
3260
+ return SetAddressBookWithDB (batch, address, strName, strPurpose);
3169
3261
}
3170
3262
3171
3263
bool CWallet::DelAddressBook (const CTxDestination& address)
@@ -3315,13 +3407,6 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
3315
3407
return true ;
3316
3408
}
3317
3409
3318
- void CWallet::AddKeypoolPubkey (const CPubKey& pubkey, const bool internal)
3319
- {
3320
- WalletBatch batch (*database);
3321
- AddKeypoolPubkeyWithDB (pubkey, internal, batch);
3322
- NotifyCanGetAddressesChanged ();
3323
- }
3324
-
3325
3410
void CWallet::AddKeypoolPubkeyWithDB (const CPubKey& pubkey, const bool internal, WalletBatch& batch)
3326
3411
{
3327
3412
LOCK (cs_wallet);
@@ -4443,12 +4528,12 @@ bool CWallet::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const
4443
4528
return true ;
4444
4529
}
4445
4530
4446
- bool CWallet::AddKeyOrigin ( const CPubKey& pubkey, const KeyOriginInfo& info)
4531
+ bool CWallet::AddKeyOriginWithDB (WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info)
4447
4532
{
4448
4533
LOCK (cs_wallet);
4449
4534
std::copy (info.fingerprint , info.fingerprint + 4 , mapKeyMetadata[pubkey.GetID ()].key_origin .fingerprint );
4450
4535
mapKeyMetadata[pubkey.GetID ()].key_origin .path = info.path ;
4451
4536
mapKeyMetadata[pubkey.GetID ()].has_key_origin = true ;
4452
4537
mapKeyMetadata[pubkey.GetID ()].hdKeypath = WriteHDKeypath (info.path );
4453
- return WriteKeyMetadata (mapKeyMetadata[pubkey.GetID ()], pubkey, true );
4538
+ return batch. WriteKeyMetadata (mapKeyMetadata[pubkey.GetID ()], pubkey, true );
4454
4539
}
0 commit comments