-
Notifications
You must be signed in to change notification settings - Fork 113
Support client_trusts_lsp=true on ldk-node #687
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
base: main
Are you sure you want to change the base?
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 |
|---|---|---|
|
|
@@ -14,12 +14,14 @@ use std::time::Duration; | |
|
|
||
| use bitcoin::hashes::{sha256, Hash}; | ||
| use bitcoin::secp256k1::{PublicKey, Secp256k1}; | ||
| use bitcoin::Transaction; | ||
| use chrono::Utc; | ||
| use lightning::events::HTLCHandlingFailureType; | ||
| use lightning::ln::channelmanager::{InterceptId, MIN_FINAL_CLTV_EXPIRY_DELTA}; | ||
| use lightning::ln::msgs::SocketAddress; | ||
| use lightning::ln::types::ChannelId; | ||
| use lightning::routing::router::{RouteHint, RouteHintHop}; | ||
| use lightning::util::errors::APIError; | ||
| use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, InvoiceBuilder, RoutingFees}; | ||
| use lightning_liquidity::events::LiquidityEvent; | ||
| use lightning_liquidity::lsps0::ser::{LSPSDateTime, LSPSRequestId}; | ||
|
|
@@ -51,7 +53,6 @@ use crate::{total_anchor_channels_reserve_sats, Config, Error}; | |
| const LIQUIDITY_REQUEST_TIMEOUT_SECS: u64 = 5; | ||
|
|
||
| const LSPS2_GETINFO_REQUEST_EXPIRY: Duration = Duration::from_secs(60 * 60 * 24); | ||
| const LSPS2_CLIENT_TRUSTS_LSP_MODE: bool = true; | ||
| const LSPS2_CHANNEL_CLTV_EXPIRY_DELTA: u32 = 72; | ||
|
|
||
| struct LSPS1Client { | ||
|
|
@@ -130,6 +131,8 @@ pub struct LSPS2ServiceConfig { | |
| pub min_payment_size_msat: u64, | ||
| /// The maximum payment size that we will accept when opening a channel. | ||
| pub max_payment_size_msat: u64, | ||
| /// Use the client trusts lsp model | ||
| pub client_trusts_lsp: bool, | ||
| } | ||
|
|
||
| pub(crate) struct LiquiditySourceBuilder<L: Deref> | ||
|
|
@@ -147,6 +150,7 @@ where | |
| kv_store: Arc<DynStore>, | ||
| config: Arc<Config>, | ||
| logger: L, | ||
| broadcaster: Arc<Broadcaster>, | ||
|
Collaborator
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. No need to add this field if we already have |
||
| } | ||
|
|
||
| impl<L: Deref> LiquiditySourceBuilder<L> | ||
|
|
@@ -156,7 +160,7 @@ where | |
| pub(crate) fn new( | ||
| wallet: Arc<Wallet>, channel_manager: Arc<ChannelManager>, keys_manager: Arc<KeysManager>, | ||
| chain_source: Arc<ChainSource>, tx_broadcaster: Arc<Broadcaster>, kv_store: Arc<DynStore>, | ||
| config: Arc<Config>, logger: L, | ||
| config: Arc<Config>, logger: L, broadcaster: Arc<Broadcaster>, | ||
| ) -> Self { | ||
| let lsps1_client = None; | ||
| let lsps2_client = None; | ||
|
|
@@ -173,6 +177,7 @@ where | |
| kv_store, | ||
| config, | ||
| logger, | ||
| broadcaster, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -305,6 +310,79 @@ where | |
| self.lsps2_client.as_ref().map(|s| (s.lsp_node_id, s.lsp_address.clone())) | ||
| } | ||
|
|
||
| pub(crate) fn lsps2_channel_needs_manual_broadcast( | ||
| &self, counterparty_node_id: PublicKey, user_channel_id: u128, | ||
| ) -> Result<bool, APIError> { | ||
|
Collaborator
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 Please clean this up, for example something like this diff --git a/src/liquidity.rs b/src/liquidity.rs
index a293311d..ddd517b1 100644
--- a/src/liquidity.rs
+++ b/src/liquidity.rs
@@ -312,22 +312,18 @@ where
pub(crate) fn lsps2_channel_needs_manual_broadcast(
&self, counterparty_node_id: PublicKey, user_channel_id: u128,
- ) -> Result<bool, APIError> {
- // if we are not in a client_trusts_lsp model, we don't check and just return false
- if !self.is_client_trusts_lsp() {
- log_debug!(self.logger, "Skipping funding transaction broadcast as client trusts LSP.");
- return Ok(false);
- }
-
- // if we are in a client_trusts_lsp model, then we check if the LSP has an LSPS2 operation in progress
- self.lsps2_service.as_ref().map_or(Ok(false), |_| {
- let lsps2_service_handler = self.liquidity_manager.lsps2_service_handler();
- if let Some(handler) = lsps2_service_handler {
- handler.channel_needs_manual_broadcast(user_channel_id, &counterparty_node_id)
- } else {
- log_error!(self.logger, "LSPS2 service handler is not available.");
- Ok(false)
- }
+ ) -> bool {
+ self.lsps2_service.as_ref().map_or(false, |lsps2_service| {
+ lsps2_service.service_config.client_trusts_lsp
+ || self
+ .liquidity_manager()
+ .lsps2_service_handler()
+ .and_then(|handler| {
+ handler
+ .channel_needs_manual_broadcast(user_channel_id, &counterparty_node_id)
+ .ok()
+ })
+ .unwrap_or(false)
})
}.. would be much more concise and readable, IMO. Also no need for 3-line util methods like (likewise below) |
||
| // if we are not in a client_trusts_lsp model, we don't check and just return false | ||
|
Collaborator
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. Please drop this redundant comment, it doesn't explain anything beyond the code below, just potentially adds to the confusion. |
||
| if !self.is_client_trusts_lsp() { | ||
| log_debug!(self.logger, "Skipping funding transaction broadcast as client trusts LSP."); | ||
|
Collaborator
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. Huh, this is very confusing/wrong. We're actually auto-broadcasting, not manually/witholding the broadcast because we're in LSP-trusts-client, right? Same below |
||
| return Ok(false); | ||
| } | ||
|
|
||
| // if we are in a client_trusts_lsp model, then we check if the LSP has an LSPS2 operation in progress | ||
| self.lsps2_service.as_ref().map_or(Ok(false), |_| { | ||
| let lsps2_service_handler = self.liquidity_manager.lsps2_service_handler(); | ||
| if let Some(handler) = lsps2_service_handler { | ||
| handler.channel_needs_manual_broadcast(user_channel_id, &counterparty_node_id) | ||
| } else { | ||
| log_error!(self.logger, "LSPS2 service handler is not available."); | ||
| Ok(false) | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| pub(crate) fn lsps2_store_funding_transaction( | ||
|
Collaborator
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. Given that we use them both at the same callsite and for the same purpose, should we just merge |
||
| &self, user_channel_id: u128, counterparty_node_id: PublicKey, funding_tx: Transaction, | ||
| ) { | ||
| if !self.is_client_trusts_lsp() { | ||
| log_debug!(self.logger, "Skipping funding transaction broadcast as client trusts LSP."); | ||
| return; | ||
| } | ||
| self.lsps2_service.as_ref().map(|_| { | ||
| let lsps2_service_handler = self.liquidity_manager.lsps2_service_handler(); | ||
| if let Some(handler) = lsps2_service_handler { | ||
| handler | ||
| .store_funding_transaction(user_channel_id, &counterparty_node_id, funding_tx) | ||
| .unwrap_or_else(|e| { | ||
| debug_assert!(false, "Failed to store funding transaction: {:?}", e); | ||
| log_error!(self.logger, "Failed to store funding transaction: {:?}", e); | ||
| }); | ||
| } else { | ||
| log_error!(self.logger, "LSPS2 service handler is not available."); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| pub(crate) fn lsps2_funding_tx_broadcast_safe( | ||
| &self, user_channel_id: u128, counterparty_node_id: PublicKey, | ||
| ) { | ||
| if !self.is_client_trusts_lsp() { | ||
| log_debug!(self.logger, "Skipping funding transaction broadcast as client trusts LSP."); | ||
| return; | ||
| } | ||
| self.lsps2_service.as_ref().map(|_| { | ||
| let lsps2_service_handler = self.liquidity_manager.lsps2_service_handler(); | ||
| if let Some(handler) = lsps2_service_handler { | ||
| handler | ||
| .set_funding_tx_broadcast_safe(user_channel_id, &counterparty_node_id) | ||
| .unwrap_or_else(|e| { | ||
| debug_assert!(false, "Failed to store funding transaction: {:?}", e); | ||
| log_error!(self.logger, "Failed to store funding transaction: {:?}", e); | ||
| }); | ||
| } else { | ||
| log_error!(self.logger, "LSPS2 service handler is not available."); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| fn is_client_trusts_lsp(&self) -> bool { | ||
| if let Some(lsps2_service) = self.lsps2_service.as_ref() { | ||
| lsps2_service.service_config.client_trusts_lsp | ||
| } else { | ||
| false | ||
| } | ||
| } | ||
|
|
||
| pub(crate) async fn handle_next_event(&self) { | ||
| match self.liquidity_manager.next_event_async().await { | ||
| LiquidityEvent::LSPS1Client(LSPS1ClientEvent::SupportedOptionsReady { | ||
|
|
@@ -594,7 +672,7 @@ where | |
| request_id, | ||
| intercept_scid, | ||
| LSPS2_CHANNEL_CLTV_EXPIRY_DELTA, | ||
| LSPS2_CLIENT_TRUSTS_LSP_MODE, | ||
| service_config.client_trusts_lsp, | ||
| user_channel_id, | ||
| ) | ||
| .await | ||
|
|
||
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.
nit: Would be cleaner if we did: