MCPcopy Create free account
hub / github.com/ElementsProject/elements / AttachChain

Method AttachChain

src/wallet/wallet.cpp:3164–3249  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3162}
3163
3164bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interfaces::Chain& chain, const bool rescan_required, bilingual_str& error, std::vector<bilingual_str>& warnings)
3165{
3166 LOCK(walletInstance->cs_wallet);
3167 // allow setting the chain if it hasn't been set already but prevent changing it
3168 assert(!walletInstance->m_chain || walletInstance->m_chain == &chain);
3169 walletInstance->m_chain = &chain;
3170
3171 // Register wallet with validationinterface. It's done before rescan to avoid
3172 // missing block connections between end of rescan and validation subscribing.
3173 // Because of wallet lock being hold, block connection notifications are going to
3174 // be pending on the validation-side until lock release. It's likely to have
3175 // block processing duplicata (if rescan block range overlaps with notification one)
3176 // but we guarantee at least than wallet state is correct after notifications delivery.
3177 // This is temporary until rescan and notifications delivery are unified under same
3178 // interface.
3179 walletInstance->m_chain_notifications_handler = walletInstance->chain().handleNotifications(walletInstance);
3180
3181 // If rescan_required = true, rescan_height remains equal to 0
3182 int rescan_height = 0;
3183 if (!rescan_required)
3184 {
3185 WalletBatch batch(walletInstance->GetDatabase());
3186 CBlockLocator locator;
3187 if (batch.ReadBestBlock(locator)) {
3188 if (const std::optional<int> fork_height = chain.findLocatorFork(locator)) {
3189 rescan_height = *fork_height;
3190 }
3191 }
3192 }
3193
3194 const std::optional<int> tip_height = chain.getHeight();
3195 if (tip_height) {
3196 walletInstance->m_last_block_processed = chain.getBlockHash(*tip_height);
3197 walletInstance->m_last_block_processed_height = *tip_height;
3198 } else {
3199 walletInstance->m_last_block_processed.SetNull();
3200 walletInstance->m_last_block_processed_height = -1;
3201 }
3202
3203 if (tip_height && *tip_height != rescan_height)
3204 {
3205 if (chain.havePruned()) {
3206 int block_height = *tip_height;
3207 while (block_height > 0 && chain.haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
3208 --block_height;
3209 }
3210
3211 if (rescan_height != block_height) {
3212 // We can't rescan beyond non-pruned blocks, stop and throw an error.
3213 // This might happen if a user uses an old wallet within a pruned node
3214 // or if they ran -disablewallet for a longer time, then decided to re-enable
3215 // Exit early and print an error.
3216 // If a block is pruned after this check, we will load the wallet,
3217 // but fail the rescan with a generic error.
3218 error = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
3219 return false;
3220 }
3221 }

Callers

nothing calls this directly

Calls 15

_Function · 0.85
FoundBlockClass · 0.85
handleNotificationsMethod · 0.80
findLocatorForkMethod · 0.80
getHeightMethod · 0.80
getBlockHashMethod · 0.80
havePrunedMethod · 0.80
haveBlockOnDiskMethod · 0.80
initMessageMethod · 0.80

Tested by

no test coverage detected