-
Notifications
You must be signed in to change notification settings - Fork 0
Wait for all channels to be usable before payout #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,12 @@ use tokio::runtime::Runtime; | |
| #[macro_use] | ||
| extern crate napi_derive; | ||
|
|
||
| /// Polling interval for event loops and state checks. | ||
| const POLL_INTERVAL: Duration = Duration::from_millis(10); | ||
|
|
||
| /// Max time to wait for channels to become usable after sync. | ||
| const CHANNEL_USABLE_TIMEOUT: Duration = Duration::from_secs(10); | ||
|
|
||
| static GLOBAL_LOGGER: OnceLock<Arc<JsLogger>> = OnceLock::new(); | ||
|
|
||
| fn logger_instance() -> &'static Arc<JsLogger> { | ||
|
|
@@ -566,7 +572,7 @@ impl MdkNode { | |
| last_event_time = now; | ||
| } | ||
|
|
||
| std::thread::sleep(std::time::Duration::from_millis(10)); | ||
| std::thread::sleep(POLL_INTERVAL); | ||
| } | ||
|
|
||
| if let Err(err) = self.node.stop() { | ||
|
|
@@ -753,7 +759,7 @@ impl MdkNode { | |
| return Ok(()); | ||
| } | ||
|
|
||
| std::thread::sleep(Duration::from_millis(50)); | ||
| std::thread::sleep(POLL_INTERVAL); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -830,13 +836,8 @@ impl MdkNode { | |
| panic!("failed to sync wallets: {err}"); | ||
| } | ||
|
|
||
| let available_balance_msat: u64 = self | ||
| .node | ||
| .list_channels() | ||
| .into_iter() | ||
| .filter(|channel| channel.is_channel_ready) | ||
| .map(|channel| channel.outbound_capacity_msat) | ||
| .sum(); | ||
| wait_for_usable_channels(&self.node); | ||
| let available_balance_msat = usable_outbound_capacity_msat(&self.node); | ||
| eprintln!("[lightning-js] pay_lnurl available_balance_msat={available_balance_msat}"); | ||
|
|
||
| if available_balance_msat == 0 { | ||
|
|
@@ -927,13 +928,9 @@ impl MdkNode { | |
| ) | ||
| })?; | ||
|
|
||
| let available_balance_msat: u64 = self | ||
| .node | ||
| .list_channels() | ||
| .into_iter() | ||
| .filter(|channel| channel.is_channel_ready) | ||
| .map(|channel| channel.outbound_capacity_msat) | ||
| .sum(); | ||
| wait_for_usable_channels(&self.node); | ||
| let available_balance_msat = usable_outbound_capacity_msat(&self.node); | ||
| eprintln!("[lightning-js] pay_bolt11 available_balance_msat={available_balance_msat}"); | ||
|
|
||
| if available_balance_msat == 0 { | ||
| if let Err(err) = self.node.stop() { | ||
|
|
@@ -1063,20 +1060,11 @@ impl MdkNode { | |
| } | ||
| eprintln!("[lightning-js] pay_bolt12_offer wallet sync complete"); | ||
|
|
||
| let channels = self.node.list_channels(); | ||
| let ready_channels: Vec<_> = channels | ||
| .iter() | ||
| .filter(|channel| channel.is_channel_ready) | ||
| .collect(); | ||
| let available_balance_msat: u64 = ready_channels | ||
| .iter() | ||
| .map(|channel| channel.outbound_capacity_msat) | ||
| .sum(); | ||
| wait_for_usable_channels(&self.node); | ||
| let available_balance_msat = usable_outbound_capacity_msat(&self.node); | ||
|
|
||
| eprintln!( | ||
| "[lightning-js] pay_bolt12_offer channels: total={} ready={} available_balance_msat={}", | ||
| channels.len(), | ||
| ready_channels.len(), | ||
| "[lightning-js] pay_bolt12_offer available_balance_msat={}", | ||
| available_balance_msat | ||
| ); | ||
|
|
||
|
|
@@ -1186,6 +1174,45 @@ impl MdkNode { | |
| } | ||
| } | ||
|
|
||
| /// Wait for all channels to become usable after node startup/sync. | ||
| fn wait_for_usable_channels(node: &Node) { | ||
| let start = Instant::now(); | ||
|
|
||
| loop { | ||
| let channels = node.list_channels(); | ||
| let total = channels.len(); | ||
| let usable = channels.iter().filter(|c| c.is_usable).count(); | ||
|
|
||
| if total > 0 && usable == total { | ||
|
Comment on lines
+1181
to
+1186
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The new wait loop only returns early when Useful? React with 👍 / 👎.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is by design as explained in the description. Dealing with channel closures is a problem for another time |
||
| eprintln!( | ||
| "[lightning-js] All channels usable ({usable}/{total}) after {}ms", | ||
| start.elapsed().as_millis() | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| if start.elapsed() >= CHANNEL_USABLE_TIMEOUT { | ||
| eprintln!( | ||
| "[lightning-js] Timeout: {usable}/{total} channels usable after {}s", | ||
| CHANNEL_USABLE_TIMEOUT.as_secs() | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| std::thread::sleep(POLL_INTERVAL); | ||
| } | ||
| } | ||
|
|
||
| /// Compute total outbound capacity across all usable channels. | ||
| fn usable_outbound_capacity_msat(node: &Node) -> u64 { | ||
| node | ||
| .list_channels() | ||
| .iter() | ||
| .filter(|c| c.is_usable) | ||
| .map(|c| c.outbound_capacity_msat) | ||
| .sum() | ||
| } | ||
|
|
||
| fn scid_from_human_readable_string(human_readable_scid: &str) -> Result<u64, ()> { | ||
| let mut parts = human_readable_scid.split('x'); | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just had a thought. Tuning these in mdk-checkout is probably easier than doing it here. Should consider passing these in from the consuming library