github.com/decred/dcrlnd@v0.7.6/docker/README.md (about) 1 # dcrlnd Docker 2 3 This document is written for people who are eager to do something with 4 the Decred Lightning Network Daemon (`dcrlnd`). This folder uses `docker-compose` to 5 package `dcrd`, `dcrwallet` and `dcrlnd` together to make deploying the daemons as easy as 6 typing a few commands. All configuration between `dcrlnd`, `dcrd` and `dcrwallet` is handled 7 automatically by their `docker-compose` config file. 8 9 ### Prerequisites 10 11 The code in this directory has been written and tested on Debian 9 using the 12 following tools: 13 14 Name | Version 15 ---------------|--------- 16 docker-compose | 1.25.5 17 docker | 19.03.10 18 19 ### Table of Contents 20 21 * [Create Lightning Network Cluster](#create-lightning-network-cluster) 22 * [Questions](#questions) 23 24 ## Create Lightning Network Cluster 25 26 This section describes a workflow on `simnet`, a development/test network 27 mode. In `simnet` mode blocks can be generated at will, 28 as the difficulty is very low. This makes it an ideal 29 environment for testing as one doesn't need to wait tens of minutes for blocks 30 to arrive in order to test channel related functionality. Additionally, it's 31 possible to spin up an arbitrary number of `dcrlnd` instances within containers to 32 create a mini development cluster. All state is saved between instances using a 33 shared volume. 34 35 36 In the workflow below, we describe the steps required to recreate the following 37 topology, and send a payment from `Alice` to `Bob`. 38 39 ``` 40 + ----- + + --- + 41 | Alice | <--- channel ---> | Bob | <--- Bob and Alice are the Lightning Network daemons which 42 + ----- + + --- + create channels and interact with each other using the 43 | | Decred network as source of truth. 44 | | 45 + - - - - - + - - - - - - + 46 | 47 + -------------- + 48 | Decred network | <--- In the current scenario for simplicity we create only one 49 + -------------- + "dcrd" node which represents the Decred network, in a 50 real situation Alice and Bob will likely be 51 connected to different Decred nodes. 52 ``` 53 54 Run `docker-compose up --no-start` to create network, volumes and build the services `dcrd`, `dcrwallet` and `dcrlnd`. 55 56 ### dcrd, dcrwallet and MVW 57 We need to start `dcrd` service and generate 18 blocks for the first coinbase to mature, because without coins, the MVW(Minimum Voting Wallet) can't buy tickets. 58 ``` 59 # Run dcrd service for the first time. 60 docker-compose start dcrd 61 62 # Use dcrctl tool that is inside dcrd 63 # to generate 18 blocks. 64 docker-compose exec dcrd dcrctl generate 18 65 ``` 66 Now we can start the `dcrwallet` and the MVW will work great. 67 `docker-compose start dcrwallet` 68 69 ### dcrlnd, add Alice and Bob's nodes 70 71 Create `Alice`s container and send funds from `dcrwallet`: 72 ```bash 73 #Create "Alice"s container 74 docker-compose run -d --name alice dcrlnd 75 76 #Log into the "Alice" container 77 docker exec -it alice bash 78 79 # Generate a new p2pkh address for Alice: 80 alice$ dcrlncli --simnet newaddress 81 ``` 82 We can keep logged in `Alice` container, just need to use another terminal tab to execute commands in docker-compose. 83 84 * Send 1DCR from `dcrwallet` to `Alice` address 85 ```bash 86 #Send from MVW to Alice's LNWallet 87 docker-compose exec dcrd dcrctl --wallet sendfrom default <alice_address> 1 88 89 #Generate a block to update the wallet balance 90 docker-compose exec dcrd dcrctl generate 1 91 92 #Check Alice's wallet balance 93 alice$ dcrlncli --simnet walletbalance 94 ``` 95 96 Create `Bob`s container and connect to `Alice`: 97 ```bash 98 #Create "Bob"s container 99 docker-compose run -d --name bob dcrlnd 100 101 #Log into the "Bob" container 102 docker exec -it bob bash 103 ``` 104 105 Connect Bob node to Alice node 106 ```bash 107 # Get identity pubkey from Bob's node 108 bob$ dcrlncli --simnet getinfo 109 { 110 "version": "0.2.0-pre+dev", 111 ------>"identity_pubkey": "02fe9daea36c1b1bd9e8dc1f5dc9edfc887d223199f2bac99e1cf92eb8cdb654e7", 112 "alias": "02fe9daea36c1b1bd9e8", 113 "color": "#3399ff", 114 "num_pending_channels": 0, 115 "num_active_channels": 0, 116 "num_inactive_channels": 0, 117 "num_peers": 0, 118 "block_height": 101, 119 "block_hash": "0000066c30cee9bae93a05b9b0edacef1fea1443f4b43a96f5d0761a70965c18", 120 "best_header_timestamp": 1576527447, 121 "synced_to_chain": true, 122 "synced_to_graph": false, 123 "testnet": false, 124 "chains": [ 125 { 126 "chain": "decred", 127 "network": "simnet" 128 } 129 ], 130 "uris": null 131 } 132 133 # Connect Alice to Bob's node 134 alice$ dcrlncli --simnet connect <bob_pubkey>@bob 135 136 # Check list of peers on "Alice" side: 137 alice$ dcrlncli --simnet listpeers 138 { 139 "peers": [ 140 { 141 "pub_key": "02fe9daea36c1b1bd9e8dc1f5dc9edfc887d223199f2bac99e1cf92eb8cdb654e7", 142 "address": "172.25.0.5:9735", 143 "bytes_sent": "139", 144 "bytes_recv": "139", 145 "atoms_sent": "0", 146 "atoms_recv": "0", 147 "inbound": false, 148 "ping_time": "0", 149 "sync_type": "ACTIVE_SYNC" 150 } 151 ] 152 } 153 ``` 154 155 Create the `Alice<->Bob` channel. 156 ```bash 157 # Open the channel with "Bob": 158 alice$ dcrlncli --simnet openchannel --node_key=<bob_pubkey> --local_amt=100000 159 160 # Include funding transaction in block thereby opening the channel: 161 # We need six confirmations to channel active 162 $ docker-compose exec dcrd dcrctl generate 6 163 164 # Check that channel with "Bob" was opened: 165 alice$ dcrlncli --simnet listchannels 166 { 167 "channels": [ 168 { 169 "active": true, 170 "remote_pubkey": "024d7bcd6b817955cbca60a2b2dff15f9615eb50f6ad16db45578722505d5817b1", 171 "channel_point": "16191b078727755138d892b7cfa08588762a7d52469710fd45d1758594dae4b5:0", 172 "chan_id": "42880953745408", 173 "capacity": "100000", 174 "local_balance": "96360", 175 "remote_balance": "0", 176 "commit_fee": "3640", 177 "commit_size": "328", 178 "fee_per_kb": "10000", 179 "unsettled_balance": "0", 180 "total_atoms_sent": "0", 181 "total_atoms_received": "0", 182 "num_updates": "0", 183 "pending_htlcs": [ 184 ], 185 "csv_delay": 288, 186 "private": false, 187 "initiator": true, 188 "chan_status_flags": "ChanStatusDefault", 189 "local_chan_reserve_atoms": "6030", 190 "remote_chan_reserve_atoms": "6030", 191 "static_remote_key": true 192 } 193 ] 194 } 195 196 ``` 197 198 Send the payment from Alice to Bob. 199 ```bash 200 # Add invoice on "Bob" side: 201 bob$ dcrlncli --simnet addinvoice --amt=50000 202 { 203 "r_hash": "<your_random_rhash_here>", 204 "pay_req": "<encoded_invoice>", 205 "add_index": 1 206 } 207 208 # Send payment from "Alice" to "Bob": 209 alice$ dcrlncli --simnet payinvoice <encoded_invoice> 210 211 # Check "Alice"'s channel balance 212 alice$ dcrlncli --simnet channelbalance 213 214 ``` 215 216 Now we have open channel in which we sent only one payment, let's imagine that we sent lots of them and we'd now like to close the channel. Let's do it! 217 218 ```bash 219 # List the "Alice" channel and retrieve "channel_point" which represents 220 # the opened channel: 221 alice$ dcrlncli --simnet listchannels 222 { 223 "channels": [ 224 { 225 "active": true, 226 "remote_pubkey": "024d7bcd6b817955cbca60a2b2dff15f9615eb50f6ad16db45578722505d5817b1", 227 ------>"channel_point": "16191b078727755138d892b7cfa08588762a7d52469710fd45d1758594dae4b5:0", 228 "chan_id": "42880953745408", 229 "capacity": "100000", 230 "local_balance": "46360", 231 "remote_balance": "50000", 232 "commit_fee": "3640", 233 "commit_size": "364", 234 "fee_per_kb": "10000", 235 "unsettled_balance": "0", 236 "total_atoms_sent": "50000", 237 "total_atoms_received": "0", 238 "num_updates": "2", 239 "pending_htlcs": [ 240 ], 241 "csv_delay": 288, 242 "private": false, 243 "initiator": true, 244 "chan_status_flags": "ChanStatusDefault", 245 "local_chan_reserve_atoms": "6030", 246 "remote_chan_reserve_atoms": "6030", 247 "static_remote_key": true 248 } 249 ] 250 } 251 252 # Channel point consists of two numbers separated by a colon. The first one 253 # is "funding_txid" and the second one is "output_index": 254 alice$ dcrlncli --simnet closechannel <funding_txid> <output_index> 255 256 # Include close transaction in a block thereby closing the channel: 257 $ docker-compose exec dcrd dcrctl generate 6 258 259 # Check "Alice" on-chain balance was credited by her settled amount in the channel: 260 alice$ dcrlncli --simnet walletbalance 261 262 # Check "Bob" on-chain balance was credited with the funds he received in the 263 # channel: 264 bob$ dcrlncli --simnet walletbalance 265 { 266 "total_balance": "50000", 267 "confirmed_balance": "50000", 268 "unconfirmed_balance": "0" 269 } 270 ``` 271 272 ## Connect through the Bob Node 273 274 We don't need to connect with all nodes for make a payment, looks this case: 275 276 ```bash 277 + ----- + + --- + (1) + ----- + 278 | Alice | <--- channel ---> | Bob | <--- channel ---> | Carol | 279 + ----- + + --- + + ----- + 280 | | | 281 | | | <--- (2) 282 + - - - - - - - - - - - - - + - - - - - - - - - - - - - + 283 | 284 + -------------- + 285 | Decred network | 286 + -------------- + 287 288 289 (1) You may connect an additional node "Carol" and make the multihop 290 payment Alice->Bob->Carol 291 292 (2) "Alice", "Bob" and "Carol" are the lightning network daemons which 293 create channels to interact with each other using the Decred network 294 as source of truth. 295 296 ``` 297 298 Create the `Alice<->Bob` channel. 299 ```bash 300 # Open the channel with "Bob": 301 alice$ dcrlncli --simnet openchannel --node_key=<bob_pubkey> --local_amt=100000 302 303 # Include funding transaction in block thereby opening the channel: 304 # We need six confirmations to channel active 305 $ docker-compose exec dcrd dcrctl generate 6 306 ``` 307 308 Create the Carol's node and get pubkey 309 310 ```bash 311 # Create "Carol"s container 312 docker-compose run -d --name carol dcrlnd 313 314 # Log into the "Carol" container 315 docker exec -it carol bash 316 317 # Get identity pubkey from Carol's node 318 carol$ dcrlncli --simnet getinfo 319 320 ``` 321 322 Bob now can create a channel with Carol 323 324 ```bash 325 # Connect Bob to Carol's node 326 bob$ dcrlncli --simnet connect <carol_pubkey>@carol 327 328 # Open the channel with "Carol": 329 bob$ dcrlncli --simnet openchannel --node_key=<carol_pubkey> --local_amt=40000 330 331 # Include funding transaction in block thereby opening the channel: 332 docker-compose exec dcrd dcrctl generate 6 333 334 # Check that channel with "Carol" was opened: 335 bob$ dcrlncli --simnet listchannels 336 337 ``` 338 339 This is what we have now: 340 341 ```bash 342 96360 0 343 + ----- + + --- + + ----- + 344 | Alice | <--- total ---> | Bob | <--- total ---> | Carol | 345 + ----- + 100000 + --- + 40000 + ----- + 346 36360 0 347 ``` 348 349 We will create an invoice on Carol's node to Alice pay her, 350 this is a multihop payment, because Alice don't know Carol and the payment will pass thougth Bob. 351 352 ```bash 353 # Generate an invoice on carol's node 354 carol$ dcrlncli --simnet addinvoice --amt 1000 355 356 # Pay this invoice with Alice's LNWallet 357 alice$ dcrlncli --simnet payinvoice <carol_invoice> 358 ``` 359 360 Look to the final channels balance: 361 ```bash 362 95358 1001 363 + ----- + + --- + + ----- + 364 | Alice | <--- total ---> | Bob | <--- total ---> | Carol | 365 + ----- + 100000 + --- + 40000 + ----- + 366 35360 1000 367 ``` 368 369 ## Questions 370 [Decred Community](https://decred.org/community) 371 372 * How to see `alice` | `bob` | `carol` logs? 373 374 ```bash 375 docker logs <alice|bob|carol> 376 ```