@@ -329,36 +329,21 @@ bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t i
329
329
{
330
330
LOCK (cs_KeyStore);
331
331
332
- if (m_storage.IsLocked ()) return false ;
333
-
334
332
auto it = m_inactive_hd_chains.find (seed_id);
335
333
if (it == m_inactive_hd_chains.end ()) {
336
334
return false ;
337
335
}
338
336
339
337
CHDChain& chain = it->second ;
340
338
341
- // Top up key pool
342
- int64_t target_size = std::max (gArgs .GetIntArg (" -keypool" , DEFAULT_KEYPOOL_SIZE), (int64_t ) 1 );
343
-
344
- // "size" of the keypools. Not really the size, actually the difference between index and the chain counter
345
- // Since chain counter is 1 based and index is 0 based, one of them needs to be offset by 1.
346
- int64_t kp_size = (internal ? chain.nInternalChainCounter : chain.nExternalChainCounter ) - (index + 1 );
339
+ if (internal) {
340
+ chain.m_next_internal_index = std::max (chain.m_next_internal_index , index + 1 );
341
+ } else {
342
+ chain.m_next_external_index = std::max (chain.m_next_external_index , index + 1 );
343
+ }
347
344
348
- // make sure the keypool fits the user-selected target (-keypool)
349
- int64_t missing = std::max (target_size - kp_size, (int64_t ) 0 );
345
+ TopUpChain (chain, 0 );
350
346
351
- if (missing > 0 ) {
352
- WalletBatch batch (m_storage.GetDatabase ());
353
- for (int64_t i = missing; i > 0 ; --i) {
354
- GenerateNewKey (batch, chain, internal);
355
- }
356
- if (internal) {
357
- WalletLogPrintf (" inactive seed with id %s added %d internal keys\n " , HexStr (seed_id), missing);
358
- } else {
359
- WalletLogPrintf (" inactive seed with id %s added %d keys\n " , HexStr (seed_id), missing);
360
- }
361
- }
362
347
return true ;
363
348
}
364
349
@@ -390,11 +375,26 @@ std::vector<WalletDestination> LegacyScriptPubKeyMan::MarkUnusedAddresses(const
390
375
if (it != mapKeyMetadata.end ()){
391
376
CKeyMetadata meta = it->second ;
392
377
if (!meta.hd_seed_id .IsNull () && meta.hd_seed_id != m_hd_chain.seed_id ) {
393
- bool internal = (meta.key_origin .path [1 ] & ~BIP32_HARDENED_KEY_LIMIT) != 0 ;
394
- int64_t index = meta.key_origin .path [2 ] & ~BIP32_HARDENED_KEY_LIMIT;
395
-
396
- if (!TopUpInactiveHDChain (meta.hd_seed_id , index , internal)) {
397
- WalletLogPrintf (" %s: Adding inactive seed keys failed\n " , __func__);
378
+ std::vector<uint32_t > path;
379
+ if (meta.has_key_origin ) {
380
+ path = meta.key_origin .path ;
381
+ } else if (!ParseHDKeypath (meta.hdKeypath , path)) {
382
+ WalletLogPrintf (" %s: Adding inactive seed keys failed, invalid hdKeypath: %s\n " ,
383
+ __func__,
384
+ meta.hdKeypath );
385
+ }
386
+ if (path.size () != 3 ) {
387
+ WalletLogPrintf (" %s: Adding inactive seed keys failed, invalid path size: %d, has_key_origin: %s\n " ,
388
+ __func__,
389
+ path.size (),
390
+ meta.has_key_origin );
391
+ } else {
392
+ bool internal = (path[1 ] & ~BIP32_HARDENED_KEY_LIMIT) != 0 ;
393
+ int64_t index = path[2 ] & ~BIP32_HARDENED_KEY_LIMIT;
394
+
395
+ if (!TopUpInactiveHDChain (meta.hd_seed_id , index , internal)) {
396
+ WalletLogPrintf (" %s: Adding inactive seed keys failed\n " , __func__);
397
+ }
398
398
}
399
399
}
400
400
}
@@ -1271,44 +1271,69 @@ bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
1271
1271
if (!CanGenerateKeys ()) {
1272
1272
return false ;
1273
1273
}
1274
- {
1275
- LOCK (cs_KeyStore);
1276
1274
1277
- if (m_storage.IsLocked ()) return false ;
1275
+ if (!TopUpChain (m_hd_chain, kpSize)) {
1276
+ return false ;
1277
+ }
1278
+ for (auto & [chain_id, chain] : m_inactive_hd_chains) {
1279
+ if (!TopUpChain (chain, kpSize)) {
1280
+ return false ;
1281
+ }
1282
+ }
1283
+ NotifyCanGetAddressesChanged ();
1284
+ return true ;
1285
+ }
1278
1286
1279
- // Top up key pool
1280
- unsigned int nTargetSize;
1281
- if (kpSize > 0 )
1282
- nTargetSize = kpSize;
1283
- else
1284
- nTargetSize = std::max (gArgs .GetIntArg (" -keypool" , DEFAULT_KEYPOOL_SIZE), (int64_t ) 0 );
1287
+ bool LegacyScriptPubKeyMan::TopUpChain (CHDChain& chain, unsigned int kpSize)
1288
+ {
1289
+ LOCK (cs_KeyStore);
1285
1290
1286
- // count amount of available keys (internal, external)
1287
- // make sure the keypool of external and internal keys fits the user selected target (-keypool)
1288
- int64_t missingExternal = std::max (std::max ((int64_t ) nTargetSize, (int64_t ) 1 ) - (int64_t )setExternalKeyPool.size (), (int64_t ) 0 );
1289
- int64_t missingInternal = std::max (std::max ((int64_t ) nTargetSize, (int64_t ) 1 ) - (int64_t )setInternalKeyPool.size (), (int64_t ) 0 );
1291
+ if (m_storage.IsLocked ()) return false ;
1290
1292
1291
- if (!IsHDEnabled () || !m_storage.CanSupportFeature (FEATURE_HD_SPLIT))
1292
- {
1293
- // don't create extra internal keys
1294
- missingInternal = 0 ;
1293
+ // Top up key pool
1294
+ unsigned int nTargetSize;
1295
+ if (kpSize > 0 ) {
1296
+ nTargetSize = kpSize;
1297
+ } else {
1298
+ nTargetSize = std::max (gArgs .GetIntArg (" -keypool" , DEFAULT_KEYPOOL_SIZE), int64_t {0 });
1299
+ }
1300
+ int64_t target = std::max ((int64_t ) nTargetSize, int64_t {1 });
1301
+
1302
+ // count amount of available keys (internal, external)
1303
+ // make sure the keypool of external and internal keys fits the user selected target (-keypool)
1304
+ int64_t missingExternal;
1305
+ int64_t missingInternal;
1306
+ if (chain == m_hd_chain) {
1307
+ missingExternal = std::max (target - (int64_t )setExternalKeyPool.size (), int64_t {0 });
1308
+ missingInternal = std::max (target - (int64_t )setInternalKeyPool.size (), int64_t {0 });
1309
+ } else {
1310
+ missingExternal = std::max (target - (chain.nExternalChainCounter - chain.m_next_external_index ), int64_t {0 });
1311
+ missingInternal = std::max (target - (chain.nInternalChainCounter - chain.m_next_internal_index ), int64_t {0 });
1312
+ }
1313
+
1314
+ if (!IsHDEnabled () || !m_storage.CanSupportFeature (FEATURE_HD_SPLIT)) {
1315
+ // don't create extra internal keys
1316
+ missingInternal = 0 ;
1317
+ }
1318
+ bool internal = false ;
1319
+ WalletBatch batch (m_storage.GetDatabase ());
1320
+ for (int64_t i = missingInternal + missingExternal; i--;) {
1321
+ if (i < missingInternal) {
1322
+ internal = true ;
1295
1323
}
1296
- bool internal = false ;
1297
- WalletBatch batch (m_storage.GetDatabase ());
1298
- for (int64_t i = missingInternal + missingExternal; i--;)
1299
- {
1300
- if (i < missingInternal) {
1301
- internal = true ;
1302
- }
1303
1324
1304
- CPubKey pubkey (GenerateNewKey (batch, m_hd_chain, internal));
1325
+ CPubKey pubkey (GenerateNewKey (batch, chain, internal));
1326
+ if (chain == m_hd_chain) {
1305
1327
AddKeypoolPubkeyWithDB (pubkey, internal, batch);
1306
1328
}
1307
- if (missingInternal + missingExternal > 0 ) {
1329
+ }
1330
+ if (missingInternal + missingExternal > 0 ) {
1331
+ if (chain == m_hd_chain) {
1308
1332
WalletLogPrintf (" keypool added %d keys (%d internal), size=%u (%u internal)\n " , missingInternal + missingExternal, missingInternal, setInternalKeyPool.size () + setExternalKeyPool.size () + set_pre_split_keypool.size (), setInternalKeyPool.size ());
1333
+ } else {
1334
+ WalletLogPrintf (" inactive seed with id %s added %d external keys, %d internal keys\n " , HexStr (chain.seed_id ), missingExternal, missingInternal);
1309
1335
}
1310
1336
}
1311
- NotifyCanGetAddressesChanged ();
1312
1337
return true ;
1313
1338
}
1314
1339
0 commit comments