Skip to content

Commit f56ae64

Browse files
committed
Add zero-reserve to the internal API of V2 channels
1 parent cd98002 commit f56ae64

3 files changed

Lines changed: 96 additions & 30 deletions

File tree

lightning/src/ln/channel.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14224,7 +14224,7 @@ impl<SP: SignerProvider> PendingV2Channel<SP> {
1422414224
counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64,
1422514225
funding_inputs: Vec<FundingTxInput>, user_id: u128, config: &UserConfig,
1422614226
current_chain_height: u32, outbound_scid_alias: u64, funding_confirmation_target: ConfirmationTarget,
14227-
logger: L,
14227+
logger: L, trusted_channel_features: Option<TrustedChannelFeatures>,
1422814228
) -> Result<Self, APIError> {
1422914229
let channel_keys_id = signer_provider.generate_channel_keys_id(false, user_id);
1423014230
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -14233,9 +14233,8 @@ impl<SP: SignerProvider> PendingV2Channel<SP> {
1423314233
ChannelId::temporary_v2_from_revocation_basepoint(&pubkeys.revocation_basepoint)
1423414234
});
1423514235

14236-
// TODO(zero_reserve): support reading and writing the `disable_channel_reserve` field
1423714236
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
14238-
funding_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS, false);
14237+
funding_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS, trusted_channel_features.is_some_and(|f| f.is_0reserve()));
1423914238

1424014239
let funding_feerate_sat_per_1000_weight = fee_estimator.bounded_sat_per_1000_weight(funding_confirmation_target);
1424114240
let funding_tx_locktime = LockTime::from_height(current_chain_height)
@@ -14353,6 +14352,7 @@ impl<SP: SignerProvider> PendingV2Channel<SP> {
1435314352
second_per_commitment_point,
1435414353
locktime: self.funding_negotiation_context.funding_tx_locktime.to_consensus_u32(),
1435514354
require_confirmed_inputs: None,
14355+
disable_channel_reserve: (self.funding.holder_selected_channel_reserve_satoshis == 0).then_some(()),
1435614356
}
1435714357
}
1435814358

@@ -14365,19 +14365,18 @@ impl<SP: SignerProvider> PendingV2Channel<SP> {
1436514365
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
1436614366
holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
1436714367
their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
14368-
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
14368+
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L, trusted_channel_features: Option<TrustedChannelFeatures>,
1436914369
) -> Result<Self, ChannelError> {
1437014370
// TODO(dual_funding): Take these as input once supported
1437114371
let (our_funding_contribution, our_funding_contribution_sats) = (SignedAmount::ZERO, 0u64);
1437214372
let our_funding_inputs = Vec::new();
1437314373

1437414374
let channel_value_satoshis =
1437514375
our_funding_contribution_sats.saturating_add(msg.common_fields.funding_satoshis);
14376-
// TODO(zero_reserve): support reading and writing the `disable_channel_reserve` field
1437714376
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
14378-
channel_value_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS, false);
14377+
channel_value_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS, msg.disable_channel_reserve.is_some());
1437914378
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
14380-
channel_value_satoshis, msg.common_fields.dust_limit_satoshis, false);
14379+
channel_value_satoshis, msg.common_fields.dust_limit_satoshis, trusted_channel_features.is_some_and(|f| f.is_0reserve()));
1438114380

1438214381
let channel_type = channel_type_from_open_channel(&msg.common_fields, our_supported_features)?;
1438314382

@@ -14399,7 +14398,7 @@ impl<SP: SignerProvider> PendingV2Channel<SP> {
1439914398
config,
1440014399
current_chain_height,
1440114400
logger,
14402-
None,
14401+
trusted_channel_features,
1440314402
our_funding_contribution_sats,
1440414403
counterparty_pubkeys,
1440514404
channel_type,
@@ -14518,6 +14517,8 @@ impl<SP: SignerProvider> PendingV2Channel<SP> {
1451814517
as u64,
1451914518
second_per_commitment_point,
1452014519
require_confirmed_inputs: None,
14520+
disable_channel_reserve: (self.funding.holder_selected_channel_reserve_satoshis == 0)
14521+
.then_some(()),
1452114522
}
1452214523
}
1452314524

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10950,6 +10950,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1095010950
&config,
1095110951
best_block_height,
1095210952
&self.logger,
10953+
trusted_channel_features,
1095310954
)
1095410955
.map_err(|e| {
1095510956
let channel_id = open_channel_msg.common_fields.temporary_channel_id;

lightning/src/ln/msgs.rs

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ pub struct OpenChannelV2 {
311311
pub second_per_commitment_point: PublicKey,
312312
/// Optionally, a requirement that only confirmed inputs can be added
313313
pub require_confirmed_inputs: Option<()>,
314+
/// Optionally, disables the channel reserve of the receiver
315+
pub disable_channel_reserve: Option<()>,
314316
}
315317

316318
/// Contains fields that are both common to [`accept_channel`] and [`accept_channel2`] messages.
@@ -390,6 +392,8 @@ pub struct AcceptChannelV2 {
390392
pub second_per_commitment_point: PublicKey,
391393
/// Optionally, a requirement that only confirmed inputs can be added
392394
pub require_confirmed_inputs: Option<()>,
395+
/// Optionally, disables the channel reserve of the receiver
396+
pub disable_channel_reserve: Option<()>,
393397
}
394398

395399
/// A [`funding_created`] message to be sent to or received from a peer.
@@ -3004,6 +3008,7 @@ impl Writeable for AcceptChannelV2 {
30043008
(0, self.common_fields.shutdown_scriptpubkey.as_ref().map(|s| WithoutLength(s)), option), // Don't encode length twice.
30053009
(1, self.common_fields.channel_type, option),
30063010
(2, self.require_confirmed_inputs, option),
3011+
(4, self.disable_channel_reserve, option),
30073012
});
30083013
Ok(())
30093014
}
@@ -3030,10 +3035,12 @@ impl LengthReadable for AcceptChannelV2 {
30303035
let mut shutdown_scriptpubkey: Option<ScriptBuf> = None;
30313036
let mut channel_type: Option<ChannelTypeFeatures> = None;
30323037
let mut require_confirmed_inputs: Option<()> = None;
3038+
let mut disable_channel_reserve: Option<()> = None;
30333039
decode_tlv_stream!(r, {
30343040
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))),
30353041
(1, channel_type, option),
30363042
(2, require_confirmed_inputs, option),
3043+
(4, disable_channel_reserve, option),
30373044
});
30383045

30393046
Ok(AcceptChannelV2 {
@@ -3057,6 +3064,7 @@ impl LengthReadable for AcceptChannelV2 {
30573064
funding_satoshis,
30583065
second_per_commitment_point,
30593066
require_confirmed_inputs,
3067+
disable_channel_reserve,
30603068
})
30613069
}
30623070
}
@@ -3465,6 +3473,7 @@ impl Writeable for OpenChannelV2 {
34653473
(0, self.common_fields.shutdown_scriptpubkey.as_ref().map(|s| WithoutLength(s)), option), // Don't encode length twice.
34663474
(1, self.common_fields.channel_type, option),
34673475
(2, self.require_confirmed_inputs, option),
3476+
(4, self.disable_channel_reserve, option),
34683477
});
34693478
Ok(())
34703479
}
@@ -3495,10 +3504,12 @@ impl LengthReadable for OpenChannelV2 {
34953504
let mut shutdown_scriptpubkey: Option<ScriptBuf> = None;
34963505
let mut channel_type: Option<ChannelTypeFeatures> = None;
34973506
let mut require_confirmed_inputs: Option<()> = None;
3507+
let mut disable_channel_reserve: Option<()> = None;
34983508
decode_tlv_stream!(r, {
34993509
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))),
35003510
(1, channel_type, option),
35013511
(2, require_confirmed_inputs, option),
3512+
(4, disable_channel_reserve, option),
35023513
});
35033514
Ok(OpenChannelV2 {
35043515
common_fields: CommonOpenChannelFields {
@@ -3525,6 +3536,7 @@ impl LengthReadable for OpenChannelV2 {
35253536
locktime,
35263537
second_per_commitment_point,
35273538
require_confirmed_inputs,
3539+
disable_channel_reserve,
35283540
})
35293541
}
35303542
}
@@ -5273,6 +5285,7 @@ mod tests {
52735285

52745286
fn do_encoding_open_channelv2(
52755287
random_bit: bool, shutdown: bool, incl_chan_type: bool, require_confirmed_inputs: bool,
5288+
disable_channel_reserve: bool,
52765289
) {
52775290
let secp_ctx = Secp256k1::new();
52785291
let (_, pubkey_1) = get_keys_from!(
@@ -5341,7 +5354,8 @@ mod tests {
53415354
funding_feerate_sat_per_1000_weight: 821716,
53425355
locktime: 305419896,
53435356
second_per_commitment_point: pubkey_7,
5344-
require_confirmed_inputs: if require_confirmed_inputs { Some(()) } else { None },
5357+
require_confirmed_inputs: require_confirmed_inputs.then_some(()),
5358+
disable_channel_reserve: disable_channel_reserve.then_some(()),
53455359
};
53465360
let encoded_value = open_channelv2.encode();
53475361
let mut target_value = Vec::new();
@@ -5426,27 +5440,46 @@ mod tests {
54265440
if require_confirmed_inputs {
54275441
target_value.append(&mut <Vec<u8>>::from_hex("0200").unwrap());
54285442
}
5443+
if disable_channel_reserve {
5444+
target_value.append(&mut <Vec<u8>>::from_hex("0400").unwrap());
5445+
}
54295446
assert_eq!(encoded_value, target_value);
54305447
}
54315448

54325449
#[test]
54335450
fn encoding_open_channelv2() {
5434-
do_encoding_open_channelv2(false, false, false, false);
5435-
do_encoding_open_channelv2(false, false, false, true);
5436-
do_encoding_open_channelv2(false, false, true, false);
5437-
do_encoding_open_channelv2(false, false, true, true);
5438-
do_encoding_open_channelv2(false, true, false, false);
5439-
do_encoding_open_channelv2(false, true, false, true);
5440-
do_encoding_open_channelv2(false, true, true, false);
5441-
do_encoding_open_channelv2(false, true, true, true);
5442-
do_encoding_open_channelv2(true, false, false, false);
5443-
do_encoding_open_channelv2(true, false, false, true);
5444-
do_encoding_open_channelv2(true, false, true, false);
5445-
do_encoding_open_channelv2(true, false, true, true);
5446-
do_encoding_open_channelv2(true, true, false, false);
5447-
do_encoding_open_channelv2(true, true, false, true);
5448-
do_encoding_open_channelv2(true, true, true, false);
5449-
do_encoding_open_channelv2(true, true, true, true);
5451+
do_encoding_open_channelv2(false, false, false, false, false);
5452+
do_encoding_open_channelv2(false, false, false, false, true);
5453+
do_encoding_open_channelv2(false, false, false, true, false);
5454+
do_encoding_open_channelv2(false, false, false, true, true);
5455+
do_encoding_open_channelv2(false, false, true, false, false);
5456+
do_encoding_open_channelv2(false, false, true, false, true);
5457+
do_encoding_open_channelv2(false, false, true, true, false);
5458+
do_encoding_open_channelv2(false, false, true, true, true);
5459+
do_encoding_open_channelv2(false, true, false, false, false);
5460+
do_encoding_open_channelv2(false, true, false, false, true);
5461+
do_encoding_open_channelv2(false, true, false, true, false);
5462+
do_encoding_open_channelv2(false, true, false, true, true);
5463+
do_encoding_open_channelv2(false, true, true, false, false);
5464+
do_encoding_open_channelv2(false, true, true, false, true);
5465+
do_encoding_open_channelv2(false, true, true, true, false);
5466+
do_encoding_open_channelv2(false, true, true, true, true);
5467+
do_encoding_open_channelv2(true, false, false, false, false);
5468+
do_encoding_open_channelv2(true, false, false, false, true);
5469+
do_encoding_open_channelv2(true, false, false, true, false);
5470+
do_encoding_open_channelv2(true, false, false, true, true);
5471+
do_encoding_open_channelv2(true, false, true, false, false);
5472+
do_encoding_open_channelv2(true, false, true, false, true);
5473+
do_encoding_open_channelv2(true, false, true, true, false);
5474+
do_encoding_open_channelv2(true, false, true, true, true);
5475+
do_encoding_open_channelv2(true, true, false, false, false);
5476+
do_encoding_open_channelv2(true, true, false, false, true);
5477+
do_encoding_open_channelv2(true, true, false, true, false);
5478+
do_encoding_open_channelv2(true, true, false, true, true);
5479+
do_encoding_open_channelv2(true, true, true, false, false);
5480+
do_encoding_open_channelv2(true, true, true, false, true);
5481+
do_encoding_open_channelv2(true, true, true, true, false);
5482+
do_encoding_open_channelv2(true, true, true, true, true);
54505483
}
54515484

54525485
fn do_encoding_accept_channel(shutdown: bool) {
@@ -5524,7 +5557,10 @@ mod tests {
55245557
do_encoding_accept_channel(true);
55255558
}
55265559

5527-
fn do_encoding_accept_channelv2(shutdown: bool) {
5560+
fn do_encoding_accept_channelv2(
5561+
shutdown: bool, incl_chan_type: bool, require_confirmed_inputs: bool,
5562+
disable_channel_reserve: bool,
5563+
) {
55285564
let secp_ctx = Secp256k1::new();
55295565
let (_, pubkey_1) = get_keys_from!(
55305566
"0101010101010101010101010101010101010101010101010101010101010101",
@@ -5580,11 +5616,16 @@ mod tests {
55805616
} else {
55815617
None
55825618
},
5583-
channel_type: None,
5619+
channel_type: if incl_chan_type {
5620+
Some(ChannelTypeFeatures::empty())
5621+
} else {
5622+
None
5623+
},
55845624
},
55855625
funding_satoshis: 1311768467284833366,
55865626
second_per_commitment_point: pubkey_7,
5587-
require_confirmed_inputs: None,
5627+
require_confirmed_inputs: require_confirmed_inputs.then_some(()),
5628+
disable_channel_reserve: disable_channel_reserve.then_some(()),
55885629
};
55895630
let encoded_value = accept_channelv2.encode();
55905631
let mut target_value =
@@ -5645,13 +5686,36 @@ mod tests {
56455686
.unwrap(),
56465687
);
56475688
}
5689+
if incl_chan_type {
5690+
target_value.append(&mut <Vec<u8>>::from_hex("0100").unwrap());
5691+
}
5692+
if require_confirmed_inputs {
5693+
target_value.append(&mut <Vec<u8>>::from_hex("0200").unwrap());
5694+
}
5695+
if disable_channel_reserve {
5696+
target_value.append(&mut <Vec<u8>>::from_hex("0400").unwrap());
5697+
}
56485698
assert_eq!(encoded_value, target_value);
56495699
}
56505700

56515701
#[test]
56525702
fn encoding_accept_channelv2() {
5653-
do_encoding_accept_channelv2(false);
5654-
do_encoding_accept_channelv2(true);
5703+
do_encoding_accept_channelv2(false, false, false, false);
5704+
do_encoding_accept_channelv2(false, false, false, true);
5705+
do_encoding_accept_channelv2(false, false, true, false);
5706+
do_encoding_accept_channelv2(false, false, true, true);
5707+
do_encoding_accept_channelv2(false, true, false, false);
5708+
do_encoding_accept_channelv2(false, true, false, true);
5709+
do_encoding_accept_channelv2(false, true, true, false);
5710+
do_encoding_accept_channelv2(false, true, true, true);
5711+
do_encoding_accept_channelv2(true, false, false, false);
5712+
do_encoding_accept_channelv2(true, false, false, true);
5713+
do_encoding_accept_channelv2(true, false, true, false);
5714+
do_encoding_accept_channelv2(true, false, true, true);
5715+
do_encoding_accept_channelv2(true, true, false, false);
5716+
do_encoding_accept_channelv2(true, true, false, true);
5717+
do_encoding_accept_channelv2(true, true, true, false);
5718+
do_encoding_accept_channelv2(true, true, true, true);
56555719
}
56565720

56575721
#[test]

0 commit comments

Comments
 (0)