| 1049 | } |
| 1050 | |
| 1051 | bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int size) |
| 1052 | { |
| 1053 | LOCK(cs_desc_man); |
| 1054 | std::set<CScript> new_spks; |
| 1055 | unsigned int target_size; |
| 1056 | if (size > 0) { |
| 1057 | target_size = size; |
| 1058 | } else { |
| 1059 | target_size = m_keypool_size; |
| 1060 | } |
| 1061 | |
| 1062 | // Calculate the new range_end |
| 1063 | int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end); |
| 1064 | |
| 1065 | // If the descriptor is not ranged, we actually just want to fill the first cache item |
| 1066 | if (!m_wallet_descriptor.descriptor->IsRange()) { |
| 1067 | new_range_end = 1; |
| 1068 | m_wallet_descriptor.range_end = 1; |
| 1069 | m_wallet_descriptor.range_start = 0; |
| 1070 | } |
| 1071 | |
| 1072 | FlatSigningProvider provider; |
| 1073 | provider.keys = GetKeys(); |
| 1074 | |
| 1075 | uint256 id = GetID(); |
| 1076 | for (int32_t i = m_max_cached_index + 1; i < new_range_end; ++i) { |
| 1077 | FlatSigningProvider out_keys; |
| 1078 | std::vector<CScript> scripts_temp; |
| 1079 | DescriptorCache temp_cache; |
| 1080 | // Maybe we have a cached xpub and we can expand from the cache first |
| 1081 | if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) { |
| 1082 | if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache)) return false; |
| 1083 | } |
| 1084 | // Add all of the scriptPubKeys to the scriptPubKey set |
| 1085 | new_spks.insert(scripts_temp.begin(), scripts_temp.end()); |
| 1086 | for (const CScript& script : scripts_temp) { |
| 1087 | m_map_script_pub_keys[script] = i; |
| 1088 | } |
| 1089 | for (const auto& pk_pair : out_keys.pubkeys) { |
| 1090 | const CPubKey& pubkey = pk_pair.second; |
| 1091 | if (m_map_pubkeys.contains(pubkey)) { |
| 1092 | // We don't need to give an error here. |
| 1093 | // It doesn't matter which of many valid indexes the pubkey has, we just need an index where we can derive it and its private key |
| 1094 | continue; |
| 1095 | } |
| 1096 | m_map_pubkeys[pubkey] = i; |
| 1097 | } |
| 1098 | // Merge and write the cache |
| 1099 | DescriptorCache new_items = m_wallet_descriptor.cache.MergeAndDiff(temp_cache); |
| 1100 | if (!batch.WriteDescriptorCacheItems(id, new_items)) { |
| 1101 | throw std::runtime_error(std::string(__func__) + ": writing cache items failed"); |
| 1102 | } |
| 1103 | m_max_cached_index++; |
| 1104 | } |
| 1105 | m_wallet_descriptor.range_end = new_range_end; |
| 1106 | batch.WriteDescriptor(GetID(), m_wallet_descriptor); |
| 1107 | |
| 1108 | // By this point, the cache size should be the size of the entire range |
no test coverage detected