diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index c141541a9..0bbd2f89c 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -90,8 +90,14 @@ const tutorialSidebar = [ collapsable: false, children: [ '/tutorials/getting-started', - '/tutorials/build_a_node_in_java', - '/tutorials/build_a_node_in_rust' + { + title: 'Building a node with LDK', + collapsable: false, + children: [ + ['/tutorials/building-a-node-with-ldk/introduction', 'Introduction'], + ['/tutorials/building-a-node-with-ldk/setting-up-a-channel-manager', 'Setting up a Channel Manager'] + ] + }, ], } ] diff --git a/docs/tutorials/building-a-node-with-ldk/introduction.md b/docs/tutorials/building-a-node-with-ldk/introduction.md new file mode 100644 index 000000000..d840a0900 --- /dev/null +++ b/docs/tutorials/building-a-node-with-ldk/introduction.md @@ -0,0 +1,35 @@ +# Building a Node with LDK + +## Learn how to build a basic LDK node from scratch using LDK + +::: tip Note +For an integrated example of an LDK node in Rust, see the [Sample Node](https://github.com/lightningdevkit/ldk-sample) +::: + +The following tutorials will show you how to build the simplest lightning node using LDK, that fufills the following tasks: + +1. **Connect to peers** +2. **Open channels** +3. **Send Payments** +4. **Receive Payments** +5. **Close channels** + +### Foundational Components + +Let's start by looking at the core components we'll need to make this node work for the tasks we outlined above. + +1. A `PeerManager`, for establishing TCP/IP connections to other nodes on the lightning network. +2. A `ChannelManager`, to open and close channels. +3. Payments & Routing, ability to create and pay invoices. + +To make the above work we also need to setup a series of supporting modules, including: +1. A `FeeEstimator` +2. A `Logger` +3. A `TransactionBroadcaster` +4. A `NetworkGraph` +5. A `Persister` +6. An `EventHandler` +7. A `TransactionFilter` +8. A `ChainMonitor` +9. A `KeysManager` +10. A `Scorer` diff --git a/docs/tutorials/building-a-node-with-ldk/setting-up-a-channel-manager.md b/docs/tutorials/building-a-node-with-ldk/setting-up-a-channel-manager.md new file mode 100644 index 000000000..e467f2192 --- /dev/null +++ b/docs/tutorials/building-a-node-with-ldk/setting-up-a-channel-manager.md @@ -0,0 +1,988 @@ +# Setting up a ChannelManager + +The ChannelManager is responsible for several tasks related to managing channel state. This includes keeping track of many channels, sending messages to appropriate channels, creating channels and more. + +## Adding a ChannelManager + +To add a `ChannelManager` to your application, run: + + + + + + + + +There are a few dependencies needed to get this working. Let's walk through setting up each one so we can plug them into our `ChannelManager`. + +### Step 1. Initialize the `FeeEstimator` + + + + + + + + + +**What it's used for:** estimating fees for on-chain transactions that LDK wants broadcasted. + +**Implementation notes:** +1. Fees must be returned in: satoshis per 1000 weight units +2. Fees must be no smaller than 253 (equivalent to 1 satoshi/vbyte, rounded up) +3. To reduce network traffic, you may want to cache fee results rather than +retrieving fresh ones every time + +**Dependencies:** *none* + +**References:** [Rust `FeeEstimator` docs](https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.FeeEstimator.html), [Java `FeeEstimator` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/FeeEstimator.java) + +### Step 2. Initialize the `Logger` +**What it's used for:** LDK logging + + + + + + + + + +**Implementation notes:** you'll likely want to write the logs to a file for debugging purposes. + +**Dependencies:** *none* + +**References:** [Rust `Logger` docs](https://docs.rs/lightning/*/lightning/util/logger/trait.Logger.html), [Java `Logger` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Logger.java) + +### Step 3. Initialize the `BroadcasterInterface` +**What it's used for:** broadcasting various transactions to the bitcoin network + + + + + + + + + +**Dependencies:** *none* + +**References:** [Rust `BroadcasterInterface` docs](https://docs.rs/lightning/*/lightning/chain/chaininterface/trait.BroadcasterInterface.html), [Java `BroadcasterInterface` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/BroadcasterInterface.java) + +### Step 4. Initialize `Persist` +**What it's used for:** persisting `ChannelMonitor`s, which contain crucial channel data, in a timely manner + + + + + + + + + + + + + +**Implementation notes:** +* `ChannelMonitor`s are objects which are capable of +responding to on-chain events for a given channel. Thus, you will have one +`ChannelMonitor` per channel. They are persisted in real-time and the `Persist` +methods will block progress on sending or receiving payments until they return. +You must ensure that `ChannelMonitor`s are durably persisted to disk before +returning or you may lose funds. +* If you implement a custom persister, it's important to read the trait docs (linked in References) to make sure you satisfy the API requirements, particularly for `update_persisted_channel` + +**Dependencies:** *none* + +**References:** [Rust `Persister` docs](https://docs.rs/lightning/*/lightning/chain/chainmonitor/trait.Persist.html), [Java `Persister` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Persist.java) + +### Optional: Initialize the Transaction `Filter` +**You must follow this step if:** you are *not* providing full blocks to LDK, +i.e. if you're using BIP 157/158 or Electrum as your chain backend + +**What it's used for:** if you are not providing full blocks, LDK uses this +object to tell you what transactions and outputs to watch for on-chain. You'll +inform LDK about these transactions/outputs in Step 14. + + + + + + + + + + +**Implementation notes:** see the [Blockchain Data](/blockchain_data/introduction.md) guide for more info + +**Dependencies:** *none* + +**References:** [Rust `Filter` docs](https://docs.rs/lightning/*/lightning/chain/trait.Filter.html), [Java `Filter` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Filter.java) + +### Step 5. Initialize the `ChainMonitor` +**What it's used for:** tracking one or more `ChannelMonitor`s and using them to monitor the chain for lighting transactions that are relevant to our node, and broadcasting transactions if need be. + + + + + + + + + +**Implementation notes:** `Filter` must be non-`None` if you're using Electrum or BIP 157/158 as your chain backend + +**Dependencies:** `FeeEstimator`, `Logger`, `BroadcasterInterface`, `Persist` + +**Optional dependency:** `Filter` + +**References:** [Rust `ChainMonitor` docs](https://docs.rs/lightning/*/lightning/chain/chainmonitor/struct.ChainMonitor.html), [Java `ChainMonitor` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ChainMonitor.java) + +### Step 6. Initialize the `KeysManager` +**What it's used for:** providing keys for signing Lightning transactions + + + + + + + + + +**Implementation notes:** +* See the [Key Management](/key_management.md) guide for more info +* Note that you must write the `key_seed` you give to the `KeysManager` on + startup to disk, and keep using it to initialize the `KeysManager` every time + you restart. This `key_seed` is used to derive your node's secret key (which + corresponds to its node pubkey) and all other secret key material. +* The current time is part of the `KeysManager`'s parameters because it is used to derive +random numbers from the seed where required, to ensure all random +generation is unique across restarts. + +**Dependencies:** random bytes + +**References:** [Rust `KeysManager` docs](https://docs.rs/lightning/*/lightning/chain/keysinterface/struct.KeysManager.html), [Java `KeysManager` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/KeysManager.java) + +### Step 7. Read `ChannelMonitor` state from disk + +**What it's used for:** if LDK is restarting and has at least 1 channel, its `ChannelMonitor`s will need to be (1) fed to the `ChannelManager` and (2) synced to chain. + + + + + + + + + +**Dependencies:** `KeysManager` + +**References:** [Rust `load_outputs_to_watch` docs](https://docs.rs/lightning/*/lightning/chain/channelmonitor/struct.ChannelMonitor.html#method.load_outputs_to_watch) + +### Step 8. Initialize the `ChannelManager` +**What it's used for:** managing channel state + + + + + + + + + +**Implementation notes:** No methods should be called on `ChannelManager` until +*after* Step 9. + +**Dependencies:** `KeysManager`, `FeeEstimator`, `ChainMonitor`, `BroadcasterInterface`, `Logger` +* If restarting: `ChannelMonitor`s and `ChannelManager` bytes from Step 7 and Step 18 respectively + +**References:** [Rust `ChannelManager` docs](https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManager.html), [Java `ChannelManager` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/ChannelManager.java) + +### Step 9. 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 + +**Example:** + + + + + + + + +**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` sample module 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. + * `ChannelManager`'s is in `channel_manager_constructor.channel_manager_latest_block_hash` + * Each `ChannelMonitor`'s is in `channel_manager_constructor.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_constructor.chain_sync_completed(..)` to complete the initial sync process. + + + +**Electrum** + +Otherwise, you can use LDK's `Confirm` interface as in the examples above. The high-level steps are as follows: + 1. Tell LDK about relevant confirmed and unconfirmed transactions. + 2. Tell LDK what your best known block header and height is. + 3. Call `channel_manager_constructor.chain_sync_completed(..)` to complete the initial sync process. + +**More details about LDK's interfaces to provide chain info in Step 14** + +**References:** [Rust `Confirm` docs](https://docs.rs/lightning/*/lightning/chain/trait.Confirm.html), [Rust `Listen` docs](https://docs.rs/lightning/*/lightning/chain/trait.Listen.html), [Rust `lightning_block_sync` module docs](https://docs.rs/lightning-block-sync/*/lightning_block_sync/) + +**Dependencies:** `ChannelManager`, `ChainMonitor`, `ChannelMonitor`s +* If providing providing full blocks or BIP 157/158: set of `ChannelMonitor`s +* If using Electrum: `ChainMonitor` + +### Step 10. Give `ChannelMonitor`s to `ChainMonitor` +**What it's used for:** `ChainMonitor` is responsible for updating the `ChannelMonitor`s during LDK node operation. + + + + + + + + + +**Dependencies:** +* `ChainMonitor`, set of `ChannelMonitor`s and their funding outpoints +* Step 9 must be completed prior to this step \ No newline at end of file