Skip to content

Commit 55e1eff

Browse files
committed
Add pending funding scopes to FundedChannel
Once a channel is funded, it may be spliced to add or remove funds. The new funding transaction is pending until confirmed on chain and thus needs to be tracked. Additionally, it may be replaced by another transaction using RBF with a higher fee. Hence, there may be more than one pending FundingScope to track for a splice. This commit adds support for tracking pending funding scopes. The following commits will account for any pending scopes where applicable (e.g., when handling commitment_signed).
1 parent 347a375 commit 55e1eff

File tree

4 files changed

+75
-12
lines changed

4 files changed

+75
-12
lines changed

lightning/src/chain/onchaintx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
368368
let prev_holder_commitment = Readable::read(reader)?;
369369
let _prev_holder_htlc_sigs: Option<Vec<Option<(usize, Signature)>>> = Readable::read(reader)?;
370370

371-
let channel_parameters = ReadableArgs::<u64>::read(reader, channel_value_satoshis)?;
371+
let channel_parameters = ReadableArgs::<Option<u64>>::read(reader, Some(channel_value_satoshis))?;
372372

373373
// Read the serialized signer bytes, but don't deserialize them, as we'll obtain our signer
374374
// by re-deriving the private key material.

lightning/src/ln/chan_utils.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,8 +1034,8 @@ impl Writeable for ChannelTransactionParameters {
10341034
}
10351035
}
10361036

1037-
impl ReadableArgs<u64> for ChannelTransactionParameters {
1038-
fn read<R: io::Read>(reader: &mut R, read_args: u64) -> Result<Self, DecodeError> {
1037+
impl ReadableArgs<Option<u64>> for ChannelTransactionParameters {
1038+
fn read<R: io::Read>(reader: &mut R, read_args: Option<u64>) -> Result<Self, DecodeError> {
10391039
let mut holder_pubkeys = RequiredWrapper(None);
10401040
let mut holder_selected_contest_delay = RequiredWrapper(None);
10411041
let mut is_outbound_from_holder = RequiredWrapper(None);
@@ -1058,10 +1058,17 @@ impl ReadableArgs<u64> for ChannelTransactionParameters {
10581058
(13, channel_value_satoshis, option),
10591059
});
10601060

1061-
let channel_value_satoshis = channel_value_satoshis.unwrap_or(read_args);
1062-
if channel_value_satoshis != read_args {
1063-
return Err(DecodeError::InvalidValue);
1064-
}
1061+
let channel_value_satoshis = match read_args {
1062+
None => channel_value_satoshis.ok_or(DecodeError::InvalidValue)?,
1063+
Some(expected_value) => {
1064+
let channel_value_satoshis = channel_value_satoshis.unwrap_or(expected_value);
1065+
if channel_value_satoshis == expected_value {
1066+
channel_value_satoshis
1067+
} else {
1068+
return Err(DecodeError::InvalidValue);
1069+
}
1070+
},
1071+
};
10651072

10661073
let mut additional_features = ChannelTypeFeatures::empty();
10671074
additional_features.set_anchors_nonzero_fee_htlc_tx_required();

lightning/src/ln/channel.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use crate::sign::{EntropySource, ChannelSigner, SignerProvider, NodeSigner, Reci
6060
use crate::events::{ClosureReason, Event};
6161
use crate::events::bump_transaction::BASE_INPUT_WEIGHT;
6262
use crate::routing::gossip::NodeId;
63-
use crate::util::ser::{Readable, ReadableArgs, TransactionU16LenLimited, Writeable, Writer};
63+
use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, TransactionU16LenLimited, Writeable, Writer};
6464
use crate::util::logger::{Logger, Record, WithContext};
6565
use crate::util::errors::APIError;
6666
use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure};
@@ -1517,6 +1517,7 @@ impl<SP: Deref> Channel<SP> where
15171517
};
15181518
let mut funded_channel = FundedChannel {
15191519
funding: chan.funding,
1520+
pending_funding: vec![],
15201521
context: chan.context,
15211522
interactive_tx_signing_session: chan.interactive_tx_signing_session,
15221523
holder_commitment_point,
@@ -1663,6 +1664,53 @@ pub(super) struct FundingScope {
16631664
funding_transaction: Option<Transaction>,
16641665
}
16651666

1667+
impl Writeable for FundingScope {
1668+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1669+
write_tlv_fields!(writer, {
1670+
(1, self.value_to_self_msat, required),
1671+
(3, self.counterparty_selected_channel_reserve_satoshis, option),
1672+
(5, self.holder_selected_channel_reserve_satoshis, required),
1673+
(7, self.channel_transaction_parameters, (required: ReadableArgs, None)),
1674+
(9, self.funding_transaction, option),
1675+
});
1676+
Ok(())
1677+
}
1678+
}
1679+
1680+
impl Readable for FundingScope {
1681+
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
1682+
let mut value_to_self_msat = RequiredWrapper(None);
1683+
let mut counterparty_selected_channel_reserve_satoshis = None;
1684+
let mut holder_selected_channel_reserve_satoshis = RequiredWrapper(None);
1685+
let mut channel_transaction_parameters = RequiredWrapper(None);
1686+
let mut funding_transaction = None;
1687+
1688+
read_tlv_fields!(reader, {
1689+
(1, value_to_self_msat, required),
1690+
(3, counterparty_selected_channel_reserve_satoshis, option),
1691+
(5, holder_selected_channel_reserve_satoshis, required),
1692+
(7, channel_transaction_parameters, (required: ReadableArgs, None)),
1693+
(9, funding_transaction, option),
1694+
});
1695+
1696+
Ok(Self {
1697+
value_to_self_msat: value_to_self_msat.0.unwrap(),
1698+
counterparty_selected_channel_reserve_satoshis,
1699+
holder_selected_channel_reserve_satoshis: holder_selected_channel_reserve_satoshis.0.unwrap(),
1700+
#[cfg(debug_assertions)]
1701+
holder_max_commitment_tx_output: Mutex::new((0, 0)),
1702+
#[cfg(debug_assertions)]
1703+
counterparty_max_commitment_tx_output: Mutex::new((0, 0)),
1704+
channel_transaction_parameters: channel_transaction_parameters.0.unwrap(),
1705+
funding_transaction,
1706+
#[cfg(any(test, fuzzing))]
1707+
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
1708+
#[cfg(any(test, fuzzing))]
1709+
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
1710+
})
1711+
}
1712+
}
1713+
16661714
impl FundingScope {
16671715
pub fn get_value_satoshis(&self) -> u64 {
16681716
self.channel_transaction_parameters.channel_value_satoshis
@@ -4943,6 +4991,7 @@ pub(super) struct DualFundingChannelContext {
49434991
// Counterparty designates channel data owned by the another channel participant entity.
49444992
pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
49454993
pub funding: FundingScope,
4994+
pending_funding: Vec<FundingScope>,
49464995
pub context: ChannelContext<SP>,
49474996
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
49484997
holder_commitment_point: HolderCommitmentPoint,
@@ -9531,6 +9580,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
95319580

95329581
let mut channel = FundedChannel {
95339582
funding: self.funding,
9583+
pending_funding: vec![],
95349584
context: self.context,
95359585
interactive_tx_signing_session: None,
95369586
is_v2_established: false,
@@ -9807,6 +9857,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
98079857
// `ChannelMonitor`.
98089858
let mut channel = FundedChannel {
98099859
funding: self.funding,
9860+
pending_funding: vec![],
98109861
context: self.context,
98119862
interactive_tx_signing_session: None,
98129863
is_v2_established: false,
@@ -10605,6 +10656,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1060510656
(49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
1060610657
(51, is_manual_broadcast, option), // Added in 0.0.124
1060710658
(53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
10659+
(54, self.pending_funding, optional_vec), // Added in 0.2
1060810660
});
1060910661

1061010662
Ok(())
@@ -10829,7 +10881,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1082910881
_ => return Err(DecodeError::InvalidValue),
1083010882
};
1083110883

10832-
let channel_parameters: ChannelTransactionParameters = ReadableArgs::<u64>::read(reader, channel_value_satoshis)?;
10884+
let channel_parameters: ChannelTransactionParameters = ReadableArgs::<Option<u64>>::read(reader, Some(channel_value_satoshis))?;
1083310885
let funding_transaction: Option<Transaction> = Readable::read(reader)?;
1083410886

1083510887
let counterparty_cur_commitment_point = Readable::read(reader)?;
@@ -10896,6 +10948,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1089610948
let mut next_holder_commitment_point_opt: Option<PublicKey> = None;
1089710949
let mut is_manual_broadcast = None;
1089810950

10951+
let mut pending_funding = Some(Vec::new());
10952+
1089910953
read_tlv_fields!(reader, {
1090010954
(0, announcement_sigs, option),
1090110955
(1, minimum_depth, option),
@@ -10931,6 +10985,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1093110985
(49, local_initiated_shutdown, option),
1093210986
(51, is_manual_broadcast, option),
1093310987
(53, funding_tx_broadcast_safe_event_emitted, option),
10988+
(54, pending_funding, optional_vec), // Added in 0.2
1093410989
});
1093510990

1093610991
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -11072,6 +11127,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1107211127
channel_transaction_parameters: channel_parameters,
1107311128
funding_transaction,
1107411129
},
11130+
pending_funding: pending_funding.unwrap(),
1107511131
context: ChannelContext {
1107611132
user_id,
1107711133

lightning/src/sign/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl_writeable_tlv_based!(DelayedPaymentOutputDescriptor, {
124124
(8, revocation_pubkey, required),
125125
(10, channel_keys_id, required),
126126
(12, channel_value_satoshis, required),
127-
(13, channel_transaction_parameters, (option: ReadableArgs, channel_value_satoshis.0.unwrap())),
127+
(13, channel_transaction_parameters, (option: ReadableArgs, Some(channel_value_satoshis.0.unwrap()))),
128128
});
129129

130130
pub(crate) const P2WPKH_WITNESS_WEIGHT: u64 = 1 /* num stack items */ +
@@ -199,7 +199,7 @@ impl_writeable_tlv_based!(StaticPaymentOutputDescriptor, {
199199
(2, output, required),
200200
(4, channel_keys_id, required),
201201
(6, channel_value_satoshis, required),
202-
(7, channel_transaction_parameters, (option: ReadableArgs, channel_value_satoshis.0.unwrap())),
202+
(7, channel_transaction_parameters, (option: ReadableArgs, Some(channel_value_satoshis.0.unwrap()))),
203203
});
204204

205205
/// Describes the necessary information to spend a spendable output.
@@ -559,7 +559,7 @@ pub struct ChannelDerivationParameters {
559559
impl_writeable_tlv_based!(ChannelDerivationParameters, {
560560
(0, value_satoshis, required),
561561
(2, keys_id, required),
562-
(4, transaction_parameters, (required: ReadableArgs, value_satoshis.0.unwrap())),
562+
(4, transaction_parameters, (required: ReadableArgs, Some(value_satoshis.0.unwrap()))),
563563
});
564564

565565
/// A descriptor used to sign for a commitment transaction's HTLC output.

0 commit comments

Comments
 (0)