@@ -34,6 +34,8 @@ use crate::ln::interactivetxs::{
34
34
InteractiveTxConstructorArgs, InteractiveTxMessageSend, InteractiveTxSigningSession, InteractiveTxMessageSendResult,
35
35
OutputOwned, SharedOwnedOutput, TX_COMMON_FIELDS_WEIGHT,
36
36
};
37
+ #[cfg(splicing)]
38
+ use crate::ln::interactivetxs::InteractiveTxMessageSend;
37
39
use crate::ln::msgs;
38
40
use crate::ln::msgs::{ClosingSigned, ClosingSignedFeeRange, DecodeError};
39
41
use crate::ln::script::{self, ShutdownScript};
@@ -1191,6 +1193,10 @@ impl UnfundedChannelContext {
1191
1193
#[derive(Clone)]
1192
1194
struct PendingSpliceInfoPre {
1193
1195
pub our_funding_contribution: i64,
1196
+ pub funding_feerate_perkw: u32,
1197
+ pub locktime: u32,
1198
+ /// The funding inputs that we plan to contributing to the splice.
1199
+ pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
1194
1200
}
1195
1201
1196
1202
#[cfg(splicing)]
@@ -4268,6 +4274,18 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
4268
4274
self.get_initial_counterparty_commitment_signature(logger)
4269
4275
}
4270
4276
4277
+ /// Splice process starting; update state, log, etc.
4278
+ #[cfg(splicing)]
4279
+ pub(crate) fn splice_start<L: Deref>(&mut self, is_outgoing: bool, logger: &L) where L::Target: Logger {
4280
+ // Set state, by this point splice_init/splice_ack handshake is complete
4281
+ // TODO(splicing)
4282
+ // self.channel_state = ChannelState::NegotiatingFunding(
4283
+ // NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
4284
+ // );
4285
+ log_info!(logger, "Splicing process started, old channel value {}, outgoing {}, channel_id {}",
4286
+ self.channel_value_satoshis, is_outgoing, self.channel_id);
4287
+ }
4288
+
4271
4289
/// Get the splice message that can be sent during splice initiation.
4272
4290
#[cfg(splicing)]
4273
4291
pub fn get_splice_init(&self, our_funding_contribution_satoshis: i64,
@@ -8077,10 +8095,15 @@ impl<SP: Deref> Channel<SP> where
8077
8095
// Note: post-splice channel value is not yet known at this point, counterpary contribution is not known
8078
8096
// (Cannot test for miminum required post-splice channel value)
8079
8097
8098
+ // Sum and convert inputs
8099
+ let mut sum_input = 0i64;
8100
+ let mut funding_inputs = Vec::new();
8101
+ for (tx_in, tx) in our_funding_inputs.into_iter() {
8102
+ sum_input += tx.output.get(tx_in.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0);
8103
+ let tx16 = TransactionU16LenLimited::new(tx).map_err(|_e| ChannelError::Warn(format!("Too large transaction")))?;
8104
+ funding_inputs.push((tx_in, tx16));
8105
+ }
8080
8106
// Check that inputs are sufficient to cover our contribution
8081
- let sum_input: i64 = our_funding_inputs.into_iter().fold(0, |acc, i|
8082
- acc + i.1.output.get(i.0.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0)
8083
- );
8084
8107
if sum_input < our_funding_contribution_satoshis {
8085
8108
return Err(ChannelError::Warn(format!(
8086
8109
"Provided inputs are insufficient for our contribution, {} {}",
@@ -8090,6 +8113,9 @@ impl<SP: Deref> Channel<SP> where
8090
8113
8091
8114
self.pending_splice_pre = Some(PendingSpliceInfoPre {
8092
8115
our_funding_contribution: our_funding_contribution_satoshis,
8116
+ funding_feerate_perkw,
8117
+ locktime,
8118
+ our_funding_inputs: funding_inputs,
8093
8119
});
8094
8120
8095
8121
let msg = self.context.get_splice_init(our_funding_contribution_satoshis, funding_feerate_perkw, locktime);
@@ -8098,7 +8124,9 @@ impl<SP: Deref> Channel<SP> where
8098
8124
8099
8125
/// Handle splice_init
8100
8126
#[cfg(splicing)]
8101
- pub fn splice_init(&mut self, msg: &msgs::SpliceInit) -> Result<msgs::SpliceAck, ChannelError> {
8127
+ pub fn splice_init<ES: Deref, L: Deref>(
8128
+ &mut self, msg: &msgs::SpliceInit, _signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, logger: &L,
8129
+ ) -> Result<msgs::SpliceAck, ChannelError> where ES::Target: EntropySource, L::Target: Logger {
8102
8130
let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
8103
8131
// TODO(splicing): Currently not possible to contribute on the splicing-acceptor side
8104
8132
let our_funding_contribution_satoshis = 0i64;
@@ -8141,16 +8169,24 @@ impl<SP: Deref> Channel<SP> where
8141
8169
let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8142
8170
8143
8171
// TODO(splicing): Store msg.funding_pubkey
8144
- // TODO(splicing): Apply start of splice (splice_start)
8172
+
8173
+ // Apply start of splice change in the state
8174
+ self.context.splice_start(false, logger);
8145
8175
8146
8176
let splice_ack_msg = self.context.get_splice_ack(our_funding_contribution_satoshis);
8177
+
8147
8178
// TODO(splicing): start interactive funding negotiation
8179
+ // let _msg = self.begin_interactive_funding_tx_construction(signer_provider, entropy_source, holder_node_id)
8180
+ // .map_err(|err| ChannelError::Warn(format!("Failed to start interactive transaction construction, {:?}", err)))?;
8181
+
8148
8182
Ok(splice_ack_msg)
8149
8183
}
8150
8184
8151
8185
/// Handle splice_ack
8152
8186
#[cfg(splicing)]
8153
- pub fn splice_ack(&mut self, msg: &msgs::SpliceAck) -> Result<(), ChannelError> {
8187
+ pub fn splice_ack<ES: Deref, L: Deref>(
8188
+ &mut self, msg: &msgs::SpliceAck, _signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, logger: &L,
8189
+ ) -> Result<Option<InteractiveTxMessageSend>, ChannelError> where ES::Target: EntropySource, L::Target: Logger {
8154
8190
let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
8155
8191
8156
8192
// check if splice is pending
@@ -8168,7 +8204,15 @@ impl<SP: Deref> Channel<SP> where
8168
8204
// Early check for reserve requirement, assuming maximum balance of full channel value
8169
8205
// This will also be checked later at tx_complete
8170
8206
let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8171
- Ok(())
8207
+
8208
+ // Apply start of splice change in the state
8209
+ self.context.splice_start(true, logger);
8210
+
8211
+ // TODO(splicing): start interactive funding negotiation
8212
+ // let tx_msg_opt = self.begin_interactive_funding_tx_construction(signer_provider, entropy_source, holder_node_id)
8213
+ // .map_err(|err| ChannelError::Warn(format!("V2 channel rejected due to sender error, {:?}", err)))?;
8214
+ // Ok(tx_msg_opt)
8215
+ Ok(None)
8172
8216
}
8173
8217
8174
8218
// Send stuff to our remote peers:
0 commit comments