-
Notifications
You must be signed in to change notification settings - Fork 114
Client trusts lsp #572
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?
Client trusts lsp #572
Changes from 1 commit
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 |
---|---|---|
|
@@ -55,7 +55,6 @@ use std::time::Duration; | |
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 { | ||
|
@@ -134,6 +133,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> | ||
|
@@ -292,6 +293,81 @@ 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, | ||
) -> bool { | ||
// 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 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(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) | ||
.unwrap_or(false) | ||
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. Unsure about 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 also fixed in commit 2cc5267 thank you for the review! |
||
} else { | ||
log_error!(self.logger, "LSPS2 service handler is not available."); | ||
false | ||
} | ||
}) | ||
} | ||
|
||
pub(crate) fn lsps2_store_funding_transaction( | ||
&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 | ||
.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 { | ||
|
@@ -580,7 +656,7 @@ where | |
request_id, | ||
intercept_scid, | ||
LSPS2_CHANNEL_CLTV_EXPIRY_DELTA, | ||
LSPS2_CLIENT_TRUSTS_LSP_MODE, | ||
service_config.client_trusts_lsp, | ||
user_channel_id, | ||
) { | ||
Ok(()) => {}, | ||
|
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.
I'm trying to understand the
client_trusts_lsp
configuration here. According to bLIP-52, I expect the LSP to dynamically switch fromlsp_trusts_client
toclient_trusts_lsp
mode upon detecting an attack, without requiring a restart.However, this configuration appears to be static and set at node startup. If that's the case, what happens when:
lsp_trusts_client
mode detects an attackclient_trusts_lsp
:true
to switch modesWhat are the potential consequences for that in-flight JIT channel during the mode transition?
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 pushed a fixup that makes the flag dynamic
I just posted a question about this https://discord.com/channels/915026692102316113/994015949176963183/1397280758196080660
my current interpretation about this is that once lsps2.buy succeeds, that flag is part of the contract for this flow. the LSP can always abort and make you start over, but it cannot change the trust model mid negotiation
we will see what they respond on discord
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.
I created a test that shows how this works (test lsps2_in_flight_under_attack_switch)
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.
Yes, as also noted on Discord, I agree with that interpretation and even think that for now we can leave the flag to be statically determined at startup.