Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds lightning-transaction-sync in favor of Confirm #251

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 67 additions & 26 deletions docs/building-a-node-with-ldk/setting-up-a-channel-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -931,16 +931,20 @@ _after_ the `ChannelMonitor`s and `ChannelManager` are synced to the chain tip (

### Sync `ChannelMonitor`s and `ChannelManager` to chain tip

**What it's used for:** this step is only necessary if you're restarting and have open channels. This step ensures that LDK channel state is up-to-date with the bitcoin blockchain
**What it's used for:** this step is only necessary if you're restarting and have open channels. This step ensures that LDK channel state is up-to-date with the bitcoin blockchain.

There are 2 main options for synchronizing to chain on startup:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Spell out numbers zero to ten.


#### Full Blocks or BIP 157/158 (Compact Block Filters)

You can use LDK's [lightning-block-sync](https://docs.rs/lightning-block-sync/*/lightning_block_sync/) crate. This provides utilities for syncing LDK via a block-based interface.

**Example:**

<CodeSwitcher :languages="{rust:'Rust', kotlin:'Kotlin', swift:'Swift'}">
<CodeSwitcher :languages="{rust:'Rust'}">
<template v-slot:rust>

```rust
// Full Blocks or BIP 157/158

use lightning_block_sync::init;
use lightning_block_sync::poll;
use lightning_block_sync::UnboundedCache;
Expand Down Expand Up @@ -1006,16 +1010,71 @@ chain_tip = Some(
.await
.unwrap(),
);
```

</template>

</CodeSwitcher>

::: tip Full block syncing in mobile environments

Block syncing for mobile clients tends to present several challenges due to resource contraints and network limitiations typically associated with mobile devices. It requires a full node and usually fetches blocks over RPC.

Compact block filters (CBFs) are an alternative approach to syncing the blockchain that addresses some of the challenges associated with mobile clients. Please start a [discussion](https://github.com/orgs/lightningdevkit/discussions) if you would like us to expose `lightning-block-sync` in our bindings.

:::

#### Electrum or Esplora

Alternatively, you can use LDK's [`lightning-transaction-sync`](https://docs.rs/lightning-transaction-sync/*/lightning_transaction_sync/) crate. This provides utilities for syncing LDK via the transaction-based [`Confirm`](https://docs.rs/lightning/*/lightning/chain/trait.Confirm.html) interface.

**Example:**

<CodeSwitcher :languages="{rust:'Rust', kotlin:'Kotlin', swift:'Swift'}">
<template v-slot:rust>

````
```rust
let tx_sync = Arc::new(EsploraSyncClient::new(
esplora_server_url,
Arc::clone(&some_logger),
));

let chain_monitor = Arc::new(ChainMonitor::new(
Some(Arc::clone(&tx_sync)),
Arc::clone(&some_broadcaster),
Arc::clone(&some_logger),
Arc::clone(&some_fee_estimator),
Arc::clone(&some_persister),
));

let channel_manager = Arc::new(ChannelManager::new(
Arc::clone(&some_fee_estimator),
Arc::clone(&chain_monitor),
Arc::clone(&some_broadcaster),
Arc::clone(&some_router),
Arc::clone(&some_logger),
Arc::clone(&some_entropy_source),
Arc::clone(&some_node_signer),
Arc::clone(&some_signer_provider),
user_config,
chain_params,
));

let confirmables = vec![
&*channel_manager as &(dyn Confirm + Sync + Send),
&*chain_monitor as &(dyn Confirm + Sync + Send),
];

tx_sync.sync(confirmables).unwrap();
```

</template>

<template v-slot:kotlin>

```java
// Electrum/Esplora
// Note: This example calls the Confirm interface directly. The lightning-transaction-sync crate will
// be available in the next bindings release.

// Retrieve transaction IDs to check the chain for un-confirmation.
val relevantTxIdsFromChannelManager: Array<ByteArray> = channelManager .as_Confirm().get_relevant_txids()
Expand Down Expand Up @@ -1062,7 +1121,8 @@ channelManagerConstructor.chain_sync_completed(customEventHandler);
<template v-slot:swift>

```Swift
// Electrum/Esplora
// Note: This example calls the Confirm interface directly. The lightning-transaction-sync crate will
// be available in the next bindings release.

// Retrieve transaction IDs to check the chain for un-confirmation.
let relevantTxIds1 = channelManager?.asConfirm().getRelevantTxids() ?? []
Expand Down Expand Up @@ -1118,25 +1178,6 @@ channelManagerConstructor.chainSyncCompleted(persister: channelManagerPersister)

</CodeSwitcher>

**Implementation notes:**

There are 2 main options for synchronizing to chain on startup:

**Full Blocks or BIP 157/158**

If you are connecting full blocks or using BIP 157/158, then it is recommended to use
LDK's `lightning_block_sync` crate as in the example above: the high-level steps that must be done for both `ChannelManager` and each `ChannelMonitor` are as follows:

1. Get the last blockhash that each object saw.
- Receive the latest block hash when through [deserializtion](https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManagerReadArgs.html) of the `ChannelManager` via `read()`
- Each `ChannelMonitor`'s is in `channel_manager.channel_monitors`, as the 2nd element in each tuple
2. For each object, if its latest known blockhash has been reorged out of the chain, then disconnect blocks using `channel_manager.as_Listen().block_disconnected(..)` or `channel_monitor.block_disconnected(..)` until you reach the last common ancestor with the main chain.
3. For each object, reconnect blocks starting from the common ancestor until it gets to your best known chain tip using `channel_manager.as_Listen().block_connected(..)` and/or `channel_monitor.block_connected(..)`.
4. Call `channel_manager.chain_sync_completed(..)` to complete the initial sync process.

**Electrum/Esplora**

Alternatively, you can use LDK's `lightning-transaction-sync` crate. This provides utilities for syncing LDK via the transaction-based `Confirm` interface.

### Optional: Initialize `P2PGossipSync or RapidGossipSync`

Expand Down
Loading