Skip to content

Commit 6e415b6

Browse files
committed
Preparations for splicing transaction negotiation
1 parent 5206e98 commit 6e415b6

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

lightning/src/ln/channel.rs

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ use crate::ln::interactivetxs::{
3434
InteractiveTxConstructorArgs, InteractiveTxMessageSend, InteractiveTxSigningSession, InteractiveTxMessageSendResult,
3535
OutputOwned, SharedOwnedOutput, TX_COMMON_FIELDS_WEIGHT,
3636
};
37+
#[cfg(splicing)]
38+
use crate::ln::interactivetxs::InteractiveTxMessageSend;
3739
use crate::ln::msgs;
3840
use crate::ln::msgs::{ClosingSigned, ClosingSignedFeeRange, DecodeError};
3941
use crate::ln::script::{self, ShutdownScript};
@@ -1187,6 +1189,10 @@ impl UnfundedChannelContext {
11871189
#[derive(Clone)]
11881190
struct PendingSpliceInfoPre {
11891191
pub our_funding_contribution: i64,
1192+
pub funding_feerate_perkw: u32,
1193+
pub locktime: u32,
1194+
/// The funding inputs that we plan to contributing to the splice.
1195+
pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
11901196
}
11911197

11921198
#[cfg(splicing)]
@@ -4265,6 +4271,18 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
42654271
self.get_initial_counterparty_commitment_signature(logger)
42664272
}
42674273

4274+
/// Splice process starting; update state, log, etc.
4275+
#[cfg(splicing)]
4276+
pub(crate) fn splice_start<L: Deref>(&mut self, is_outgoing: bool, logger: &L) where L::Target: Logger {
4277+
// Set state, by this point splice_init/splice_ack handshake is complete
4278+
// TODO(splicing)
4279+
// self.channel_state = ChannelState::NegotiatingFunding(
4280+
// NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
4281+
// );
4282+
log_info!(logger, "Splicing process started, old channel value {}, outgoing {}, channel_id {}",
4283+
self.channel_value_satoshis, is_outgoing, self.channel_id);
4284+
}
4285+
42684286
/// Get the splice message that can be sent during splice initiation.
42694287
#[cfg(splicing)]
42704288
pub fn get_splice_init(&self, our_funding_contribution_satoshis: i64,
@@ -8062,10 +8080,15 @@ impl<SP: Deref> Channel<SP> where
80628080
// Note: post-splice channel value is not yet known at this point, counterpary contribution is not known
80638081
// (Cannot test for miminum required post-splice channel value)
80648082

8083+
// Sum and convert inputs
8084+
let mut sum_input = 0i64;
8085+
let mut funding_inputs = Vec::new();
8086+
for (tx_in, tx) in our_funding_inputs.into_iter() {
8087+
sum_input += tx.output.get(tx_in.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0);
8088+
let tx16 = TransactionU16LenLimited::new(tx).map_err(|_e| ChannelError::Warn(format!("Too large transaction")))?;
8089+
funding_inputs.push((tx_in, tx16));
8090+
}
80658091
// Check that inputs are sufficient to cover our contribution
8066-
let sum_input: i64 = our_funding_inputs.into_iter().fold(0, |acc, i|
8067-
acc + i.1.output.get(i.0.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0)
8068-
);
80698092
if sum_input < our_funding_contribution_satoshis {
80708093
return Err(ChannelError::Warn(format!(
80718094
"Provided inputs are insufficient for our contribution, {} {}",
@@ -8075,6 +8098,9 @@ impl<SP: Deref> Channel<SP> where
80758098

80768099
self.pending_splice_pre = Some(PendingSpliceInfoPre {
80778100
our_funding_contribution: our_funding_contribution_satoshis,
8101+
funding_feerate_perkw,
8102+
locktime,
8103+
our_funding_inputs: funding_inputs,
80788104
});
80798105

80808106
let msg = self.context.get_splice_init(our_funding_contribution_satoshis, funding_feerate_perkw, locktime);
@@ -8083,7 +8109,9 @@ impl<SP: Deref> Channel<SP> where
80838109

80848110
/// Handle splice_init
80858111
#[cfg(splicing)]
8086-
pub fn splice_init(&mut self, msg: &msgs::SpliceInit) -> Result<msgs::SpliceAck, ChannelError> {
8112+
pub fn splice_init<ES: Deref, L: Deref>(
8113+
&mut self, msg: &msgs::SpliceInit, _signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, logger: &L,
8114+
) -> Result<msgs::SpliceAck, ChannelError> where ES::Target: EntropySource, L::Target: Logger {
80878115
let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
80888116
// TODO(splicing): Currently not possible to contribute on the splicing-acceptor side
80898117
let our_funding_contribution_satoshis = 0i64;
@@ -8126,16 +8154,24 @@ impl<SP: Deref> Channel<SP> where
81268154
let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
81278155

81288156
// TODO(splicing): Store msg.funding_pubkey
8129-
// TODO(splicing): Apply start of splice (splice_start)
8157+
8158+
// Apply start of splice change in the state
8159+
self.context.splice_start(false, logger);
81308160

81318161
let splice_ack_msg = self.context.get_splice_ack(our_funding_contribution_satoshis);
8162+
81328163
// TODO(splicing): start interactive funding negotiation
8164+
// let _msg = self.begin_interactive_funding_tx_construction(signer_provider, entropy_source, holder_node_id)
8165+
// .map_err(|err| ChannelError::Warn(format!("Failed to start interactive transaction construction, {:?}", err)))?;
8166+
81338167
Ok(splice_ack_msg)
81348168
}
81358169

81368170
/// Handle splice_ack
81378171
#[cfg(splicing)]
8138-
pub fn splice_ack(&mut self, msg: &msgs::SpliceAck) -> Result<(), ChannelError> {
8172+
pub fn splice_ack<ES: Deref, L: Deref>(
8173+
&mut self, msg: &msgs::SpliceAck, _signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, logger: &L,
8174+
) -> Result<Option<InteractiveTxMessageSend>, ChannelError> where ES::Target: EntropySource, L::Target: Logger {
81398175
let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
81408176

81418177
// check if splice is pending
@@ -8153,7 +8189,15 @@ impl<SP: Deref> Channel<SP> where
81538189
// Early check for reserve requirement, assuming maximum balance of full channel value
81548190
// This will also be checked later at tx_complete
81558191
let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8156-
Ok(())
8192+
8193+
// Apply start of splice change in the state
8194+
self.context.splice_start(true, logger);
8195+
8196+
// TODO(splicing): start interactive funding negotiation
8197+
// let tx_msg_opt = self.begin_interactive_funding_tx_construction(signer_provider, entropy_source, holder_node_id)
8198+
// .map_err(|err| ChannelError::Warn(format!("V2 channel rejected due to sender error, {:?}", err)))?;
8199+
// Ok(tx_msg_opt)
8200+
Ok(None)
81578201
}
81588202

81598203
// 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
@@ -9429,7 +9429,7 @@ where
94299429
), msg.channel_id)),
94309430
hash_map::Entry::Occupied(mut chan_entry) => {
94319431
if let ChannelPhase::Funded(chan) = chan_entry.get_mut() {
9432-
match chan.splice_init(msg) {
9432+
match chan.splice_init(msg, &self.signer_provider, &self.entropy_source, self.get_our_node_id(), &self.logger) {
94339433
Ok(splice_ack_msg) => {
94349434
peer_state.pending_msg_events.push(events::MessageSendEvent::SendSpliceAck {
94359435
node_id: *counterparty_node_id,
@@ -9474,8 +9474,12 @@ where
94749474
), msg.channel_id)),
94759475
hash_map::Entry::Occupied(mut chan) => {
94769476
if let ChannelPhase::Funded(chan) = chan.get_mut() {
9477-
match chan.splice_ack(msg) {
9478-
Ok(_) => {}
9477+
match chan.splice_ack(msg, &self.signer_provider, &self.entropy_source, self.get_our_node_id(), &self.logger) {
9478+
Ok(tx_msg_opt) => {
9479+
if let Some(tx_msg_opt) = tx_msg_opt {
9480+
peer_state.pending_msg_events.push(tx_msg_opt.into_msg_send_event(counterparty_node_id.clone()));
9481+
}
9482+
}
94799483
Err(err) => {
94809484
return Err(MsgHandleErrInternal::from_chan_no_close(err, msg.channel_id));
94819485
}

0 commit comments

Comments
 (0)