Skip to content

Allow chain sources to fetch blocks at caller-requested heights #2200

Description

@evanlinjin

Context

Related to #2199. That issue covers continuous prev-11 emission during sync. This issue covers the underlying primitive: letting a caller ask a chain source for blocks at specific heights, on demand.

Use case

A wallet wants MTP only when it actually matters — e.g., when constructing a spend that uses relative timelocks, or surfacing confirmation timestamps in a UI. Paying for prev-11 fetches on every routine sync is wasteful when the wallet may go long stretches without needing MTP at all.

The desired flow:

  1. Wallet syncs normally with no prev-11 emission. Local chain has confirmation blocks but no MTP windows.
  2. When the wallet needs MTP (e.g., before a spend), it canonicalizes and discovers some confirmed txs (and/or the tip) have None MTPs because the surrounding heights aren't in the local chain.
  3. Wallet asks the chain source to fetch a chain update covering those specific heights, passing its current local checkpoint chain as the baseline.
  4. Wallet applies the update; canonicalization now yields Some(_) MTPs.

Goal

Each chain source exposes a way to request a chain update for a caller-supplied set of heights. The returned update is reorg-aware (anchored to the current best chain) and applies cleanly to a LocalChain<Header>.

Scope

  • bdk_electrum
  • bdk_esplora

Design notes

  • Input shape. Two things: the caller's local checkpoint chain (its current CheckPoint) and the set/iterator of heights it wants. The checkpoint serves a dual purpose — it tells the source which heights the caller already has (so they aren't refetched) and provides the reorg anchor for building the update.
  • Output shape. The same chain-update type each source already produces, so application is uniform.
  • Reorg safety. Heights must be resolved against the source's current view of the best chain; if a requested height is below a reorg point relative to the caller's checkpoint, the update should reflect that.
  • Composability with Optionally emit prev-11 block headers per confirmation block and chain tip (for MTP) #2199. If both this and Optionally emit prev-11 block headers per confirmation block and chain tip (for MTP) #2199 exist, the prev-11 builder flag can be implemented in terms of this primitive — or they can coexist as two entry points.

Acceptance criteria

  • Each crate exposes a method that takes the caller's checkpoint and a set of heights, and returns a chain update.
  • Returned update applies via the existing LocalChain apply path.
  • Test covering: requesting heights [H1, H2, H3] yields an update whose checkpoint chain contains exactly those heights (plus whatever connecting tip is needed for application).
  • Test covering: a height already represented in the caller's checkpoint chain does not trigger a fetch.
  • Test covering: end-to-end MTP — sync without prev-11, canonicalize and find missing MTPs, fetch the missing heights, re-canonicalize, all MTPs present.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions