Skip to content

Commit 663864a

Browse files
committed
Enable 0conf and 0reserve on channels with trusted peers
1 parent bf7713d commit 663864a

File tree

7 files changed

+106
-67
lines changed

7 files changed

+106
-67
lines changed

Cargo.toml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ default = []
3939
#lightning-liquidity = { version = "0.2.0", features = ["std"] }
4040
#lightning-macros = { version = "0.2.0" }
4141

42-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std"] }
43-
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
44-
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std"] }
45-
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
46-
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["tokio"] }
47-
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
48-
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
49-
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["rest-client", "rpc-client", "tokio"] }
50-
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
51-
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std"] }
52-
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
42+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std"] }
43+
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
44+
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std"] }
45+
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
46+
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["tokio"] }
47+
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
48+
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
49+
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["rest-client", "rpc-client", "tokio"] }
50+
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
51+
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std"] }
52+
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a" }
5353

5454
bdk_chain = { version = "0.23.0", default-features = false, features = ["std"] }
5555
bdk_esplora = { version = "0.22.0", default-features = false, features = ["async-https-rustls", "tokio"]}
@@ -79,13 +79,13 @@ async-trait = { version = "0.1", default-features = false }
7979
vss-client = { package = "vss-client-ng", version = "0.5" }
8080
prost = { version = "0.11.6", default-features = false}
8181
#bitcoin-payment-instructions = { version = "0.6" }
82-
bitcoin-payment-instructions = { git = "https://github.com/joostjager/bitcoin-payment-instructions", branch = "ldk-dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
82+
bitcoin-payment-instructions = { git = "https://github.com/tankyleo/bitcoin-payment-instructions", branch = "ldk-688544da72cb348e4405d39a75e4d81102c1278a" }
8383

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

8787
[dev-dependencies]
88-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std", "_test_utils"] }
88+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "688544da72cb348e4405d39a75e4d81102c1278a", features = ["std", "_test_utils"] }
8989
rand = { version = "0.9.2", default-features = false, features = ["std", "thread_rng", "os_rng"] }
9090
proptest = "1.0.0"
9191
regex = "1.5.6"

src/builder.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -435,16 +435,16 @@ impl NodeBuilder {
435435
/// Configures the [`Node`] instance to source inbound liquidity from the given
436436
/// [bLIP-51 / LSPS1] service.
437437
///
438-
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
438+
/// Will mark the LSP as trusted for 0-confirmation, 0-reserve channels, see [`Config::trusted_peers_0conf_0reserve`].
439439
///
440440
/// The given `token` will be used by the LSP to authenticate the user.
441441
///
442442
/// [bLIP-51 / LSPS1]: https://github.com/lightning/blips/blob/master/blip-0051.md
443443
pub fn set_liquidity_source_lsps1(
444444
&mut self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
445445
) -> &mut Self {
446-
// Mark the LSP as trusted for 0conf
447-
self.config.trusted_peers_0conf.push(node_id.clone());
446+
// Mark the LSP as trusted for 0conf, 0reserve
447+
self.config.trusted_peers_0conf_0reserve.push(node_id.clone());
448448

449449
let liquidity_source_config =
450450
self.liquidity_source_config.get_or_insert(LiquiditySourceConfig::default());
@@ -456,16 +456,16 @@ impl NodeBuilder {
456456
/// Configures the [`Node`] instance to source just-in-time inbound liquidity from the given
457457
/// [bLIP-52 / LSPS2] service.
458458
///
459-
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
459+
/// Will mark the LSP as trusted for 0-confirmation, 0-reserve channels, see [`Config::trusted_peers_0conf_0reserve`].
460460
///
461461
/// The given `token` will be used by the LSP to authenticate the user.
462462
///
463463
/// [bLIP-52 / LSPS2]: https://github.com/lightning/blips/blob/master/blip-0052.md
464464
pub fn set_liquidity_source_lsps2(
465465
&mut self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
466466
) -> &mut Self {
467-
// Mark the LSP as trusted for 0conf
468-
self.config.trusted_peers_0conf.push(node_id.clone());
467+
// Mark the LSP as trusted for 0conf, 0reserve
468+
self.config.trusted_peers_0conf_0reserve.push(node_id.clone());
469469

470470
let liquidity_source_config =
471471
self.liquidity_source_config.get_or_insert(LiquiditySourceConfig::default());
@@ -956,7 +956,7 @@ impl ArcedNodeBuilder {
956956
/// Configures the [`Node`] instance to source inbound liquidity from the given
957957
/// [bLIP-51 / LSPS1] service.
958958
///
959-
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
959+
/// Will mark the LSP as trusted for 0-confirmation, 0-reserve channels, see [`Config::trusted_peers_0conf_0reserve`].
960960
///
961961
/// The given `token` will be used by the LSP to authenticate the user.
962962
///
@@ -970,7 +970,7 @@ impl ArcedNodeBuilder {
970970
/// Configures the [`Node`] instance to source just-in-time inbound liquidity from the given
971971
/// [bLIP-52 / LSPS2] service.
972972
///
973-
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
973+
/// Will mark the LSP as trusted for 0-confirmation, 0-reserve channels, see [`Config::trusted_peers_0conf_0reserve`].
974974
///
975975
/// The given `token` will be used by the LSP to authenticate the user.
976976
///

src/config.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub(crate) const LNURL_AUTH_TIMEOUT_SECS: u64 = 15;
123123
/// | `listening_addresses` | None |
124124
/// | `announcement_addresses` | None |
125125
/// | `node_alias` | None |
126-
/// | `trusted_peers_0conf` | [] |
126+
/// | `trusted_peers_0conf_0reserve` | [] |
127127
/// | `probing_liquidity_limit_multiplier` | 3 |
128128
/// | `anchor_channels_config` | Some(..) |
129129
/// | `route_parameters` | None |
@@ -156,12 +156,19 @@ pub struct Config {
156156
/// **Note**: We will only allow opening and accepting public channels if the `node_alias` and the
157157
/// `listening_addresses` are set.
158158
pub node_alias: Option<NodeAlias>,
159-
/// A list of peers that we allow to establish zero confirmation channels to us.
160-
///
161-
/// **Note:** Allowing payments via zero-confirmation channels is potentially insecure if the
162-
/// funding transaction ends up never being confirmed on-chain. Zero-confirmation channels
163-
/// should therefore only be accepted from trusted peers.
164-
pub trusted_peers_0conf: Vec<PublicKey>,
159+
/// A list of peers that we trust. If a peer on this list opens a channel to us, we will
160+
/// forward their HTLCs before any confirmations of the funding transaction (zero-conf), and
161+
/// allow them to spend their entire balance (zero-reserve). If we open a channel to a peer
162+
/// on this list, we will allow them to spend their entire channel balance (note that for
163+
/// channels *we* open, the decision of whether to accept HTLC forwards with no
164+
/// confirmations of the funding transaction is *the peer's* decision).
165+
///
166+
/// **Note:** Allowing payments via zero-confirmation channels is potentially insecure if
167+
/// the funding transaction never gets confirmed on-chain. Zero-reserve channels
168+
/// allow the counterparty to make cheating attempts with no financial penalty.
169+
/// Zero-confirmation, and zero-reserve channels should therefore only be accepted from and
170+
/// opened to trusted peers.
171+
pub trusted_peers_0conf_0reserve: Vec<PublicKey>,
165172
/// The liquidity factor by which we filter the outgoing channels used for sending probes.
166173
///
167174
/// Channels with available liquidity less than the required amount times this value won't be
@@ -208,7 +215,7 @@ impl Default for Config {
208215
network: DEFAULT_NETWORK,
209216
listening_addresses: None,
210217
announcement_addresses: None,
211-
trusted_peers_0conf: Vec::new(),
218+
trusted_peers_0conf_0reserve: Vec::new(),
212219
probing_liquidity_limit_multiplier: DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER,
213220
anchor_channels_config: Some(AnchorChannelsConfig::default()),
214221
tor_config: None,

src/event.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use lightning::events::{
2222
ReplayEvent,
2323
};
2424
use lightning::impl_writeable_tlv_based_enum;
25-
use lightning::ln::channelmanager::PaymentId;
25+
use lightning::ln::channelmanager::{PaymentId, TrustedChannelFeatures};
2626
use lightning::ln::types::ChannelId;
2727
use lightning::routing::gossip::NodeId;
2828
use lightning::sign::EntropySource;
@@ -1258,7 +1258,6 @@ where
12581258
let user_channel_id: u128 = u128::from_ne_bytes(
12591259
self.keys_manager.get_secure_random_bytes()[..16].try_into().unwrap(),
12601260
);
1261-
let allow_0conf = self.config.trusted_peers_0conf.contains(&counterparty_node_id);
12621261
let mut channel_override_config = None;
12631262
if let Some((lsp_node_id, _)) = self
12641263
.liquidity_source
@@ -1284,11 +1283,14 @@ where
12841283
});
12851284
}
12861285
}
1287-
let res = if allow_0conf {
1288-
self.channel_manager.accept_inbound_channel_from_trusted_peer_0conf(
1286+
let is_trusted_peer =
1287+
self.config.trusted_peers_0conf_0reserve.contains(&counterparty_node_id);
1288+
let res = if is_trusted_peer {
1289+
self.channel_manager.accept_inbound_channel_from_trusted_peer(
12891290
&temporary_channel_id,
12901291
&counterparty_node_id,
12911292
user_channel_id,
1293+
TrustedChannelFeatures::ZeroConfZeroReserve,
12921294
channel_override_config,
12931295
)
12941296
} else {
@@ -1305,21 +1307,21 @@ where
13051307
log_info!(
13061308
self.logger,
13071309
"Accepting inbound{}{} channel of {}sats from{} peer {}",
1308-
if allow_0conf { " 0conf" } else { "" },
1310+
if is_trusted_peer { " 0conf, 0reserve" } else { "" },
13091311
if anchor_channel { " Anchor" } else { "" },
13101312
funding_satoshis,
1311-
if allow_0conf { " trusted" } else { "" },
1313+
if is_trusted_peer { " trusted" } else { "" },
13121314
counterparty_node_id,
13131315
);
13141316
},
13151317
Err(e) => {
13161318
log_error!(
13171319
self.logger,
13181320
"Error while accepting inbound{}{} channel from{} peer {}: {:?}",
1319-
if allow_0conf { " 0conf" } else { "" },
1321+
if is_trusted_peer { " 0conf, 0reserve" } else { "" },
13201322
if anchor_channel { " Anchor" } else { "" },
13211323
counterparty_node_id,
1322-
if allow_0conf { " trusted" } else { "" },
1324+
if is_trusted_peer { " trusted" } else { "" },
13231325
e,
13241326
);
13251327
},

src/lib.rs

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,27 +1196,57 @@ impl Node {
11961196
self.keys_manager.get_secure_random_bytes()[..16].try_into().unwrap(),
11971197
);
11981198

1199-
match self.channel_manager.create_channel(
1200-
peer_info.node_id,
1201-
channel_amount_sats,
1202-
push_msat,
1203-
user_channel_id,
1204-
None,
1205-
Some(user_config),
1206-
) {
1207-
Ok(_) => {
1208-
log_info!(
1209-
self.logger,
1210-
"Initiated channel creation with peer {}. ",
1211-
peer_info.node_id
1212-
);
1213-
self.peer_store.add_peer(peer_info)?;
1214-
Ok(UserChannelId(user_channel_id))
1215-
},
1216-
Err(e) => {
1217-
log_error!(self.logger, "Failed to initiate channel creation: {:?}", e);
1218-
Err(Error::ChannelCreationFailed)
1219-
},
1199+
let is_trusted_peer = self.config.trusted_peers_0conf_0reserve.contains(&node_id);
1200+
if is_trusted_peer {
1201+
match self.channel_manager.create_channel_to_trusted_peer_0reserve(
1202+
peer_info.node_id,
1203+
channel_amount_sats,
1204+
push_msat,
1205+
user_channel_id,
1206+
None,
1207+
Some(user_config),
1208+
) {
1209+
Ok(_) => {
1210+
log_info!(
1211+
self.logger,
1212+
"Initiated 0reserve channel creation with peer {}. ",
1213+
peer_info.node_id
1214+
);
1215+
self.peer_store.add_peer(peer_info)?;
1216+
Ok(UserChannelId(user_channel_id))
1217+
},
1218+
Err(e) => {
1219+
log_error!(
1220+
self.logger,
1221+
"Failed to initiate 0reserve channel creation: {:?}",
1222+
e
1223+
);
1224+
Err(Error::ChannelCreationFailed)
1225+
},
1226+
}
1227+
} else {
1228+
match self.channel_manager.create_channel(
1229+
peer_info.node_id,
1230+
channel_amount_sats,
1231+
push_msat,
1232+
user_channel_id,
1233+
None,
1234+
Some(user_config),
1235+
) {
1236+
Ok(_) => {
1237+
log_info!(
1238+
self.logger,
1239+
"Initiated channel creation with peer {}. ",
1240+
peer_info.node_id
1241+
);
1242+
self.peer_store.add_peer(peer_info)?;
1243+
Ok(UserChannelId(user_channel_id))
1244+
},
1245+
Err(e) => {
1246+
log_error!(self.logger, "Failed to initiate channel creation: {:?}", e);
1247+
Err(Error::ChannelCreationFailed)
1248+
},
1249+
}
12201250
}
12211251
}
12221252

tests/common/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -381,20 +381,20 @@ macro_rules! setup_builder {
381381
pub(crate) use setup_builder;
382382

383383
pub(crate) fn setup_two_nodes(
384-
chain_source: &TestChainSource, allow_0conf: bool, anchor_channels: bool,
384+
chain_source: &TestChainSource, allow_0conf_0reserve: bool, anchor_channels: bool,
385385
anchors_trusted_no_reserve: bool,
386386
) -> (TestNode, TestNode) {
387387
setup_two_nodes_with_store(
388388
chain_source,
389-
allow_0conf,
389+
allow_0conf_0reserve,
390390
anchor_channels,
391391
anchors_trusted_no_reserve,
392392
TestStoreType::TestSyncStore,
393393
)
394394
}
395395

396396
pub(crate) fn setup_two_nodes_with_store(
397-
chain_source: &TestChainSource, allow_0conf: bool, anchor_channels: bool,
397+
chain_source: &TestChainSource, allow_0conf_0reserve: bool, anchor_channels: bool,
398398
anchors_trusted_no_reserve: bool, store_type: TestStoreType,
399399
) -> (TestNode, TestNode) {
400400
println!("== Node A ==");
@@ -405,8 +405,8 @@ pub(crate) fn setup_two_nodes_with_store(
405405
println!("\n== Node B ==");
406406
let mut config_b = random_config(anchor_channels);
407407
config_b.store_type = store_type;
408-
if allow_0conf {
409-
config_b.node_config.trusted_peers_0conf.push(node_a.node_id());
408+
if allow_0conf_0reserve {
409+
config_b.node_config.trusted_peers_0conf_0reserve.push(node_a.node_id());
410410
}
411411
if anchor_channels && anchors_trusted_no_reserve {
412412
config_b
@@ -789,8 +789,8 @@ pub async fn splice_in_with_all(
789789
}
790790

791791
pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
792-
node_a: TestNode, node_b: TestNode, bitcoind: &BitcoindClient, electrsd: &E, allow_0conf: bool,
793-
expect_anchor_channel: bool, force_close: bool,
792+
node_a: TestNode, node_b: TestNode, bitcoind: &BitcoindClient, electrsd: &E,
793+
allow_0conf_0reserve: bool, expect_anchor_channel: bool, force_close: bool,
794794
) {
795795
let addr_a = node_a.onchain_payment().new_address().unwrap();
796796
let addr_b = node_b.onchain_payment().new_address().unwrap();
@@ -864,7 +864,7 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
864864

865865
wait_for_tx(electrsd, funding_txo_a.txid).await;
866866

867-
if !allow_0conf {
867+
if !allow_0conf_0reserve {
868868
generate_blocks_and_wait(&bitcoind, electrsd, 6).await;
869869
}
870870

tests/integration_tests_rust.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ async fn channel_full_cycle_force_close_trusted_no_reserve() {
7171
}
7272

7373
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
74-
async fn channel_full_cycle_0conf() {
74+
async fn channel_full_cycle_0conf_0reserve() {
7575
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
7676
let chain_source = random_chain_source(&bitcoind, &electrsd);
7777
let (node_a, node_b) = setup_two_nodes(&chain_source, true, true, false);

0 commit comments

Comments
 (0)