source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
-[[package]]
-name = "futures"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
-
-[[package]]
-name = "futures-executor"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
-
-[[package]]
-name = "futures-macro"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
-
-[[package]]
-name = "futures-task"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
-
-[[package]]
-name = "futures-util"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project-lite",
- "pin-utils",
- "slab",
-]
-
[[package]]
name = "hermit-abi"
version = "0.2.6"
"bitcoin",
"bitcoin-bech32",
"chrono",
- "futures",
"hex",
"libc",
"lightning",
[[package]]
name = "lightning"
-version = "0.0.114"
+version = "0.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "800ec68a160529ba3ca12c5db629867c4a8de2df272792c1246602966a5b789b"
+checksum = "e009e1c0c21f66378b491bb40f548682138c63e09db6f3a05af59f8804bb9f4a"
dependencies = [
"bitcoin",
]
[[package]]
name = "lightning-background-processor"
-version = "0.0.114"
+version = "0.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7af76b912df8827d9e6bde2fadbbb7b1e2d04f7da92009d244394bd2faa37380"
+checksum = "721b05b9848a09d5b943915449b5ffb31e24708007763640cf9d79b124a17e19"
dependencies = [
"bitcoin",
"lightning",
[[package]]
name = "lightning-block-sync"
-version = "0.0.114"
+version = "0.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71a6fcb6ffc245cf0aee4a4654145a2a7e670be2d879c14b8ed456cdc4235255"
+checksum = "7c60cf241b3c219ee865aad91eab85a879b23c1756a335a5a311790ad6c1c3d2"
dependencies = [
"bitcoin",
"chunked_transfer",
- "futures-util",
"lightning",
- "serde",
"serde_json",
]
[[package]]
name = "lightning-invoice"
-version = "0.22.0"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adfb59c6d13e130aece30fc72a7c17d74b201aed0ffb201b740f36e07aaece32"
+checksum = "c4e44b0e2822c8811470137d2339fdfe67a699b3248bb1606d1d02eb6a1e9f0a"
dependencies = [
"bech32 0.9.1",
+ "bitcoin",
"bitcoin_hashes",
"lightning",
"num-traits",
[[package]]
name = "lightning-net-tokio"
-version = "0.0.114"
+version = "0.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19197703db1195ed908ccd84cd76baaa5916e0d22750a2e1b7188f66516812bd"
+checksum = "4561ec5d4df2dd410a8b80955791fcfb007ef9210395db6e914b9527397b868c"
dependencies = [
"bitcoin",
"lightning",
[[package]]
name = "lightning-persister"
-version = "0.0.114"
+version = "0.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fce2d2ebf01ec7c9f4fad02846207999118a4ec3992c06d6eab93df7a862066c"
+checksum = "c52ed57ec33fb945f464b7e91b5df49f49fec649e1b44909f3ce517e96b0449a"
dependencies = [
"bitcoin",
"libc",
[[package]]
name = "lightning-rapid-gossip-sync"
-version = "0.0.114"
+version = "0.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6073e6cac4019f39e0bb02d3c92ebbb22950a46a663059b3b0e19f7928e00edb"
+checksum = "dd84d74a9b3892db22a60ac11dfc12e76b257b3174db6743e818ecc24834f3be"
dependencies = [
"bitcoin",
"lightning",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
[[package]]
name = "proc-macro2"
version = "1.0.49"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.152"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
[[package]]
name = "serde_json"
"serde",
]
-[[package]]
-name = "slab"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
-dependencies = [
- "autocfg",
-]
-
[[package]]
name = "syn"
version = "1.0.107"
use lightning::chain::keysinterface::{EntropySource, InMemorySigner, KeysManager};
use lightning::chain::{chainmonitor, ChannelMonitorUpdateStatus};
use lightning::chain::{Filter, Watch};
+use lightning::events::{Event, PaymentFailureReason, PaymentPurpose};
use lightning::ln::channelmanager;
use lightning::ln::channelmanager::{
ChainParameters, ChannelManagerReadArgs, SimpleArcChannelManager,
use lightning::routing::gossip::{NodeId, P2PGossipSync};
use lightning::routing::router::DefaultRouter;
use lightning::util::config::UserConfig;
-use lightning::util::events::{Event, PaymentPurpose};
use lightning::util::ser::ReadableArgs;
-use lightning_background_processor::{BackgroundProcessor, GossipSync};
+use lightning_background_processor::{process_events_async, GossipSync};
use lightning_block_sync::init;
use lightning_block_sync::poll;
use lightning_block_sync::SpvClient;
channel_manager: &Arc<ChannelManager>, bitcoind_client: &BitcoindClient,
network_graph: &NetworkGraph, keys_manager: &KeysManager,
inbound_payments: &PaymentInfoStorage, outbound_payments: &PaymentInfoStorage,
- network: Network, event: &Event,
+ network: Network, event: Event,
) {
match event {
Event::FundingGenerationReady {
.expect("Lightning funding tx should always be to a SegWit output")
.to_address();
let mut outputs = vec![HashMap::with_capacity(1)];
- outputs[0].insert(addr, *channel_value_satoshis as f64 / 100_000_000.0);
+ outputs[0].insert(addr, channel_value_satoshis as f64 / 100_000_000.0);
let raw_tx = bitcoind_client.create_raw_transaction(outputs).await;
// Have your wallet put the inputs into the transaction such that the output is
if channel_manager
.funding_transaction_generated(
&temporary_channel_id,
- counterparty_node_id,
+ &counterparty_node_id,
final_tx,
)
.is_err()
receiver_node_id: _,
via_channel_id: _,
via_user_channel_id: _,
+ claim_deadline: _,
+ onion_fields: _,
} => {
println!(
"\nEVENT: received payment from payment hash {} of {} millisatoshis",
print!("> ");
io::stdout().flush().unwrap();
let payment_preimage = match purpose {
- PaymentPurpose::InvoicePayment { payment_preimage, .. } => *payment_preimage,
- PaymentPurpose::SpontaneousPayment(preimage) => Some(*preimage),
+ PaymentPurpose::InvoicePayment { payment_preimage, .. } => payment_preimage,
+ PaymentPurpose::SpontaneousPayment(preimage) => Some(preimage),
};
channel_manager.claim_funds(payment_preimage.unwrap());
}
io::stdout().flush().unwrap();
let (payment_preimage, payment_secret) = match purpose {
PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
- (*payment_preimage, Some(*payment_secret))
+ (payment_preimage, Some(payment_secret))
}
- PaymentPurpose::SpontaneousPayment(preimage) => (Some(*preimage), None),
+ PaymentPurpose::SpontaneousPayment(preimage) => (Some(preimage), None),
};
let mut payments = inbound_payments.lock().unwrap();
- match payments.entry(*payment_hash) {
+ match payments.entry(payment_hash) {
Entry::Occupied(mut e) => {
let payment = e.get_mut();
payment.status = HTLCStatus::Succeeded;
preimage: payment_preimage,
secret: payment_secret,
status: HTLCStatus::Succeeded,
- amt_msat: MillisatAmount(Some(*amount_msat)),
+ amt_msat: MillisatAmount(Some(amount_msat)),
});
}
}
Event::PaymentSent { payment_preimage, payment_hash, fee_paid_msat, .. } => {
let mut payments = outbound_payments.lock().unwrap();
for (hash, payment) in payments.iter_mut() {
- if *hash == *payment_hash {
- payment.preimage = Some(*payment_preimage);
+ if *hash == payment_hash {
+ payment.preimage = Some(payment_preimage);
payment.status = HTLCStatus::Succeeded;
println!(
"\nEVENT: successfully sent payment of {} millisatoshis{} from \
Event::PaymentPathFailed { .. } => {}
Event::ProbeSuccessful { .. } => {}
Event::ProbeFailed { .. } => {}
- Event::PaymentFailed { payment_hash, .. } => {
+ Event::PaymentFailed { payment_hash, reason, .. } => {
print!(
- "\nEVENT: Failed to send payment to payment hash {:?}: exhausted payment retry attempts",
- hex_utils::hex_str(&payment_hash.0)
+ "\nEVENT: Failed to send payment to payment hash {:?}: {:?}",
+ hex_utils::hex_str(&payment_hash.0),
+ if let Some(r) = reason { r } else { PaymentFailureReason::RetriesExhausted }
);
print!("> ");
io::stdout().flush().unwrap();
next_channel_id,
fee_earned_msat,
claim_from_onchain_tx,
+ outbound_amount_forwarded_msat,
} => {
let read_only_network_graph = network_graph.read_only();
let nodes = read_only_network_graph.nodes();
.unwrap_or_default()
};
let from_prev_str =
- format!(" from {}{}", node_str(prev_channel_id), channel_str(prev_channel_id));
+ format!(" from {}{}", node_str(&prev_channel_id), channel_str(&prev_channel_id));
let to_next_str =
- format!(" to {}{}", node_str(next_channel_id), channel_str(next_channel_id));
+ format!(" to {}{}", node_str(&next_channel_id), channel_str(&next_channel_id));
- let from_onchain_str = if *claim_from_onchain_tx {
+ let from_onchain_str = if claim_from_onchain_tx {
"from onchain downstream claim"
} else {
"from HTLC fulfill message"
};
+ let amt_args = if let Some(v) = outbound_amount_forwarded_msat {
+ format!("{}", v)
+ } else {
+ "?".to_string()
+ };
if let Some(fee_earned) = fee_earned_msat {
println!(
- "\nEVENT: Forwarded payment{}{}, earning {} msat {}",
- from_prev_str, to_next_str, fee_earned, from_onchain_str
+ "\nEVENT: Forwarded payment for {} msat{}{}, earning {} msat {}",
+ amt_args, from_prev_str, to_next_str, fee_earned, from_onchain_str
);
} else {
println!(
- "\nEVENT: Forwarded payment{}{}, claiming onchain {}",
- from_prev_str, to_next_str, from_onchain_str
+ "\nEVENT: Forwarded payment for {} msat{}{}, claiming onchain {}",
+ amt_args, from_prev_str, to_next_str, from_onchain_str
);
}
print!("> ");
.unwrap();
bitcoind_client.broadcast_transaction(&spending_tx);
}
+ Event::ChannelPending { channel_id, counterparty_node_id, .. } => {
+ println!(
+ "\nEVENT: Channel {} with peer {} is pending awaiting funding lock-in!",
+ hex_utils::hex_str(&channel_id),
+ hex_utils::hex_str(&counterparty_node_id.serialize()),
+ );
+ print!("> ");
+ io::stdout().flush().unwrap();
+ }
Event::ChannelReady {
ref channel_id,
user_channel_id: _,
Event::ChannelClosed { channel_id, reason, user_channel_id: _ } => {
println!(
"\nEVENT: Channel {} closed due to: {:?}",
- hex_utils::hex_str(channel_id),
+ hex_utils::hex_str(&channel_id),
reason
);
print!("> ");
}
});
- // Step 18: Handle LDK Events
- let channel_manager_event_listener = channel_manager.clone();
- let keys_manager_listener = keys_manager.clone();
// TODO: persist payment info to disk
let inbound_payments: PaymentInfoStorage = Arc::new(Mutex::new(HashMap::new()));
let outbound_payments: PaymentInfoStorage = Arc::new(Mutex::new(HashMap::new()));
- let inbound_pmts_for_events = inbound_payments.clone();
- let outbound_pmts_for_events = outbound_payments.clone();
+
+ // Step 18: Handle LDK Events
+ let channel_manager_event_listener = Arc::clone(&channel_manager);
+ let bitcoind_client_event_listener = Arc::clone(&bitcoind_client);
+ let network_graph_event_listener = Arc::clone(&network_graph);
+ let keys_manager_event_listener = Arc::clone(&keys_manager);
+ let inbound_payments_event_listener = Arc::clone(&inbound_payments);
+ let outbound_payments_event_listener = Arc::clone(&outbound_payments);
let network = args.network;
- let bitcoind_rpc = bitcoind_client.clone();
- let network_graph_events = network_graph.clone();
- let handle = tokio::runtime::Handle::current();
let event_handler = move |event: Event| {
- handle.block_on(handle_ldk_events(
- &channel_manager_event_listener,
- &bitcoind_rpc,
- &network_graph_events,
- &keys_manager_listener,
- &inbound_pmts_for_events,
- &outbound_pmts_for_events,
- network,
- &event,
- ));
+ let channel_manager_event_listener = Arc::clone(&channel_manager_event_listener);
+ let bitcoind_client_event_listener = Arc::clone(&bitcoind_client_event_listener);
+ let network_graph_event_listener = Arc::clone(&network_graph_event_listener);
+ let keys_manager_event_listener = Arc::clone(&keys_manager_event_listener);
+ let inbound_payments_event_listener = Arc::clone(&inbound_payments_event_listener);
+ let outbound_payments_event_listener = Arc::clone(&outbound_payments_event_listener);
+ async move {
+ handle_ldk_events(
+ &channel_manager_event_listener,
+ &bitcoind_client_event_listener,
+ &network_graph_event_listener,
+ &keys_manager_event_listener,
+ &inbound_payments_event_listener,
+ &outbound_payments_event_listener,
+ network,
+ event,
+ )
+ .await;
+ }
};
// Step 19: Persist ChannelManager and NetworkGraph
let persister = Arc::new(FilesystemPersister::new(ldk_data_dir.clone()));
// Step 20: Background Processing
- let background_processor = BackgroundProcessor::start(
+ let (bp_exit, bp_exit_check) = tokio::sync::watch::channel(());
+ let background_processor = tokio::spawn(process_events_async(
persister,
event_handler,
chain_monitor.clone(),
peer_manager.clone(),
logger.clone(),
Some(scorer.clone()),
- );
+ move |t| {
+ let mut bp_exit_fut_check = bp_exit_check.clone();
+ Box::pin(async move {
+ tokio::select! {
+ _ = tokio::time::sleep(t) => false,
+ _ = bp_exit_fut_check.changed() => true,
+ }
+ })
+ },
+ false,
+ ));
// Regularly reconnect to channel peers.
let connect_cm = Arc::clone(&channel_manager);
peer_manager.disconnect_all_peers();
// Stop the background processor.
- background_processor.stop().unwrap();
+ bp_exit.send(()).unwrap();
+ background_processor.await.unwrap().unwrap();
}
#[tokio::main]