Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions ldk-server-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,19 @@ enum Commands {
CloseChannel {
#[arg(help = "The local user_channel_id of this channel")]
user_channel_id: String,
#[arg(help = "The hex-encoded public key of the node to close a channel with")]
counterparty_node_id: String,
#[arg(
help = "The hex-encoded public key of the node to close a channel with. If not provided, it will be looked up from the channel list"
)]
counterparty_node_id: Option<String>,
},
#[command(about = "Force close the channel specified by the given channel ID")]
ForceCloseChannel {
#[arg(help = "The local user_channel_id of this channel")]
user_channel_id: String,
#[arg(help = "The hex-encoded public key of the node to close a channel with")]
counterparty_node_id: String,
#[arg(
help = "The hex-encoded public key of the node to close a channel with. If not provided, it will be looked up from the channel list"
)]
counterparty_node_id: Option<String>,
#[arg(long, help = "The reason for force-closing, defaults to \"\"")]
force_close_reason: Option<String>,
},
Expand Down Expand Up @@ -339,9 +343,9 @@ enum Commands {
#[arg(help = "The local user_channel_id of this channel")]
user_channel_id: String,
#[arg(
help = "The hex-encoded public key of the counterparty node to update channel config with"
help = "The hex-encoded public key of the counterparty node to update channel config with. If not provided, it will be looked up from the channel list"
)]
counterparty_node_id: String,
counterparty_node_id: Option<String>,
#[arg(
long,
help = "Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound over the channel. This can be updated by using update-channel-config."
Expand Down
15 changes: 9 additions & 6 deletions ldk-server-protos/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,9 @@ pub struct UpdateChannelConfigRequest {
#[prost(string, tag = "1")]
pub user_channel_id: ::prost::alloc::string::String,
/// The hex-encoded public key of the counterparty node to update channel config with.
#[prost(string, tag = "2")]
pub counterparty_node_id: ::prost::alloc::string::String,
/// If not provided, it will be resolved from the channel list.
#[prost(string, optional, tag = "2")]
pub counterparty_node_id: ::core::option::Option<::prost::alloc::string::String>,
/// The updated channel configuration settings for a channel.
#[prost(message, optional, tag = "3")]
pub channel_config: ::core::option::Option<super::types::ChannelConfig>,
Expand All @@ -431,8 +432,9 @@ pub struct CloseChannelRequest {
#[prost(string, tag = "1")]
pub user_channel_id: ::prost::alloc::string::String,
/// The hex-encoded public key of the node to close a channel with.
#[prost(string, tag = "2")]
pub counterparty_node_id: ::prost::alloc::string::String,
/// If not provided, it will be resolved from the channel list.
#[prost(string, optional, tag = "2")]
pub counterparty_node_id: ::core::option::Option<::prost::alloc::string::String>,
}
/// The response `content` for the `CloseChannel` API, when HttpStatusCode is OK (200).
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
Expand All @@ -452,8 +454,9 @@ pub struct ForceCloseChannelRequest {
#[prost(string, tag = "1")]
pub user_channel_id: ::prost::alloc::string::String,
/// The hex-encoded public key of the node to close a channel with.
#[prost(string, tag = "2")]
pub counterparty_node_id: ::prost::alloc::string::String,
/// If not provided, it will be resolved from the channel list.
#[prost(string, optional, tag = "2")]
pub counterparty_node_id: ::core::option::Option<::prost::alloc::string::String>,
/// The reason for force-closing.
#[prost(string, optional, tag = "3")]
pub force_close_reason: ::core::option::Option<::prost::alloc::string::String>,
Expand Down
9 changes: 6 additions & 3 deletions ldk-server-protos/src/proto/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ message UpdateChannelConfigRequest {
string user_channel_id = 1;

// The hex-encoded public key of the counterparty node to update channel config with.
string counterparty_node_id = 2;
// If not provided, it will be resolved from the channel list.
optional string counterparty_node_id = 2;

// The updated channel configuration settings for a channel.
types.ChannelConfig channel_config = 3;
Expand All @@ -354,7 +355,8 @@ message CloseChannelRequest {
string user_channel_id = 1;

// The hex-encoded public key of the node to close a channel with.
string counterparty_node_id = 2;
// If not provided, it will be resolved from the channel list.
optional string counterparty_node_id = 2;
}

// The response `content` for the `CloseChannel` API, when HttpStatusCode is OK (200).
Expand All @@ -367,7 +369,8 @@ message ForceCloseChannelRequest {
// The local `user_channel_id` of this channel.
string user_channel_id = 1;
// The hex-encoded public key of the node to close a channel with.
string counterparty_node_id = 2;
// If not provided, it will be resolved from the channel list.
optional string counterparty_node_id = 2;
// The reason for force-closing.
optional string force_close_reason = 3;
}
Expand Down
26 changes: 24 additions & 2 deletions ldk-server/src/api/close_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ pub(crate) fn handle_close_channel_request(
context: Context, request: CloseChannelRequest,
) -> Result<CloseChannelResponse, LdkServerError> {
let user_channel_id = parse_user_channel_id(&request.user_channel_id)?;
let counterparty_node_id = parse_counterparty_node_id(&request.counterparty_node_id)?;
let counterparty_node_id =
resolve_counterparty_node_id(&context, &user_channel_id, request.counterparty_node_id)?;

context.node.close_channel(&user_channel_id, counterparty_node_id)?;

Expand All @@ -34,7 +35,8 @@ pub(crate) fn handle_force_close_channel_request(
context: Context, request: ForceCloseChannelRequest,
) -> Result<ForceCloseChannelResponse, LdkServerError> {
let user_channel_id = parse_user_channel_id(&request.user_channel_id)?;
let counterparty_node_id = parse_counterparty_node_id(&request.counterparty_node_id)?;
let counterparty_node_id =
resolve_counterparty_node_id(&context, &user_channel_id, request.counterparty_node_id)?;

context.node.force_close_channel(
&user_channel_id,
Expand All @@ -60,3 +62,23 @@ fn parse_counterparty_node_id(id: &str) -> Result<PublicKey, LdkServerError> {
)
})
}

fn resolve_counterparty_node_id(
context: &Context, user_channel_id: &UserChannelId, counterparty_node_id: Option<String>,
) -> Result<PublicKey, LdkServerError> {
match counterparty_node_id {
Some(id) => parse_counterparty_node_id(&id),
None => context
.node
.list_channels()
.into_iter()
.find(|c| c.user_channel_id == *user_channel_id)
.map(|c| c.counterparty_node_id)
.ok_or_else(|| {
LdkServerError::new(
InvalidRequestError,
"Channel not found for given user_channel_id.".to_string(),
)
}),
}
}
35 changes: 24 additions & 11 deletions ldk-server/src/api/update_channel_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,43 @@ pub(crate) fn handle_update_channel_config_request(
.parse::<u128>()
.map_err(|_| LdkServerError::new(InvalidRequestError, "Invalid UserChannelId."))?;

// FIXME: Use ldk/ldk-node's partial config update api.
let current_config = context
let channel = context
.node
.list_channels()
.into_iter()
.find(|c| c.user_channel_id.0 == user_channel_id)
.ok_or_else(|| {
LdkServerError::new(InvalidRequestError, "Channel not found for given user_channel_id.")
})?
.config;
})?;

// FIXME: Use ldk/ldk-node's partial config update api.
let updated_channel_config = build_channel_config_from_proto(
current_config,
channel.config,
request.channel_config.ok_or_else(|| {
LdkServerError::new(InvalidRequestError, "Channel config must be provided.")
})?,
)?;

let counterparty_node_id = PublicKey::from_str(&request.counterparty_node_id).map_err(|e| {
LdkServerError::new(
InvalidRequestError,
format!("Invalid counterparty node id, error {}", e),
)
})?;
let counterparty_node_id = match request.counterparty_node_id {
Some(id) => {
let node_id = PublicKey::from_str(&id).map_err(|e| {
LdkServerError::new(
InvalidRequestError,
format!("Invalid counterparty node id, error {}", e),
)
})?;

if node_id != channel.counterparty_node_id {
return Err(LdkServerError::new(
InvalidRequestError,
format!("Channel with user_channel_id {user_channel_id} is not connected to counterparty node id {node_id}."),
));
}

node_id
},
None => channel.counterparty_node_id,
};

context
.node
Expand Down