├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md ├── pull_request_template.md └── workflows │ └── main.yml ├── .gitignore ├── .golangci.yml ├── .travis.yml ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── aezeed ├── README.md ├── bench_test.go ├── cipherseed.go ├── cipherseed_rpctest.go ├── cipherseed_test.go ├── errors.go └── wordlist.go ├── autopilot ├── agent.go ├── agent_constraints.go ├── agent_constraints_test.go ├── agent_test.go ├── betweenness_centrality.go ├── betweenness_centrality_test.go ├── centrality_testdata_test.go ├── choice.go ├── choice_test.go ├── combinedattach.go ├── externalscoreattach.go ├── externalscoreattach_test.go ├── graph.go ├── graph_test.go ├── interface.go ├── log.go ├── manager.go ├── prefattach.go ├── prefattach_test.go ├── simple_graph.go ├── top_centrality.go └── top_centrality_test.go ├── breacharbiter.go ├── breacharbiter_test.go ├── brontide ├── README.md ├── conn.go ├── listener.go ├── noise.go └── noise_test.go ├── buffer ├── buffer_test.go ├── read.go ├── utils.go └── write.go ├── build ├── deployment.go ├── deployment_dev.go ├── deployment_prod.go ├── log.go ├── log_default.go ├── log_nolog.go ├── log_stdlog.go ├── loglevel_critical.go ├── loglevel_debug.go ├── loglevel_default.go ├── loglevel_error.go ├── loglevel_info.go ├── loglevel_off.go ├── loglevel_trace.go ├── loglevel_warn.go ├── logrotator.go ├── prefix_log.go └── version.go ├── cert ├── go.mod ├── selfsigned.go ├── selfsigned_test.go └── tls.go ├── chainntnfs ├── README.md ├── bitcoindnotify │ ├── bitcoind.go │ ├── bitcoind_dev.go │ ├── bitcoind_test.go │ └── driver.go ├── btcdnotify │ ├── btcd.go │ ├── btcd_dev.go │ ├── btcd_test.go │ └── driver.go ├── height_hint_cache.go ├── height_hint_cache_test.go ├── interface.go ├── interface_dev.go ├── interface_test.go ├── log.go ├── neutrinonotify │ ├── driver.go │ ├── neutrino.go │ └── neutrino_dev.go ├── test_utils.go ├── txnotifier.go └── txnotifier_test.go ├── chainparams.go ├── chainregistry.go ├── chanacceptor ├── acceptor_test.go ├── chainedacceptor.go ├── interface.go └── rpcacceptor.go ├── chanbackup ├── backup.go ├── backup_test.go ├── backupfile.go ├── backupfile_test.go ├── crypto.go ├── crypto_test.go ├── log.go ├── multi.go ├── multi_test.go ├── pubsub.go ├── pubsub_test.go ├── recover.go ├── recover_test.go ├── single.go └── single_test.go ├── chanfitness ├── chanevent.go ├── chanevent_test.go ├── chaneventstore.go ├── chaneventstore_test.go └── log.go ├── channel_notifier.go ├── channeldb ├── README.md ├── addr.go ├── addr_test.go ├── channel.go ├── channel_cache.go ├── channel_cache_test.go ├── channel_test.go ├── codec.go ├── db.go ├── db_test.go ├── doc.go ├── duplicate_payments.go ├── error.go ├── fees.go ├── forwarding_log.go ├── forwarding_log_test.go ├── forwarding_package.go ├── forwarding_package_test.go ├── graph.go ├── graph_test.go ├── invoice_test.go ├── invoices.go ├── kvdb │ ├── backend.go │ ├── config.go │ ├── etcd │ │ ├── bucket.go │ │ ├── bucket_test.go │ │ ├── db.go │ │ ├── db_test.go │ │ ├── driver.go │ │ ├── driver_test.go │ │ ├── embed.go │ │ ├── fixture_test.go │ │ ├── readwrite_bucket.go │ │ ├── readwrite_bucket_test.go │ │ ├── readwrite_cursor.go │ │ ├── readwrite_cursor_test.go │ │ ├── readwrite_tx.go │ │ ├── readwrite_tx_test.go │ │ ├── stm.go │ │ ├── stm_test.go │ │ └── walletdb_interface_test.go │ ├── interface.go │ ├── kvdb_etcd.go │ └── kvdb_no_etcd.go ├── legacy_serialization.go ├── log.go ├── meta.go ├── meta_test.go ├── migration │ ├── create_tlb.go │ ├── create_tlb_test.go │ └── log.go ├── migration12 │ ├── invoices.go │ ├── log.go │ ├── migration.go │ └── migration_test.go ├── migration13 │ ├── log.go │ ├── migration.go │ └── migration_test.go ├── migration16 │ ├── log.go │ ├── migration.go │ └── migration_test.go ├── migration_01_to_11 │ ├── addr.go │ ├── channel.go │ ├── channel_test.go │ ├── codec.go │ ├── db.go │ ├── error.go │ ├── graph.go │ ├── graph_test.go │ ├── invoices.go │ ├── legacy_serialization.go │ ├── log.go │ ├── meta.go │ ├── meta_test.go │ ├── migration_09_legacy_serialization.go │ ├── migration_10_route_tlv_records.go │ ├── migration_11_invoices.go │ ├── migration_11_invoices_test.go │ ├── migrations.go │ ├── migrations_test.go │ ├── options.go │ ├── payment_control.go │ ├── payments.go │ ├── payments_test.go │ ├── route.go │ └── zpay32 │ │ ├── amountunits.go │ │ ├── bech32.go │ │ ├── decode.go │ │ ├── hophint.go │ │ └── invoice.go ├── migtest │ ├── migtest.go │ └── raw_db.go ├── mp_payment.go ├── nodes.go ├── nodes_test.go ├── options.go ├── paginate.go ├── payment_control.go ├── payment_control_test.go ├── payments.go ├── payments_test.go ├── reject_cache.go ├── reject_cache_test.go ├── reports.go ├── reports_test.go ├── waitingproof.go ├── waitingproof_test.go ├── witness_cache.go └── witness_cache_test.go ├── channelnotifier ├── channelnotifier.go └── log.go ├── chanrestore.go ├── clock ├── default_clock.go ├── go.mod ├── interface.go ├── test_clock.go └── test_clock_test.go ├── cmd ├── lncli │ ├── arg_parse.go │ ├── arg_parse_test.go │ ├── autopilotrpc_active.go │ ├── autopilotrpc_default.go │ ├── cmd_bake_macaroon.go │ ├── cmd_build_route.go │ ├── cmd_invoice.go │ ├── cmd_open_channel.go │ ├── cmd_pay.go │ ├── cmd_query_mission_control.go │ ├── cmd_query_probability.go │ ├── cmd_reset_mission_control.go │ ├── cmd_version.go │ ├── commands.go │ ├── invoicesrpc_active.go │ ├── invoicesrpc_default.go │ ├── main.go │ ├── routerrpc.go │ ├── types.go │ ├── walletrpc_active.go │ ├── walletrpc_default.go │ ├── walletrpc_types.go │ ├── watchtower_active.go │ ├── watchtower_default.go │ └── wtclient.go └── lnd │ └── main.go ├── config.go ├── contractcourt ├── anchor_resolver.go ├── briefcase.go ├── briefcase_test.go ├── chain_arbitrator.go ├── chain_arbitrator_test.go ├── chain_watcher.go ├── chain_watcher_test.go ├── channel_arbitrator.go ├── channel_arbitrator_test.go ├── commit_sweep_resolver.go ├── commit_sweep_resolver_test.go ├── contract_resolvers.go ├── htlc_incoming_contest_resolver.go ├── htlc_incoming_resolver_test.go ├── htlc_outgoing_contest_resolver.go ├── htlc_outgoing_contest_resolver_test.go ├── htlc_success_resolver.go ├── htlc_success_resolver_test.go ├── htlc_timeout_resolver.go ├── htlc_timeout_resolver_test.go ├── interfaces.go ├── log.go ├── mock_registry_test.go └── utils_test.go ├── contrib └── lncli.bash-completion ├── discovery ├── bootstrapper.go ├── chan_series.go ├── gossiper.go ├── gossiper_test.go ├── log.go ├── message_store.go ├── message_store_test.go ├── mock_test.go ├── reliable_sender.go ├── reliable_sender_test.go ├── sync_manager.go ├── sync_manager_test.go ├── syncer.go └── syncer_test.go ├── doc.go ├── docker ├── README.md ├── btcd │ ├── Dockerfile │ ├── start-btcctl.sh │ └── start-btcd.sh ├── docker-compose.ltc.yml ├── docker-compose.yml ├── lnd │ ├── Dockerfile │ └── start-lnd.sh └── ltcd │ ├── Dockerfile │ ├── start-ltcctl.sh │ └── start-ltcd.sh ├── docs ├── DOCKER.md ├── INSTALL.md ├── MAKEFILE.md ├── code_contribution_guidelines.md ├── configuring_tor.md ├── debugging_lnd.md ├── etcd.md ├── fuzz.md ├── grpc │ ├── c#.md │ ├── java.md │ ├── javascript.md │ ├── python.md │ └── ruby.md ├── macaroons.md ├── nat_traversal.md ├── psbt.md ├── recovery.md ├── release.md ├── ruby-thing.rb ├── safety.md └── watchtower.md ├── feature ├── default_sets.go ├── deps.go ├── deps_test.go ├── manager.go ├── manager_internal_test.go ├── required.go └── set.go ├── fundingmanager.go ├── fundingmanager_test.go ├── fuzz ├── brontide │ ├── fuzz_utils.go │ ├── random_actone.go │ ├── random_actthree.go │ ├── random_acttwo.go │ ├── random_init_decrypt.go │ ├── random_init_enc_dec.go │ ├── random_init_encrypt.go │ ├── random_resp_decrypt.go │ ├── random_resp_enc_dec.go │ ├── random_resp_encrypt.go │ ├── static_actone.go │ ├── static_actthree.go │ ├── static_acttwo.go │ ├── static_init_decrypt.go │ ├── static_init_enc_dec.go │ ├── static_init_encrypt.go │ ├── static_resp_decrypt.go │ ├── static_resp_enc_dec.go │ └── static_resp_encrypt.go ├── lnwire │ ├── accept_channel.go │ ├── announce_signatures.go │ ├── channel_announcement.go │ ├── channel_reestablish.go │ ├── channel_update.go │ ├── closing_signed.go │ ├── commit_sig.go │ ├── error.go │ ├── funding_created.go │ ├── funding_locked.go │ ├── funding_signed.go │ ├── fuzz_utils.go │ ├── gossip_timestamp_range.go │ ├── init.go │ ├── node_announcement.go │ ├── open_channel.go │ ├── ping.go │ ├── pong.go │ ├── query_channel_range.go │ ├── query_short_chan_ids.go │ ├── query_short_chan_ids_zlib.go │ ├── reply_channel_range.go │ ├── reply_channel_range_zlib.go │ ├── reply_short_chan_ids_end.go │ ├── revoke_and_ack.go │ ├── shutdown.go │ ├── update_add_htlc.go │ ├── update_fail_htlc.go │ ├── update_fail_malformed_htlc.go │ ├── update_fee.go │ └── update_fulfill_htlc.go └── wtwire │ ├── create_session.go │ ├── create_session_reply.go │ ├── delete_session.go │ ├── delete_session_reply.go │ ├── error.go │ ├── fuzz_utils.go │ ├── init.go │ ├── state_update.go │ └── state_update_reply.go ├── go.mod ├── go.sum ├── htlcswitch ├── circuit.go ├── circuit_map.go ├── circuit_test.go ├── decayedlog.go ├── decayedlog_test.go ├── failure.go ├── failure_detail.go ├── hodl │ ├── config_dev.go │ ├── config_prod.go │ ├── flags.go │ ├── mask_dev.go │ ├── mask_prod.go │ └── mask_test.go ├── hop │ ├── error_encryptor.go │ ├── forwarding_info.go │ ├── iterator.go │ ├── iterator_test.go │ ├── log.go │ ├── network.go │ ├── payload.go │ ├── payload_test.go │ └── type.go ├── htlcnotifier.go ├── interceptable_switch.go ├── interfaces.go ├── link.go ├── link_isolated_test.go ├── link_test.go ├── linkfailure.go ├── log.go ├── mailbox.go ├── mailbox_test.go ├── mock.go ├── packet.go ├── payment_result.go ├── payment_result_test.go ├── sequencer.go ├── switch.go ├── switch_test.go └── test_utils.go ├── input ├── input.go ├── script_utils.go ├── script_utils_test.go ├── signdescriptor.go ├── signdescriptor_test.go ├── signer.go ├── size.go ├── size_test.go ├── test_utils.go ├── txout.go ├── txout_test.go └── witnessgen.go ├── invoices ├── interface.go ├── invoice_expiry_watcher.go ├── invoice_expiry_watcher_test.go ├── invoiceregistry.go ├── invoiceregistry_test.go ├── log.go ├── resolution.go ├── resolution_result.go ├── test_utils_test.go └── update.go ├── keychain ├── btcwallet.go ├── derivation.go ├── ecdh.go ├── interface_test.go └── signer.go ├── labels └── labels.go ├── lncfg ├── address.go ├── address_test.go ├── autopilot.go ├── bitcoind.go ├── btcd.go ├── caches.go ├── chain.go ├── config.go ├── db.go ├── interface.go ├── monitoring_off.go ├── monitoring_on.go ├── neutrino.go ├── protocol.go ├── protocol_experimental_off.go ├── protocol_experimental_on.go ├── protocol_legacy_off.go ├── protocol_legacy_on.go ├── tor.go ├── watchtower.go ├── workers.go ├── workers_test.go └── wtclient.go ├── lnd.go ├── lnpeer ├── errors.go └── peer.go ├── lnrpc ├── .clang-format ├── README.md ├── autopilotrpc │ ├── autopilot.pb.go │ ├── autopilot.pb.gw.go │ ├── autopilot.proto │ ├── autopilot.swagger.json │ ├── autopilot_server.go │ ├── config_active.go │ ├── config_default.go │ ├── driver.go │ └── log.go ├── chainrpc │ ├── chainnotifier.pb.go │ ├── chainnotifier.pb.gw.go │ ├── chainnotifier.proto │ ├── chainnotifier.swagger.json │ ├── chainnotifier_server.go │ ├── config_active.go │ ├── config_default.go │ ├── driver.go │ └── log.go ├── file_utils.go ├── gen_protos.sh ├── invoicesrpc │ ├── addinvoice.go │ ├── config_active.go │ ├── config_default.go │ ├── driver.go │ ├── invoices.pb.go │ ├── invoices.pb.gw.go │ ├── invoices.proto │ ├── invoices.swagger.json │ ├── invoices_server.go │ ├── log.go │ └── utils.go ├── lnclipb │ ├── lncli.pb.go │ ├── lncli.proto │ └── lncli.swagger.json ├── marshall_utils.go ├── rest-annotations.yaml ├── routerrpc │ ├── config.go │ ├── driver.go │ ├── forward_interceptor.go │ ├── log.go │ ├── router.pb.go │ ├── router.pb.gw.go │ ├── router.proto │ ├── router.swagger.json │ ├── router_backend.go │ ├── router_backend_test.go │ ├── router_server.go │ ├── router_server_deprecated.go │ ├── routing_config.go │ └── subscribe_events.go ├── rpc.pb.go ├── rpc.pb.gw.go ├── rpc.proto ├── rpc.swagger.json ├── rpc_utils.go ├── signrpc │ ├── config_active.go │ ├── config_default.go │ ├── driver.go │ ├── log.go │ ├── signer.pb.go │ ├── signer.pb.gw.go │ ├── signer.proto │ ├── signer.swagger.json │ └── signer_server.go ├── sub_server.go ├── verrpc │ ├── driver.go │ ├── log.go │ ├── server.go │ ├── verrpc.pb.go │ ├── verrpc.pb.gw.go │ ├── verrpc.proto │ └── verrpc.swagger.json ├── walletrpc │ ├── config_active.go │ ├── config_default.go │ ├── driver.go │ ├── log.go │ ├── walletkit.pb.go │ ├── walletkit.pb.gw.go │ ├── walletkit.proto │ ├── walletkit.swagger.json │ └── walletkit_server.go ├── walletunlocker.pb.go ├── walletunlocker.pb.gw.go ├── walletunlocker.proto ├── walletunlocker.swagger.json ├── watchtowerrpc │ ├── config_active.go │ ├── config_default.go │ ├── driver.go │ ├── handler.go │ ├── interface.go │ ├── log.go │ ├── watchtower.pb.go │ ├── watchtower.pb.gw.go │ ├── watchtower.proto │ └── watchtower.swagger.json ├── websocket_proxy.go └── wtclientrpc │ ├── config.go │ ├── driver.go │ ├── wtclient.go │ ├── wtclient.pb.go │ ├── wtclient.pb.gw.go │ ├── wtclient.proto │ └── wtclient.swagger.json ├── lntest ├── bitcoind.go ├── btcd.go ├── doc.go ├── harness.go ├── itest │ ├── lnd_forward_interceptor_test.go │ ├── lnd_mpp_test.go │ ├── lnd_multi-hop-error-propagation.go │ ├── lnd_multi-hop-payments.go │ ├── lnd_multi-hop_htlc_local_chain_claim_test.go │ ├── lnd_multi-hop_htlc_local_timeout_test.go │ ├── lnd_multi-hop_htlc_receiver_chain_claim_test.go │ ├── lnd_multi-hop_htlc_remote_chain_claim_test.go │ ├── lnd_multi-hop_local_force_close_on_chain_htlc_timeout_test.go │ ├── lnd_multi-hop_remote_force_close_on_chain_htlc_timeout_test.go │ ├── lnd_multi-hop_test.go │ ├── lnd_send_multi_path_payment.go │ ├── lnd_single_hop_invoice_test.go │ ├── lnd_test.go │ ├── lnd_wumbo_channels_test.go │ ├── log_check_errors.sh │ ├── log_error_whitelist.txt │ ├── log_substitutions.txt │ ├── macaroons.go │ ├── onchain.go │ ├── psbt.go │ └── rest_api.go ├── neutrino.go ├── node.go ├── timeouts.go ├── timeouts_darwin.go └── wait │ └── wait.go ├── lntypes ├── hash.go └── preimage.go ├── lnwallet ├── README.md ├── btcwallet │ ├── blockchain.go │ ├── btcwallet.go │ ├── btcwallet_rpctest.go │ ├── config.go │ ├── driver.go │ └── signer.go ├── chainfee │ ├── estimator.go │ ├── estimator_test.go │ ├── log.go │ └── rates.go ├── chancloser │ ├── chancloser.go │ ├── chancloser_test.go │ └── log.go ├── chanfunding │ ├── assembler.go │ ├── canned_assembler.go │ ├── coin_select.go │ ├── coin_select_test.go │ ├── log.go │ ├── psbt_assembler.go │ ├── psbt_assembler_test.go │ └── wallet_assembler.go ├── channel.go ├── channel_test.go ├── chanvalidate │ ├── validate.go │ └── validate_test.go ├── commit_sort.go ├── commit_sort_test.go ├── commitment.go ├── config.go ├── errors.go ├── interface.go ├── interface_test.go ├── log.go ├── parameters.go ├── reservation.go ├── sigpool.go ├── test_utils.go ├── test_vectors_anchors.json ├── test_vectors_legacy.json ├── transactions.go ├── transactions_test.go └── wallet.go ├── lnwire ├── README.md ├── accept_channel.go ├── accept_channel_test.go ├── announcement_signatures.go ├── channel_announcement.go ├── channel_id.go ├── channel_id_test.go ├── channel_reestablish.go ├── channel_update.go ├── closing_signed.go ├── commit_sig.go ├── error.go ├── features.go ├── features_test.go ├── funding_created.go ├── funding_locked.go ├── funding_signed.go ├── gossip_timestamp_range.go ├── init_message.go ├── lnwire.go ├── lnwire_test.go ├── message.go ├── msat.go ├── msat_test.go ├── netaddress.go ├── netaddress_test.go ├── node_announcement.go ├── node_announcement_test.go ├── onion_error.go ├── onion_error_test.go ├── open_channel.go ├── ping.go ├── pong.go ├── query_channel_range.go ├── query_short_chan_ids.go ├── query_short_chan_ids_test.go ├── reply_channel_range.go ├── reply_channel_range_test.go ├── reply_short_chan_ids_end.go ├── revoke_and_ack.go ├── short_channel_id.go ├── short_channel_id_test.go ├── shutdown.go ├── signature.go ├── signature_test.go ├── update_add_htlc.go ├── update_fail_htlc.go ├── update_fail_malformed_htlc.go ├── update_fee.go └── update_fulfill_htlc.go ├── log.go ├── logo.png ├── macaroons ├── README.md ├── auth.go ├── constraints.go ├── constraints_test.go ├── security.go ├── security_rpctest.go ├── security_test.go ├── service.go ├── service_test.go ├── store.go └── store_test.go ├── make ├── release_flags.mk └── testing_flags.mk ├── mobile ├── README.md ├── bindings.go ├── gen_bindings.sh └── sample_lnd.conf ├── mock.go ├── monitoring ├── log.go ├── monitoring_off.go └── monitoring_on.go ├── multimutex ├── hash_mutex.go └── multimutex.go ├── nat ├── pmp.go ├── traversal.go └── upnp.go ├── netann ├── chan_status_manager.go ├── chan_status_manager_test.go ├── channel_announcement.go ├── channel_announcement_test.go ├── channel_state.go ├── channel_update.go ├── channel_update_test.go ├── host_ann.go ├── host_ann_test.go ├── interface.go ├── log.go ├── node_announcement.go ├── node_signer.go └── sign.go ├── nursery_store.go ├── nursery_store_test.go ├── peer ├── brontide.go ├── brontide_test.go ├── config.go ├── interfaces.go ├── log.go └── test_utils.go ├── peernotifier ├── log.go └── peernotifier.go ├── pilot.go ├── pool ├── read.go ├── read_buffer.go ├── recycle.go ├── recycle_test.go ├── worker.go ├── worker_test.go ├── write.go └── write_buffer.go ├── queue ├── circular_buf.go ├── circular_buf_test.go ├── gc_queue.go ├── gc_queue_test.go ├── go.mod ├── go.sum ├── priority_queue.go ├── priority_queue_test.go ├── queue.go └── queue_test.go ├── record ├── amp.go ├── custom_records.go ├── experimental.go ├── hop.go ├── mpp.go └── record_test.go ├── routing ├── README.md ├── ann_validation.go ├── chainview │ ├── bitcoind.go │ ├── btcd.go │ ├── interface.go │ ├── interface_test.go │ ├── log.go │ ├── neutrino.go │ └── queue.go ├── conf.go ├── conf_experimental.go ├── control_tower.go ├── control_tower_test.go ├── errors.go ├── graph.go ├── heap.go ├── heap_test.go ├── integrated_routing_context_test.go ├── integrated_routing_test.go ├── localchans │ ├── log.go │ ├── manager.go │ └── manager_test.go ├── log.go ├── missioncontrol.go ├── missioncontrol_state.go ├── missioncontrol_state_test.go ├── missioncontrol_store.go ├── missioncontrol_store_test.go ├── missioncontrol_test.go ├── mock_graph_test.go ├── mock_test.go ├── nodepair.go ├── notifications.go ├── notifications_test.go ├── pathfind.go ├── pathfind_test.go ├── payment_lifecycle.go ├── payment_lifecycle_test.go ├── payment_session.go ├── payment_session_source.go ├── payment_session_test.go ├── probability_estimator.go ├── probability_estimator_test.go ├── result_interpretation.go ├── result_interpretation_test.go ├── route │ ├── route.go │ └── route_test.go ├── router.go ├── router_test.go ├── stats.go ├── testdata │ ├── basic_graph.json │ └── spec_example.json ├── unified_policies.go ├── unified_policies_test.go ├── validation_barrier.go └── validation_barrier_test.go ├── rpcserver.go ├── sample-lnd.conf ├── scripts ├── install_bitcoind.sh ├── install_travis_proto.sh └── release.sh ├── server.go ├── server_test.go ├── shachain ├── element.go ├── element_test.go ├── producer.go ├── producer_test.go ├── store.go ├── store_test.go └── utils.go ├── signal ├── log.go └── signal.go ├── subrpcserver_config.go ├── subscribe ├── subscribe.go └── subscribe_test.go ├── sweep ├── backend_mock_test.go ├── bucket_list.go ├── defaults.go ├── defaults_rpctest.go ├── fee_estimator_mock_test.go ├── interface.go ├── log.go ├── store.go ├── store_mock.go ├── store_test.go ├── sweeper.go ├── sweeper_test.go ├── test_utils.go ├── tx_input_set.go ├── tx_input_set_test.go ├── txgenerator.go ├── txgenerator_test.go ├── walletsweep.go └── walletsweep_test.go ├── test_utils.go ├── ticker ├── force.go ├── go.mod ├── ticker.go └── ticker_test.go ├── tlv ├── bench_test.go ├── primitive.go ├── primitive_test.go ├── record.go ├── record_test.go ├── stream.go ├── stream_test.go ├── tlv_test.go ├── truncated.go ├── truncated_test.go ├── varint.go └── varint_test.go ├── tor ├── README.md ├── add_onion.go ├── add_onion_test.go ├── controller.go ├── controller_test.go ├── net.go ├── onionaddr.go └── tor.go ├── utxonursery.go ├── utxonursery_test.go ├── walletunlocker ├── service.go └── service_test.go ├── watchtower ├── blob │ ├── derivation.go │ ├── justice_kit.go │ ├── justice_kit_test.go │ ├── type.go │ └── type_test.go ├── conf.go ├── config.go ├── errors.go ├── interface.go ├── log.go ├── lookout │ ├── interface.go │ ├── justice_descriptor.go │ ├── justice_descriptor_test.go │ ├── log.go │ ├── lookout.go │ ├── lookout_test.go │ ├── mock.go │ └── punisher.go ├── standalone.go ├── wtclient │ ├── backup_task.go │ ├── backup_task_internal_test.go │ ├── candidate_iterator.go │ ├── candidate_iterator_test.go │ ├── client.go │ ├── client_test.go │ ├── errors.go │ ├── interface.go │ ├── log.go │ ├── session_negotiator.go │ ├── session_queue.go │ ├── stats.go │ └── task_pipeline.go ├── wtdb │ ├── client_chan_summary.go │ ├── client_db.go │ ├── client_db_test.go │ ├── client_session.go │ ├── codec.go │ ├── codec_test.go │ ├── db_common.go │ ├── log.go │ ├── session_id.go │ ├── session_info.go │ ├── session_state_update.go │ ├── tower.go │ ├── tower_db.go │ ├── tower_db_test.go │ └── version.go ├── wtmock │ ├── client_db.go │ ├── keyring.go │ ├── peer.go │ ├── signer.go │ └── tower_db.go ├── wtpolicy │ ├── policy.go │ └── policy_test.go ├── wtserver │ ├── create_session.go │ ├── delete_session.go │ ├── interface.go │ ├── log.go │ ├── server.go │ ├── server_test.go │ └── state_update.go └── wtwire │ ├── create_session.go │ ├── create_session_reply.go │ ├── delete_session.go │ ├── delete_session_reply.go │ ├── error.go │ ├── error_code.go │ ├── features.go │ ├── init.go │ ├── init_test.go │ ├── message.go │ ├── state_update.go │ ├── state_update_reply.go │ ├── summary.go │ ├── wtwire.go │ └── wtwire_test.go ├── witness_beacon.go └── zpay32 ├── README.md ├── amountunits.go ├── bech32.go ├── decode.go ├── encode.go ├── hophint.go ├── invoice.go ├── invoice_internal_test.go └── invoice_test.go /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Background 2 | 3 | Describe your issue here. 4 | 5 | ### Your environment 6 | 7 | * version of `lnd` 8 | * which operating system (`uname -a` on *Nix) 9 | * version of `btcd`, `bitcoind`, or other backend 10 | * any other relevant environment details 11 | 12 | ### Steps to reproduce 13 | 14 | Tell us how to reproduce this issue. Please provide stacktraces and links to code in question. 15 | 16 | ### Expected behaviour 17 | 18 | Tell us what should happen 19 | 20 | ### Actual behaviour 21 | 22 | Tell us what happens instead 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ---> Go 2 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 3 | *.o 4 | *.a 5 | *.so 6 | 7 | # Folders 8 | _obj 9 | _test 10 | 11 | # Architecture specific extensions/prefixes 12 | *.[568vq] 13 | [568vq].out 14 | 15 | *.cgo1.go 16 | *.cgo2.c 17 | _cgo_defun.c 18 | _cgo_gotypes.go 19 | _cgo_export.* 20 | 21 | _testmain.go 22 | 23 | *.exe 24 | *.test 25 | *.prof 26 | 27 | /lnd 28 | /lnd-debug 29 | /lncli 30 | /lncli-debug 31 | /lnd-itest 32 | /lncli-itest 33 | 34 | # Integration test log files 35 | lntest/itest/output*.log 36 | lntest/itest/pprof*.log 37 | lntest/itest/.backendlogs 38 | lntest/itest/.minerlogs 39 | 40 | cmd/cmd 41 | *.key 42 | *.hex 43 | 44 | cmd/lncli/lncli 45 | 46 | # Files from mobile build. 47 | mobile/build 48 | mobile/*_generated.go 49 | 50 | # vim 51 | *.swp 52 | 53 | *.hex 54 | *.db 55 | *.bin 56 | 57 | vendor 58 | *.idea 59 | *.iml 60 | profile.cov 61 | profile.tmp 62 | 63 | .DS_Store 64 | 65 | .vscode 66 | 67 | # Coverage test 68 | coverage.txt -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | cache: 3 | directories: 4 | - ~/bitcoin/bitcoin-0.19.1/bin 5 | - $DOWNLOAD_CACHE 6 | - $GOCACHE 7 | - $GOPATH/pkg/mod 8 | - $GOPATH/src/github.com/btcsuite 9 | - $GOPATH/src/github.com/golang 10 | - $GOPATH/src/github.com/grpc-ecosystem 11 | - $GOPATH/src/gopkg.in/alecthomas 12 | - $GOPATH/src/google.golang.org 13 | 14 | # Remove Travis' default flag --depth=50 from the git clone command to make sure 15 | # we have the whole git history, including the commit we lint against. 16 | git: 17 | depth: false 18 | 19 | go: 20 | - "1.14.x" 21 | 22 | env: 23 | global: 24 | - GOCACHE=$HOME/.go-build 25 | - DOWNLOAD_CACHE=$HOME/download_cache 26 | 27 | sudo: required 28 | 29 | jobs: 30 | include: 31 | - stage: Integration Test 32 | name: Btcd Integration 33 | script: 34 | - make itest 35 | 36 | - name: Bitcoind Integration 37 | script: 38 | - bash ./scripts/install_bitcoind.sh 39 | - make itest backend=bitcoind 40 | 41 | - name: Neutrino Integration 42 | script: 43 | - make itest backend=neutrino 44 | 45 | 46 | after_script: 47 | - LOG_FILES=./lntest/itest/*.log 48 | - echo "Uploading to termbin.com..." && find $LOG_FILES | xargs -I{} sh -c "cat {} | nc termbin.com 9999 | xargs -r0 printf '{} uploaded to %s'" 49 | - echo "Uploading to file.io..." && tar -zcvO $LOG_FILES | curl -s -F 'file=@-;filename=logs.tar.gz' https://file.io | xargs -r0 printf 'logs.tar.gz uploaded to %s\n' 50 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.14.5-alpine as builder 2 | 3 | # Force Go to use the cgo based DNS resolver. This is required to ensure DNS 4 | # queries required to connect to linked containers succeed. 5 | ENV GODEBUG netdns=cgo 6 | 7 | # Pass a tag, branch or a commit using build-arg. This allows a docker 8 | # image to be built from a specified Git state. The default image 9 | # will use the Git tip of master by default. 10 | ARG checkout="master" 11 | 12 | # Install dependencies and build the binaries. 13 | RUN apk add --no-cache --update alpine-sdk \ 14 | git \ 15 | make \ 16 | gcc \ 17 | && git clone https://github.com/lightningnetwork/lnd /go/src/github.com/lightningnetwork/lnd \ 18 | && cd /go/src/github.com/lightningnetwork/lnd \ 19 | && git checkout $checkout \ 20 | && make \ 21 | && make install tags="signrpc walletrpc chainrpc invoicesrpc" 22 | 23 | # Start a new, final image. 24 | FROM alpine as final 25 | 26 | # Define a root volume for data persistence. 27 | VOLUME /root/.lnd 28 | 29 | # Add bash, jq and ca-certs, for quality of life and SSL-related reasons. 30 | RUN apk --no-cache add \ 31 | bash \ 32 | jq \ 33 | ca-certificates 34 | 35 | # Copy the binaries from the builder image. 36 | COPY --from=builder /go/bin/lncli /bin/ 37 | COPY --from=builder /go/bin/lnd /bin/ 38 | 39 | # Expose lnd ports (p2p, rpc). 40 | EXPOSE 9735 10009 41 | 42 | # Specify the start command and entrypoint as the lnd daemon. 43 | ENTRYPOINT ["lnd"] 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015-2018 Lightning Labs and The Lightning Network Developers 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /aezeed/cipherseed_rpctest.go: -------------------------------------------------------------------------------- 1 | // +build rpctest 2 | 3 | package aezeed 4 | 5 | import "github.com/btcsuite/btcwallet/waddrmgr" 6 | 7 | func init() { 8 | // For the purposes of our itest, we'll crank down the scrypt params a 9 | // bit. 10 | scryptN = waddrmgr.FastScryptOptions.N 11 | scryptR = waddrmgr.FastScryptOptions.R 12 | scryptP = waddrmgr.FastScryptOptions.P 13 | } 14 | -------------------------------------------------------------------------------- /aezeed/errors.go: -------------------------------------------------------------------------------- 1 | package aezeed 2 | 3 | import "fmt" 4 | 5 | var ( 6 | // ErrIncorrectVersion is returned if a seed bares a mismatched 7 | // external version to that of the package executing the aezeed scheme. 8 | ErrIncorrectVersion = fmt.Errorf("wrong seed version") 9 | 10 | // ErrInvalidPass is returned if the user enters an invalid passphrase 11 | // for a particular enciphered mnemonic. 12 | ErrInvalidPass = fmt.Errorf("invalid passphrase") 13 | 14 | // ErrIncorrectMnemonic is returned if we detect that the checksum of 15 | // the specified mnemonic doesn't match. This indicates the user input 16 | // the wrong mnemonic. 17 | ErrIncorrectMnemonic = fmt.Errorf("mnemonic phrase checksum doesn't " + 18 | "match") 19 | ) 20 | 21 | // ErrUnknownMnenomicWord is returned when attempting to decipher and 22 | // enciphered mnemonic, but a word encountered isn't a member of our word list. 23 | type ErrUnknownMnenomicWord struct { 24 | // Word is the unknown word in the mnemonic phrase. 25 | Word string 26 | 27 | // Index is the index (starting from zero) within the slice of strings 28 | // that makes up the mnemonic that points to the incorrect word. 29 | Index uint8 30 | } 31 | 32 | // Error returns a human readable string describing the error. 33 | func (e ErrUnknownMnenomicWord) Error() string { 34 | return fmt.Sprintf("word %v isn't a part of default word list "+ 35 | "(index=%v)", e.Word, e.Index) 36 | } 37 | -------------------------------------------------------------------------------- /autopilot/graph_test.go: -------------------------------------------------------------------------------- 1 | package autopilot_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/btcsuite/btcutil" 7 | "github.com/lightningnetwork/lnd/autopilot" 8 | ) 9 | 10 | // TestMedian tests the Median method. 11 | func TestMedian(t *testing.T) { 12 | t.Parallel() 13 | 14 | testCases := []struct { 15 | values []btcutil.Amount 16 | median btcutil.Amount 17 | }{ 18 | { 19 | values: []btcutil.Amount{}, 20 | median: 0, 21 | }, 22 | { 23 | values: []btcutil.Amount{10}, 24 | median: 10, 25 | }, 26 | { 27 | values: []btcutil.Amount{10, 20}, 28 | median: 15, 29 | }, 30 | { 31 | values: []btcutil.Amount{10, 20, 30}, 32 | median: 20, 33 | }, 34 | { 35 | values: []btcutil.Amount{30, 10, 20}, 36 | median: 20, 37 | }, 38 | { 39 | values: []btcutil.Amount{10, 10, 10, 10, 5000000}, 40 | median: 10, 41 | }, 42 | } 43 | 44 | for _, test := range testCases { 45 | res := autopilot.Median(test.values) 46 | if res != test.median { 47 | t.Fatalf("expected median %v, got %v", test.median, res) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /autopilot/log.go: -------------------------------------------------------------------------------- 1 | package autopilot 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("ATPL", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /brontide/README.md: -------------------------------------------------------------------------------- 1 | brontide 2 | ========== 3 | 4 | [![Build Status](http://img.shields.io/travis/lightningnetwork/lnd.svg)](https://travis-ci.org/lightningnetwork/lnd) 5 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lightningnetwork/lnd/blob/master/LICENSE) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/lightningnetwork/lnd/brontide) 7 | 8 | The brontide package implements a secure crypto messaging protocol based off of 9 | the [Noise Protocol Framework](http://noiseprotocol.org/noise.html). The 10 | package exposes the raw state machine that handles the handshake and subsequent 11 | message encryption/decryption scheme. Additionally, the package exposes a 12 | [net.Conn](https://golang.org/pkg/net/#Conn) and a 13 | [net.Listener](https://golang.org/pkg/net/#Listener) interface implementation 14 | which allows the encrypted transport to be seamlessly integrated into a 15 | codebase. 16 | 17 | The secure messaging scheme implemented within this package is described in 18 | detail in [BOLT #8 of the Lightning Network specifications](https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md). 19 | 20 | This package has intentionally been designed so it can be used as a standalone 21 | package for any projects needing secure encrypted+authenticated communications 22 | between network enabled programs. 23 | 24 | ## Installation and Updating 25 | 26 | ```bash 27 | $ go get -u github.com/lightningnetwork/lnd/brontide 28 | ``` 29 | -------------------------------------------------------------------------------- /buffer/buffer_test.go: -------------------------------------------------------------------------------- 1 | package buffer_test 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/lightningnetwork/lnd/buffer" 8 | ) 9 | 10 | // TestRecycleSlice asserts that RecycleSlice always zeros a byte slice. 11 | func TestRecycleSlice(t *testing.T) { 12 | tests := []struct { 13 | name string 14 | slice []byte 15 | }{ 16 | { 17 | name: "length zero", 18 | }, 19 | { 20 | name: "length one", 21 | slice: []byte("a"), 22 | }, 23 | { 24 | name: "length power of two length", 25 | slice: bytes.Repeat([]byte("b"), 16), 26 | }, 27 | { 28 | name: "length non power of two", 29 | slice: bytes.Repeat([]byte("c"), 27), 30 | }, 31 | } 32 | 33 | for _, test := range tests { 34 | t.Run(test.name, func(t *testing.T) { 35 | buffer.RecycleSlice(test.slice) 36 | 37 | expSlice := make([]byte, len(test.slice)) 38 | if !bytes.Equal(expSlice, test.slice) { 39 | t.Fatalf("slice not recycled, want: %v, got: %v", 40 | expSlice, test.slice) 41 | } 42 | }) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /buffer/read.go: -------------------------------------------------------------------------------- 1 | package buffer 2 | 3 | import ( 4 | "github.com/lightningnetwork/lnd/lnwire" 5 | ) 6 | 7 | // ReadSize represents the size of the maximum message that can be read off the 8 | // wire by brontide. The buffer is used to hold the ciphertext while the 9 | // brontide state machine decrypts the message. 10 | const ReadSize = lnwire.MaxMessagePayload + 16 11 | 12 | // Read is a static byte array sized to the maximum-allowed Lightning message 13 | // size, plus 16 bytes for the MAC. 14 | type Read [ReadSize]byte 15 | 16 | // Recycle zeroes the Read, making it fresh for another use. 17 | func (b *Read) Recycle() { 18 | RecycleSlice(b[:]) 19 | } 20 | -------------------------------------------------------------------------------- /buffer/utils.go: -------------------------------------------------------------------------------- 1 | package buffer 2 | 3 | // RecycleSlice zeroes byte slice, making it fresh for another use. 4 | // Zeroing the buffer using a logarithmic number of calls to the optimized copy 5 | // method. Benchmarking shows this to be ~30 times faster than a for loop that 6 | // sets each index to 0 for ~65KB buffers use for wire messages. Inspired by: 7 | // https://stackoverflow.com/questions/30614165/is-there-analog-of-memset-in-go 8 | func RecycleSlice(b []byte) { 9 | if len(b) == 0 { 10 | return 11 | } 12 | 13 | b[0] = 0 14 | for i := 1; i < len(b); i *= 2 { 15 | copy(b[i:], b[:i]) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /buffer/write.go: -------------------------------------------------------------------------------- 1 | package buffer 2 | 3 | import ( 4 | "github.com/lightningnetwork/lnd/lnwire" 5 | ) 6 | 7 | // WriteSize represents the size of the maximum plaintext message than can be 8 | // sent using brontide. The buffer does not include extra space for the MAC, as 9 | // that is applied by the Noise protocol after encrypting the plaintext. 10 | const WriteSize = lnwire.MaxMessagePayload 11 | 12 | // Write is static byte array occupying to maximum-allowed plaintext-message 13 | // size. 14 | type Write [WriteSize]byte 15 | 16 | // Recycle zeroes the Write, making it fresh for another use. 17 | func (b *Write) Recycle() { 18 | RecycleSlice(b[:]) 19 | } 20 | -------------------------------------------------------------------------------- /build/deployment.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | // DeploymentType is an enum specifying the deployment to compile. 4 | type DeploymentType byte 5 | 6 | const ( 7 | // Development is a deployment that includes extra testing hooks and 8 | // logging configurations. 9 | Development DeploymentType = iota 10 | 11 | // Production is a deployment that strips out testing logic and uses 12 | // Default logging. 13 | Production 14 | ) 15 | 16 | // String returns a human readable name for a build type. 17 | func (b DeploymentType) String() string { 18 | switch b { 19 | case Development: 20 | return "development" 21 | case Production: 22 | return "production" 23 | default: 24 | return "unknown" 25 | } 26 | } 27 | 28 | // IsProdBuild returns true if this is a production build. 29 | func IsProdBuild() bool { 30 | return Deployment == Production 31 | } 32 | 33 | // IsDevBuild returns true if this is a development build. 34 | func IsDevBuild() bool { 35 | return Deployment == Development 36 | } 37 | -------------------------------------------------------------------------------- /build/deployment_dev.go: -------------------------------------------------------------------------------- 1 | // +build dev 2 | 3 | package build 4 | 5 | // Deployment specifies a development build. 6 | const Deployment = Development 7 | -------------------------------------------------------------------------------- /build/deployment_prod.go: -------------------------------------------------------------------------------- 1 | // +build !dev 2 | 3 | package build 4 | 5 | // Deployment specifies a production build. 6 | const Deployment = Production 7 | -------------------------------------------------------------------------------- /build/log_default.go: -------------------------------------------------------------------------------- 1 | // +build !stdlog,!nolog 2 | 3 | package build 4 | 5 | import "os" 6 | 7 | // LoggingType is a log type that writes to both stdout and the log rotator, if 8 | // present. 9 | const LoggingType = LogTypeDefault 10 | 11 | // Write writes the byte slice to both stdout and the log rotator, if present. 12 | func (w *LogWriter) Write(b []byte) (int, error) { 13 | os.Stdout.Write(b) 14 | if w.RotatorPipe != nil { 15 | w.RotatorPipe.Write(b) 16 | } 17 | return len(b), nil 18 | } 19 | -------------------------------------------------------------------------------- /build/log_nolog.go: -------------------------------------------------------------------------------- 1 | // +build nolog 2 | 3 | package build 4 | 5 | // LoggingType is a log type that writes no logs. 6 | const LoggingType = LogTypeNone 7 | 8 | // Write is a noop. 9 | func (w *LogWriter) Write(b []byte) (int, error) { 10 | return len(b), nil 11 | } 12 | -------------------------------------------------------------------------------- /build/log_stdlog.go: -------------------------------------------------------------------------------- 1 | // +build stdlog 2 | 3 | package build 4 | 5 | import "os" 6 | 7 | // LoggingType is a log type that only writes to stdout. 8 | const LoggingType = LogTypeStdOut 9 | 10 | // Write writes the provided byte slice to stdout. 11 | func (w *LogWriter) Write(b []byte) (int, error) { 12 | os.Stdout.Write(b) 13 | return len(b), nil 14 | } 15 | -------------------------------------------------------------------------------- /build/loglevel_critical.go: -------------------------------------------------------------------------------- 1 | // +build dev,critical 2 | 3 | package build 4 | 5 | // LogLevel specifies a critical log level. 6 | var LogLevel = "critical" 7 | -------------------------------------------------------------------------------- /build/loglevel_debug.go: -------------------------------------------------------------------------------- 1 | // +build dev,debug 2 | 3 | package build 4 | 5 | // LogLevel specifies a debug log level. 6 | var LogLevel = "debug" 7 | -------------------------------------------------------------------------------- /build/loglevel_default.go: -------------------------------------------------------------------------------- 1 | // +build !info,!debug,!trace,!warn,!error,!critical,!off 2 | 3 | package build 4 | 5 | // LogLevel specifies a default log level of info. 6 | var LogLevel = "info" 7 | -------------------------------------------------------------------------------- /build/loglevel_error.go: -------------------------------------------------------------------------------- 1 | // +build dev,error 2 | 3 | package build 4 | 5 | // LogLevel specifies an error log level. 6 | var LogLevel = "error" 7 | -------------------------------------------------------------------------------- /build/loglevel_info.go: -------------------------------------------------------------------------------- 1 | // +build dev,info 2 | 3 | package build 4 | 5 | // LogLevel specifies an info log level. 6 | var LogLevel = "info" 7 | -------------------------------------------------------------------------------- /build/loglevel_off.go: -------------------------------------------------------------------------------- 1 | // +build dev,off 2 | 3 | package build 4 | 5 | // LogLevel specifies an off log level. 6 | var LogLevel = "off" 7 | -------------------------------------------------------------------------------- /build/loglevel_trace.go: -------------------------------------------------------------------------------- 1 | // +build dev,trace 2 | 3 | package build 4 | 5 | // LogLevel specifies a trace log level. 6 | var LogLevel = "trace" 7 | -------------------------------------------------------------------------------- /build/loglevel_warn.go: -------------------------------------------------------------------------------- 1 | // +build dev,warn 2 | 3 | package build 4 | 5 | // LogLevel specifies a warning log level. 6 | var LogLevel = "warn" 7 | -------------------------------------------------------------------------------- /cert/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/lightningnetwork/lnd/cert 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /chainntnfs/README.md: -------------------------------------------------------------------------------- 1 | chainntnfs 2 | ========== 3 | 4 | [![Build Status](http://img.shields.io/travis/lightningnetwork/lnd.svg)](https://travis-ci.org/lightningnetwork/lnd) 5 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lightningnetwork/lnd/blob/master/LICENSE) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/lightningnetwork/lnd/chainntnfs) 7 | 8 | The chainntnfs package implements a set of interfaces which allow callers to 9 | receive notifications in response to specific on-chain events. The set of 10 | notifications available include: 11 | 12 | * Notifications for each new block connected to the current best chain. 13 | * Notifications once a `txid` has reached a specified number of 14 | confirmations. 15 | * Notifications once a target outpoint (`txid:index`) has been spent. 16 | 17 | These notifications are used within `lnd` in order to properly handle the 18 | workflows for: channel funding, cooperative channel closures, forced channel 19 | closures, channel contract breaches, sweeping time-locked outputs, and finally 20 | pruning the channel graph. 21 | 22 | This package is intentionally general enough to be applicable outside the 23 | specific use cases within `lnd` outlined above. The current sole concrete 24 | implementation of the `ChainNotifier` interface depends on `btcd`. 25 | 26 | ## Installation and Updating 27 | 28 | ```bash 29 | $ go get -u github.com/lightningnetwork/lnd/chainntnfs 30 | ``` 31 | -------------------------------------------------------------------------------- /chainntnfs/interface_dev.go: -------------------------------------------------------------------------------- 1 | // +build dev 2 | 3 | package chainntnfs 4 | 5 | import "github.com/btcsuite/btcd/chaincfg/chainhash" 6 | 7 | // TestChainNotifier enables the use of methods that are only present during 8 | // testing for ChainNotifiers. 9 | type TestChainNotifier interface { 10 | ChainNotifier 11 | 12 | // UnsafeStart enables notifiers to start up with a specific best block. 13 | // Used for testing. 14 | UnsafeStart(int32, *chainhash.Hash, int32, func() error) error 15 | } 16 | -------------------------------------------------------------------------------- /chainntnfs/log.go: -------------------------------------------------------------------------------- 1 | package chainntnfs 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // Log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var Log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("NTFN", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | Log = logger 29 | } 30 | -------------------------------------------------------------------------------- /chanacceptor/interface.go: -------------------------------------------------------------------------------- 1 | package chanacceptor 2 | 3 | import ( 4 | "github.com/btcsuite/btcd/btcec" 5 | "github.com/lightningnetwork/lnd/lnwire" 6 | ) 7 | 8 | // ChannelAcceptRequest is a struct containing the requesting node's public key 9 | // along with the lnwire.OpenChannel message that they sent when requesting an 10 | // inbound channel. This information is provided to each acceptor so that they 11 | // can each leverage their own decision-making with this information. 12 | type ChannelAcceptRequest struct { 13 | // Node is the public key of the node requesting to open a channel. 14 | Node *btcec.PublicKey 15 | 16 | // OpenChanMsg is the actual OpenChannel protocol message that the peer 17 | // sent to us. 18 | OpenChanMsg *lnwire.OpenChannel 19 | } 20 | 21 | // ChannelAcceptor is an interface that represents a predicate on the data 22 | // contained in ChannelAcceptRequest. 23 | type ChannelAcceptor interface { 24 | Accept(req *ChannelAcceptRequest) bool 25 | } 26 | -------------------------------------------------------------------------------- /chanacceptor/rpcacceptor.go: -------------------------------------------------------------------------------- 1 | package chanacceptor 2 | 3 | // RPCAcceptor represents the RPC-controlled variant of the ChannelAcceptor. 4 | // One RPCAcceptor allows one RPC client. 5 | type RPCAcceptor struct { 6 | acceptClosure func(req *ChannelAcceptRequest) bool 7 | } 8 | 9 | // Accept is a predicate on the ChannelAcceptRequest which is sent to the RPC 10 | // client who will respond with the ultimate decision. This assumes an accept 11 | // closure has been specified during creation. 12 | // 13 | // NOTE: Part of the ChannelAcceptor interface. 14 | func (r *RPCAcceptor) Accept(req *ChannelAcceptRequest) bool { 15 | return r.acceptClosure(req) 16 | } 17 | 18 | // NewRPCAcceptor creates and returns an instance of the RPCAcceptor. 19 | func NewRPCAcceptor(closure func(*ChannelAcceptRequest) bool) *RPCAcceptor { 20 | return &RPCAcceptor{ 21 | acceptClosure: closure, 22 | } 23 | } 24 | 25 | // A compile-time constraint to ensure RPCAcceptor implements the ChannelAcceptor 26 | // interface. 27 | var _ ChannelAcceptor = (*RPCAcceptor)(nil) 28 | -------------------------------------------------------------------------------- /chanbackup/log.go: -------------------------------------------------------------------------------- 1 | package chanbackup 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("CHBU", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | 31 | // logClosure is used to provide a closure over expensive logging operations so 32 | // don't have to be performed when the logging level doesn't warrant it. 33 | type logClosure func() string 34 | 35 | // String invokes the underlying function and returns the result. 36 | func (c logClosure) String() string { 37 | return c() 38 | } 39 | 40 | // newLogClosure returns a new closure over a function that returns a string 41 | // which itself provides a Stringer interface so that it can be used with the 42 | // logging system. 43 | func newLogClosure(c func() string) logClosure { 44 | return logClosure(c) 45 | } 46 | -------------------------------------------------------------------------------- /chanfitness/log.go: -------------------------------------------------------------------------------- 1 | package chanfitness 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // Subsystem defines the logging code for this subsystem. 9 | const Subsystem = "CHFT" 10 | 11 | // log is a logger that is initialized with no output filters. This 12 | // means the package will not perform any logging by default until the caller 13 | // requests it. 14 | var log btclog.Logger 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | UseLogger(build.NewSubLogger(Subsystem, nil)) 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | UseLogger(btclog.Disabled) 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | // This should be used in preference to SetLogWriter if the caller is also 29 | // using btclog. 30 | func UseLogger(logger btclog.Logger) { 31 | log = logger 32 | } 33 | -------------------------------------------------------------------------------- /channeldb/README.md: -------------------------------------------------------------------------------- 1 | channeldb 2 | ========== 3 | 4 | [![Build Status](http://img.shields.io/travis/lightningnetwork/lnd.svg)](https://travis-ci.org/lightningnetwork/lnd) 5 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lightningnetwork/lnd/blob/master/LICENSE) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/lightningnetwork/lnd/channeldb) 7 | 8 | The channeldb implements the persistent storage engine for `lnd` and 9 | generically a data storage layer for the required state within the Lightning 10 | Network. The backing storage engine is 11 | [boltdb](https://github.com/coreos/bbolt), an embedded pure-go key-value store 12 | based off of LMDB. 13 | 14 | The package implements an object-oriented storage model with queries and 15 | mutations flowing through a particular object instance rather than the database 16 | itself. The storage implemented by the objects includes: open channels, past 17 | commitment revocation states, the channel graph which includes authenticated 18 | node and channel announcements, outgoing payments, and invoices 19 | 20 | ## Installation and Updating 21 | 22 | ```bash 23 | $ go get -u github.com/lightningnetwork/lnd/channeldb 24 | ``` 25 | -------------------------------------------------------------------------------- /channeldb/doc.go: -------------------------------------------------------------------------------- 1 | package channeldb 2 | -------------------------------------------------------------------------------- /channeldb/fees.go: -------------------------------------------------------------------------------- 1 | package channeldb 2 | -------------------------------------------------------------------------------- /channeldb/kvdb/config.go: -------------------------------------------------------------------------------- 1 | package kvdb 2 | 3 | // BoltBackendName is the name of the backend that should be passed into 4 | // kvdb.Create to initialize a new instance of kvdb.Backend backed by a live 5 | // instance of bbolt. 6 | const BoltBackendName = "bdb" 7 | 8 | // EtcdBackendName is the name of the backend that should be passed into 9 | // kvdb.Create to initialize a new instance of kvdb.Backend backed by a live 10 | // instance of etcd. 11 | const EtcdBackendName = "etcd" 12 | 13 | // BoltConfig holds bolt configuration. 14 | type BoltConfig struct { 15 | NoFreeListSync bool `long:"nofreelistsync" description:"If true, prevents the database from syncing its freelist to disk"` 16 | } 17 | 18 | // EtcdConfig holds etcd configuration. 19 | type EtcdConfig struct { 20 | Host string `long:"host" description:"Etcd database host."` 21 | 22 | User string `long:"user" description:"Etcd database user."` 23 | 24 | Pass string `long:"pass" description:"Password for the database user."` 25 | 26 | CertFile string `long:"cert_file" description:"Path to the TLS certificate for etcd RPC."` 27 | 28 | KeyFile string `long:"key_file" description:"Path to the TLS private key for etcd RPC."` 29 | 30 | InsecureSkipVerify bool `long:"insecure_skip_verify" description:"Whether we intend to skip TLS verification"` 31 | 32 | CollectStats bool `long:"collect_stats" description:"Whether to collect etcd commit stats."` 33 | } 34 | -------------------------------------------------------------------------------- /channeldb/kvdb/etcd/bucket_test.go: -------------------------------------------------------------------------------- 1 | // +build kvdb_etcd 2 | 3 | package etcd 4 | 5 | // bkey is a helper functon used in tests to create a bucket key from passed 6 | // bucket list. 7 | func bkey(buckets ...string) string { 8 | var bucketKey []byte 9 | 10 | rootID := makeBucketID([]byte("")) 11 | parent := rootID[:] 12 | 13 | for _, bucketName := range buckets { 14 | bucketKey = makeBucketKey(parent, []byte(bucketName)) 15 | id := makeBucketID(bucketKey) 16 | parent = id[:] 17 | } 18 | 19 | return string(bucketKey) 20 | } 21 | 22 | // bval is a helper function used in tests to create a bucket value (the value 23 | // for a bucket key) from the passed bucket list. 24 | func bval(buckets ...string) string { 25 | id := makeBucketID([]byte(bkey(buckets...))) 26 | return string(id[:]) 27 | } 28 | 29 | // vkey is a helper function used in tests to create a value key from the 30 | // passed key and bucket list. 31 | func vkey(key string, buckets ...string) string { 32 | rootID := makeBucketID([]byte("")) 33 | bucket := rootID[:] 34 | 35 | for _, bucketName := range buckets { 36 | bucketKey := makeBucketKey(bucket, []byte(bucketName)) 37 | id := makeBucketID(bucketKey) 38 | bucket = id[:] 39 | } 40 | 41 | return string(makeValueKey(bucket, []byte(key))) 42 | } 43 | -------------------------------------------------------------------------------- /channeldb/kvdb/etcd/driver_test.go: -------------------------------------------------------------------------------- 1 | // +build kvdb_etcd 2 | 3 | package etcd 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/btcsuite/btcwallet/walletdb" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestOpenCreateFailure(t *testing.T) { 13 | t.Parallel() 14 | 15 | db, err := walletdb.Open(dbType) 16 | assert.Error(t, err) 17 | assert.Nil(t, db) 18 | 19 | db, err = walletdb.Open(dbType, "wrong") 20 | assert.Error(t, err) 21 | assert.Nil(t, db) 22 | 23 | db, err = walletdb.Create(dbType) 24 | assert.Error(t, err) 25 | assert.Nil(t, db) 26 | 27 | db, err = walletdb.Create(dbType, "wrong") 28 | assert.Error(t, err) 29 | assert.Nil(t, db) 30 | } 31 | -------------------------------------------------------------------------------- /channeldb/kvdb/etcd/walletdb_interface_test.go: -------------------------------------------------------------------------------- 1 | // +build kvdb_etcd 2 | 3 | package etcd 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/btcsuite/btcwallet/walletdb/walletdbtest" 9 | ) 10 | 11 | // TestWalletDBInterface performs the WalletDB interface test suite for the 12 | // etcd database driver. 13 | func TestWalletDBInterface(t *testing.T) { 14 | f := NewEtcdTestFixture(t) 15 | defer f.Cleanup() 16 | walletdbtest.TestInterface(t, dbType, f.BackendConfig()) 17 | } 18 | -------------------------------------------------------------------------------- /channeldb/kvdb/kvdb_no_etcd.go: -------------------------------------------------------------------------------- 1 | // +build !kvdb_etcd 2 | 3 | package kvdb 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | ) 9 | 10 | // TestBackend is conditionally set to bdb when the kvdb_etcd build tag is 11 | // not defined, allowing testing our database code with bolt backend. 12 | const TestBackend = BoltBackendName 13 | 14 | var errEtcdNotAvailable = fmt.Errorf("etcd backend not available") 15 | 16 | // GetEtcdBackend is a stub returning nil and errEtcdNotAvailable error. 17 | func GetEtcdBackend(ctx context.Context, prefix string, 18 | etcdConfig *EtcdConfig) (Backend, error) { 19 | 20 | return nil, errEtcdNotAvailable 21 | } 22 | 23 | // GetTestEtcdBackend is a stub returning nil, an empty closure and an 24 | // errEtcdNotAvailable error. 25 | func GetEtcdTestBackend(path, name string) (Backend, func(), error) { 26 | return nil, func() {}, errEtcdNotAvailable 27 | } 28 | -------------------------------------------------------------------------------- /channeldb/log.go: -------------------------------------------------------------------------------- 1 | package channeldb 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | mig "github.com/lightningnetwork/lnd/channeldb/migration" 7 | "github.com/lightningnetwork/lnd/channeldb/migration12" 8 | "github.com/lightningnetwork/lnd/channeldb/migration13" 9 | "github.com/lightningnetwork/lnd/channeldb/migration16" 10 | "github.com/lightningnetwork/lnd/channeldb/migration_01_to_11" 11 | ) 12 | 13 | // log is a logger that is initialized with no output filters. This 14 | // means the package will not perform any logging by default until the caller 15 | // requests it. 16 | var log btclog.Logger 17 | 18 | func init() { 19 | UseLogger(build.NewSubLogger("CHDB", nil)) 20 | } 21 | 22 | // DisableLog disables all library log output. Logging output is disabled 23 | // by default until UseLogger is called. 24 | func DisableLog() { 25 | UseLogger(btclog.Disabled) 26 | } 27 | 28 | // UseLogger uses a specified Logger to output package logging info. 29 | // This should be used in preference to SetLogWriter if the caller is also 30 | // using btclog. 31 | func UseLogger(logger btclog.Logger) { 32 | log = logger 33 | mig.UseLogger(logger) 34 | migration_01_to_11.UseLogger(logger) 35 | migration12.UseLogger(logger) 36 | migration13.UseLogger(logger) 37 | migration16.UseLogger(logger) 38 | } 39 | -------------------------------------------------------------------------------- /channeldb/migration/create_tlb.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/lightningnetwork/lnd/channeldb/kvdb" 7 | ) 8 | 9 | // CreateTLB creates a new top-level bucket with the passed bucket identifier. 10 | func CreateTLB(bucket []byte) func(kvdb.RwTx) error { 11 | return func(tx kvdb.RwTx) error { 12 | log.Infof("Creating top-level bucket: \"%s\" ...", bucket) 13 | 14 | if tx.ReadBucket(bucket) != nil { 15 | return fmt.Errorf("top-level bucket \"%s\" "+ 16 | "already exists", bucket) 17 | } 18 | 19 | _, err := tx.CreateTopLevelBucket(bucket) 20 | if err != nil { 21 | return err 22 | } 23 | 24 | log.Infof("Created top-level bucket: \"%s\"", bucket) 25 | return nil 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /channeldb/migration/log.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import "github.com/btcsuite/btclog" 4 | 5 | // log is a logger that is initialized as disabled. This means the package will 6 | // not perform any logging by default until a logger is set. 7 | var log = btclog.Disabled 8 | 9 | // UseLogger uses a specified Logger to output package logging info. 10 | func UseLogger(logger btclog.Logger) { 11 | log = logger 12 | } 13 | -------------------------------------------------------------------------------- /channeldb/migration12/log.go: -------------------------------------------------------------------------------- 1 | package migration12 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | ) 6 | 7 | // log is a logger that is initialized as disabled. This means the package will 8 | // not perform any logging by default until a logger is set. 9 | var log = btclog.Disabled 10 | 11 | // UseLogger uses a specified Logger to output package logging info. 12 | func UseLogger(logger btclog.Logger) { 13 | log = logger 14 | } 15 | -------------------------------------------------------------------------------- /channeldb/migration13/log.go: -------------------------------------------------------------------------------- 1 | package migration13 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | ) 6 | 7 | // log is a logger that is initialized as disabled. This means the package will 8 | // not perform any logging by default until a logger is set. 9 | var log = btclog.Disabled 10 | 11 | // UseLogger uses a specified Logger to output package logging info. 12 | func UseLogger(logger btclog.Logger) { 13 | log = logger 14 | } 15 | -------------------------------------------------------------------------------- /channeldb/migration16/log.go: -------------------------------------------------------------------------------- 1 | package migration16 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | ) 6 | 7 | // log is a logger that is initialized as disabled. This means the package will 8 | // not perform any logging by default until a logger is set. 9 | var log = btclog.Disabled 10 | 11 | // UseLogger uses a specified Logger to output package logging info. 12 | func UseLogger(logger btclog.Logger) { 13 | log = logger 14 | } 15 | -------------------------------------------------------------------------------- /channeldb/migration_01_to_11/log.go: -------------------------------------------------------------------------------- 1 | package migration_01_to_11 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | ) 6 | 7 | // log is a logger that is initialized as disabled. This means the package will 8 | // not perform any logging by default until a logger is set. 9 | var log = btclog.Disabled 10 | 11 | // UseLogger uses a specified Logger to output package logging info. 12 | func UseLogger(logger btclog.Logger) { 13 | log = logger 14 | } 15 | -------------------------------------------------------------------------------- /channeldb/migration_01_to_11/meta.go: -------------------------------------------------------------------------------- 1 | package migration_01_to_11 2 | 3 | import ( 4 | "github.com/lightningnetwork/lnd/channeldb/kvdb" 5 | ) 6 | 7 | var ( 8 | // metaBucket stores all the meta information concerning the state of 9 | // the database. 10 | metaBucket = []byte("metadata") 11 | 12 | // dbVersionKey is a boltdb key and it's used for storing/retrieving 13 | // current database version. 14 | dbVersionKey = []byte("dbp") 15 | ) 16 | 17 | // Meta structure holds the database meta information. 18 | type Meta struct { 19 | // DbVersionNumber is the current schema version of the database. 20 | DbVersionNumber uint32 21 | } 22 | 23 | // putMeta is an internal helper function used in order to allow callers to 24 | // re-use a database transaction. See the publicly exported PutMeta method for 25 | // more information. 26 | func putMeta(meta *Meta, tx kvdb.RwTx) error { 27 | metaBucket, err := tx.CreateTopLevelBucket(metaBucket) 28 | if err != nil { 29 | return err 30 | } 31 | 32 | return putDbVersion(metaBucket, meta) 33 | } 34 | 35 | func putDbVersion(metaBucket kvdb.RwBucket, meta *Meta) error { 36 | scratch := make([]byte, 4) 37 | byteOrder.PutUint32(scratch, meta.DbVersionNumber) 38 | return metaBucket.Put(dbVersionKey, scratch) 39 | } 40 | -------------------------------------------------------------------------------- /channeldb/migration_01_to_11/options.go: -------------------------------------------------------------------------------- 1 | package migration_01_to_11 2 | 3 | const ( 4 | // DefaultRejectCacheSize is the default number of rejectCacheEntries to 5 | // cache for use in the rejection cache of incoming gossip traffic. This 6 | // produces a cache size of around 1MB. 7 | DefaultRejectCacheSize = 50000 8 | 9 | // DefaultChannelCacheSize is the default number of ChannelEdges cached 10 | // in order to reply to gossip queries. This produces a cache size of 11 | // around 40MB. 12 | DefaultChannelCacheSize = 20000 13 | ) 14 | 15 | // Options holds parameters for tuning and customizing a channeldb.DB. 16 | type Options struct { 17 | // RejectCacheSize is the maximum number of rejectCacheEntries to hold 18 | // in the rejection cache. 19 | RejectCacheSize int 20 | 21 | // ChannelCacheSize is the maximum number of ChannelEdges to hold in the 22 | // channel cache. 23 | ChannelCacheSize int 24 | 25 | // NoFreelistSync, if true, prevents the database from syncing its 26 | // freelist to disk, resulting in improved performance at the expense of 27 | // increased startup time. 28 | NoFreelistSync bool 29 | } 30 | 31 | // DefaultOptions returns an Options populated with default values. 32 | func DefaultOptions() Options { 33 | return Options{ 34 | RejectCacheSize: DefaultRejectCacheSize, 35 | ChannelCacheSize: DefaultChannelCacheSize, 36 | NoFreelistSync: true, 37 | } 38 | } 39 | 40 | // OptionModifier is a function signature for modifying the default Options. 41 | type OptionModifier func(*Options) 42 | -------------------------------------------------------------------------------- /channeldb/migration_01_to_11/payment_control.go: -------------------------------------------------------------------------------- 1 | package migration_01_to_11 2 | 3 | import "github.com/lightningnetwork/lnd/channeldb/kvdb" 4 | 5 | // fetchPaymentStatus fetches the payment status of the payment. If the payment 6 | // isn't found, it will default to "StatusUnknown". 7 | func fetchPaymentStatus(bucket kvdb.RBucket) PaymentStatus { 8 | if bucket.Get(paymentSettleInfoKey) != nil { 9 | return StatusSucceeded 10 | } 11 | 12 | if bucket.Get(paymentFailInfoKey) != nil { 13 | return StatusFailed 14 | } 15 | 16 | if bucket.Get(paymentCreationInfoKey) != nil { 17 | return StatusInFlight 18 | } 19 | 20 | return StatusUnknown 21 | } 22 | -------------------------------------------------------------------------------- /channelnotifier/log.go: -------------------------------------------------------------------------------- 1 | package channelnotifier 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This means the 9 | // package will not perform any logging by default until the caller requests 10 | // it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("CHNF", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled by 19 | // default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. This 25 | // should be used in preference to SetLogWriter if the caller is also using 26 | // btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /clock/default_clock.go: -------------------------------------------------------------------------------- 1 | package clock 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // DefaultClock implements Clock interface by simply calling the appropriate 8 | // time functions. 9 | type DefaultClock struct{} 10 | 11 | // NewDefaultClock constructs a new DefaultClock. 12 | func NewDefaultClock() Clock { 13 | return &DefaultClock{} 14 | } 15 | 16 | // Now simply returns time.Now(). 17 | func (DefaultClock) Now() time.Time { 18 | return time.Now() 19 | } 20 | 21 | // TickAfter simply wraps time.After(). 22 | func (DefaultClock) TickAfter(duration time.Duration) <-chan time.Time { 23 | return time.After(duration) 24 | } 25 | -------------------------------------------------------------------------------- /clock/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/lightningnetwork/lnd/clock 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /clock/interface.go: -------------------------------------------------------------------------------- 1 | package clock 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // Clock is an interface that provides a time functions for LND packages. 8 | // This is useful during testing when a concrete time reference is needed. 9 | type Clock interface { 10 | // Now returns the current local time (as defined by the Clock). 11 | Now() time.Time 12 | 13 | // TickAfter returns a channel that will receive a tick after the specified 14 | // duration has passed. 15 | TickAfter(duration time.Duration) <-chan time.Time 16 | } 17 | -------------------------------------------------------------------------------- /cmd/lncli/arg_parse.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "regexp" 5 | "strconv" 6 | "time" 7 | ) 8 | 9 | // reTimeRange matches systemd.time-like short negative timeranges, e.g. "-200s". 10 | var reTimeRange = regexp.MustCompile(`^-\d{1,18}[s|m|h|d|w|M|y]$`) 11 | 12 | // secondsPer allows translating s(seconds), m(minutes), h(ours), d(ays), 13 | // w(eeks), M(onths) and y(ears) into corresponding seconds. 14 | var secondsPer = map[string]int64{ 15 | "s": 1, 16 | "m": 60, 17 | "h": 3600, 18 | "d": 86400, 19 | "w": 604800, 20 | "M": 2630016, // 30.44 days 21 | "y": 31557600, // 365.25 days 22 | } 23 | 24 | // parseTime parses UNIX timestamps or short timeranges inspired by sytemd (when starting with "-"), 25 | // e.g. "-1M" for one month (30.44 days) ago. 26 | func parseTime(s string, base time.Time) (uint64, error) { 27 | if reTimeRange.MatchString(s) { 28 | last := len(s) - 1 29 | 30 | d, err := strconv.ParseInt(s[1:last], 10, 64) 31 | if err != nil { 32 | return uint64(0), err 33 | } 34 | 35 | mul := secondsPer[string(s[last])] 36 | return uint64(base.Unix() - d*mul), nil 37 | } 38 | 39 | return strconv.ParseUint(s, 10, 64) 40 | } 41 | -------------------------------------------------------------------------------- /cmd/lncli/autopilotrpc_default.go: -------------------------------------------------------------------------------- 1 | // +build !autopilotrpc 2 | 3 | package main 4 | 5 | import "github.com/urfave/cli" 6 | 7 | // autopilotCommands will return nil for non-autopilotrpc builds. 8 | func autopilotCommands() []cli.Command { 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /cmd/lncli/cmd_query_mission_control.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/lightningnetwork/lnd/lnrpc/routerrpc" 7 | 8 | "github.com/urfave/cli" 9 | ) 10 | 11 | var queryMissionControlCommand = cli.Command{ 12 | Name: "querymc", 13 | Category: "Payments", 14 | Usage: "Query the internal mission control state.", 15 | Action: actionDecorator(queryMissionControl), 16 | } 17 | 18 | func queryMissionControl(ctx *cli.Context) error { 19 | conn := getClientConn(ctx, false) 20 | defer conn.Close() 21 | 22 | client := routerrpc.NewRouterClient(conn) 23 | 24 | req := &routerrpc.QueryMissionControlRequest{} 25 | rpcCtx := context.Background() 26 | snapshot, err := client.QueryMissionControl(rpcCtx, req) 27 | if err != nil { 28 | return err 29 | } 30 | 31 | printRespJSON(snapshot) 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /cmd/lncli/cmd_reset_mission_control.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/lightningnetwork/lnd/lnrpc/routerrpc" 7 | 8 | "github.com/urfave/cli" 9 | ) 10 | 11 | var resetMissionControlCommand = cli.Command{ 12 | Name: "resetmc", 13 | Category: "Payments", 14 | Usage: "Reset internal mission control state.", 15 | Action: actionDecorator(resetMissionControl), 16 | } 17 | 18 | func resetMissionControl(ctx *cli.Context) error { 19 | conn := getClientConn(ctx, false) 20 | defer conn.Close() 21 | 22 | client := routerrpc.NewRouterClient(conn) 23 | 24 | req := &routerrpc.ResetMissionControlRequest{} 25 | rpcCtx := context.Background() 26 | _, err := client.ResetMissionControl(rpcCtx, req) 27 | return err 28 | } 29 | -------------------------------------------------------------------------------- /cmd/lncli/invoicesrpc_default.go: -------------------------------------------------------------------------------- 1 | // +build !invoicesrpc 2 | 3 | package main 4 | 5 | import "github.com/urfave/cli" 6 | 7 | // invoicesCommands will return nil for non-invoicesrpc builds. 8 | func invoicesCommands() []cli.Command { 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /cmd/lncli/routerrpc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/urfave/cli" 4 | 5 | // routerCommands returns a list of routerrpc commands. 6 | func routerCommands() []cli.Command { 7 | return []cli.Command{ 8 | queryMissionControlCommand, 9 | queryProbCommand, 10 | resetMissionControlCommand, 11 | buildRouteCommand, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /cmd/lncli/walletrpc_default.go: -------------------------------------------------------------------------------- 1 | // +build !walletrpc 2 | 3 | package main 4 | 5 | import "github.com/urfave/cli" 6 | 7 | // walletCommands will return nil for non-walletrpc builds. 8 | func walletCommands() []cli.Command { 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /cmd/lncli/watchtower_active.go: -------------------------------------------------------------------------------- 1 | // +build watchtowerrpc 2 | 3 | package main 4 | 5 | import ( 6 | "context" 7 | 8 | "github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc" 9 | "github.com/urfave/cli" 10 | ) 11 | 12 | func watchtowerCommands() []cli.Command { 13 | return []cli.Command{ 14 | { 15 | Name: "tower", 16 | Usage: "Interact with the watchtower.", 17 | Category: "Watchtower", 18 | Subcommands: []cli.Command{ 19 | towerInfoCommand, 20 | }, 21 | }, 22 | } 23 | } 24 | 25 | func getWatchtowerClient(ctx *cli.Context) (watchtowerrpc.WatchtowerClient, func()) { 26 | conn := getClientConn(ctx, false) 27 | cleanup := func() { 28 | conn.Close() 29 | } 30 | return watchtowerrpc.NewWatchtowerClient(conn), cleanup 31 | } 32 | 33 | var towerInfoCommand = cli.Command{ 34 | Name: "info", 35 | Usage: "Returns basic information related to the active watchtower.", 36 | Action: actionDecorator(towerInfo), 37 | } 38 | 39 | func towerInfo(ctx *cli.Context) error { 40 | if ctx.NArg() != 0 || ctx.NumFlags() > 0 { 41 | return cli.ShowCommandHelp(ctx, "info") 42 | } 43 | 44 | client, cleanup := getWatchtowerClient(ctx) 45 | defer cleanup() 46 | 47 | req := &watchtowerrpc.GetInfoRequest{} 48 | resp, err := client.GetInfo(context.Background(), req) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | printRespJSON(resp) 54 | 55 | return nil 56 | } 57 | -------------------------------------------------------------------------------- /cmd/lncli/watchtower_default.go: -------------------------------------------------------------------------------- 1 | // +build !watchtowerrpc 2 | 3 | package main 4 | 5 | import "github.com/urfave/cli" 6 | 7 | // watchtowerCommands will return nil for non-watchtowerrpc builds. 8 | func watchtowerCommands() []cli.Command { 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /cmd/lnd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/jessevdk/go-flags" 8 | "github.com/lightningnetwork/lnd" 9 | "github.com/lightningnetwork/lnd/signal" 10 | ) 11 | 12 | func main() { 13 | // Load the configuration, and parse any command line options. This 14 | // function will also set up logging properly. 15 | loadedConfig, err := lnd.LoadConfig() 16 | if err != nil { 17 | _, _ = fmt.Fprintln(os.Stderr, err) 18 | os.Exit(1) 19 | } 20 | 21 | // Hook interceptor for os signals. 22 | signal.Intercept() 23 | 24 | // Call the "real" main in a nested manner so the defers will properly 25 | // be executed in the case of a graceful shutdown. 26 | err = lnd.Main( 27 | loadedConfig, lnd.ListenerCfg{}, signal.ShutdownChannel(), 28 | ) 29 | if err != nil { 30 | if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp { 31 | } else { 32 | _, _ = fmt.Fprintln(os.Stderr, err) 33 | } 34 | os.Exit(1) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contractcourt/log.go: -------------------------------------------------------------------------------- 1 | package contractcourt 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("CNCT", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | 31 | // logClosure is used to provide a closure over expensive logging operations so 32 | // don't have to be performed when the logging level doesn't warrant it. 33 | type logClosure func() string 34 | 35 | // String invokes the underlying function and returns the result. 36 | func (c logClosure) String() string { 37 | return c() 38 | } 39 | 40 | // newLogClosure returns a new closure over a function that returns a string 41 | // which itself provides a Stringer interface so that it can be used with the 42 | // logging system. 43 | func newLogClosure(c func() string) logClosure { 44 | return logClosure(c) 45 | } 46 | -------------------------------------------------------------------------------- /contractcourt/mock_registry_test.go: -------------------------------------------------------------------------------- 1 | package contractcourt 2 | 3 | import ( 4 | "github.com/lightningnetwork/lnd/channeldb" 5 | "github.com/lightningnetwork/lnd/invoices" 6 | "github.com/lightningnetwork/lnd/lntypes" 7 | "github.com/lightningnetwork/lnd/lnwire" 8 | ) 9 | 10 | type notifyExitHopData struct { 11 | payHash lntypes.Hash 12 | paidAmount lnwire.MilliSatoshi 13 | hodlChan chan<- interface{} 14 | expiry uint32 15 | currentHeight int32 16 | } 17 | 18 | type mockRegistry struct { 19 | notifyChan chan notifyExitHopData 20 | notifyErr error 21 | notifyResolution invoices.HtlcResolution 22 | } 23 | 24 | func (r *mockRegistry) NotifyExitHopHtlc(payHash lntypes.Hash, 25 | paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32, 26 | circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, 27 | payload invoices.Payload) (invoices.HtlcResolution, error) { 28 | 29 | r.notifyChan <- notifyExitHopData{ 30 | hodlChan: hodlChan, 31 | payHash: payHash, 32 | paidAmount: paidAmount, 33 | expiry: expiry, 34 | currentHeight: currentHeight, 35 | } 36 | 37 | return r.notifyResolution, r.notifyErr 38 | } 39 | 40 | func (r *mockRegistry) HodlUnsubscribeAll(subscriber chan<- interface{}) {} 41 | 42 | func (r *mockRegistry) LookupInvoice(lntypes.Hash) (channeldb.Invoice, 43 | error) { 44 | 45 | return channeldb.Invoice{}, channeldb.ErrInvoiceNotFound 46 | } 47 | -------------------------------------------------------------------------------- /contractcourt/utils_test.go: -------------------------------------------------------------------------------- 1 | package contractcourt 2 | 3 | import ( 4 | "os" 5 | "runtime/pprof" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | // timeout implements a test level timeout. 11 | func timeout(t *testing.T) func() { 12 | done := make(chan struct{}) 13 | go func() { 14 | select { 15 | case <-time.After(5 * time.Second): 16 | pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) 17 | 18 | panic("test timeout") 19 | case <-done: 20 | } 21 | }() 22 | 23 | return func() { 24 | close(done) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /discovery/log.go: -------------------------------------------------------------------------------- 1 | package discovery 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("DISC", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | 31 | // logClosure is used to provide a closure over expensive logging operations 32 | // so don't have to be performed when the logging level doesn't warrant it. 33 | type logClosure func() string 34 | 35 | // String invokes the underlying function and returns the result. 36 | func (c logClosure) String() string { 37 | return c() 38 | } 39 | 40 | // newLogClosure returns a new closure over a function that returns a string 41 | // which itself provides a Stringer interface so that it can be used with the 42 | // logging system. 43 | func newLogClosure(c func() string) logClosure { 44 | return logClosure(c) 45 | } 46 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | package lnd 2 | -------------------------------------------------------------------------------- /docker/lnd/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.13-alpine as builder 2 | 3 | LABEL maintainer="Olaoluwa Osuntokun " 4 | 5 | # Force Go to use the cgo based DNS resolver. This is required to ensure DNS 6 | # queries required to connect to linked containers succeed. 7 | ENV GODEBUG netdns=cgo 8 | 9 | # Install dependencies and install/build lnd. 10 | RUN apk add --no-cache --update alpine-sdk \ 11 | git \ 12 | make 13 | 14 | # Copy in the local repository to build from. 15 | COPY . /go/src/github.com/lightningnetwork/lnd 16 | 17 | RUN cd /go/src/github.com/lightningnetwork/lnd \ 18 | && make \ 19 | && make install tags="signrpc walletrpc chainrpc invoicesrpc" 20 | 21 | # Start a new, final image to reduce size. 22 | FROM alpine as final 23 | 24 | # Expose lnd ports (server, rpc). 25 | EXPOSE 9735 10009 26 | 27 | # Copy the binaries and entrypoint from the builder image. 28 | COPY --from=builder /go/bin/lncli /bin/ 29 | COPY --from=builder /go/bin/lnd /bin/ 30 | 31 | # Add bash. 32 | RUN apk add --no-cache \ 33 | bash 34 | 35 | # Copy the entrypoint script. 36 | COPY "docker/lnd/start-lnd.sh" . 37 | RUN chmod +x start-lnd.sh 38 | -------------------------------------------------------------------------------- /docs/nat_traversal.md: -------------------------------------------------------------------------------- 1 | # NAT Traversal 2 | 3 | `lnd` has support for NAT traversal using a number of different techniques. At 4 | the time of writing this documentation, UPnP and NAT-PMP are supported. NAT 5 | traversal can be enabled through `lnd`'s `--nat` flag. 6 | 7 | ```shell 8 | $ lnd ... --nat 9 | ``` 10 | 11 | On startup, `lnd` will try the different techniques until one is found that's 12 | supported by your hardware. The underlying dependencies used for these 13 | techniques rely on using system-specific binaries in order to detect your 14 | gateway device's address. This is needed because we need to be able to reach the 15 | gateway device to determine if it supports the specific NAT traversal technique 16 | currently being tried. Because of this, due to uncommon setups, it is possible 17 | that these binaries are not found in your system. If this is case, `lnd` will 18 | exit stating such error. 19 | 20 | As a bonus, `lnd` spawns a background thread that automatically detects IP 21 | address changes and propagates the new address update to the rest of the 22 | network. This is especially beneficial for users who were provided dynamic IP 23 | addresses from their internet service provider. 24 | -------------------------------------------------------------------------------- /docs/ruby-thing.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | File.open("INSTALL.md", 'r') do |f| 4 | f.each_line do |line| 5 | forbidden_words = ['Table of contents', 'define', 'pragma'] 6 | next if !line.start_with?("#") || forbidden_words.any? { |w| line =~ /#{w}/ } 7 | 8 | title = line.gsub("#", "").strip 9 | href = title.gsub(" ", "-").downcase 10 | puts " " * (line.count("#")-1) + "* [#{title}](\##{href})" 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /feature/required.go: -------------------------------------------------------------------------------- 1 | package feature 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // ErrUnknownRequired signals that a feature vector requires certain features 10 | // that our node is unaware of or does not implement. 11 | type ErrUnknownRequired struct { 12 | unknown []lnwire.FeatureBit 13 | } 14 | 15 | // NewErrUnknownRequired initializes an ErrUnknownRequired with the unknown 16 | // feature bits. 17 | func NewErrUnknownRequired(unknown []lnwire.FeatureBit) ErrUnknownRequired { 18 | return ErrUnknownRequired{ 19 | unknown: unknown, 20 | } 21 | } 22 | 23 | // Error returns a human-readable description of the error. 24 | func (e ErrUnknownRequired) Error() string { 25 | return fmt.Sprintf("feature vector contains unknown required "+ 26 | "features: %v", e.unknown) 27 | } 28 | 29 | // ValidateRequired returns an error if the feature vector contains a non-zero 30 | // number of unknown, required feature bits. 31 | func ValidateRequired(fv *lnwire.FeatureVector) error { 32 | unknown := fv.UnknownRequiredFeatures() 33 | if len(unknown) > 0 { 34 | return NewErrUnknownRequired(unknown) 35 | } 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /feature/set.go: -------------------------------------------------------------------------------- 1 | package feature 2 | 3 | // Set is an enum identifying various feature sets, which separates the single 4 | // feature namespace into distinct categories depending what context a feature 5 | // vector is being used. 6 | type Set uint8 7 | 8 | const ( 9 | // SetInit identifies features that should be sent in an Init message to 10 | // a remote peer. 11 | SetInit Set = iota 12 | 13 | // SetLegacyGlobal identifies features that should be set in the legacy 14 | // GlobalFeatures field of an Init message, which maintains backwards 15 | // compatibility with nodes that haven't implemented flat features. 16 | SetLegacyGlobal 17 | 18 | // SetNodeAnn identifies features that should be advertised on node 19 | // announcements. 20 | SetNodeAnn 21 | 22 | // SetInvoice identifies features that should be advertised on invoices 23 | // generated by the daemon. 24 | SetInvoice 25 | ) 26 | 27 | // String returns a human-readable description of a Set. 28 | func (s Set) String() string { 29 | switch s { 30 | case SetInit: 31 | return "SetInit" 32 | case SetLegacyGlobal: 33 | return "SetLegacyGlobal" 34 | case SetNodeAnn: 35 | return "SetNodeAnn" 36 | case SetInvoice: 37 | return "SetInvoice" 38 | default: 39 | return "SetUnknown" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /fuzz/brontide/random_actone.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/brontide" 7 | ) 8 | 9 | // Fuzz_random_actone is a go-fuzz harness for ActOne in the brontide 10 | // handshake. 11 | func Fuzz_random_actone(data []byte) int { 12 | // Check if data is large enough. 13 | if len(data) < brontide.ActOneSize { 14 | return -1 15 | } 16 | 17 | // This will return brontide machines with random keys. 18 | _, responder := getBrontideMachines() 19 | 20 | // Copy data into [ActOneSize]byte. 21 | var actOne [brontide.ActOneSize]byte 22 | copy(actOne[:], data) 23 | 24 | // Responder receives ActOne, should fail on the MAC check. 25 | if err := responder.RecvActOne(actOne); err == nil { 26 | nilAndPanic(nil, responder, nil) 27 | } 28 | 29 | return 1 30 | } 31 | -------------------------------------------------------------------------------- /fuzz/brontide/random_acttwo.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/brontide" 7 | ) 8 | 9 | // Fuzz_random_acttwo is a go-fuzz harness for ActTwo in the brontide 10 | // handshake. 11 | func Fuzz_random_acttwo(data []byte) int { 12 | // Check if data is large enough. 13 | if len(data) < brontide.ActTwoSize { 14 | return -1 15 | } 16 | 17 | // This will return brontide machines with random keys. 18 | initiator, _ := getBrontideMachines() 19 | 20 | // Generate ActOne - this isn't sent to the responder because nothing is 21 | // done with the responder machine and this would slow down fuzzing. 22 | // GenActOne needs to be called to set the appropriate state in the 23 | // initiator machine. 24 | _, err := initiator.GenActOne() 25 | if err != nil { 26 | nilAndPanic(initiator, nil, err) 27 | } 28 | 29 | // Copy data into [ActTwoSize]byte. 30 | var actTwo [brontide.ActTwoSize]byte 31 | copy(actTwo[:], data) 32 | 33 | // Initiator receives ActTwo, should fail. 34 | if err := initiator.RecvActTwo(actTwo); err == nil { 35 | nilAndPanic(initiator, nil, nil) 36 | } 37 | 38 | return 1 39 | } 40 | -------------------------------------------------------------------------------- /fuzz/brontide/random_init_decrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | ) 8 | 9 | // Fuzz_random_init_decrypt is a go-fuzz harness that decrypts arbitrary data 10 | // with the initiator. 11 | func Fuzz_random_init_decrypt(data []byte) int { 12 | // This will return brontide machines with random keys. 13 | initiator, responder := getBrontideMachines() 14 | 15 | // Complete the brontide handshake. 16 | completeHandshake(initiator, responder) 17 | 18 | // Create a reader with the byte array. 19 | r := bytes.NewReader(data) 20 | 21 | // Decrypt the encrypted message using ReadMessage w/ initiator machine. 22 | if _, err := initiator.ReadMessage(r); err == nil { 23 | nilAndPanic(initiator, responder, nil) 24 | } 25 | 26 | return 1 27 | } 28 | -------------------------------------------------------------------------------- /fuzz/brontide/random_init_enc_dec.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_random_init_enc_dec is a go-fuzz harness that tests round-trip 11 | // encryption and decryption between the initiator and the responder. 12 | func Fuzz_random_init_enc_dec(data []byte) int { 13 | // Ensure that length of message is not greater than max allowed size. 14 | if len(data) > math.MaxUint16 { 15 | return 0 16 | } 17 | 18 | // This will return brontide machines with random keys. 19 | initiator, responder := getBrontideMachines() 20 | 21 | // Complete the brontide handshake. 22 | completeHandshake(initiator, responder) 23 | 24 | var b bytes.Buffer 25 | 26 | // Encrypt the message using WriteMessage w/ initiator machine. 27 | if err := initiator.WriteMessage(data); err != nil { 28 | nilAndPanic(initiator, responder, err) 29 | } 30 | 31 | // Flush the encrypted message w/ initiator machine. 32 | if _, err := initiator.Flush(&b); err != nil { 33 | nilAndPanic(initiator, responder, err) 34 | } 35 | 36 | // Decrypt the ciphertext using ReadMessage w/ responder machine. 37 | plaintext, err := responder.ReadMessage(&b) 38 | if err != nil { 39 | nilAndPanic(initiator, responder, err) 40 | } 41 | 42 | // Check that the decrypted message and the original message are equal. 43 | if !bytes.Equal(data, plaintext) { 44 | nilAndPanic(initiator, responder, nil) 45 | } 46 | 47 | return 1 48 | } 49 | -------------------------------------------------------------------------------- /fuzz/brontide/random_init_encrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_random_init_encrypt is a go-fuzz harness that encrypts arbitrary data 11 | // with the initiator. 12 | func Fuzz_random_init_encrypt(data []byte) int { 13 | // Ensure that length of message is not greater than max allowed size. 14 | if len(data) > math.MaxUint16 { 15 | return 0 16 | } 17 | 18 | // This will return brontide machines with random keys. 19 | initiator, responder := getBrontideMachines() 20 | 21 | // Complete the brontide handshake. 22 | completeHandshake(initiator, responder) 23 | 24 | var b bytes.Buffer 25 | 26 | // Encrypt the message using WriteMessage w/ initiator machine. 27 | if err := initiator.WriteMessage(data); err != nil { 28 | nilAndPanic(initiator, responder, err) 29 | } 30 | 31 | // Flush the encrypted message w/ initiator machine. 32 | if _, err := initiator.Flush(&b); err != nil { 33 | nilAndPanic(initiator, responder, err) 34 | } 35 | 36 | return 1 37 | } 38 | -------------------------------------------------------------------------------- /fuzz/brontide/random_resp_decrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | ) 8 | 9 | // Fuzz_random_resp_decrypt is a go-fuzz harness that decrypts arbitrary data 10 | // with the responder. 11 | func Fuzz_random_resp_decrypt(data []byte) int { 12 | // This will return brontide machines with random keys. 13 | initiator, responder := getBrontideMachines() 14 | 15 | // Complete the brontide handshake. 16 | completeHandshake(initiator, responder) 17 | 18 | // Create a reader with the byte array. 19 | r := bytes.NewReader(data) 20 | 21 | // Decrypt the encrypted message using ReadMessage w/ responder machine. 22 | if _, err := responder.ReadMessage(r); err == nil { 23 | nilAndPanic(initiator, responder, nil) 24 | } 25 | 26 | return 1 27 | } 28 | -------------------------------------------------------------------------------- /fuzz/brontide/random_resp_enc_dec.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_random_resp_enc_dec is a go-fuzz harness that tests round-trip 11 | // encryption and decryption between the responder and the initiator. 12 | func Fuzz_random_resp_enc_dec(data []byte) int { 13 | // Ensure that length of message is not greater than max allowed size. 14 | if len(data) > math.MaxUint16 { 15 | return 0 16 | } 17 | 18 | // This will return brontide machines with random keys. 19 | initiator, responder := getBrontideMachines() 20 | 21 | // Complete the brontide handshake. 22 | completeHandshake(initiator, responder) 23 | 24 | var b bytes.Buffer 25 | 26 | // Encrypt the message using WriteMessage w/ responder machine. 27 | if err := responder.WriteMessage(data); err != nil { 28 | nilAndPanic(initiator, responder, err) 29 | } 30 | 31 | // Flush the encrypted message w/ responder machine. 32 | if _, err := responder.Flush(&b); err != nil { 33 | nilAndPanic(initiator, responder, err) 34 | } 35 | 36 | // Decrypt the ciphertext using ReadMessage w/ initiator machine. 37 | plaintext, err := initiator.ReadMessage(&b) 38 | if err != nil { 39 | nilAndPanic(initiator, responder, err) 40 | } 41 | 42 | // Check that the decrypted message and the original message are equal. 43 | if !bytes.Equal(data, plaintext) { 44 | nilAndPanic(initiator, responder, nil) 45 | } 46 | 47 | return 1 48 | } 49 | -------------------------------------------------------------------------------- /fuzz/brontide/random_resp_encrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_random_resp_encrypt is a go-fuzz harness that encrypts arbitrary data 11 | // with the responder. 12 | func Fuzz_random_resp_encrypt(data []byte) int { 13 | // Ensure that length of message is not greater than max allowed size. 14 | if len(data) > math.MaxUint16 { 15 | return 0 16 | } 17 | 18 | // This will return brontide machines with random keys. 19 | initiator, responder := getBrontideMachines() 20 | 21 | // Complete the brontide handshake. 22 | completeHandshake(initiator, responder) 23 | 24 | var b bytes.Buffer 25 | 26 | // Encrypt the message using WriteMessage w/ responder machine. 27 | if err := responder.WriteMessage(data); err != nil { 28 | nilAndPanic(initiator, responder, err) 29 | } 30 | 31 | // Flush the encrypted message w/ responder machine. 32 | if _, err := responder.Flush(&b); err != nil { 33 | nilAndPanic(initiator, responder, err) 34 | } 35 | 36 | return 1 37 | } 38 | -------------------------------------------------------------------------------- /fuzz/brontide/static_actone.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/brontide" 7 | ) 8 | 9 | // Fuzz_static_actone is a go-fuzz harness for ActOne in the brontide 10 | // handshake. 11 | func Fuzz_static_actone(data []byte) int { 12 | // Check if data is large enough. 13 | if len(data) < brontide.ActOneSize { 14 | return -1 15 | } 16 | 17 | // This will return brontide machines with static keys. 18 | _, responder := getStaticBrontideMachines() 19 | 20 | // Copy data into [ActOneSize]byte. 21 | var actOne [brontide.ActOneSize]byte 22 | copy(actOne[:], data) 23 | 24 | // Responder receives ActOne, should fail. 25 | if err := responder.RecvActOne(actOne); err == nil { 26 | nilAndPanic(nil, responder, nil) 27 | } 28 | 29 | return 1 30 | } 31 | -------------------------------------------------------------------------------- /fuzz/brontide/static_acttwo.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/brontide" 7 | ) 8 | 9 | // Fuzz_static_acttwo is a go-fuzz harness for ActTwo in the brontide 10 | // handshake. 11 | func Fuzz_static_acttwo(data []byte) int { 12 | // Check if data is large enough. 13 | if len(data) < brontide.ActTwoSize { 14 | return -1 15 | } 16 | 17 | // This will return brontide machines with static keys. 18 | initiator, _ := getStaticBrontideMachines() 19 | 20 | // Generate ActOne - this isn't sent to the responder because nothing is 21 | // done with the responder machine and this would slow down fuzzing. 22 | // GenActOne needs to be called to set the appropriate state in the initiator 23 | // machine. 24 | _, err := initiator.GenActOne() 25 | if err != nil { 26 | nilAndPanic(initiator, nil, err) 27 | } 28 | 29 | // Copy data into [ActTwoSize]byte. 30 | var actTwo [brontide.ActTwoSize]byte 31 | copy(actTwo[:], data) 32 | 33 | // Initiator receives ActTwo, should fail. 34 | if err := initiator.RecvActTwo(actTwo); err == nil { 35 | nilAndPanic(initiator, nil, nil) 36 | } 37 | 38 | return 1 39 | } 40 | -------------------------------------------------------------------------------- /fuzz/brontide/static_init_decrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | ) 8 | 9 | // Fuzz_static_init_decrypt is a go-fuzz harness that decrypts arbitrary data 10 | // with the initiator. 11 | func Fuzz_static_init_decrypt(data []byte) int { 12 | // This will return brontide machines with static keys. 13 | initiator, responder := getStaticBrontideMachines() 14 | 15 | // Complete the brontide handshake. 16 | completeHandshake(initiator, responder) 17 | 18 | // Create a reader with the byte array. 19 | r := bytes.NewReader(data) 20 | 21 | // Decrypt the encrypted message using ReadMessage w/ initiator machine. 22 | if _, err := initiator.ReadMessage(r); err == nil { 23 | nilAndPanic(initiator, responder, nil) 24 | } 25 | 26 | return 1 27 | } 28 | -------------------------------------------------------------------------------- /fuzz/brontide/static_init_enc_dec.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_static_init_enc_dec is a go-fuzz harness that tests round-trip 11 | // encryption and decryption 12 | // between the initiator and the responder. 13 | func Fuzz_static_init_enc_dec(data []byte) int { 14 | // Ensure that length of message is not greater than max allowed size. 15 | if len(data) > math.MaxUint16 { 16 | return 0 17 | } 18 | 19 | // This will return brontide machines with static keys. 20 | initiator, responder := getStaticBrontideMachines() 21 | 22 | // Complete the brontide handshake. 23 | completeHandshake(initiator, responder) 24 | 25 | var b bytes.Buffer 26 | 27 | // Encrypt the message using WriteMessage w/ initiator machine. 28 | if err := initiator.WriteMessage(data); err != nil { 29 | nilAndPanic(initiator, responder, err) 30 | } 31 | 32 | // Flush the encrypted message w/ initiator machine. 33 | if _, err := initiator.Flush(&b); err != nil { 34 | nilAndPanic(initiator, responder, err) 35 | } 36 | 37 | // Decrypt the ciphertext using ReadMessage w/ responder machine. 38 | plaintext, err := responder.ReadMessage(&b) 39 | if err != nil { 40 | nilAndPanic(initiator, responder, err) 41 | } 42 | 43 | // Check that the decrypted message and the original message are equal. 44 | if !bytes.Equal(data, plaintext) { 45 | nilAndPanic(initiator, responder, nil) 46 | } 47 | 48 | return 1 49 | } 50 | -------------------------------------------------------------------------------- /fuzz/brontide/static_init_encrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_static_init_encrypt is a go-fuzz harness that encrypts arbitrary data 11 | // with the initiator. 12 | func Fuzz_static_init_encrypt(data []byte) int { 13 | // Ensure that length of message is not greater than max allowed size. 14 | if len(data) > math.MaxUint16 { 15 | return 0 16 | } 17 | 18 | // This will return brontide machines with static keys. 19 | initiator, responder := getStaticBrontideMachines() 20 | 21 | // Complete the brontide handshake. 22 | completeHandshake(initiator, responder) 23 | 24 | var b bytes.Buffer 25 | 26 | // Encrypt the message using WriteMessage w/ initiator machine. 27 | if err := initiator.WriteMessage(data); err != nil { 28 | nilAndPanic(initiator, responder, err) 29 | } 30 | 31 | // Flush the encrypted message w/ initiator machine. 32 | if _, err := initiator.Flush(&b); err != nil { 33 | nilAndPanic(initiator, responder, err) 34 | } 35 | 36 | return 1 37 | } 38 | -------------------------------------------------------------------------------- /fuzz/brontide/static_resp_decrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | ) 8 | 9 | // Fuzz_static_resp_decrypt is a go-fuzz harness that decrypts arbitrary data 10 | // with the responder. 11 | func Fuzz_static_resp_decrypt(data []byte) int { 12 | // This will return brontide machines with static keys. 13 | initiator, responder := getStaticBrontideMachines() 14 | 15 | // Complete the brontide handshake. 16 | completeHandshake(initiator, responder) 17 | 18 | // Create a reader with the byte array. 19 | r := bytes.NewReader(data) 20 | 21 | // Decrypt the encrypted message using ReadMessage w/ responder machine. 22 | if _, err := responder.ReadMessage(r); err == nil { 23 | nilAndPanic(initiator, responder, nil) 24 | } 25 | 26 | return 1 27 | } 28 | -------------------------------------------------------------------------------- /fuzz/brontide/static_resp_enc_dec.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_static_resp_enc_dec is a go-fuzz harness that tests round-trip 11 | // encryption and decryption between the responder and the initiator. 12 | func Fuzz_static_resp_enc_dec(data []byte) int { 13 | // Ensure that length of message is not greater than max allowed size. 14 | if len(data) > math.MaxUint16 { 15 | return 0 16 | } 17 | 18 | // This will return brontide machines with static keys. 19 | initiator, responder := getStaticBrontideMachines() 20 | 21 | // Complete the brontide handshake. 22 | completeHandshake(initiator, responder) 23 | 24 | var b bytes.Buffer 25 | 26 | // Encrypt the message using WriteMessage w/ responder machine. 27 | if err := responder.WriteMessage(data); err != nil { 28 | nilAndPanic(initiator, responder, err) 29 | } 30 | 31 | // Flush the encrypted message w/ responder machine. 32 | if _, err := responder.Flush(&b); err != nil { 33 | nilAndPanic(initiator, responder, err) 34 | } 35 | 36 | // Decrypt the ciphertext using ReadMessage w/ initiator machine. 37 | plaintext, err := initiator.ReadMessage(&b) 38 | if err != nil { 39 | nilAndPanic(initiator, responder, err) 40 | } 41 | 42 | // Check that the decrypted message and the original message are equal. 43 | if !bytes.Equal(data, plaintext) { 44 | nilAndPanic(initiator, responder, nil) 45 | } 46 | 47 | return 1 48 | } 49 | -------------------------------------------------------------------------------- /fuzz/brontide/static_resp_encrypt.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package brontidefuzz 4 | 5 | import ( 6 | "bytes" 7 | "math" 8 | ) 9 | 10 | // Fuzz_static_resp_encrypt is a go-fuzz harness that encrypts arbitrary data 11 | // with the responder. 12 | func Fuzz_static_resp_encrypt(data []byte) int { 13 | // Ensure that length of message is not greater than max allowed size. 14 | if len(data) > math.MaxUint16 { 15 | return 0 16 | } 17 | 18 | // This will return brontide machines with static keys. 19 | initiator, responder := getStaticBrontideMachines() 20 | 21 | // Complete the brontide handshake. 22 | completeHandshake(initiator, responder) 23 | 24 | var b bytes.Buffer 25 | 26 | // Encrypt the message using WriteMessage w/ responder machine. 27 | if err := responder.WriteMessage(data); err != nil { 28 | nilAndPanic(initiator, responder, err) 29 | } 30 | 31 | // Flush the encrypted message w/ responder machine. 32 | if _, err := responder.Flush(&b); err != nil { 33 | nilAndPanic(initiator, responder, err) 34 | } 35 | 36 | return 1 37 | } 38 | -------------------------------------------------------------------------------- /fuzz/lnwire/announce_signatures.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_announce_signatures is used by go-fuzz. 10 | func Fuzz_announce_signatures(data []byte) int { 11 | // Prefix with MsgAnnounceSignatures. 12 | data = prefixWithMsgType(data, lnwire.MsgAnnounceSignatures) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.AnnounceSignatures{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/channel_announcement.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_channel_announcement is used by go-fuzz. 10 | func Fuzz_channel_announcement(data []byte) int { 11 | // Prefix with MsgChannelAnnouncement. 12 | data = prefixWithMsgType(data, lnwire.MsgChannelAnnouncement) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.ChannelAnnouncement{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/channel_reestablish.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_channel_reestablish is used by go-fuzz. 10 | func Fuzz_channel_reestablish(data []byte) int { 11 | // Prefix with MsgChannelReestablish. 12 | data = prefixWithMsgType(data, lnwire.MsgChannelReestablish) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.ChannelReestablish{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/channel_update.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_channel_update is used by go-fuzz. 10 | func Fuzz_channel_update(data []byte) int { 11 | // Prefix with MsgChannelUpdate. 12 | data = prefixWithMsgType(data, lnwire.MsgChannelUpdate) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.ChannelUpdate{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/closing_signed.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_closing_signed is used by go-fuzz. 10 | func Fuzz_closing_signed(data []byte) int { 11 | // Prefix with MsgClosingSigned. 12 | data = prefixWithMsgType(data, lnwire.MsgClosingSigned) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.ClosingSigned{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/commit_sig.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_commit_sig is used by go-fuzz. 10 | func Fuzz_commit_sig(data []byte) int { 11 | // Prefix with MsgCommitSig. 12 | data = prefixWithMsgType(data, lnwire.MsgCommitSig) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.CommitSig{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/error.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_error is used by go-fuzz. 10 | func Fuzz_error(data []byte) int { 11 | // Prefix with MsgError. 12 | data = prefixWithMsgType(data, lnwire.MsgError) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.Error{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/funding_created.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_funding_created is used by go-fuzz. 10 | func Fuzz_funding_created(data []byte) int { 11 | // Prefix with MsgFundingCreated. 12 | data = prefixWithMsgType(data, lnwire.MsgFundingCreated) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.FundingCreated{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/funding_locked.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_funding_locked is used by go-fuzz. 10 | func Fuzz_funding_locked(data []byte) int { 11 | // Prefix with MsgFundingLocked. 12 | data = prefixWithMsgType(data, lnwire.MsgFundingLocked) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.FundingLocked{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/funding_signed.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_funding_signed is used by go-fuzz. 10 | func Fuzz_funding_signed(data []byte) int { 11 | // Prefix with MsgFundingSigned. 12 | prefixWithMsgType(data, lnwire.MsgFundingSigned) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.FundingSigned{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/gossip_timestamp_range.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_gossip_timestamp_range is used by go-fuzz. 10 | func Fuzz_gossip_timestamp_range(data []byte) int { 11 | // Prefix with MsgGossipTimestampRange. 12 | data = prefixWithMsgType(data, lnwire.MsgGossipTimestampRange) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.GossipTimestampRange{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/init.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_init is used by go-fuzz. 10 | func Fuzz_init(data []byte) int { 11 | // Prefix with MsgInit. 12 | data = prefixWithMsgType(data, lnwire.MsgInit) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.Init{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/ping.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_ping is used by go-fuzz. 10 | func Fuzz_ping(data []byte) int { 11 | // Prefix with MsgPing. 12 | data = prefixWithMsgType(data, lnwire.MsgPing) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.Ping{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/pong.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_pong is used by go-fuzz. 10 | func Fuzz_pong(data []byte) int { 11 | // Prefix with MsgPong. 12 | data = prefixWithMsgType(data, lnwire.MsgPong) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.Pong{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/query_channel_range.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_query_channel_range is used by go-fuzz. 10 | func Fuzz_query_channel_range(data []byte) int { 11 | // Prefix with MsgQueryChannelRange. 12 | data = prefixWithMsgType(data, lnwire.MsgQueryChannelRange) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.QueryChannelRange{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/query_short_chan_ids.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_query_short_chan_ids is used by go-fuzz. 10 | func Fuzz_query_short_chan_ids(data []byte) int { 11 | // Prefix with MsgQueryShortChanIDs. 12 | data = prefixWithMsgType(data, lnwire.MsgQueryShortChanIDs) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.QueryShortChanIDs{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/query_short_chan_ids_zlib.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "bytes" 7 | "compress/zlib" 8 | "encoding/binary" 9 | 10 | "github.com/lightningnetwork/lnd/lnwire" 11 | ) 12 | 13 | // Fuzz_query_short_chan_ids_zlib is used by go-fuzz. 14 | func Fuzz_query_short_chan_ids_zlib(data []byte) int { 15 | 16 | var buf bytes.Buffer 17 | zlibWriter := zlib.NewWriter(&buf) 18 | _, err := zlibWriter.Write(data) 19 | if err != nil { 20 | // Zlib bug? 21 | panic(err) 22 | } 23 | 24 | if err := zlibWriter.Close(); err != nil { 25 | // Zlib bug? 26 | panic(err) 27 | } 28 | 29 | compressedPayload := buf.Bytes() 30 | 31 | chainhash := []byte("00000000000000000000000000000000") 32 | numBytesInBody := len(compressedPayload) + 1 33 | zlibByte := []byte("\x01") 34 | 35 | bodyBytes := make([]byte, 2) 36 | binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody)) 37 | 38 | payload := append(chainhash, bodyBytes...) 39 | payload = append(payload, zlibByte...) 40 | payload = append(payload, compressedPayload...) 41 | 42 | // Prefix with MsgQueryShortChanIDs. 43 | payload = prefixWithMsgType(payload, lnwire.MsgQueryShortChanIDs) 44 | 45 | // Create an empty message so that the FuzzHarness func can check 46 | // if the max payload constraint is violated. 47 | emptyMsg := lnwire.QueryShortChanIDs{} 48 | 49 | // Pass the message into our general fuzz harness for wire messages! 50 | return harness(payload, &emptyMsg) 51 | } 52 | -------------------------------------------------------------------------------- /fuzz/lnwire/reply_channel_range.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_reply_channel_range is used by go-fuzz. 10 | func Fuzz_reply_channel_range(data []byte) int { 11 | // Prefix with MsgReplyChannelRange. 12 | data = prefixWithMsgType(data, lnwire.MsgReplyChannelRange) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.ReplyChannelRange{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/reply_short_chan_ids_end.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_reply_short_chan_ids_end is used by go-fuzz. 10 | func Fuzz_reply_short_chan_ids_end(data []byte) int { 11 | // Prefix with MsgReplyShortChanIDsEnd. 12 | data = prefixWithMsgType(data, lnwire.MsgReplyShortChanIDsEnd) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.ReplyShortChanIDsEnd{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/revoke_and_ack.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_revoke_and_ack is used by go-fuzz. 10 | func Fuzz_revoke_and_ack(data []byte) int { 11 | // Prefix with MsgRevokeAndAck. 12 | data = prefixWithMsgType(data, lnwire.MsgRevokeAndAck) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.RevokeAndAck{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/shutdown.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_shutdown is used by go-fuzz. 10 | func Fuzz_shutdown(data []byte) int { 11 | // Prefix with MsgShutdown. 12 | data = prefixWithMsgType(data, lnwire.MsgShutdown) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.Shutdown{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/update_add_htlc.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_update_add_htlc is used by go-fuzz. 10 | func Fuzz_update_add_htlc(data []byte) int { 11 | // Prefix with MsgUpdateAddHTLC. 12 | data = prefixWithMsgType(data, lnwire.MsgUpdateAddHTLC) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.UpdateAddHTLC{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/update_fail_htlc.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_update_fail_htlc is used by go-fuzz. 10 | func Fuzz_update_fail_htlc(data []byte) int { 11 | // Prefix with MsgUpdateFailHTLC. 12 | data = prefixWithMsgType(data, lnwire.MsgUpdateFailHTLC) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.UpdateFailHTLC{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/update_fail_malformed_htlc.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_update_fail_malformed_htlc is used by go-fuzz. 10 | func Fuzz_update_fail_malformed_htlc(data []byte) int { 11 | // Prefix with MsgUpdateFailMalformedHTLC. 12 | data = prefixWithMsgType(data, lnwire.MsgUpdateFailMalformedHTLC) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.UpdateFailMalformedHTLC{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/update_fee.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_update_fee is used by go-fuzz. 10 | func Fuzz_update_fee(data []byte) int { 11 | // Prefix with MsgUpdateFee. 12 | data = prefixWithMsgType(data, lnwire.MsgUpdateFee) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.UpdateFee{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/lnwire/update_fulfill_htlc.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package lnwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // Fuzz_update_fulfill_htlc is used by go-fuzz. 10 | func Fuzz_update_fulfill_htlc(data []byte) int { 11 | // Prefix with MsgUpdateFulfillHTLC. 12 | data = prefixWithMsgType(data, lnwire.MsgUpdateFulfillHTLC) 13 | 14 | // Create an empty message so that the FuzzHarness func can check 15 | // if the max payload constraint is violated. 16 | emptyMsg := lnwire.UpdateFulfillHTLC{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/create_session.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_create_session is used by go-fuzz. 10 | func Fuzz_create_session(data []byte) int { 11 | // Prefix with MsgCreateSession. 12 | data = prefixWithMsgType(data, wtwire.MsgCreateSession) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.CreateSession{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/create_session_reply.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_create_session_reply is used by go-fuzz. 10 | func Fuzz_create_session_reply(data []byte) int { 11 | // Prefix with MsgCreateSessionReply. 12 | data = prefixWithMsgType(data, wtwire.MsgCreateSessionReply) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.CreateSessionReply{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/delete_session.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_delete_session is used by go-fuzz. 10 | func Fuzz_delete_session(data []byte) int { 11 | // Prefix with MsgDeleteSession. 12 | data = prefixWithMsgType(data, wtwire.MsgDeleteSession) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.DeleteSession{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/delete_session_reply.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_delete_session_reply is used by go-fuzz. 10 | func Fuzz_delete_session_reply(data []byte) int { 11 | // Prefix with MsgDeleteSessionReply. 12 | data = prefixWithMsgType(data, wtwire.MsgDeleteSessionReply) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.DeleteSessionReply{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/error.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_error is used by go-fuzz. 10 | func Fuzz_error(data []byte) int { 11 | // Prefix with MsgError. 12 | data = prefixWithMsgType(data, wtwire.MsgError) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.Error{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/init.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_init is used by go-fuzz. 10 | func Fuzz_init(data []byte) int { 11 | // Prefix with MsgInit. 12 | data = prefixWithMsgType(data, wtwire.MsgInit) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.Init{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/state_update.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_state_update is used by go-fuzz. 10 | func Fuzz_state_update(data []byte) int { 11 | // Prefix with MsgStateUpdate. 12 | data = prefixWithMsgType(data, wtwire.MsgStateUpdate) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.StateUpdate{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /fuzz/wtwire/state_update_reply.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package wtwirefuzz 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/watchtower/wtwire" 7 | ) 8 | 9 | // Fuzz_state_update_reply is used by go-fuzz. 10 | func Fuzz_state_update_reply(data []byte) int { 11 | // Prefix with MsgStateUpdateReply. 12 | data = prefixWithMsgType(data, wtwire.MsgStateUpdateReply) 13 | 14 | // Create an empty message so that the FuzzHarness func can check if the 15 | // max payload constraint is violated. 16 | emptyMsg := wtwire.StateUpdateReply{} 17 | 18 | // Pass the message into our general fuzz harness for wire messages! 19 | return harness(data, &emptyMsg) 20 | } 21 | -------------------------------------------------------------------------------- /htlcswitch/hodl/config_prod.go: -------------------------------------------------------------------------------- 1 | // +build !dev 2 | 3 | package hodl 4 | 5 | // Config is an empty struct disabling command line hodl flags in production. 6 | type Config struct{} 7 | 8 | // Mask in production always returns MaskNone. 9 | func (c *Config) Mask() Mask { 10 | return MaskNone 11 | } 12 | -------------------------------------------------------------------------------- /htlcswitch/hodl/mask_dev.go: -------------------------------------------------------------------------------- 1 | // +build dev 2 | 3 | package hodl 4 | 5 | import ( 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | // MaskFromFlags merges a variadic set of Flags into a single Mask. 11 | func MaskFromFlags(flags ...Flag) Mask { 12 | var mask Mask 13 | for _, flag := range flags { 14 | mask |= Mask(flag) 15 | } 16 | 17 | return mask 18 | } 19 | 20 | // Active returns true if the bit corresponding to the flag is set within the 21 | // mask. 22 | func (m Mask) Active(flag Flag) bool { 23 | return (Flag(m) & flag) > 0 24 | } 25 | 26 | // String returns a human-readable description of all active Flags. 27 | func (m Mask) String() string { 28 | if m == MaskNone { 29 | return "hodl.Mask(NONE)" 30 | } 31 | 32 | var activeFlags []string 33 | for i := uint(0); i < 32; i++ { 34 | flag := Flag(1 << i) 35 | if m.Active(flag) { 36 | activeFlags = append(activeFlags, flag.String()) 37 | } 38 | } 39 | 40 | return fmt.Sprintf("hodl.Mask(%s)", strings.Join(activeFlags, "|")) 41 | } 42 | -------------------------------------------------------------------------------- /htlcswitch/hodl/mask_prod.go: -------------------------------------------------------------------------------- 1 | // +build !dev 2 | 3 | package hodl 4 | 5 | // MaskFromFlags in production always returns MaskNone. 6 | func MaskFromFlags(_ ...Flag) Mask { 7 | return MaskNone 8 | } 9 | 10 | // Active in production always returns false for all Flags. 11 | func (m Mask) Active(_ Flag) bool { 12 | return false 13 | } 14 | 15 | // String returns the human-readable identifier for MaskNone. 16 | func (m Mask) String() string { 17 | return "hodl.Mask(NONE)" 18 | } 19 | -------------------------------------------------------------------------------- /htlcswitch/hop/forwarding_info.go: -------------------------------------------------------------------------------- 1 | package hop 2 | 3 | import ( 4 | "github.com/lightningnetwork/lnd/lnwire" 5 | ) 6 | 7 | // ForwardingInfo contains all the information that is necessary to forward and 8 | // incoming HTLC to the next hop encoded within a valid HopIterator instance. 9 | // Forwarding links are to use this information to authenticate the information 10 | // received within the incoming HTLC, to ensure that the prior hop didn't 11 | // tamper with the end-to-end routing information at all. 12 | type ForwardingInfo struct { 13 | // Network is the target blockchain network that the HTLC will travel 14 | // over next. 15 | Network Network 16 | 17 | // NextHop is the channel ID of the next hop. The received HTLC should 18 | // be forwarded to this particular channel in order to continue the 19 | // end-to-end route. 20 | NextHop lnwire.ShortChannelID 21 | 22 | // AmountToForward is the amount of milli-satoshis that the receiving 23 | // node should forward to the next hop. 24 | AmountToForward lnwire.MilliSatoshi 25 | 26 | // OutgoingCTLV is the specified value of the CTLV timelock to be used 27 | // in the outgoing HTLC. 28 | OutgoingCTLV uint32 29 | } 30 | -------------------------------------------------------------------------------- /htlcswitch/hop/log.go: -------------------------------------------------------------------------------- 1 | package hop 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | ) 6 | 7 | // log is a logger that is initialized with no output filters. This 8 | // means the package will not perform any logging by default until the caller 9 | // requests it. 10 | var log btclog.Logger 11 | 12 | // UseLogger uses a specified Logger to output package logging info. This 13 | // function is called from the parent package htlcswitch logger initialization. 14 | func UseLogger(logger btclog.Logger) { 15 | log = logger 16 | } 17 | -------------------------------------------------------------------------------- /htlcswitch/hop/network.go: -------------------------------------------------------------------------------- 1 | package hop 2 | 3 | // Network indicates the blockchain network that is intended to be the next hop 4 | // for a forwarded HTLC. The existence of this field within the ForwardingInfo 5 | // struct enables the ability for HTLC to cross chain-boundaries at will. 6 | type Network uint8 7 | 8 | const ( 9 | // BitcoinNetwork denotes that an HTLC is to be forwarded along the 10 | // Bitcoin link with the specified short channel ID. 11 | BitcoinNetwork Network = iota 12 | 13 | // LitecoinNetwork denotes that an HTLC is to be forwarded along the 14 | // Litecoin link with the specified short channel ID. 15 | LitecoinNetwork 16 | ) 17 | 18 | // String returns the string representation of the target Network. 19 | func (c Network) String() string { 20 | switch c { 21 | case BitcoinNetwork: 22 | return "Bitcoin" 23 | case LitecoinNetwork: 24 | return "Litecoin" 25 | default: 26 | return "Kekcoin" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /htlcswitch/hop/type.go: -------------------------------------------------------------------------------- 1 | package hop 2 | 3 | import "github.com/lightningnetwork/lnd/lnwire" 4 | 5 | var ( 6 | // Exit is a special "hop" denoting that an incoming HTLC is meant to 7 | // pay finally to the receiving node. 8 | Exit lnwire.ShortChannelID 9 | 10 | // Source is a sentinel "hop" denoting that an incoming HTLC is 11 | // initiated by our own switch. 12 | Source lnwire.ShortChannelID 13 | ) 14 | -------------------------------------------------------------------------------- /input/txout.go: -------------------------------------------------------------------------------- 1 | package input 2 | 3 | import ( 4 | "encoding/binary" 5 | "io" 6 | 7 | "github.com/btcsuite/btcd/wire" 8 | ) 9 | 10 | // writeTxOut serializes a wire.TxOut struct into the passed io.Writer stream. 11 | func writeTxOut(w io.Writer, txo *wire.TxOut) error { 12 | var scratch [8]byte 13 | 14 | binary.BigEndian.PutUint64(scratch[:], uint64(txo.Value)) 15 | if _, err := w.Write(scratch[:]); err != nil { 16 | return err 17 | } 18 | 19 | if err := wire.WriteVarBytes(w, 0, txo.PkScript); err != nil { 20 | return err 21 | } 22 | 23 | return nil 24 | } 25 | 26 | // readTxOut deserializes a wire.TxOut struct from the passed io.Reader stream. 27 | func readTxOut(r io.Reader, txo *wire.TxOut) error { 28 | var scratch [8]byte 29 | 30 | if _, err := io.ReadFull(r, scratch[:]); err != nil { 31 | return err 32 | } 33 | value := int64(binary.BigEndian.Uint64(scratch[:])) 34 | 35 | pkScript, err := wire.ReadVarBytes(r, 0, 80, "pkScript") 36 | if err != nil { 37 | return err 38 | } 39 | 40 | *txo = wire.TxOut{ 41 | Value: value, 42 | PkScript: pkScript, 43 | } 44 | 45 | return nil 46 | } 47 | -------------------------------------------------------------------------------- /input/txout_test.go: -------------------------------------------------------------------------------- 1 | package input 2 | 3 | import ( 4 | "bytes" 5 | "reflect" 6 | "testing" 7 | 8 | "github.com/btcsuite/btcd/wire" 9 | ) 10 | 11 | func TestTxOutSerialization(t *testing.T) { 12 | txo := wire.TxOut{ 13 | Value: 1e7, 14 | PkScript: []byte{ 15 | 0x41, // OP_DATA_65 16 | 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 17 | 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 18 | 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 19 | 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 20 | 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 21 | 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 22 | 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 23 | 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 24 | 0xa6, // 65-byte signature 25 | 0xac, // OP_CHECKSIG 26 | }, 27 | } 28 | 29 | var buf bytes.Buffer 30 | 31 | if err := writeTxOut(&buf, &txo); err != nil { 32 | t.Fatalf("unable to serialize txout: %v", err) 33 | } 34 | 35 | var deserializedTxo wire.TxOut 36 | if err := readTxOut(&buf, &deserializedTxo); err != nil { 37 | t.Fatalf("unable to deserialize txout: %v", err) 38 | } 39 | 40 | if !reflect.DeepEqual(txo, deserializedTxo) { 41 | t.Fatalf("original and deserialized txouts are different:\n"+ 42 | "original : %+v\n"+ 43 | "deserialized : %+v\n", 44 | txo, deserializedTxo) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /invoices/interface.go: -------------------------------------------------------------------------------- 1 | package invoices 2 | 3 | import ( 4 | "github.com/lightningnetwork/lnd/record" 5 | ) 6 | 7 | // Payload abstracts access to any additional fields provided in the final hop's 8 | // TLV onion payload. 9 | type Payload interface { 10 | // MultiPath returns the record corresponding the option_mpp parsed from 11 | // the onion payload. 12 | MultiPath() *record.MPP 13 | 14 | // CustomRecords returns the custom tlv type records that were parsed 15 | // from the payload. 16 | CustomRecords() record.CustomSet 17 | } 18 | -------------------------------------------------------------------------------- /invoices/log.go: -------------------------------------------------------------------------------- 1 | package invoices 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("INVC", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /keychain/signer.go: -------------------------------------------------------------------------------- 1 | package keychain 2 | 3 | import "github.com/btcsuite/btcd/btcec" 4 | 5 | func NewPubKeyDigestSigner(keyDesc KeyDescriptor, 6 | signer DigestSignerRing) *PubKeyDigestSigner { 7 | 8 | return &PubKeyDigestSigner{ 9 | keyDesc: keyDesc, 10 | digestSigner: signer, 11 | } 12 | } 13 | 14 | type PubKeyDigestSigner struct { 15 | keyDesc KeyDescriptor 16 | digestSigner DigestSignerRing 17 | } 18 | 19 | func (p *PubKeyDigestSigner) PubKey() *btcec.PublicKey { 20 | return p.keyDesc.PubKey 21 | } 22 | 23 | func (p *PubKeyDigestSigner) SignDigest(digest [32]byte) (*btcec.Signature, 24 | error) { 25 | 26 | return p.digestSigner.SignDigest(p.keyDesc, digest) 27 | } 28 | 29 | func (p *PubKeyDigestSigner) SignDigestCompact(digest [32]byte) ([]byte, 30 | error) { 31 | 32 | return p.digestSigner.SignDigestCompact(p.keyDesc, digest) 33 | } 34 | 35 | type PrivKeyDigestSigner struct { 36 | PrivKey *btcec.PrivateKey 37 | } 38 | 39 | func (p *PrivKeyDigestSigner) PubKey() *btcec.PublicKey { 40 | return p.PrivKey.PubKey() 41 | } 42 | 43 | func (p *PrivKeyDigestSigner) SignDigest(digest [32]byte) (*btcec.Signature, 44 | error) { 45 | 46 | return p.PrivKey.Sign(digest[:]) 47 | } 48 | 49 | func (p *PrivKeyDigestSigner) SignDigestCompact(digest [32]byte) ([]byte, 50 | error) { 51 | 52 | return btcec.SignCompact(btcec.S256(), p.PrivKey, digest[:], true) 53 | } 54 | 55 | var _ SingleKeyDigestSigner = (*PubKeyDigestSigner)(nil) 56 | var _ SingleKeyDigestSigner = (*PrivKeyDigestSigner)(nil) 57 | -------------------------------------------------------------------------------- /labels/labels.go: -------------------------------------------------------------------------------- 1 | // Package labels contains labels used to label transactions broadcast by lnd. 2 | // These labels are used across packages, so they are declared in a separate 3 | // package to avoid dependency issues. 4 | package labels 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/btcsuite/btcwallet/wtxmgr" 10 | ) 11 | 12 | // External labels a transaction as user initiated via the api. This 13 | // label is only used when a custom user provided label is not given. 14 | const External = "external" 15 | 16 | // ValidateAPI returns the generic api label if the label provided is empty. 17 | // This allows us to label all transactions published by the api, even if 18 | // no label is provided. If a label is provided, it is validated against 19 | // the known restrictions. 20 | func ValidateAPI(label string) (string, error) { 21 | if len(label) > wtxmgr.TxLabelLimit { 22 | return "", fmt.Errorf("label length: %v exceeds "+ 23 | "limit of %v", len(label), wtxmgr.TxLabelLimit) 24 | } 25 | 26 | // If no label was provided by the user, add the generic user 27 | // send label. 28 | if len(label) == 0 { 29 | return External, nil 30 | } 31 | 32 | return label, nil 33 | } 34 | -------------------------------------------------------------------------------- /lncfg/autopilot.go: -------------------------------------------------------------------------------- 1 | package lncfg 2 | 3 | // AutoPilot holds the configuration options for the daemon's autopilot. 4 | type AutoPilot struct { 5 | Active bool `long:"active" description:"If the autopilot agent should be active or not."` 6 | Heuristic map[string]float64 `long:"heuristic" description:"Heuristic to activate, and the weight to give it during scoring."` 7 | MaxChannels int `long:"maxchannels" description:"The maximum number of channels that should be created"` 8 | Allocation float64 `long:"allocation" description:"The percentage of total funds that should be committed to automatic channel establishment"` 9 | MinChannelSize int64 `long:"minchansize" description:"The smallest channel that the autopilot agent should create"` 10 | MaxChannelSize int64 `long:"maxchansize" description:"The largest channel that the autopilot agent should create"` 11 | Private bool `long:"private" description:"Whether the channels created by the autopilot agent should be private or not. Private channels won't be announced to the network."` 12 | MinConfs int32 `long:"minconfs" description:"The minimum number of confirmations each of your inputs in funding transactions created by the autopilot agent must have."` 13 | ConfTarget uint32 `long:"conftarget" description:"The confirmation target (in blocks) for channels opened by autopilot."` 14 | } 15 | -------------------------------------------------------------------------------- /lncfg/bitcoind.go: -------------------------------------------------------------------------------- 1 | package lncfg 2 | 3 | // Bitcoind holds the configuration options for the daemon's connection to 4 | // bitcoind. 5 | type Bitcoind struct { 6 | Dir string `long:"dir" description:"The base directory that contains the node's data, logs, configuration file, etc."` 7 | RPCHost string `long:"rpchost" description:"The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used."` 8 | RPCUser string `long:"rpcuser" description:"Username for RPC connections"` 9 | RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"` 10 | ZMQPubRawBlock string `long:"zmqpubrawblock" description:"The address listening for ZMQ connections to deliver raw block notifications"` 11 | ZMQPubRawTx string `long:"zmqpubrawtx" description:"The address listening for ZMQ connections to deliver raw transaction notifications"` 12 | EstimateMode string `long:"estimatemode" description:"The fee estimate mode. Must be either ECONOMICAL or CONSERVATIVE."` 13 | } 14 | -------------------------------------------------------------------------------- /lncfg/btcd.go: -------------------------------------------------------------------------------- 1 | package lncfg 2 | 3 | // Btcd holds the configuration options for the daemon's connection to btcd. 4 | type Btcd struct { 5 | Dir string `long:"dir" description:"The base directory that contains the node's data, logs, configuration file, etc."` 6 | RPCHost string `long:"rpchost" description:"The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used."` 7 | RPCUser string `long:"rpcuser" description:"Username for RPC connections"` 8 | RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"` 9 | RPCCert string `long:"rpccert" description:"File containing the daemon's certificate file"` 10 | RawRPCCert string `long:"rawrpccert" description:"The raw bytes of the daemon's PEM-encoded certificate chain which will be used to authenticate the RPC connection."` 11 | } 12 | -------------------------------------------------------------------------------- /lncfg/interface.go: -------------------------------------------------------------------------------- 1 | package lncfg 2 | 3 | // Validator is a generic interface for validating sub configurations. 4 | type Validator interface { 5 | // Validate returns an error if a particular configuration is invalid or 6 | // insane. 7 | Validate() error 8 | } 9 | 10 | // Validate accepts a variadic list of Validators and checks that each one 11 | // passes its Validate method. An error is returned from the first Validator 12 | // that fails. 13 | func Validate(validators ...Validator) error { 14 | for _, validator := range validators { 15 | if err := validator.Validate(); err != nil { 16 | return err 17 | } 18 | } 19 | 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /lncfg/monitoring_off.go: -------------------------------------------------------------------------------- 1 | // +build !monitoring 2 | 3 | package lncfg 4 | 5 | // Prometheus configures the Prometheus exporter when monitoring is enabled. 6 | // Monitoring is currently disabled. 7 | type Prometheus struct{} 8 | 9 | // DefaultPrometheus is the default configuration for the Prometheus metrics 10 | // exporter when monitoring is enabled. Monitoring is currently disabled. 11 | func DefaultPrometheus() Prometheus { 12 | return Prometheus{} 13 | } 14 | 15 | // Enabled returns whether or not Prometheus monitoring is enabled. Monitoring 16 | // is currently disabled, so Enabled will always return false. 17 | func (p *Prometheus) Enabled() bool { 18 | return false 19 | } 20 | -------------------------------------------------------------------------------- /lncfg/monitoring_on.go: -------------------------------------------------------------------------------- 1 | // +build monitoring 2 | 3 | package lncfg 4 | 5 | // Prometheus is the set of configuration data that specifies the listening 6 | // address of the Prometheus exporter. 7 | type Prometheus struct { 8 | // Listen is the listening address that we should use to allow the main 9 | // Prometheus server to scrape our metrics. 10 | Listen string `long:"listen" description:"the interface we should listen on for Prometheus"` 11 | 12 | // Enable indicates whether to export lnd gRPC performance metrics to 13 | // Prometheus. Default is false. 14 | Enable bool `long:"enable" description:"enable Prometheus exporting of lnd gRPC performance metrics."` 15 | } 16 | 17 | // DefaultPrometheus is the default configuration for the Prometheus metrics 18 | // exporter. 19 | func DefaultPrometheus() Prometheus { 20 | return Prometheus{ 21 | Listen: "127.0.0.1:8989", 22 | Enable: false, 23 | } 24 | } 25 | 26 | // Enabled returns whether or not Prometheus monitoring is enabled. Monitoring 27 | // is disabled by default, but may be enabled by the user. 28 | func (p *Prometheus) Enabled() bool { 29 | return p.Enable 30 | } 31 | -------------------------------------------------------------------------------- /lncfg/neutrino.go: -------------------------------------------------------------------------------- 1 | package lncfg 2 | 3 | import "time" 4 | 5 | // Neutrino holds the configuration options for the daemon's connection to 6 | // neutrino. 7 | type Neutrino struct { 8 | AddPeers []string `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"` 9 | ConnectPeers []string `long:"connect" description:"Connect only to the specified peers at startup"` 10 | MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"` 11 | BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"` 12 | BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."` 13 | FeeURL string `long:"feeurl" description:"Optional URL for fee estimation. If a URL is not specified, static fees will be used for estimation."` 14 | AssertFilterHeader string `long:"assertfilterheader" description:"Optional filter header in height:hash format to assert the state of neutrino's filter header chain on startup. If the assertion does not hold, then the filter header chain will be re-synced from the genesis block."` 15 | } 16 | -------------------------------------------------------------------------------- /lncfg/protocol.go: -------------------------------------------------------------------------------- 1 | package lncfg 2 | 3 | // ProtocolOptions is a struct that we use to be able to test backwards 4 | // compatibility of protocol additions, while defaulting to the latest within 5 | // lnd, or to enable experimental protocol changes. 6 | type ProtocolOptions struct { 7 | // LegacyProtocol is a sub-config that houses all the legacy protocol 8 | // options. These are mostly used for integration tests as most modern 9 | // nodes shuld always run with them on by default. 10 | LegacyProtocol `group:"legacy" namespace:"legacy"` 11 | 12 | // ExperimentalProtocol is a sub-config that houses any experimental 13 | // protocol features that also require a build-tag to activate. 14 | ExperimentalProtocol 15 | 16 | // WumboChans should be set if we want to enable support for wumbo 17 | // (channels larger than 0.16 BTC) channels, which is the opposite of 18 | // mini. 19 | WumboChans bool `long:"wumbo-channels" description:"if set, then lnd will create and accept requests for channels larger chan 0.16 BTC"` 20 | } 21 | 22 | // Wumbo returns true if lnd should permit the creation and acceptance of wumbo 23 | // channels. 24 | func (l *ProtocolOptions) Wumbo() bool { 25 | return l.WumboChans 26 | } 27 | -------------------------------------------------------------------------------- /lncfg/protocol_experimental_off.go: -------------------------------------------------------------------------------- 1 | // +build !dev 2 | 3 | package lncfg 4 | 5 | // ExperimentalProtocol is a sub-config that houses any experimental protocol 6 | // features that also require a build-tag to activate. 7 | type ExperimentalProtocol struct { 8 | } 9 | 10 | // AnchorCommitments returns true if support for the anchor commitment type 11 | // should be signaled. 12 | func (l *ExperimentalProtocol) AnchorCommitments() bool { 13 | return false 14 | } 15 | -------------------------------------------------------------------------------- /lncfg/protocol_experimental_on.go: -------------------------------------------------------------------------------- 1 | // +build dev 2 | 3 | package lncfg 4 | 5 | // ExperimentalProtocol is a sub-config that houses any experimental protocol 6 | // features that also require a build-tag to activate. 7 | type ExperimentalProtocol struct { 8 | // Anchors should be set if we want to support opening or accepting 9 | // channels having the anchor commitment type. 10 | Anchors bool `long:"anchors" description:"EXPERIMENTAL: enable experimental support for anchor commitments, won't work with watchtowers"` 11 | } 12 | 13 | // AnchorCommitments returns true if support for the anchor commitment type 14 | // should be signaled. 15 | func (l *ExperimentalProtocol) AnchorCommitments() bool { 16 | return l.Anchors 17 | } 18 | -------------------------------------------------------------------------------- /lncfg/protocol_legacy_off.go: -------------------------------------------------------------------------------- 1 | // +build !dev 2 | 3 | package lncfg 4 | 5 | // Legacy is a sub-config that houses all the legacy protocol options. These 6 | // are mostly used for integration tests as most modern nodes shuld always run 7 | // with them on by default. 8 | type LegacyProtocol struct { 9 | } 10 | 11 | // LegacyOnion returns true if the old legacy onion format should be used when 12 | // we're an intermediate or final hop. This controls if we set the 13 | // TLVOnionPayloadOptional bit or not. 14 | func (l *LegacyProtocol) LegacyOnion() bool { 15 | return false 16 | } 17 | 18 | // NoStaticRemoteKey returns true if the old commitment format with a tweaked 19 | // remote key should be used for new funded channels. 20 | func (l *LegacyProtocol) NoStaticRemoteKey() bool { 21 | return false 22 | } 23 | -------------------------------------------------------------------------------- /lncfg/protocol_legacy_on.go: -------------------------------------------------------------------------------- 1 | // +build dev 2 | 3 | package lncfg 4 | 5 | // Legacy is a sub-config that houses all the legacy protocol options. These 6 | // are mostly used for integration tests as most modern nodes shuld always run 7 | // with them on by default. 8 | type LegacyProtocol struct { 9 | // LegacyOnionFormat if set to true, then we won't signal 10 | // TLVOnionPayloadOptional. As a result, nodes that include us in the 11 | // route won't use the new modern onion framing. 12 | LegacyOnionFormat bool `long:"onion" description:"force node to not advertise the new modern TLV onion format"` 13 | 14 | // CommitmentTweak guards if we should use the old legacy commitment 15 | // protocol, or the newer variant that doesn't have a tweak for the 16 | // remote party's output in the commitment. If set to true, then we 17 | // won't signal StaticRemoteKeyOptional. 18 | CommitmentTweak bool `long:"committweak" description:"force node to not advertise the new commitment format"` 19 | } 20 | 21 | // LegacyOnion returns true if the old legacy onion format should be used when 22 | // we're an intermediate or final hop. This controls if we set the 23 | // TLVOnionPayloadOptional bit or not. 24 | func (l *LegacyProtocol) LegacyOnion() bool { 25 | return l.LegacyOnionFormat 26 | } 27 | 28 | // NoStaticRemoteKey returns true if the old commitment format with a tweaked 29 | // remote key should be used for new funded channels. 30 | func (l *LegacyProtocol) NoStaticRemoteKey() bool { 31 | return l.CommitmentTweak 32 | } 33 | -------------------------------------------------------------------------------- /lncfg/watchtower.go: -------------------------------------------------------------------------------- 1 | package lncfg 2 | 3 | import "github.com/lightningnetwork/lnd/watchtower" 4 | 5 | // Watchtower holds the daemon specific configuration parameters for running a 6 | // watchtower that shares resources with the daemon. 7 | type Watchtower struct { 8 | Active bool `long:"active" description:"If the watchtower should be active or not"` 9 | 10 | TowerDir string `long:"towerdir" description:"Directory of the watchtower.db"` 11 | 12 | watchtower.Conf 13 | } 14 | -------------------------------------------------------------------------------- /lnpeer/errors.go: -------------------------------------------------------------------------------- 1 | package lnpeer 2 | 3 | import "fmt" 4 | 5 | var ( 6 | // ErrPeerExiting signals that the peer received a disconnect request. 7 | ErrPeerExiting = fmt.Errorf("peer exiting") 8 | ) 9 | -------------------------------------------------------------------------------- /lnrpc/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Proto 3 | BasedOnStyle: Google 4 | IndentWidth: 4 5 | AllowShortFunctionsOnASingleLine: None 6 | SpaceBeforeParens: Always 7 | CompactNamespaces: false 8 | -------------------------------------------------------------------------------- /lnrpc/autopilotrpc/config_active.go: -------------------------------------------------------------------------------- 1 | // +build autopilotrpc 2 | 3 | package autopilotrpc 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/autopilot" 7 | ) 8 | 9 | // Config is the primary configuration struct for the autopilot RPC server. It 10 | // contains all the items required for the rpc server to carry out its 11 | // duties. The fields with struct tags are meant to be parsed as normal 12 | // configuration options, while if able to be populated, the latter fields MUST 13 | // also be specified. 14 | type Config struct { 15 | // Manager is the running autopilot manager. 16 | Manager *autopilot.Manager 17 | } 18 | -------------------------------------------------------------------------------- /lnrpc/autopilotrpc/config_default.go: -------------------------------------------------------------------------------- 1 | // +build !autopilotrpc 2 | 3 | package autopilotrpc 4 | 5 | // Config is empty for non-autopilotrpc builds. 6 | type Config struct{} 7 | -------------------------------------------------------------------------------- /lnrpc/chainrpc/config_active.go: -------------------------------------------------------------------------------- 1 | // +build chainrpc 2 | 3 | package chainrpc 4 | 5 | import ( 6 | "github.com/lightningnetwork/lnd/chainntnfs" 7 | "github.com/lightningnetwork/lnd/macaroons" 8 | ) 9 | 10 | // Config is the primary configuration struct for the chain notifier RPC server. 11 | // It contains all the items required for the server to carry out its duties. 12 | // The fields with struct tags are meant to be parsed as normal configuration 13 | // options, while if able to be populated, the latter fields MUST also be 14 | // specified. 15 | type Config struct { 16 | // ChainNotifierMacPath is the path for the chain notifier macaroon. If 17 | // unspecified then we assume that the macaroon will be found under the 18 | // network directory, named DefaultChainNotifierMacFilename. 19 | ChainNotifierMacPath string `long:"notifiermacaroonpath" description:"Path to the chain notifier macaroon"` 20 | 21 | // NetworkDir is the main network directory wherein the chain notifier 22 | // RPC server will find the macaroon named 23 | // DefaultChainNotifierMacFilename. 24 | NetworkDir string 25 | 26 | // MacService is the main macaroon service that we'll use to handle 27 | // authentication for the chain notifier RPC server. 28 | MacService *macaroons.Service 29 | 30 | // ChainNotifier is the chain notifier instance that backs the chain 31 | // notifier RPC server. The job of the chain notifier RPC server is 32 | // simply to proxy valid requests to the active chain notifier instance. 33 | ChainNotifier chainntnfs.ChainNotifier 34 | } 35 | -------------------------------------------------------------------------------- /lnrpc/chainrpc/config_default.go: -------------------------------------------------------------------------------- 1 | // +build !chainrpc 2 | 3 | package chainrpc 4 | 5 | // Config is empty for non-chainrpc builds. 6 | type Config struct{} 7 | -------------------------------------------------------------------------------- /lnrpc/file_utils.go: -------------------------------------------------------------------------------- 1 | package lnrpc 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | // FileExists reports whether the named file or directory exists. 8 | func FileExists(name string) bool { 9 | if _, err := os.Stat(name); err != nil { 10 | if os.IsNotExist(err) { 11 | return false 12 | } 13 | } 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /lnrpc/gen_protos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Generating root gRPC server protos" 4 | 5 | PROTOS="rpc.proto walletunlocker.proto **/*.proto" 6 | 7 | # For each of the sub-servers, we then generate their protos, but a restricted 8 | # set as they don't yet require REST proxies, or swagger docs. 9 | for file in $PROTOS; do 10 | DIRECTORY=$(dirname "${file}") 11 | echo "Generating protos from ${file}, into ${DIRECTORY}" 12 | 13 | # Generate the protos. 14 | protoc -I/usr/local/include -I. \ 15 | --go_out=plugins=grpc,paths=source_relative:. \ 16 | "${file}" 17 | 18 | # Generate the REST reverse proxy. 19 | protoc -I/usr/local/include -I. \ 20 | --grpc-gateway_out=logtostderr=true,paths=source_relative,grpc_api_configuration=rest-annotations.yaml:. \ 21 | "${file}" 22 | 23 | 24 | # Finally, generate the swagger file which describes the REST API in detail. 25 | protoc -I/usr/local/include -I. \ 26 | --swagger_out=logtostderr=true,grpc_api_configuration=rest-annotations.yaml:. \ 27 | "${file}" 28 | done 29 | -------------------------------------------------------------------------------- /lnrpc/invoicesrpc/config_default.go: -------------------------------------------------------------------------------- 1 | // +build !invoicesrpc 2 | 3 | package invoicesrpc 4 | 5 | // Config is empty for non-invoicesrpc builds. 6 | type Config struct{} 7 | -------------------------------------------------------------------------------- /lnrpc/invoicesrpc/log.go: -------------------------------------------------------------------------------- 1 | package invoicesrpc 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This means the 9 | // package will not perform any logging by default until the caller requests 10 | // it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("IRPC", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled by 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. This 25 | // should be used in preference to SetLogWriter if the caller is also using 26 | // btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | 31 | // logClosure is used to provide a closure over expensive logging operations so 32 | // don't have to be performed when the logging level doesn't warrant it. 33 | type logClosure func() string 34 | 35 | // String invokes the underlying function and returns the result. 36 | func (c logClosure) String() string { 37 | return c() 38 | } 39 | 40 | // newLogClosure returns a new closure over a function that returns a string 41 | // which itself provides a Stringer interface so that it can be used with the 42 | // logging system. 43 | func newLogClosure(c func() string) logClosure { 44 | return logClosure(c) 45 | } 46 | -------------------------------------------------------------------------------- /lnrpc/lnclipb/lncli.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "verrpc/verrpc.proto"; 4 | 5 | package lnclipb; 6 | 7 | option go_package = "github.com/lightningnetwork/lnd/lnrpc/lnclipb"; 8 | 9 | message VersionResponse { 10 | // The version information for lncli. 11 | verrpc.Version lncli = 1; 12 | 13 | // The version information for lnd. 14 | verrpc.Version lnd = 2; 15 | }; 16 | -------------------------------------------------------------------------------- /lnrpc/lnclipb/lncli.swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "lnclipb/lncli.proto", 5 | "version": "version not set" 6 | }, 7 | "consumes": [ 8 | "application/json" 9 | ], 10 | "produces": [ 11 | "application/json" 12 | ], 13 | "paths": {}, 14 | "definitions": { 15 | "protobufAny": { 16 | "type": "object", 17 | "properties": { 18 | "type_url": { 19 | "type": "string" 20 | }, 21 | "value": { 22 | "type": "string", 23 | "format": "byte" 24 | } 25 | } 26 | }, 27 | "runtimeError": { 28 | "type": "object", 29 | "properties": { 30 | "error": { 31 | "type": "string" 32 | }, 33 | "code": { 34 | "type": "integer", 35 | "format": "int32" 36 | }, 37 | "message": { 38 | "type": "string" 39 | }, 40 | "details": { 41 | "type": "array", 42 | "items": { 43 | "$ref": "#/definitions/protobufAny" 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lnrpc/signrpc/config_default.go: -------------------------------------------------------------------------------- 1 | // +build !signrpc 2 | 3 | package signrpc 4 | 5 | // Config is empty for non-signrpc builds. 6 | type Config struct{} 7 | -------------------------------------------------------------------------------- /lnrpc/signrpc/log.go: -------------------------------------------------------------------------------- 1 | package signrpc 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("SGNR", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | 31 | // logClosure is used to provide a closure over expensive logging operations so 32 | // don't have to be performed when the logging level doesn't warrant it. 33 | type logClosure func() string // nolint:unused 34 | 35 | // String invokes the underlying function and returns the result. 36 | func (c logClosure) String() string { 37 | return c() 38 | } 39 | 40 | // newLogClosure returns a new closure over a function that returns a string 41 | // which itself provides a Stringer interface so that it can be used with the 42 | // logging system. 43 | func newLogClosure(c func() string) logClosure { // nolint:unused 44 | return logClosure(c) 45 | } 46 | -------------------------------------------------------------------------------- /lnrpc/verrpc/driver.go: -------------------------------------------------------------------------------- 1 | package verrpc 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/lightningnetwork/lnd/lnrpc" 7 | ) 8 | 9 | func init() { 10 | subServer := &lnrpc.SubServerDriver{ 11 | SubServerName: subServerName, 12 | New: func(c lnrpc.SubServerConfigDispatcher) (lnrpc.SubServer, 13 | lnrpc.MacaroonPerms, error) { 14 | 15 | return &Server{}, macPermissions, nil 16 | }, 17 | } 18 | 19 | // We'll register ourselves as a sub-RPC server within the global lnrpc 20 | // package namespace. 21 | if err := lnrpc.RegisterSubServer(subServer); err != nil { 22 | panic(fmt.Sprintf("failed to register sub server driver '%s': %v", 23 | subServerName, err)) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lnrpc/verrpc/log.go: -------------------------------------------------------------------------------- 1 | package verrpc 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // Subsystem defines the logging code for this subsystem. 14 | const Subsystem = "VRPC" 15 | 16 | // The default amount of logging is none. 17 | func init() { 18 | UseLogger(build.NewSubLogger(Subsystem, nil)) 19 | } 20 | 21 | // DisableLog disables all library log output. Logging output is disabled 22 | // by default until UseLogger is called. 23 | func DisableLog() { 24 | UseLogger(btclog.Disabled) 25 | } 26 | 27 | // UseLogger uses a specified Logger to output package logging info. 28 | // This should be used in preference to SetLogWriter if the caller is also 29 | // using btclog. 30 | func UseLogger(logger btclog.Logger) { 31 | log = logger 32 | } 33 | -------------------------------------------------------------------------------- /lnrpc/verrpc/verrpc.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package verrpc; 4 | 5 | option go_package = "github.com/lightningnetwork/lnd/lnrpc/verrpc"; 6 | 7 | // Versioner is a service that can be used to get information about the version 8 | // and build information of the running daemon. 9 | service Versioner { 10 | /* lncli: `version` 11 | GetVersion returns the current version and build information of the running 12 | daemon. 13 | */ 14 | rpc GetVersion (VersionRequest) returns (Version); 15 | } 16 | 17 | message VersionRequest { 18 | } 19 | 20 | message Version { 21 | // A verbose description of the daemon's commit. 22 | string commit = 1; 23 | 24 | // The SHA1 commit hash that the daemon is compiled with. 25 | string commit_hash = 2; 26 | 27 | // The semantic version. 28 | string version = 3; 29 | 30 | // The major application version. 31 | uint32 app_major = 4; 32 | 33 | // The minor application version. 34 | uint32 app_minor = 5; 35 | 36 | // The application patch number. 37 | uint32 app_patch = 6; 38 | 39 | // The application pre-release modifier, possibly empty. 40 | string app_pre_release = 7; 41 | 42 | // The list of build tags that were supplied during compilation. 43 | repeated string build_tags = 8; 44 | 45 | // The version of go that compiled the executable. 46 | string go_version = 9; 47 | } 48 | -------------------------------------------------------------------------------- /lnrpc/walletrpc/config_default.go: -------------------------------------------------------------------------------- 1 | // +build !walletrpc 2 | 3 | package walletrpc 4 | 5 | // Config is the primary configuration struct for the WalletKit RPC server. 6 | // When the server isn't active (via the build flag), callers outside this 7 | // package will see this shell of a config file. 8 | type Config struct{} 9 | -------------------------------------------------------------------------------- /lnrpc/watchtowerrpc/config_active.go: -------------------------------------------------------------------------------- 1 | // +build watchtowerrpc 2 | 3 | package watchtowerrpc 4 | 5 | // Config is the primary configuration struct for the watchtower RPC server. It 6 | // contains all items required for the RPC server to carry out its duties. The 7 | // fields with struct tags are meant to parsed as normal configuration options, 8 | // while if able to be populated, the latter fields MUST also be specified. 9 | type Config struct { 10 | // Active indicates if the watchtower is enabled. 11 | Active bool 12 | 13 | // Tower is the active watchtower which serves as the primary source for 14 | // information presented via RPC. 15 | Tower WatchtowerBackend 16 | } 17 | -------------------------------------------------------------------------------- /lnrpc/watchtowerrpc/config_default.go: -------------------------------------------------------------------------------- 1 | // +build !watchtowerrpc 2 | 3 | package watchtowerrpc 4 | 5 | // Config is empty for non-watchtowerrpc builds. 6 | type Config struct{} 7 | -------------------------------------------------------------------------------- /lnrpc/watchtowerrpc/interface.go: -------------------------------------------------------------------------------- 1 | package watchtowerrpc 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/btcsuite/btcd/btcec" 7 | ) 8 | 9 | // WatchtowerBackend abstracts access to the watchtower information that is 10 | // served via RPC connections. 11 | type WatchtowerBackend interface { 12 | // PubKey returns the public key for the watchtower used to 13 | // authentication and encrypt traffic with clients. 14 | PubKey() *btcec.PublicKey 15 | 16 | // ListeningAddrs returns the listening addresses where the watchtower 17 | // server can accept client connections. 18 | ListeningAddrs() []net.Addr 19 | 20 | // ExternalIPs returns the addresses where the watchtower can be reached 21 | // by clients externally. 22 | ExternalIPs() []net.Addr 23 | } 24 | -------------------------------------------------------------------------------- /lnrpc/watchtowerrpc/watchtower.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package watchtowerrpc; 4 | 5 | option go_package = "github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc"; 6 | 7 | // Watchtower is a service that grants access to the watchtower server 8 | // functionality of the daemon. 9 | service Watchtower { 10 | /* lncli: tower info 11 | GetInfo returns general information concerning the companion watchtower 12 | including its public key and URIs where the server is currently 13 | listening for clients. 14 | */ 15 | rpc GetInfo (GetInfoRequest) returns (GetInfoResponse); 16 | } 17 | 18 | message GetInfoRequest { 19 | } 20 | 21 | message GetInfoResponse { 22 | // The public key of the watchtower. 23 | bytes pubkey = 1; 24 | 25 | // The listening addresses of the watchtower. 26 | repeated string listeners = 2; 27 | 28 | // The URIs of the watchtower. 29 | repeated string uris = 3; 30 | } 31 | -------------------------------------------------------------------------------- /lnrpc/wtclientrpc/config.go: -------------------------------------------------------------------------------- 1 | package wtclientrpc 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/lncfg" 6 | "github.com/lightningnetwork/lnd/watchtower/wtclient" 7 | ) 8 | 9 | // Config is the primary configuration struct for the watchtower RPC server. It 10 | // contains all the items required for the RPC server to carry out its duties. 11 | // The fields with struct tags are meant to be parsed as normal configuration 12 | // options, while if able to be populated, the latter fields MUST also be 13 | // specified. 14 | type Config struct { 15 | // Active indicates if the watchtower client is enabled. 16 | Active bool 17 | 18 | // Client is the backing watchtower client that we'll interact with 19 | // through the watchtower RPC subserver. 20 | Client wtclient.Client 21 | 22 | // Resolver is a custom resolver that will be used to resolve watchtower 23 | // addresses to ensure we don't leak any information when running over 24 | // non-clear networks, e.g. Tor, etc. 25 | Resolver lncfg.TCPResolver 26 | 27 | // Log is the logger instance we should log output to. 28 | Log btclog.Logger 29 | } 30 | -------------------------------------------------------------------------------- /lntest/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package lntest provides testing utilities for the lnd repository. 3 | 4 | This package contains infrastructure for integration tests that launch full lnd 5 | nodes in a controlled environment and interact with them via RPC. Using a 6 | NetworkHarness, a test can launch multiple lnd nodes, open channels between 7 | them, create defined network topologies, and anything else that is possible with 8 | RPC commands. 9 | */ 10 | package lntest 11 | -------------------------------------------------------------------------------- /lntest/itest/log_check_errors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASEDIR=$(dirname "$0") 4 | 5 | echo "" 6 | 7 | # Filter all log files for errors, substitute variable data and match against whitelist. 8 | cat $BASEDIR/*.log | grep "\[ERR\]" | \ 9 | sed -r -f $BASEDIR/log_substitutions.txt | \ 10 | sort | uniq | \ 11 | grep -Fvi -f $BASEDIR/log_error_whitelist.txt 12 | 13 | # If something shows up (not on whitelist) exit with error code 1. 14 | if [[ $? -eq 0 ]]; then 15 | echo "" 16 | echo "In the itest logs, the log line (patterns) above were detected." 17 | echo "[ERR] lines are generally reserved for internal errors." 18 | echo "Resolve the issue by either changing the log level or adding an " 19 | echo "exception to log_error_whitelist.txt" 20 | echo "" 21 | 22 | exit 1 23 | fi 24 | 25 | echo "No itest errors detected." 26 | echo "" 27 | -------------------------------------------------------------------------------- /lntest/timeouts.go: -------------------------------------------------------------------------------- 1 | // +build !darwin 2 | 3 | package lntest 4 | 5 | import "time" 6 | 7 | const ( 8 | // MinerMempoolTimeout is the max time we will wait for a transaction 9 | // to propagate to the mining node's mempool. 10 | MinerMempoolTimeout = time.Minute 11 | 12 | // ChannelOpenTimeout is the max time we will wait before a channel to 13 | // be considered opened. 14 | ChannelOpenTimeout = time.Second * 30 15 | 16 | // ChannelCloseTimeout is the max time we will wait before a channel is 17 | // considered closed. 18 | ChannelCloseTimeout = time.Second * 30 19 | 20 | // DefaultTimeout is a timeout that will be used for various wait 21 | // scenarios where no custom timeout value is defined. 22 | DefaultTimeout = time.Second * 30 23 | 24 | // AsyncBenchmarkTimeout is the timeout used when running the async 25 | // payments benchmark. 26 | AsyncBenchmarkTimeout = 2 * time.Minute 27 | ) 28 | -------------------------------------------------------------------------------- /lntest/timeouts_darwin.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package lntest 4 | 5 | import "time" 6 | 7 | const ( 8 | // MinerMempoolTimeout is the max time we will wait for a transaction 9 | // to propagate to the mining node's mempool. 10 | MinerMempoolTimeout = time.Minute 11 | 12 | // ChannelOpenTimeout is the max time we will wait before a channel to 13 | // be considered opened. 14 | ChannelOpenTimeout = time.Second * 30 15 | 16 | // ChannelCloseTimeout is the max time we will wait before a channel is 17 | // considered closed. 18 | ChannelCloseTimeout = time.Second * 30 19 | 20 | // DefaultTimeout is a timeout that will be used for various wait 21 | // scenarios where no custom timeout value is defined. 22 | DefaultTimeout = time.Second * 30 23 | 24 | // AsyncBenchmarkTimeout is the timeout used when running the async 25 | // payments benchmark. This timeout takes considerably longer on darwin 26 | // after go1.12 corrected its use of fsync. 27 | AsyncBenchmarkTimeout = time.Minute * 3 28 | ) 29 | -------------------------------------------------------------------------------- /lntypes/hash.go: -------------------------------------------------------------------------------- 1 | package lntypes 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | ) 7 | 8 | // HashSize of array used to store hashes. 9 | const HashSize = 32 10 | 11 | // ZeroHash is a predefined hash containing all zeroes. 12 | var ZeroHash Hash 13 | 14 | // Hash is used in several of the lightning messages and common structures. It 15 | // typically represents a payment hash. 16 | type Hash [HashSize]byte 17 | 18 | // String returns the Hash as a hexadecimal string. 19 | func (hash Hash) String() string { 20 | return hex.EncodeToString(hash[:]) 21 | } 22 | 23 | // MakeHash returns a new Hash from a byte slice. An error is returned if 24 | // the number of bytes passed in is not HashSize. 25 | func MakeHash(newHash []byte) (Hash, error) { 26 | nhlen := len(newHash) 27 | if nhlen != HashSize { 28 | return Hash{}, fmt.Errorf("invalid hash length of %v, want %v", 29 | nhlen, HashSize) 30 | } 31 | 32 | var hash Hash 33 | copy(hash[:], newHash) 34 | 35 | return hash, nil 36 | } 37 | 38 | // MakeHashFromStr creates a Hash from a hex hash string. 39 | func MakeHashFromStr(newHash string) (Hash, error) { 40 | // Return error if hash string is of incorrect length. 41 | if len(newHash) != HashSize*2 { 42 | return Hash{}, fmt.Errorf("invalid hash string length of %v, "+ 43 | "want %v", len(newHash), HashSize*2) 44 | } 45 | 46 | hash, err := hex.DecodeString(newHash) 47 | if err != nil { 48 | return Hash{}, err 49 | } 50 | 51 | return MakeHash(hash) 52 | } 53 | -------------------------------------------------------------------------------- /lnwallet/README.md: -------------------------------------------------------------------------------- 1 | lnwallet 2 | ========= 3 | 4 | [![Build Status](http://img.shields.io/travis/lightningnetwork/lnd.svg)](https://travis-ci.org/lightningnetwork/lnd) 5 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lightningnetwork/lnd/blob/master/LICENSE) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/lightningnetwork/lnd/lnwallet) 7 | 8 | The lnwallet package implements an abstracted wallet controller that is able to 9 | drive channel funding workflows, a number of script utilities, witness 10 | generation functions for the various Lightning scripts, revocation key 11 | derivation, and the commitment update state machine. 12 | 13 | The package is used within `lnd` as the core wallet of the daemon. The wallet 14 | itself is composed of several distinct interfaces that decouple the 15 | implementation of things like signing and blockchain access. This separation 16 | allows new `WalletController` implementations to be easily dropped into 17 | `lnd` without disrupting the code base. A series of integration tests at the 18 | interface level are also in place to ensure conformance of the implementation 19 | with the interface. 20 | 21 | 22 | ## Installation and Updating 23 | 24 | ```bash 25 | $ go get -u github.com/lightningnetwork/lnd/lnwallet 26 | ``` 27 | -------------------------------------------------------------------------------- /lnwallet/btcwallet/btcwallet_rpctest.go: -------------------------------------------------------------------------------- 1 | // +build rpctest 2 | 3 | package btcwallet 4 | 5 | import ( 6 | "github.com/btcsuite/btcwallet/snacl" 7 | "github.com/btcsuite/btcwallet/waddrmgr" 8 | ) 9 | 10 | func init() { 11 | // Instruct waddrmgr to use the cranked down scrypt parameters when 12 | // creating new wallet encryption keys. This will speed up the itests 13 | // considerably. 14 | fastScrypt := waddrmgr.FastScryptOptions 15 | keyGen := func(passphrase *[]byte, config *waddrmgr.ScryptOptions) ( 16 | *snacl.SecretKey, error) { 17 | 18 | return snacl.NewSecretKey( 19 | passphrase, fastScrypt.N, fastScrypt.R, fastScrypt.P, 20 | ) 21 | } 22 | waddrmgr.SetSecretKeyGen(keyGen) 23 | } 24 | -------------------------------------------------------------------------------- /lnwallet/btcwallet/driver.go: -------------------------------------------------------------------------------- 1 | package btcwallet 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/btcsuite/btcwallet/chain" 7 | "github.com/lightningnetwork/lnd/lnwallet" 8 | ) 9 | 10 | const ( 11 | walletType = "btcwallet" 12 | ) 13 | 14 | // createNewWallet creates a new instance of BtcWallet given the proper list of 15 | // initialization parameters. This function is the factory function required to 16 | // properly create an instance of the lnwallet.WalletDriver struct for 17 | // BtcWallet. 18 | func createNewWallet(args ...interface{}) (lnwallet.WalletController, error) { 19 | if len(args) != 1 { 20 | return nil, fmt.Errorf("incorrect number of arguments to .New(...), "+ 21 | "expected 1, instead passed %v", len(args)) 22 | } 23 | 24 | config, ok := args[0].(*Config) 25 | if !ok { 26 | return nil, fmt.Errorf("first argument to btcdnotifier.New is " + 27 | "incorrect, expected a *rpcclient.ConnConfig") 28 | } 29 | 30 | return New(*config) 31 | } 32 | 33 | // init registers a driver for the BtcWallet concrete implementation of the 34 | // lnwallet.WalletController interface. 35 | func init() { 36 | // Register the driver. 37 | driver := &lnwallet.WalletDriver{ 38 | WalletType: walletType, 39 | New: createNewWallet, 40 | BackEnds: chain.BackEnds, 41 | } 42 | 43 | if err := lnwallet.RegisterWallet(driver); err != nil { 44 | panic(fmt.Sprintf("failed to register wallet driver '%s': %v", 45 | walletType, err)) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lnwallet/chainfee/log.go: -------------------------------------------------------------------------------- 1 | package chainfee 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This means the 9 | // package will not perform any logging by default until the caller requests 10 | // it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("CFEE", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled by 19 | // default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. This 25 | // should be used in preference to SetLogWriter if the caller is also using 26 | // btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /lnwallet/chancloser/log.go: -------------------------------------------------------------------------------- 1 | package chancloser 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // chancloserLog is a logger that is initialized with the btclog.Disabled 9 | // logger. 10 | var chancloserLog btclog.Logger 11 | 12 | // The default amount of logging is none. 13 | func init() { 14 | UseLogger(build.NewSubLogger("CHCL", nil)) 15 | } 16 | 17 | // DisableLog disables all logging output. 18 | func DisableLog() { 19 | UseLogger(btclog.Disabled) 20 | } 21 | 22 | // UseLogger uses a specified Logger to output package logging info. 23 | func UseLogger(logger btclog.Logger) { 24 | chancloserLog = logger 25 | } 26 | 27 | // logClosure is used to provide a closure over expensive logging operations 28 | // so they aren't performed when the logging level doesn't warrant it. 29 | type logClosure func() string 30 | 31 | // String invokes the underlying function and returns the result. 32 | func (c logClosure) String() string { 33 | return c() 34 | } 35 | 36 | // newLogClosure returns a new closure over a function that returns a string 37 | // which itself provides a Stringer interface so that it can be used with the 38 | // logging system. 39 | func newLogClosure(c func() string) logClosure { 40 | return logClosure(c) 41 | } 42 | -------------------------------------------------------------------------------- /lnwallet/chanfunding/log.go: -------------------------------------------------------------------------------- 1 | package chanfunding 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("CHFD", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /lnwallet/parameters.go: -------------------------------------------------------------------------------- 1 | package lnwallet 2 | 3 | import ( 4 | "github.com/btcsuite/btcutil" 5 | "github.com/btcsuite/btcwallet/wallet/txrules" 6 | "github.com/lightningnetwork/lnd/input" 7 | ) 8 | 9 | // DefaultDustLimit is used to calculate the dust HTLC amount which will be 10 | // send to other node during funding process. 11 | func DefaultDustLimit() btcutil.Amount { 12 | return txrules.GetDustThreshold(input.P2WSHSize, txrules.DefaultRelayFeePerKb) 13 | } 14 | -------------------------------------------------------------------------------- /lnwire/README.md: -------------------------------------------------------------------------------- 1 | lnwire 2 | ====== 3 | 4 | [![Build Status](http://img.shields.io/travis/lightningnetwork/lnd.svg)](https://travis-ci.org/lightningnetwork/lnd) 5 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lightningnetwork/lnd/blob/master/LICENSE) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/lightningnetwork/lnd/lnwire) 7 | 8 | The lnwire package implements the Lightning Network wire protocol. 9 | 10 | This package has intentionally been designed so it can be used as a standalone 11 | package for any projects needing to interface with lightning peers at the wire 12 | protocol level. 13 | 14 | ## Installation and Updating 15 | 16 | ```bash 17 | $ go get -u github.com/lightningnetwork/lnd/lnwire 18 | ``` 19 | -------------------------------------------------------------------------------- /lnwire/netaddress_test.go: -------------------------------------------------------------------------------- 1 | package lnwire 2 | 3 | import ( 4 | "encoding/hex" 5 | "net" 6 | "testing" 7 | 8 | "github.com/btcsuite/btcd/btcec" 9 | ) 10 | 11 | func TestNetAddressDisplay(t *testing.T) { 12 | t.Parallel() 13 | 14 | pubKeyStr := "036a0c5ea35df8a528b98edf6f290b28676d51d0fe202b073fe677612a39c0aa09" 15 | pubHex, err := hex.DecodeString(pubKeyStr) 16 | if err != nil { 17 | t.Fatalf("unable to decode str: %v", err) 18 | } 19 | 20 | pubKey, err := btcec.ParsePubKey(pubHex, btcec.S256()) 21 | if err != nil { 22 | t.Fatalf("unable to parse pubkey: %v", err) 23 | } 24 | addr, _ := net.ResolveTCPAddr("tcp", "10.0.0.2:9000") 25 | 26 | netAddr := NetAddress{ 27 | IdentityKey: pubKey, 28 | Address: addr, 29 | } 30 | 31 | if addr.Network() != netAddr.Network() { 32 | t.Fatalf("network addr mismatch: %v", err) 33 | } 34 | 35 | expectedAddr := pubKeyStr + "@" + addr.String() 36 | addrString := netAddr.String() 37 | if expectedAddr != addrString { 38 | t.Fatalf("expected %v, got %v", expectedAddr, addrString) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lnwire/node_announcement_test.go: -------------------------------------------------------------------------------- 1 | package lnwire 2 | 3 | import "testing" 4 | 5 | // TestNodeAliasValidation tests that the NewNodeAlias method will only accept 6 | // valid node announcements. 7 | func TestNodeAliasValidation(t *testing.T) { 8 | t.Parallel() 9 | 10 | var testCases = []struct { 11 | alias string 12 | valid bool 13 | }{ 14 | // UTF-8 alias with valid length. 15 | { 16 | alias: "meruem", 17 | valid: true, 18 | }, 19 | 20 | // UTF-8 alias with invalid length. 21 | { 22 | alias: "p3kysxqr23swl33m6h5grmzddgw5nsgkky3g52zc6frpwz", 23 | valid: false, 24 | }, 25 | 26 | // String with non UTF-8 characters. 27 | { 28 | alias: "\xE0\x80\x80", 29 | valid: false, 30 | }, 31 | } 32 | for i, testCase := range testCases { 33 | _, err := NewNodeAlias(testCase.alias) 34 | switch { 35 | case err != nil && testCase.valid: 36 | t.Fatalf("#%v: alias should have been invalid", i) 37 | 38 | case err == nil && !testCase.valid: 39 | t.Fatalf("#%v: invalid alias was missed", i) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lnwire/short_channel_id_test.go: -------------------------------------------------------------------------------- 1 | package lnwire 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/davecgh/go-spew/spew" 8 | ) 9 | 10 | func TestShortChannelIDEncoding(t *testing.T) { 11 | t.Parallel() 12 | 13 | var testCases = []ShortChannelID{ 14 | { 15 | BlockHeight: (1 << 24) - 1, 16 | TxIndex: (1 << 24) - 1, 17 | TxPosition: (1 << 16) - 1, 18 | }, 19 | { 20 | BlockHeight: 2304934, 21 | TxIndex: 2345, 22 | TxPosition: 5, 23 | }, 24 | { 25 | BlockHeight: 9304934, 26 | TxIndex: 2345, 27 | TxPosition: 5233, 28 | }, 29 | } 30 | 31 | for _, testCase := range testCases { 32 | chanInt := testCase.ToUint64() 33 | 34 | newChanID := NewShortChanIDFromInt(chanInt) 35 | 36 | if !reflect.DeepEqual(testCase, newChanID) { 37 | t.Fatalf("chan ID's don't match: expected %v got %v", 38 | spew.Sdump(testCase), spew.Sdump(newChanID)) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libonomy/lnd/22cd1203fe96a1417b428a009f4e28d31f921d85/logo.png -------------------------------------------------------------------------------- /macaroons/auth.go: -------------------------------------------------------------------------------- 1 | package macaroons 2 | 3 | import ( 4 | "context" 5 | "encoding/hex" 6 | 7 | macaroon "gopkg.in/macaroon.v2" 8 | ) 9 | 10 | // MacaroonCredential wraps a macaroon to implement the 11 | // credentials.PerRPCCredentials interface. 12 | type MacaroonCredential struct { 13 | *macaroon.Macaroon 14 | } 15 | 16 | // RequireTransportSecurity implements the PerRPCCredentials interface. 17 | func (m MacaroonCredential) RequireTransportSecurity() bool { 18 | return true 19 | } 20 | 21 | // GetRequestMetadata implements the PerRPCCredentials interface. This method 22 | // is required in order to pass the wrapped macaroon into the gRPC context. 23 | // With this, the macaroon will be available within the request handling scope 24 | // of the ultimate gRPC server implementation. 25 | func (m MacaroonCredential) GetRequestMetadata(ctx context.Context, 26 | uri ...string) (map[string]string, error) { 27 | 28 | macBytes, err := m.MarshalBinary() 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | md := make(map[string]string) 34 | md["macaroon"] = hex.EncodeToString(macBytes) 35 | return md, nil 36 | } 37 | 38 | // NewMacaroonCredential returns a copy of the passed macaroon wrapped in a 39 | // MacaroonCredential struct which implements PerRPCCredentials. 40 | func NewMacaroonCredential(m *macaroon.Macaroon) MacaroonCredential { 41 | ms := MacaroonCredential{} 42 | ms.Macaroon = m.Clone() 43 | return ms 44 | } 45 | -------------------------------------------------------------------------------- /macaroons/security.go: -------------------------------------------------------------------------------- 1 | // +build !rpctest 2 | 3 | package macaroons 4 | 5 | import "github.com/btcsuite/btcwallet/snacl" 6 | 7 | var ( 8 | // Below are the default scrypt parameters that are used when creating 9 | // the encryption key for the macaroon database with snacl.NewSecretKey. 10 | scryptN = snacl.DefaultN 11 | scryptR = snacl.DefaultR 12 | scryptP = snacl.DefaultP 13 | ) 14 | -------------------------------------------------------------------------------- /macaroons/security_rpctest.go: -------------------------------------------------------------------------------- 1 | // +build rpctest 2 | 3 | package macaroons 4 | 5 | import "github.com/btcsuite/btcwallet/waddrmgr" 6 | 7 | var ( 8 | // Below are the reduced scrypt parameters that are used when creating 9 | // the encryption key for the macaroon database with snacl.NewSecretKey. 10 | // We use very low values for our itest/rpctest to speed things up. 11 | scryptN = waddrmgr.FastScryptOptions.N 12 | scryptR = waddrmgr.FastScryptOptions.R 13 | scryptP = waddrmgr.FastScryptOptions.P 14 | ) 15 | -------------------------------------------------------------------------------- /macaroons/security_test.go: -------------------------------------------------------------------------------- 1 | package macaroons 2 | 3 | import "github.com/btcsuite/btcwallet/waddrmgr" 4 | 5 | func init() { 6 | // Below are the reduced scrypt parameters that are used when creating 7 | // the encryption key for the macaroon database with snacl.NewSecretKey. 8 | // We use very low values for our itest/rpctest to speed things up. 9 | scryptN = waddrmgr.FastScryptOptions.N 10 | scryptR = waddrmgr.FastScryptOptions.R 11 | scryptP = waddrmgr.FastScryptOptions.P 12 | } 13 | -------------------------------------------------------------------------------- /make/release_flags.mk: -------------------------------------------------------------------------------- 1 | VERSION_TAG = $(shell date +%Y%m%d)-01 2 | VERSION_CHECK = @$(call print, "Building master with date version tag") 3 | 4 | BUILD_SYSTEM = darwin-386 \ 5 | darwin-amd64 \ 6 | dragonfly-amd64 \ 7 | freebsd-386 \ 8 | freebsd-amd64 \ 9 | freebsd-arm \ 10 | illumos-amd64 \ 11 | linux-386 \ 12 | linux-amd64 \ 13 | linux-armv6 \ 14 | linux-armv7 \ 15 | linux-arm64 \ 16 | linux-ppc64 \ 17 | linux-ppc64le \ 18 | linux-mips \ 19 | linux-mipsle \ 20 | linux-mips64 \ 21 | linux-mips64le \ 22 | linux-s390x \ 23 | netbsd-386 \ 24 | netbsd-amd64 \ 25 | netbsd-arm \ 26 | netbsd-arm64 \ 27 | openbsd-386 \ 28 | openbsd-amd64 \ 29 | openbsd-arm \ 30 | openbsd-arm64 \ 31 | solaris-amd64 \ 32 | windows-386 \ 33 | windows-amd64 \ 34 | windows-arm 35 | 36 | RELEASE_TAGS = autopilotrpc signrpc walletrpc chainrpc invoicesrpc watchtowerrpc 37 | 38 | # One can either specify a git tag as the version suffix or one is generated 39 | # from the current date. 40 | ifneq ($(tag),) 41 | VERSION_TAG = $(tag) 42 | VERSION_CHECK = ./scripts/release.sh check-tag "$(VERSION_TAG)" 43 | endif 44 | 45 | # By default we will build all systems. But with the 'sys' tag, a specific 46 | # system can be specified. This is useful to release for a subset of 47 | # systems/architectures. 48 | ifneq ($(sys),) 49 | BUILD_SYSTEM = $(sys) 50 | endif 51 | 52 | # Use all build tags by default but allow them to be overwritten. 53 | ifneq ($(tags),) 54 | RELEASE_TAGS = $(tags) 55 | endif 56 | -------------------------------------------------------------------------------- /mobile/sample_lnd.conf: -------------------------------------------------------------------------------- 1 | [Application Options] 2 | debuglevel=info 3 | maxbackoff=2s 4 | nolisten=1 5 | norest=1 6 | 7 | [Routing] 8 | routing.assumechanvalid=1 9 | 10 | [Bitcoin] 11 | bitcoin.active=1 12 | bitcoin.testnet=1 13 | bitcoin.node=neutrino 14 | -------------------------------------------------------------------------------- /monitoring/log.go: -------------------------------------------------------------------------------- 1 | package monitoring 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This means the 9 | // package will not perform any logging by default until the caller requests 10 | // it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("PROM", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled by 19 | // default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. This 25 | // should be used in preference to SetLogWriter if the caller is also using 26 | // btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /monitoring/monitoring_off.go: -------------------------------------------------------------------------------- 1 | // +build !monitoring 2 | 3 | package monitoring 4 | 5 | import ( 6 | "fmt" 7 | 8 | "google.golang.org/grpc" 9 | 10 | "github.com/lightningnetwork/lnd/lncfg" 11 | ) 12 | 13 | // GetPromInterceptors returns the set of interceptors for Prometheus 14 | // monitoring if monitoring is enabled, else empty slices. Monitoring is 15 | // currently disabled. 16 | func GetPromInterceptors() ([]grpc.UnaryServerInterceptor, []grpc.StreamServerInterceptor) { 17 | return []grpc.UnaryServerInterceptor{}, []grpc.StreamServerInterceptor{} 18 | } 19 | 20 | // ExportPrometheusMetrics is required for lnd to compile so that Prometheus 21 | // metric exporting can be hidden behind a build tag. 22 | func ExportPrometheusMetrics(_ *grpc.Server, _ lncfg.Prometheus) error { 23 | return fmt.Errorf("lnd must be built with the monitoring tag to " + 24 | "enable exporting Prometheus metrics") 25 | } 26 | -------------------------------------------------------------------------------- /monitoring/monitoring_on.go: -------------------------------------------------------------------------------- 1 | // +build monitoring 2 | 3 | package monitoring 4 | 5 | import ( 6 | "net/http" 7 | "sync" 8 | 9 | "google.golang.org/grpc" 10 | 11 | "github.com/grpc-ecosystem/go-grpc-prometheus" 12 | "github.com/lightningnetwork/lnd/lncfg" 13 | "github.com/prometheus/client_golang/prometheus/promhttp" 14 | ) 15 | 16 | var started sync.Once 17 | 18 | // GetPromInterceptors returns the set of interceptors for Prometheus 19 | // monitoring. 20 | func GetPromInterceptors() ([]grpc.UnaryServerInterceptor, []grpc.StreamServerInterceptor) { 21 | unaryInterceptors := []grpc.UnaryServerInterceptor{ 22 | grpc_prometheus.UnaryServerInterceptor, 23 | } 24 | streamInterceptors := []grpc.StreamServerInterceptor{ 25 | grpc_prometheus.StreamServerInterceptor, 26 | } 27 | return unaryInterceptors, streamInterceptors 28 | } 29 | 30 | // ExportPrometheusMetrics sets server options, registers gRPC metrics and 31 | // launches the Prometheus exporter on the specified address. 32 | func ExportPrometheusMetrics(grpcServer *grpc.Server, cfg lncfg.Prometheus) error { 33 | started.Do(func() { 34 | log.Infof("Prometheus exporter started on %v/metrics", cfg.Listen) 35 | 36 | grpc_prometheus.Register(grpcServer) 37 | 38 | http.Handle("/metrics", promhttp.Handler()) 39 | go func() { 40 | http.ListenAndServe(cfg.Listen, nil) 41 | }() 42 | }) 43 | 44 | return nil 45 | } 46 | -------------------------------------------------------------------------------- /netann/interface.go: -------------------------------------------------------------------------------- 1 | package netann 2 | 3 | import ( 4 | "github.com/btcsuite/btcd/wire" 5 | "github.com/lightningnetwork/lnd/channeldb" 6 | ) 7 | 8 | // DB abstracts the required database functionality needed by the 9 | // ChanStatusManager. 10 | type DB interface { 11 | // FetchAllOpenChannels returns a slice of all open channels known to 12 | // the daemon. This may include private or pending channels. 13 | FetchAllOpenChannels() ([]*channeldb.OpenChannel, error) 14 | } 15 | 16 | // ChannelGraph abstracts the required channel graph queries used by the 17 | // ChanStatusManager. 18 | type ChannelGraph interface { 19 | // FetchChannelEdgesByOutpoint returns the channel edge info and most 20 | // recent channel edge policies for a given outpoint. 21 | FetchChannelEdgesByOutpoint(*wire.OutPoint) (*channeldb.ChannelEdgeInfo, 22 | *channeldb.ChannelEdgePolicy, *channeldb.ChannelEdgePolicy, error) 23 | } 24 | -------------------------------------------------------------------------------- /netann/log.go: -------------------------------------------------------------------------------- 1 | package netann 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This means the 9 | // package will not perform any logging by default until the caller requests 10 | // it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("NANN", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled by 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. This 25 | // should be used in preference to SetLogWriter if the caller is also using 26 | // btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /netann/sign.go: -------------------------------------------------------------------------------- 1 | package netann 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/btcsuite/btcd/btcec" 7 | "github.com/lightningnetwork/lnd/input" 8 | "github.com/lightningnetwork/lnd/lnwallet" 9 | "github.com/lightningnetwork/lnd/lnwire" 10 | ) 11 | 12 | // SignAnnouncement signs any type of gossip message that is announced on the 13 | // network. 14 | func SignAnnouncement(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey, 15 | msg lnwire.Message) (input.Signature, error) { 16 | 17 | var ( 18 | data []byte 19 | err error 20 | ) 21 | 22 | switch m := msg.(type) { 23 | case *lnwire.ChannelAnnouncement: 24 | data, err = m.DataToSign() 25 | case *lnwire.ChannelUpdate: 26 | data, err = m.DataToSign() 27 | case *lnwire.NodeAnnouncement: 28 | data, err = m.DataToSign() 29 | default: 30 | return nil, fmt.Errorf("can't sign %T message", m) 31 | } 32 | if err != nil { 33 | return nil, fmt.Errorf("unable to get data to sign: %v", err) 34 | } 35 | 36 | return signer.SignMessage(pubKey, data) 37 | } 38 | -------------------------------------------------------------------------------- /peer/interfaces.go: -------------------------------------------------------------------------------- 1 | package peer 2 | 3 | import "github.com/lightningnetwork/lnd/lnwire" 4 | 5 | // LinkUpdater is an interface implemented by most messages in BOLT 2 that are 6 | // allowed to update the channel state. 7 | type LinkUpdater interface { 8 | // TargetChanID returns the channel id of the link for which this message 9 | // is intended. 10 | TargetChanID() lnwire.ChannelID 11 | } 12 | -------------------------------------------------------------------------------- /peer/log.go: -------------------------------------------------------------------------------- 1 | package peer 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // peerLog is a logger that is initialized with the btclog.Disabled logger. 9 | var peerLog btclog.Logger 10 | 11 | // The default amount of logging is none. 12 | func init() { 13 | UseLogger(build.NewSubLogger("PEER", nil)) 14 | } 15 | 16 | // DisableLog disables all logging output. 17 | func DisableLog() { 18 | UseLogger(btclog.Disabled) 19 | } 20 | 21 | // UseLogger uses a specified Logger to output package logging info. 22 | func UseLogger(logger btclog.Logger) { 23 | peerLog = logger 24 | } 25 | 26 | // logClosure is used to provide a closure over expensive logging operations 27 | // so they aren't performed when the logging level doesn't warrant it. 28 | type logClosure func() string 29 | 30 | // String invokes the underlying function and returns the result. 31 | func (c logClosure) String() string { 32 | return c() 33 | } 34 | 35 | // newLogClosure returns a new closure over a function that returns a string 36 | // which itself provides a Stringer interface so that it can be used with the 37 | // logging system. 38 | func newLogClosure(c func() string) logClosure { 39 | return logClosure(c) 40 | } 41 | -------------------------------------------------------------------------------- /peernotifier/log.go: -------------------------------------------------------------------------------- 1 | package peernotifier 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("PRNF", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /queue/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/lightningnetwork/lnd/queue 2 | 3 | require github.com/lightningnetwork/lnd/ticker v1.0.0 4 | 5 | replace github.com/lightningnetwork/lnd/ticker v1.0.0 => ../ticker 6 | 7 | go 1.12 8 | -------------------------------------------------------------------------------- /queue/go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libonomy/lnd/22cd1203fe96a1417b428a009f4e28d31f921d85/queue/go.sum -------------------------------------------------------------------------------- /record/custom_records.go: -------------------------------------------------------------------------------- 1 | package record 2 | 3 | import "fmt" 4 | 5 | const ( 6 | // CustomTypeStart is the start of the custom tlv type range as defined 7 | // in BOLT 01. 8 | CustomTypeStart = 65536 9 | ) 10 | 11 | // CustomSet stores a set of custom key/value pairs. 12 | type CustomSet map[uint64][]byte 13 | 14 | // Validate checks that all custom records are in the custom type range. 15 | func (c CustomSet) Validate() error { 16 | for key := range c { 17 | if key < CustomTypeStart { 18 | return fmt.Errorf("no custom records with types "+ 19 | "below %v allowed", CustomTypeStart) 20 | } 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /record/experimental.go: -------------------------------------------------------------------------------- 1 | package record 2 | 3 | const ( 4 | // KeySendType is the custom record identifier for keysend preimages. 5 | KeySendType uint64 = 5482373484 6 | ) 7 | -------------------------------------------------------------------------------- /record/hop.go: -------------------------------------------------------------------------------- 1 | package record 2 | 3 | import ( 4 | "github.com/lightningnetwork/lnd/tlv" 5 | ) 6 | 7 | const ( 8 | // AmtOnionType is the type used in the onion to refrence the amount to 9 | // send to the next hop. 10 | AmtOnionType tlv.Type = 2 11 | 12 | // LockTimeTLV is the type used in the onion to refenernce the CLTV 13 | // value that should be used for the next hop's HTLC. 14 | LockTimeOnionType tlv.Type = 4 15 | 16 | // NextHopOnionType is the type used in the onion to reference the ID 17 | // of the next hop. 18 | NextHopOnionType tlv.Type = 6 19 | ) 20 | 21 | // NewAmtToFwdRecord creates a tlv.Record that encodes the amount_to_forward 22 | // (type 2) for an onion payload. 23 | func NewAmtToFwdRecord(amt *uint64) tlv.Record { 24 | return tlv.MakeDynamicRecord( 25 | AmtOnionType, amt, func() uint64 { 26 | return tlv.SizeTUint64(*amt) 27 | }, 28 | tlv.ETUint64, tlv.DTUint64, 29 | ) 30 | } 31 | 32 | // NewLockTimeRecord creates a tlv.Record that encodes the outgoing_cltv_value 33 | // (type 4) for an onion payload. 34 | func NewLockTimeRecord(lockTime *uint32) tlv.Record { 35 | return tlv.MakeDynamicRecord( 36 | LockTimeOnionType, lockTime, func() uint64 { 37 | return tlv.SizeTUint32(*lockTime) 38 | }, 39 | tlv.ETUint32, tlv.DTUint32, 40 | ) 41 | } 42 | 43 | // NewNextHopIDRecord creates a tlv.Record that encodes the short_channel_id 44 | // (type 6) for an onion payload. 45 | func NewNextHopIDRecord(cid *uint64) tlv.Record { 46 | return tlv.MakePrimitiveRecord(NextHopOnionType, cid) 47 | } 48 | -------------------------------------------------------------------------------- /routing/README.md: -------------------------------------------------------------------------------- 1 | routing 2 | ======= 3 | 4 | [![Build Status](http://img.shields.io/travis/lightningnetwork/lnd.svg)](https://travis-ci.org/lightningnetwork/lnd) 5 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lightningnetwork/lnd/blob/master/LICENSE) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/lightningnetwork/lnd/routing) 7 | 8 | The routing package implements authentication+validation of channel 9 | announcements, pruning of the channel graph, path finding within the network, 10 | sending outgoing payments into the network and synchronizing new peers to our 11 | channel graph state. 12 | 13 | ## Installation and Updating 14 | 15 | ```bash 16 | $ go get -u github.com/lightningnetwork/lnd/routing 17 | ``` 18 | -------------------------------------------------------------------------------- /routing/chainview/log.go: -------------------------------------------------------------------------------- 1 | package chainview 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("CRTR", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until either UseLogger or SetLogWriter are called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /routing/conf.go: -------------------------------------------------------------------------------- 1 | // +build !experimental 2 | 3 | package routing 4 | 5 | // Conf provides the command line routing configuration. There are no fields in 6 | // the production build so that this section is hidden by default. 7 | type Conf struct{} 8 | 9 | // UseAssumeChannelValid always returns false when not in experimental builds. 10 | func (c *Conf) UseAssumeChannelValid() bool { 11 | return false 12 | } 13 | -------------------------------------------------------------------------------- /routing/conf_experimental.go: -------------------------------------------------------------------------------- 1 | // +build experimental 2 | 3 | package routing 4 | 5 | // Conf exposes the experimental command line routing configurations. 6 | type Conf struct { 7 | AssumeChannelValid bool `long:"assumechanvalid" description:"Skip checking channel spentness during graph validation. (default: false)"` 8 | } 9 | 10 | // UseAssumeChannelValid returns true if the router should skip checking for 11 | // spentness when processing channel updates and announcements. 12 | func (c *Conf) UseAssumeChannelValid() bool { 13 | return c.AssumeChannelValid 14 | } 15 | -------------------------------------------------------------------------------- /routing/localchans/log.go: -------------------------------------------------------------------------------- 1 | package localchans 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | ) 6 | 7 | // log is a logger that is initialized with no output filters. This 8 | // means the package will not perform any logging by default until the caller 9 | // requests it. 10 | var log btclog.Logger 11 | 12 | // UseLogger uses a specified Logger to output package logging info. This 13 | // function is called from the parent package htlcswitch logger initialization. 14 | func UseLogger(logger btclog.Logger) { 15 | log = logger 16 | } 17 | -------------------------------------------------------------------------------- /routing/nodepair.go: -------------------------------------------------------------------------------- 1 | package routing 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/lightningnetwork/lnd/routing/route" 7 | ) 8 | 9 | // DirectedNodePair stores a directed pair of nodes. 10 | type DirectedNodePair struct { 11 | From, To route.Vertex 12 | } 13 | 14 | // NewDirectedNodePair instantiates a new DirectedNodePair struct. 15 | func NewDirectedNodePair(from, to route.Vertex) DirectedNodePair { 16 | return DirectedNodePair{ 17 | From: from, 18 | To: to, 19 | } 20 | } 21 | 22 | // String converts a node pair to its human readable representation. 23 | func (d DirectedNodePair) String() string { 24 | return fmt.Sprintf("%v -> %v", d.From, d.To) 25 | } 26 | 27 | // Reverse returns a reversed copy of the pair. 28 | func (d DirectedNodePair) Reverse() DirectedNodePair { 29 | return DirectedNodePair{From: d.To, To: d.From} 30 | } 31 | -------------------------------------------------------------------------------- /scripts/install_bitcoind.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ev 4 | 5 | export BITCOIND_VERSION=0.20.0 6 | 7 | if sudo cp ~/bitcoin/bitcoin-$BITCOIND_VERSION/bin/bitcoind /usr/local/bin/bitcoind 8 | then 9 | echo "found cached bitcoind" 10 | else 11 | mkdir -p ~/bitcoin && \ 12 | pushd ~/bitcoin && \ 13 | wget https://bitcoin.org/bin/bitcoin-core-$BITCOIND_VERSION/bitcoin-$BITCOIND_VERSION-x86_64-linux-gnu.tar.gz && \ 14 | tar xvfz bitcoin-$BITCOIND_VERSION-x86_64-linux-gnu.tar.gz && \ 15 | sudo cp ./bitcoin-$BITCOIND_VERSION/bin/bitcoind /usr/local/bin/bitcoind && \ 16 | popd 17 | fi 18 | 19 | -------------------------------------------------------------------------------- /shachain/producer_test.go: -------------------------------------------------------------------------------- 1 | package shachain 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/btcsuite/btcd/chaincfg/chainhash" 8 | ) 9 | 10 | // TestShaChainProducerRestore checks the ability of shachain producer to be 11 | // properly recreated from binary representation. 12 | func TestShaChainProducerRestore(t *testing.T) { 13 | t.Parallel() 14 | 15 | var err error 16 | 17 | seed := chainhash.DoubleHashH([]byte("shachaintest")) 18 | sender := NewRevocationProducer(seed) 19 | 20 | s1, err := sender.AtIndex(0) 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | 25 | var b bytes.Buffer 26 | if err := sender.Encode(&b); err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | sender, err = NewRevocationProducerFromBytes(b.Bytes()) 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | 35 | s3, err := sender.AtIndex(0) 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | 40 | if !s1.IsEqual(s3) { 41 | t.Fatalf("secrets should match: %v:%v", s1.String(), s3.String()) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /signal/log.go: -------------------------------------------------------------------------------- 1 | package signal 2 | 3 | import "github.com/btcsuite/btclog" 4 | 5 | // log is a logger that is initialized with no output filters. This 6 | // means the package will not perform any logging by default until the caller 7 | // requests it. 8 | var log btclog.Logger 9 | 10 | // The default amount of logging is none. 11 | func init() { 12 | DisableLog() 13 | } 14 | 15 | // DisableLog disables all library log output. Logging output is disabled 16 | // by default until UseLogger is called. 17 | func DisableLog() { 18 | UseLogger(btclog.Disabled) 19 | } 20 | 21 | // UseLogger uses a specified Logger to output package logging info. 22 | // This should be used in preference to SetLogWriter if the caller is also 23 | // using btclog. 24 | func UseLogger(logger btclog.Logger) { 25 | log = logger 26 | } 27 | -------------------------------------------------------------------------------- /sweep/bucket_list.go: -------------------------------------------------------------------------------- 1 | package sweep 2 | 3 | // bucket contains a set of inputs that are not mutually exclusive. 4 | type bucket pendingInputs 5 | 6 | // tryAdd tries to add a new input to this bucket. 7 | func (b bucket) tryAdd(input *pendingInput) bool { 8 | exclusiveGroup := input.params.ExclusiveGroup 9 | if exclusiveGroup != nil { 10 | for _, input := range b { 11 | existingGroup := input.params.ExclusiveGroup 12 | if existingGroup != nil && 13 | *existingGroup == *exclusiveGroup { 14 | 15 | return false 16 | } 17 | } 18 | } 19 | 20 | b[*input.OutPoint()] = input 21 | 22 | return true 23 | } 24 | 25 | // bucketList is a list of buckets that contain non-mutually exclusive inputs. 26 | type bucketList struct { 27 | buckets []bucket 28 | } 29 | 30 | // add adds a new input. If the input is not accepted by any of the existing 31 | // buckets, a new bucket will be created. 32 | func (b *bucketList) add(input *pendingInput) { 33 | for _, existingBucket := range b.buckets { 34 | if existingBucket.tryAdd(input) { 35 | return 36 | } 37 | } 38 | 39 | // Create a new bucket and add the input. It is not necessary to check 40 | // the return value of tryAdd because it will always succeed on an empty 41 | // bucket. 42 | newBucket := make(bucket) 43 | newBucket.tryAdd(input) 44 | b.buckets = append(b.buckets, newBucket) 45 | } 46 | -------------------------------------------------------------------------------- /sweep/defaults.go: -------------------------------------------------------------------------------- 1 | // +build !rpctest 2 | 3 | package sweep 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | var ( 10 | // DefaultBatchWindowDuration specifies duration of the sweep batch 11 | // window. The sweep is held back during the batch window to allow more 12 | // inputs to be added and thereby lower the fee per input. 13 | DefaultBatchWindowDuration = 30 * time.Second 14 | ) 15 | -------------------------------------------------------------------------------- /sweep/defaults_rpctest.go: -------------------------------------------------------------------------------- 1 | // +build rpctest 2 | 3 | package sweep 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | var ( 10 | // DefaultBatchWindowDuration specifies duration of the sweep batch 11 | // window. The sweep is held back during the batch window to allow more 12 | // inputs to be added and thereby lower the fee per input. 13 | // 14 | // To speed up integration tests waiting for a sweep to happen, the 15 | // batch window is shortened. 16 | DefaultBatchWindowDuration = 2 * time.Second 17 | ) 18 | -------------------------------------------------------------------------------- /sweep/interface.go: -------------------------------------------------------------------------------- 1 | package sweep 2 | 3 | import ( 4 | "github.com/btcsuite/btcd/wire" 5 | "github.com/lightningnetwork/lnd/lnwallet" 6 | ) 7 | 8 | // Wallet contains all wallet related functionality required by sweeper. 9 | type Wallet interface { 10 | // PublishTransaction performs cursory validation (dust checks, etc) and 11 | // broadcasts the passed transaction to the Bitcoin network. 12 | PublishTransaction(tx *wire.MsgTx, label string) error 13 | 14 | // ListUnspentWitness returns all unspent outputs which are version 0 15 | // witness programs. The 'minconfirms' and 'maxconfirms' parameters 16 | // indicate the minimum and maximum number of confirmations an output 17 | // needs in order to be returned by this method. 18 | ListUnspentWitness(minconfirms, maxconfirms int32) ([]*lnwallet.Utxo, 19 | error) 20 | 21 | // WithCoinSelectLock will execute the passed function closure in a 22 | // synchronized manner preventing any coin selection operations from 23 | // proceeding while the closure is executing. This can be seen as the 24 | // ability to execute a function closure under an exclusive coin 25 | // selection lock. 26 | WithCoinSelectLock(f func() error) error 27 | } 28 | -------------------------------------------------------------------------------- /sweep/log.go: -------------------------------------------------------------------------------- 1 | package sweep 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This means the 9 | // package will not perform any logging by default until the caller requests 10 | // it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("SWPR", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled by 19 | // default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. This 25 | // should be used in preference to SetLogWriter if the caller is also using 26 | // btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | 31 | // logClosure is used to provide a closure over expensive logging operations so 32 | // don't have to be performed when the logging level doesn't warrant it. 33 | type logClosure func() string 34 | 35 | // String invokes the underlying function and returns the result. 36 | func (c logClosure) String() string { 37 | return c() 38 | } 39 | 40 | // newLogClosure returns a new closure over a function that returns a string 41 | // which itself provides a Stringer interface so that it can be used with the 42 | // logging system. 43 | func newLogClosure(c func() string) logClosure { 44 | return logClosure(c) 45 | } 46 | -------------------------------------------------------------------------------- /ticker/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/lightningnetwork/lnd/ticker 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /tor/README.md: -------------------------------------------------------------------------------- 1 | tor 2 | === 3 | 4 | The tor package contains utility functions that allow for interacting with the 5 | Tor daemon. So far, supported functions include: 6 | 7 | * Routing all traffic over Tor's exposed SOCKS5 proxy. 8 | * Routing DNS queries over Tor (A, AAAA, SRV). 9 | * Limited Tor Control functionality (synchronous messages only). So far, this 10 | includes: 11 | * Support for SAFECOOKIE, HASHEDPASSWORD, and NULL authentication methods. 12 | * Creating v2 and v3 onion services. 13 | 14 | In the future, the Tor Control functionality will be extended to support v3 15 | onion services, asynchronous messages, etc. 16 | 17 | ## Installation and Updating 18 | 19 | ```bash 20 | $ go get -u github.com/lightningnetwork/lnd/tor 21 | ``` 22 | -------------------------------------------------------------------------------- /tor/controller_test.go: -------------------------------------------------------------------------------- 1 | package tor 2 | 3 | import "testing" 4 | 5 | // TestParseTorVersion is a series of tests for different version strings that 6 | // check the correctness of determining whether they support creating v3 onion 7 | // services through Tor control's port. 8 | func TestParseTorVersion(t *testing.T) { 9 | t.Parallel() 10 | 11 | tests := []struct { 12 | version string 13 | valid bool 14 | }{ 15 | { 16 | version: "0.3.3.6", 17 | valid: true, 18 | }, 19 | { 20 | version: "0.3.3.7", 21 | valid: true, 22 | }, 23 | { 24 | version: "0.3.4.6", 25 | valid: true, 26 | }, 27 | { 28 | version: "0.4.3.6", 29 | valid: true, 30 | }, 31 | { 32 | version: "0.4.0.5", 33 | valid: true, 34 | }, 35 | { 36 | version: "1.3.3.6", 37 | valid: true, 38 | }, 39 | { 40 | version: "0.3.3.6-rc", 41 | valid: true, 42 | }, 43 | { 44 | version: "0.3.3.7-rc", 45 | valid: true, 46 | }, 47 | { 48 | version: "0.3.3.5-rc", 49 | valid: false, 50 | }, 51 | { 52 | version: "0.3.3.5", 53 | valid: false, 54 | }, 55 | { 56 | version: "0.3.2.6", 57 | valid: false, 58 | }, 59 | { 60 | version: "0.1.3.6", 61 | valid: false, 62 | }, 63 | { 64 | version: "0.0.6.3", 65 | valid: false, 66 | }, 67 | } 68 | 69 | for i, test := range tests { 70 | err := supportsV3(test.version) 71 | if test.valid != (err == nil) { 72 | t.Fatalf("test %d with version string %v failed: %v", i, 73 | test.version, err) 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /watchtower/errors.go: -------------------------------------------------------------------------------- 1 | package watchtower 2 | 3 | import "errors" 4 | 5 | var ( 6 | // ErrNoListeners signals that no listening ports were provided, 7 | // rendering the tower unable to receive client requests. 8 | ErrNoListeners = errors.New("no listening ports were specified") 9 | 10 | // ErrNoNetwork signals that no tor.Net is provided in the Config, which 11 | // prevents resolution of listening addresses. 12 | ErrNoNetwork = errors.New("no network specified, must be tor or clearnet") 13 | ) 14 | -------------------------------------------------------------------------------- /watchtower/interface.go: -------------------------------------------------------------------------------- 1 | package watchtower 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/lightningnetwork/lnd/watchtower/lookout" 7 | "github.com/lightningnetwork/lnd/watchtower/wtserver" 8 | ) 9 | 10 | // DB abstracts the persistent functionality required to run the watchtower 11 | // daemon. It composes the database interfaces required by the lookout and 12 | // wtserver subsystems. 13 | type DB interface { 14 | lookout.DB 15 | wtserver.DB 16 | } 17 | 18 | // AddressNormalizer is a function signature that allows the tower to resolve 19 | // TCP addresses on clear or onion networks. 20 | type AddressNormalizer func(addrs []string, defaultPort string, 21 | resolver func(string, string) (*net.TCPAddr, error)) ([]net.Addr, error) 22 | -------------------------------------------------------------------------------- /watchtower/log.go: -------------------------------------------------------------------------------- 1 | package watchtower 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | "github.com/lightningnetwork/lnd/watchtower/lookout" 7 | "github.com/lightningnetwork/lnd/watchtower/wtserver" 8 | ) 9 | 10 | // log is a logger that is initialized with no output filters. This 11 | // means the package will not perform any logging by default until the caller 12 | // requests it. 13 | var log btclog.Logger 14 | 15 | // The default amount of logging is none. 16 | func init() { 17 | UseLogger(build.NewSubLogger("WTWR", nil)) 18 | } 19 | 20 | // DisableLog disables all library log output. Logging output is disabled 21 | // by default until UseLogger is called. 22 | func DisableLog() { 23 | UseLogger(btclog.Disabled) 24 | } 25 | 26 | // UseLogger uses a specified Logger to output package logging info. 27 | // This should be used in preference to SetLogWriter if the caller is also 28 | // using btclog. 29 | func UseLogger(logger btclog.Logger) { 30 | log = logger 31 | lookout.UseLogger(logger) 32 | wtserver.UseLogger(logger) 33 | } 34 | -------------------------------------------------------------------------------- /watchtower/lookout/log.go: -------------------------------------------------------------------------------- 1 | package lookout 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("WTWR", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /watchtower/lookout/mock.go: -------------------------------------------------------------------------------- 1 | // +build dev 2 | 3 | package lookout 4 | 5 | import ( 6 | "fmt" 7 | "sync" 8 | 9 | "github.com/btcsuite/btcd/chaincfg/chainhash" 10 | "github.com/btcsuite/btcd/wire" 11 | "github.com/lightningnetwork/lnd/chainntnfs" 12 | ) 13 | 14 | type MockBackend struct { 15 | mu sync.RWMutex 16 | 17 | blocks chan *chainntnfs.BlockEpoch 18 | epochs map[chainhash.Hash]*wire.MsgBlock 19 | quit chan struct{} 20 | } 21 | 22 | func NewMockBackend() *MockBackend { 23 | return &MockBackend{ 24 | blocks: make(chan *chainntnfs.BlockEpoch), 25 | epochs: make(map[chainhash.Hash]*wire.MsgBlock), 26 | quit: make(chan struct{}), 27 | } 28 | } 29 | 30 | func (m *MockBackend) RegisterBlockEpochNtfn(*chainntnfs.BlockEpoch) ( 31 | *chainntnfs.BlockEpochEvent, error) { 32 | 33 | return &chainntnfs.BlockEpochEvent{ 34 | Epochs: m.blocks, 35 | }, nil 36 | } 37 | 38 | func (m *MockBackend) GetBlock(hash *chainhash.Hash) (*wire.MsgBlock, error) { 39 | m.mu.RLock() 40 | defer m.mu.RUnlock() 41 | 42 | block, ok := m.epochs[*hash] 43 | if !ok { 44 | return nil, fmt.Errorf("unknown block for hash %x", hash) 45 | } 46 | 47 | return block, nil 48 | } 49 | 50 | func (m *MockBackend) ConnectEpoch(epoch *chainntnfs.BlockEpoch, 51 | block *wire.MsgBlock) { 52 | 53 | m.mu.Lock() 54 | m.epochs[*epoch.Hash] = block 55 | m.mu.Unlock() 56 | 57 | select { 58 | case m.blocks <- epoch: 59 | case <-m.quit: 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /watchtower/wtclient/errors.go: -------------------------------------------------------------------------------- 1 | package wtclient 2 | 3 | import "errors" 4 | 5 | var ( 6 | // ErrClientExiting signals that the watchtower client is shutting down. 7 | ErrClientExiting = errors.New("watchtower client shutting down") 8 | 9 | // ErrTowerCandidatesExhausted signals that a TowerCandidateIterator has 10 | // cycled through all available candidates. 11 | ErrTowerCandidatesExhausted = errors.New("exhausted all tower " + 12 | "candidates") 13 | 14 | // ErrPermanentTowerFailure signals that the tower has reported that it 15 | // has permanently failed or the client believes this has happened based 16 | // on the tower's behavior. 17 | ErrPermanentTowerFailure = errors.New("permanent tower failure") 18 | 19 | // ErrNegotiatorExiting signals that the SessionNegotiator is shutting 20 | // down. 21 | ErrNegotiatorExiting = errors.New("negotiator exiting") 22 | 23 | // ErrNoTowerAddrs signals that the client could not be created because 24 | // we have no addresses with which we can reach a tower. 25 | ErrNoTowerAddrs = errors.New("no tower addresses") 26 | 27 | // ErrFailedNegotiation signals that the session negotiator could not 28 | // acquire a new session as requested. 29 | ErrFailedNegotiation = errors.New("session negotiation unsuccessful") 30 | 31 | // ErrUnregisteredChannel signals that the client was unable to backup a 32 | // revoked state because the channel had not been previously registered 33 | // with the client. 34 | ErrUnregisteredChannel = errors.New("channel is not registered") 35 | ) 36 | -------------------------------------------------------------------------------- /watchtower/wtclient/log.go: -------------------------------------------------------------------------------- 1 | package wtclient 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("WTCL", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /watchtower/wtdb/client_chan_summary.go: -------------------------------------------------------------------------------- 1 | package wtdb 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/lightningnetwork/lnd/lnwire" 7 | ) 8 | 9 | // ChannelSummaries is a map for a given channel id to it's ClientChanSummary. 10 | type ChannelSummaries map[lnwire.ChannelID]ClientChanSummary 11 | 12 | // ClientChanSummary tracks channel-specific information. A new 13 | // ClientChanSummary is inserted in the database the first time the client 14 | // encounters a particular channel. 15 | type ClientChanSummary struct { 16 | // SweepPkScript is the pkscript to which all justice transactions will 17 | // deposit recovered funds for this particular channel. 18 | SweepPkScript []byte 19 | 20 | // TODO(conner): later extend with info about initial commit height, 21 | // ineligible states, etc. 22 | } 23 | 24 | // Encode writes the ClientChanSummary to the passed io.Writer. 25 | func (s *ClientChanSummary) Encode(w io.Writer) error { 26 | return WriteElement(w, s.SweepPkScript) 27 | } 28 | 29 | // Decode reads a ClientChanSummary form the passed io.Reader. 30 | func (s *ClientChanSummary) Decode(r io.Reader) error { 31 | return ReadElement(r, &s.SweepPkScript) 32 | } 33 | -------------------------------------------------------------------------------- /watchtower/wtdb/log.go: -------------------------------------------------------------------------------- 1 | package wtdb 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("WTDB", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | 31 | // logClosure is used to provide a closure over expensive logging operations so 32 | // don't have to be performed when the logging level doesn't warrant it. 33 | type logClosure func() string // nolint:unused 34 | 35 | // String invokes the underlying function and returns the result. 36 | func (c logClosure) String() string { 37 | return c() 38 | } 39 | 40 | // newLogClosure returns a new closure over a function that returns a string 41 | // which itself provides a Stringer interface so that it can be used with the 42 | // logging system. 43 | func newLogClosure(c func() string) logClosure { // nolint:unused 44 | return logClosure(c) 45 | } 46 | -------------------------------------------------------------------------------- /watchtower/wtdb/session_id.go: -------------------------------------------------------------------------------- 1 | package wtdb 2 | 3 | import ( 4 | "encoding/hex" 5 | 6 | "github.com/btcsuite/btcd/btcec" 7 | ) 8 | 9 | // SessionIDSize is 33-bytes; it is a serialized, compressed public key. 10 | const SessionIDSize = 33 11 | 12 | // SessionID is created from the remote public key of a client, and serves as a 13 | // unique identifier and authentication for sending state updates. 14 | type SessionID [SessionIDSize]byte 15 | 16 | // NewSessionIDFromPubKey creates a new SessionID from a public key. 17 | func NewSessionIDFromPubKey(pubKey *btcec.PublicKey) SessionID { 18 | var sid SessionID 19 | copy(sid[:], pubKey.SerializeCompressed()) 20 | return sid 21 | } 22 | 23 | // String returns a hex encoding of the session id. 24 | func (s SessionID) String() string { 25 | return hex.EncodeToString(s[:]) 26 | } 27 | -------------------------------------------------------------------------------- /watchtower/wtdb/session_state_update.go: -------------------------------------------------------------------------------- 1 | package wtdb 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/lightningnetwork/lnd/watchtower/blob" 7 | ) 8 | 9 | // SessionStateUpdate holds a state update sent by a client along with its 10 | // SessionID. 11 | type SessionStateUpdate struct { 12 | // ID the session id of the client who sent the state update. 13 | ID SessionID 14 | 15 | // SeqNum the sequence number of the update within the session. 16 | SeqNum uint16 17 | 18 | // LastApplied the highest index that client has acknowledged is 19 | // committed 20 | LastApplied uint16 21 | 22 | // Hint is the 16-byte prefix of the revoked commitment transaction. 23 | Hint blob.BreachHint 24 | 25 | // EncryptedBlob is a ciphertext containing the sweep information for 26 | // exacting justice if the commitment transaction matching the breach 27 | // hint is broadcast. 28 | EncryptedBlob []byte 29 | } 30 | 31 | // Encode serializes the state update into the provided io.Writer. 32 | func (u *SessionStateUpdate) Encode(w io.Writer) error { 33 | return WriteElements(w, 34 | u.ID, 35 | u.SeqNum, 36 | u.LastApplied, 37 | u.Hint, 38 | u.EncryptedBlob, 39 | ) 40 | } 41 | 42 | // Decode deserializes the target state update from the provided io.Reader. 43 | func (u *SessionStateUpdate) Decode(r io.Reader) error { 44 | return ReadElements(r, 45 | &u.ID, 46 | &u.SeqNum, 47 | &u.LastApplied, 48 | &u.Hint, 49 | &u.EncryptedBlob, 50 | ) 51 | } 52 | -------------------------------------------------------------------------------- /watchtower/wtserver/log.go: -------------------------------------------------------------------------------- 1 | package wtserver 2 | 3 | import ( 4 | "github.com/btcsuite/btclog" 5 | "github.com/lightningnetwork/lnd/build" 6 | ) 7 | 8 | // log is a logger that is initialized with no output filters. This 9 | // means the package will not perform any logging by default until the caller 10 | // requests it. 11 | var log btclog.Logger 12 | 13 | // The default amount of logging is none. 14 | func init() { 15 | UseLogger(build.NewSubLogger("WTWR", nil)) 16 | } 17 | 18 | // DisableLog disables all library log output. Logging output is disabled 19 | // by default until UseLogger is called. 20 | func DisableLog() { 21 | UseLogger(btclog.Disabled) 22 | } 23 | 24 | // UseLogger uses a specified Logger to output package logging info. 25 | // This should be used in preference to SetLogWriter if the caller is also 26 | // using btclog. 27 | func UseLogger(logger btclog.Logger) { 28 | log = logger 29 | } 30 | -------------------------------------------------------------------------------- /watchtower/wtwire/features.go: -------------------------------------------------------------------------------- 1 | package wtwire 2 | 3 | import "github.com/lightningnetwork/lnd/lnwire" 4 | 5 | // FeatureNames holds a mapping from each feature bit understood by this 6 | // implementation to its common name. 7 | var FeatureNames = map[lnwire.FeatureBit]string{ 8 | AltruistSessionsRequired: "altruist-sessions", 9 | AltruistSessionsOptional: "altruist-sessions", 10 | } 11 | 12 | const ( 13 | // AltruistSessionsRequired specifies that the advertising node requires 14 | // the remote party to understand the protocol for creating and updating 15 | // watchtower sessions. 16 | AltruistSessionsRequired lnwire.FeatureBit = 0 17 | 18 | // AltruistSessionsOptional specifies that the advertising node can 19 | // support a remote party who understand the protocol for creating and 20 | // updating watchtower sessions. 21 | AltruistSessionsOptional lnwire.FeatureBit = 1 22 | ) 23 | -------------------------------------------------------------------------------- /watchtower/wtwire/summary.go: -------------------------------------------------------------------------------- 1 | package wtwire 2 | 3 | import "fmt" 4 | 5 | // MessageSummary creates a human-readable description of a given Message. If 6 | // the type is unknown, an empty string is returned. 7 | func MessageSummary(msg Message) string { 8 | switch msg := msg.(type) { 9 | case *Init: 10 | return "" 11 | 12 | case *CreateSession: 13 | return fmt.Sprintf("blob_type=%s, max_updates=%d "+ 14 | "reward_base=%d reward_rate=%d sweep_fee_rate=%d", 15 | msg.BlobType, msg.MaxUpdates, msg.RewardBase, 16 | msg.RewardRate, msg.SweepFeeRate) 17 | 18 | case *CreateSessionReply: 19 | return fmt.Sprintf("code=%d", msg.Code) 20 | 21 | case *StateUpdate: 22 | return fmt.Sprintf("seqnum=%d last_applied=%d is_complete=%d "+ 23 | "hint=%x", msg.SeqNum, msg.LastApplied, msg.IsComplete, 24 | msg.Hint) 25 | 26 | case *StateUpdateReply: 27 | return fmt.Sprintf("code=%d last_applied=%d", msg.Code, 28 | msg.LastApplied) 29 | 30 | case *Error: 31 | return fmt.Sprintf("code=%d", msg.Code) 32 | 33 | default: 34 | return "" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /zpay32/README.md: -------------------------------------------------------------------------------- 1 | zpay32 2 | ======= 3 | 4 | [![Build Status](http://img.shields.io/travis/lightningnetwork/lnd.svg)](https://travis-ci.org/lightningnetwork/lnd) 5 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/lightningnetwork/lnd/blob/master/LICENSE) 6 | [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/lightningnetwork/lnd/zpay32) 7 | 8 | The zpay32 package implements a basic scheme for the encoding of payment 9 | requests between two `lnd` nodes within the Lightning Network. The zpay32 10 | encoding scheme uses the 11 | [zbase32](https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt) 12 | scheme along with a checksum to encode a serialized payment request. 13 | 14 | The payment request serialized by the package consist of: the destination's 15 | public key, the payment hash to use for the payment, and the value of payment 16 | to send. 17 | 18 | ## Installation and Updating 19 | 20 | ```bash 21 | $ go get -u github.com/lightningnetwork/lnd/zpay32 22 | ``` 23 | --------------------------------------------------------------------------------