---
# System prepended metadata

title: bdk_nakamoto

---

## bdk_nakamoto

wip: see the code [ValuedMammal/bdk/feat/bdk-nakamoto](https://github.com/ValuedMammal/bdk/tree/feat/bdk-nakamoto).

### Flow

- Build a sync/scan request
    - Collect an inventory of keychain SPKs
    - Get the new remote tip and define a range of heights to sync
    - In a way, we can think of sync as a special case of a full chain rescan. With Sync we start from the last local checkpoint and scan spks up to the last revealed index. With Scan we start from 0 or some arbitrary height, and the scan inventory includes lookahead spks, because it could be the case we haven't yet revealed any addresses.

- Run the client
    - On startup it will begin looking for peers
    - The client will store its own header chain and cfilter database

- Perform a rescan
    - `rescan` is a method on nakamoto client `Handle` that takes a range of heights and begins matching cfilters against the inventory of watched spks
    - We then subscribe to events and wait for them to arrive
    - On every `BlockMatched` event we index the tx data into a new `TxGraph` which will eventually become the graph update
    - Ideally we want to capture the most recent 10 blocks from the new remote tip to ensure consistency. We deal with potential reorgs by simply overwriting any existing blocks in local chain with the new chain update.
    - We know that a sync/scan is complete when **1)** the count of blocks matched (and processed) equals the count of filters matched, and **2)** all new block ids have been collected up to and including the new remote tip.

- Apply updates
    - **Chain**: We form a chain update by creating a new `CheckPoint` using the base block id passed in by the caller and extending it with the new blocks.
        - In the case that we start scanning from a height *below* the last local tip, we must iterate the local cp (backward) to find a new base and ensure correct ordering.
    - **Graph**: Apply the new graph to the old one


### Structures

The bdk_nakamoto lib crate contains these data structures:

- `ClientHandle<H, K>`
    - client handle
    - spks
    - block map (height, hash)
    - indexed tx graph
    - last local checkpoint
    - stop height
    - best current height
    - filters matched (count)
    - blocks matched (count)

- `Request<K>`
    - checkpoint
    - (ref) keychain-txout-index


- `Update`
    - checkpoint
    - indexed tx graph

- `Error` enum
    - nakamoto client error
    - client handle error
    - channel receiver

### Ideas:
- `ClientHandle` construction
    - Build a new `Request` from the latest checkpoint and a reference to the local keychain index. Then call `into_client_handle` on the request together with a nakamoto client `Handle`.
- If the client holds an indexed graph, it will need to index the set of watched spks before applying tx data
    - We're given a reference to the keychain indexer, which gives us a snapshot of the keychains and their last revealed indices. From there we create a temporary clone of the index by creating a new `KeychainTxOutIndex`, adding the descriptors and revealing the necessary spks. Finally the `ClientHandle` initializes its own `IndexedTxGraph` with the cloned index.
    - During sync we apply matching blocks to the indexed graph using `apply_block_relevant`
    - The graph update is done by getting the initial changeset of the client's graph and applying it to the local graph - but this can be made more efficient by aggregating the changesets from `apply_block_relevant` and returning only the changeset produced by the current sync (since we don't need the entire initial changeset). 
    - The client should allow "inspecting" spks during sync process in order to track progress

- Unimplemented
    - Tracking the spend status of utxos
    - watch for confirmation of mempool txs

- Scenarios to consider:
    - **Full scan**: sync a new wallet
    - **Sync**: sync an existing wallet
        - from last local cp to new remote tip
    - **Partial rescan**: scan a user-defined range of heights
        - where the starting height may be below the last local tip