Skip to content

Commit c40f6dd

Browse files
committed
Preparations for splicing transaction negotiation
1 parent f59873d commit c40f6dd

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

lightning/src/ln/channel.rs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,10 @@ impl FundingScope {
17241724
#[derive(Clone)]
17251725
struct PendingSpliceInfoPre {
17261726
pub our_funding_contribution: i64,
1727+
pub funding_feerate_perkw: u32,
1728+
pub locktime: u32,
1729+
/// The funding inputs that we plan to contributing to the splice.
1730+
pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
17271731
}
17281732

17291733
#[cfg(splicing)]
@@ -4733,6 +4737,18 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
47334737
self.get_initial_counterparty_commitment_signature(funding, logger)
47344738
}
47354739

4740+
/// Splice process starting; update state, log, etc.
4741+
#[cfg(splicing)]
4742+
pub(crate) fn splice_start<L: Deref>(&mut self, is_outgoing: bool, logger: &L) where L::Target: Logger {
4743+
// Set state, by this point splice_init/splice_ack handshake is complete
4744+
// TODO(splicing)
4745+
// self.channel_state = ChannelState::NegotiatingFunding(
4746+
// NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
4747+
// );
4748+
log_info!(logger, "Splicing process started, old channel value {}, outgoing {}, channel_id {}",
4749+
self.channel_value_satoshis, is_outgoing, self.channel_id);
4750+
}
4751+
47364752
/// Get the splice message that can be sent during splice initiation.
47374753
#[cfg(splicing)]
47384754
pub fn get_splice_init(&self, our_funding_contribution_satoshis: i64,
@@ -8550,10 +8566,15 @@ impl<SP: Deref> FundedChannel<SP> where
85508566
// Note: post-splice channel value is not yet known at this point, counterpary contribution is not known
85518567
// (Cannot test for miminum required post-splice channel value)
85528568

8569+
// Sum and convert inputs
8570+
let mut sum_input = 0i64;
8571+
let mut funding_inputs = Vec::new();
8572+
for (tx_in, tx) in our_funding_inputs.into_iter() {
8573+
sum_input += tx.output.get(tx_in.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0);
8574+
let tx16 = TransactionU16LenLimited::new(tx).map_err(|_e| ChannelError::Warn(format!("Too large transaction")))?;
8575+
funding_inputs.push((tx_in, tx16));
8576+
}
85538577
// Check that inputs are sufficient to cover our contribution
8554-
let sum_input: i64 = our_funding_inputs.into_iter().fold(0, |acc, i|
8555-
acc + i.1.output.get(i.0.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0)
8556-
);
85578578
if sum_input < our_funding_contribution_satoshis {
85588579
return Err(ChannelError::Warn(format!(
85598580
"Provided inputs are insufficient for our contribution, {} {}",
@@ -8563,6 +8584,9 @@ impl<SP: Deref> FundedChannel<SP> where
85638584

85648585
self.pending_splice_pre = Some(PendingSpliceInfoPre {
85658586
our_funding_contribution: our_funding_contribution_satoshis,
8587+
funding_feerate_perkw,
8588+
locktime,
8589+
our_funding_inputs: funding_inputs,
85668590
});
85678591

85688592
let msg = self.context.get_splice_init(our_funding_contribution_satoshis, funding_feerate_perkw, locktime);
@@ -8571,7 +8595,9 @@ impl<SP: Deref> FundedChannel<SP> where
85718595

85728596
/// Handle splice_init
85738597
#[cfg(splicing)]
8574-
pub fn splice_init(&mut self, msg: &msgs::SpliceInit) -> Result<msgs::SpliceAck, ChannelError> {
8598+
pub fn splice_init<ES: Deref, L: Deref>(
8599+
&mut self, msg: &msgs::SpliceInit, _signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, logger: &L,
8600+
) -> Result<msgs::SpliceAck, ChannelError> where ES::Target: EntropySource, L::Target: Logger {
85758601
let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
85768602
// TODO(splicing): Currently not possible to contribute on the splicing-acceptor side
85778603
let our_funding_contribution_satoshis = 0i64;
@@ -8614,16 +8640,24 @@ impl<SP: Deref> FundedChannel<SP> where
86148640
let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
86158641

86168642
// TODO(splicing): Store msg.funding_pubkey
8617-
// TODO(splicing): Apply start of splice (splice_start)
8643+
8644+
// Apply start of splice change in the state
8645+
self.context.splice_start(false, logger);
86188646

86198647
let splice_ack_msg = self.context.get_splice_ack(our_funding_contribution_satoshis);
8648+
86208649
// TODO(splicing): start interactive funding negotiation
8650+
// let _msg = self.begin_interactive_funding_tx_construction(signer_provider, entropy_source, holder_node_id)
8651+
// .map_err(|err| ChannelError::Warn(format!("Failed to start interactive transaction construction, {:?}", err)))?;
8652+
86218653
Ok(splice_ack_msg)
86228654
}
86238655

86248656
/// Handle splice_ack
86258657
#[cfg(splicing)]
8626-
pub fn splice_ack(&mut self, msg: &msgs::SpliceAck) -> Result<(), ChannelError> {
8658+
pub fn splice_ack<ES: Deref, L: Deref>(
8659+
&mut self, msg: &msgs::SpliceAck, _signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, logger: &L,
8660+
) -> Result<Option<InteractiveTxMessageSend>, ChannelError> where ES::Target: EntropySource, L::Target: Logger {
86278661
let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
86288662

86298663
// check if splice is pending
@@ -8641,7 +8675,15 @@ impl<SP: Deref> FundedChannel<SP> where
86418675
// Early check for reserve requirement, assuming maximum balance of full channel value
86428676
// This will also be checked later at tx_complete
86438677
let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8644-
Ok(())
8678+
8679+
// Apply start of splice change in the state
8680+
self.context.splice_start(true, logger);
8681+
8682+
// TODO(splicing): start interactive funding negotiation
8683+
// let tx_msg_opt = self.begin_interactive_funding_tx_construction(signer_provider, entropy_source, holder_node_id)
8684+
// .map_err(|err| ChannelError::Warn(format!("V2 channel rejected due to sender error, {:?}", err)))?;
8685+
// Ok(tx_msg_opt)
8686+
Ok(None)
86458687
}
86468688

86478689
// Send stuff to our remote peers:

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9536,7 +9536,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
95369536
), msg.channel_id)),
95379537
hash_map::Entry::Occupied(mut chan_entry) => {
95389538
if let Some(chan) = chan_entry.get_mut().as_funded_mut() {
9539-
match chan.splice_init(msg) {
9539+
match chan.splice_init(msg, &self.signer_provider, &self.entropy_source, self.get_our_node_id(), &self.logger) {
95409540
Ok(splice_ack_msg) => {
95419541
peer_state.pending_msg_events.push(events::MessageSendEvent::SendSpliceAck {
95429542
node_id: *counterparty_node_id,
@@ -9581,8 +9581,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
95819581
), msg.channel_id)),
95829582
hash_map::Entry::Occupied(mut chan) => {
95839583
if let Some(chan) = chan.get_mut().as_funded_mut() {
9584-
match chan.splice_ack(msg) {
9585-
Ok(_) => {}
9584+
match chan.splice_ack(msg, &self.signer_provider, &self.entropy_source, self.get_our_node_id(), &self.logger) {
9585+
Ok(tx_msg_opt) => {
9586+
if let Some(tx_msg_opt) = tx_msg_opt {
9587+
peer_state.pending_msg_events.push(tx_msg_opt.into_msg_send_event(counterparty_node_id.clone()));
9588+
}
9589+
}
95869590
Err(err) => {
95879591
return Err(MsgHandleErrInternal::from_chan_no_close(err, msg.channel_id));
95889592
}

0 commit comments

Comments
 (0)