Skip to content
Merged
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
26 changes: 13 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ default = []
#lightning-liquidity = { version = "0.2.0", features = ["std"] }
#lightning-macros = { version = "0.2.0" }

lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std"] }
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std"] }
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["tokio"] }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["rest-client", "rpc-client", "tokio"] }
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std"] }
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std"] }
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std"] }
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["tokio"] }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["rest-client", "rpc-client", "tokio"] }
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std"] }
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }

bdk_chain = { version = "0.23.0", default-features = false, features = ["std"] }
bdk_esplora = { version = "0.22.0", default-features = false, features = ["async-https-rustls", "tokio"]}
Expand Down Expand Up @@ -79,13 +79,13 @@ async-trait = { version = "0.1", default-features = false }
vss-client = { package = "vss-client-ng", version = "0.5" }
prost = { version = "0.11.6", default-features = false}
#bitcoin-payment-instructions = { version = "0.6" }
bitcoin-payment-instructions = { git = "https://github.com/joostjager/bitcoin-payment-instructions", branch = "ldk-dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
bitcoin-payment-instructions = { git = "https://github.com/tankyleo/bitcoin-payment-instructions", rev = "654c25c2c1234fadf01adec1554497610f554f09" }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winbase"] }

[dev-dependencies]
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std", "_test_utils"] }
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std", "_test_utils"] }
rand = { version = "0.9.2", default-features = false, features = ["std", "thread_rng", "os_rng"] }
proptest = "1.0.0"
regex = "1.5.6"
Expand Down
4 changes: 4 additions & 0 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ interface Node {
[Throws=NodeError]
UserChannelId open_announced_channel_with_all(PublicKey node_id, SocketAddress address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
[Throws=NodeError]
UserChannelId open_0reserve_channel(PublicKey node_id, SocketAddress address, u64 channel_amount_sats, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
[Throws=NodeError]
UserChannelId open_0reserve_channel_with_all(PublicKey node_id, SocketAddress address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
[Throws=NodeError]
void splice_in([ByRef]UserChannelId user_channel_id, PublicKey counterparty_node_id, u64 splice_amount_sats);
[Throws=NodeError]
void splice_in_with_all([ByRef]UserChannelId user_channel_id, PublicKey counterparty_node_id);
Expand Down
5 changes: 3 additions & 2 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use lightning::events::{
ReplayEvent,
};
use lightning::impl_writeable_tlv_based_enum;
use lightning::ln::channelmanager::PaymentId;
use lightning::ln::channelmanager::{PaymentId, TrustedChannelFeatures};
use lightning::ln::types::ChannelId;
use lightning::routing::gossip::NodeId;
use lightning::sign::EntropySource;
Expand Down Expand Up @@ -1285,10 +1285,11 @@ where
}
}
let res = if allow_0conf {
self.channel_manager.accept_inbound_channel_from_trusted_peer_0conf(
self.channel_manager.accept_inbound_channel_from_trusted_peer(
&temporary_channel_id,
&counterparty_node_id,
user_channel_id,
TrustedChannelFeatures::ZeroConf,
channel_override_config,
)
} else {
Expand Down
110 changes: 99 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ impl Node {
fn open_channel_inner(
&self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: FundingAmount,
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
announce_for_forwarding: bool,
announce_for_forwarding: bool, set_0reserve: bool,
) -> Result<UserChannelId, Error> {
if !*self.is_running.read().unwrap() {
return Err(Error::NotRunning);
Expand Down Expand Up @@ -1196,25 +1196,46 @@ impl Node {
self.keys_manager.get_secure_random_bytes()[..16].try_into().unwrap(),
);

match self.channel_manager.create_channel(
peer_info.node_id,
channel_amount_sats,
push_msat,
user_channel_id,
None,
Some(user_config),
) {
let result = if set_0reserve {
self.channel_manager.create_channel_to_trusted_peer_0reserve(
peer_info.node_id,
channel_amount_sats,
push_msat,
user_channel_id,
None,
Some(user_config),
)
} else {
self.channel_manager.create_channel(
peer_info.node_id,
channel_amount_sats,
push_msat,
user_channel_id,
None,
Some(user_config),
)
};

let zero_reserve_string = if set_0reserve { "0reserve " } else { "" };

match result {
Ok(_) => {
log_info!(
self.logger,
"Initiated channel creation with peer {}. ",
"Initiated {}channel creation with peer {}. ",
zero_reserve_string,
peer_info.node_id
);
self.peer_store.add_peer(peer_info)?;
Ok(UserChannelId(user_channel_id))
},
Err(e) => {
log_error!(self.logger, "Failed to initiate channel creation: {:?}", e);
log_error!(
self.logger,
"Failed to initiate {}channel creation: {:?}",
zero_reserve_string,
e
);
Err(Error::ChannelCreationFailed)
},
}
Expand Down Expand Up @@ -1290,6 +1311,7 @@ impl Node {
push_to_counterparty_msat,
channel_config,
false,
false,
)
}

Expand Down Expand Up @@ -1330,6 +1352,7 @@ impl Node {
push_to_counterparty_msat,
channel_config,
true,
false,
)
}

Expand Down Expand Up @@ -1358,6 +1381,7 @@ impl Node {
push_to_counterparty_msat,
channel_config,
false,
false,
)
}

Expand Down Expand Up @@ -1395,6 +1419,70 @@ impl Node {
push_to_counterparty_msat,
channel_config,
true,
false,
)
}

/// Connect to a node and open a new unannounced channel, in which the target node can
/// spend its entire balance.
///
/// This channel allows the target node to try to steal your funds with no financial
/// penalty, so this channel should only be opened to nodes you trust.
///
/// Disconnects and reconnects are handled automatically.
///
/// If `push_to_counterparty_msat` is set, the given value will be pushed (read: sent) to the
/// channel counterparty on channel open. This can be useful to start out with the balance not
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
///
/// If Anchor channels are enabled, this will ensure the configured
/// [`AnchorChannelsConfig::per_channel_reserve_sats`] is available and will be retained before
/// opening the channel.
///
/// Returns a [`UserChannelId`] allowing to locally keep track of the channel.
///
/// [`AnchorChannelsConfig::per_channel_reserve_sats`]: crate::config::AnchorChannelsConfig::per_channel_reserve_sats
pub fn open_0reserve_channel(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go ahead with these new APIs, they need to be exposed in uniffi bindings.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done below

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are getting a combinatorial explosion with these

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed offline, we retain separate calls for now, and will ship your ChannelBuilder::new().with_no_reserve().announced().fund_withall() suggestion in case there is further expansion of these calls.

&self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
) -> Result<UserChannelId, Error> {
self.open_channel_inner(
node_id,
address,
FundingAmount::Exact { amount_sats: channel_amount_sats },
push_to_counterparty_msat,
channel_config,
false,
true,
)
}

/// Connect to a node and open a new unannounced channel, using all available on-chain funds
/// minus fees and anchor reserves. The target node will be able to spend its entire channel
/// balance.
///
/// This channel allows the target node to try to steal your funds with no financial
/// penalty, so this channel should only be opened to nodes you trust.
///
/// Disconnects and reconnects are handled automatically.
///
/// If `push_to_counterparty_msat` is set, the given value will be pushed (read: sent) to the
/// channel counterparty on channel open. This can be useful to start out with the balance not
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
///
/// Returns a [`UserChannelId`] allowing to locally keep track of the channel.
pub fn open_0reserve_channel_with_all(
&self, node_id: PublicKey, address: SocketAddress, push_to_counterparty_msat: Option<u64>,
channel_config: Option<ChannelConfig>,
) -> Result<UserChannelId, Error> {
self.open_channel_inner(
node_id,
address,
FundingAmount::Max,
push_to_counterparty_msat,
channel_config,
false,
true,
)
}

Expand Down
38 changes: 29 additions & 9 deletions src/liquidity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ pub struct LSPS2ServiceConfig {
///
/// [`bLIP-52`]: https://github.com/lightning/blips/blob/master/blip-0052.md#trust-models
pub client_trusts_lsp: bool,
/// When set, clients that we open channels to will be allowed to spend their entire channel
/// balance. This allows clients to try to steal your funds with no financial penalty, so
/// this should only be set if you trust your clients.
pub allow_client_0reserve: bool,
Comment on lines +145 to +148
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this wording kinda suggests that all channels opened to these clients will be effected but in reality it is only the channels we open to them.

Suggested change
/// When set, clients that we open channels to will be allowed to spend their entire channel
/// balance. This allows clients to try to steal your funds with no financial penalty, so
/// this should only be set if you trust your clients.
pub allow_client_0reserve: bool,
/// When set, channels that we open to clients will be allowed to spend their entire
/// balance. This allows clients to try to potentially steal your channel funds with no financial penalty, so
/// this should only be set if you trust your clients.
pub allow_client_0reserve: bool,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, might be good to slightly improve docs further in a follow-up.

}

pub(crate) struct LiquiditySourceBuilder<L: Deref>
Expand Down Expand Up @@ -786,22 +790,38 @@ where
config.channel_config.forwarding_fee_base_msat = 0;
config.channel_config.forwarding_fee_proportional_millionths = 0;

match self.channel_manager.create_channel(
their_network_key,
channel_amount_sats,
0,
user_channel_id,
None,
Some(config),
) {
let result = if service_config.allow_client_0reserve {
self.channel_manager.create_channel_to_trusted_peer_0reserve(
their_network_key,
channel_amount_sats,
0,
user_channel_id,
None,
Some(config),
)
} else {
self.channel_manager.create_channel(
their_network_key,
channel_amount_sats,
0,
user_channel_id,
None,
Some(config),
)
};

match result {
Ok(_) => {},
Err(e) => {
// TODO: We just silently fail here. Eventually we will need to remember
// the pending requests and regularly retry opening the channel until we
// succeed.
let zero_reserve_string =
if service_config.allow_client_0reserve { "0reserve " } else { "" };
log_error!(
self.logger,
"Failed to open LSPS2 channel to {}: {:?}",
"Failed to open LSPS2 {}channel to {}: {:?}",
zero_reserve_string,
their_network_key,
e
);
Expand Down
3 changes: 3 additions & 0 deletions tests/integration_tests_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,7 @@ async fn do_lsps2_client_service_integration(client_trusts_lsp: bool) {
min_channel_opening_fee_msat: 0,
max_client_to_self_delay: 1024,
client_trusts_lsp,
allow_client_0reserve: false,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should def. add a test coverage for the new APIs in a follow-up (preferably a new 0-reserve specific test, maybe (also?) a full-cycle variant like we do for 0conf?).

};

let service_config = random_config(true);
Expand Down Expand Up @@ -2023,6 +2024,7 @@ async fn lsps2_client_trusts_lsp() {
min_channel_opening_fee_msat: 0,
max_client_to_self_delay: 1024,
client_trusts_lsp: true,
allow_client_0reserve: false,
};

let service_config = random_config(true);
Expand Down Expand Up @@ -2197,6 +2199,7 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() {
min_channel_opening_fee_msat: 0,
max_client_to_self_delay: 1024,
client_trusts_lsp: false,
allow_client_0reserve: false,
};

let service_config = random_config(true);
Expand Down
Loading