Skip to content

Commit 3dfc379

Browse files
committed
Update get_funding_created flow.
- Introduce a new enum that tracks if the Funding Transaction is a previously received transaction or a newly created one. - Update the flow and sanity checks accordingly to allow using previously used transaction if present.
1 parent 4fb0352 commit 3dfc379

File tree

3 files changed

+78
-12
lines changed

3 files changed

+78
-12
lines changed

lightning/src/ln/channel.rs

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,9 @@ impl OutboundContext {
12761276
}
12771277
}
12781278

1279-
struct FundingTransaction {
1279+
/// Represents a funding transaction used in the establishment [`Channel`]
1280+
#[derive(Clone)]
1281+
pub struct FundingTransaction {
12801282
funding_transaction: Transaction,
12811283
outpoint: OutPoint,
12821284
is_batch_funding: bool,
@@ -7316,6 +7318,27 @@ impl<SP: Deref> Channel<SP> where
73167318
}
73177319
}
73187320

7321+
/// Represents whether the associated [`FundingTransaction`] instance is newly created
7322+
/// or was generated during a previous channel handshake.
7323+
#[allow(unused)]
7324+
pub enum TransactionEnum {
7325+
New(FundingTransaction),
7326+
Old(FundingTransaction),
7327+
}
7328+
7329+
impl TransactionEnum {
7330+
/// Creates a new `TransactionEnum::New` variant representing a newly created funding transaction.
7331+
pub fn new_funding_transaction(transaction: Transaction, txo: OutPoint, is_batch_funding: bool) -> Self {
7332+
TransactionEnum::New(
7333+
FundingTransaction {
7334+
funding_transaction: transaction,
7335+
outpoint: txo,
7336+
is_batch_funding
7337+
}
7338+
)
7339+
}
7340+
}
7341+
73197342
/// A not-yet-funded outbound (from holder) channel using V1 channel establishment.
73207343
pub(super) struct OutboundV1Channel<SP: Deref> where SP::Target: SignerProvider {
73217344
pub context: ChannelContext<SP>,
@@ -7408,7 +7431,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
74087431
/// Note that channel_id changes during this call!
74097432
/// Do NOT broadcast the funding transaction until after a successful funding_signed call!
74107433
/// If an Err is returned, it is a ChannelError::Close.
7411-
pub fn get_funding_created<L: Deref>(&mut self, funding_transaction: Transaction, funding_txo: OutPoint, is_batch_funding: bool, logger: &L)
7434+
pub fn get_funding_created<L: Deref>(&mut self, transaction: TransactionEnum, logger: &L)
74127435
-> Result<Option<msgs::FundingCreated>, (Self, ChannelError)> where L::Target: Logger {
74137436
if !self.context.is_outbound() {
74147437
panic!("Tried to create outbound funding_created message on an inbound channel!");
@@ -7425,6 +7448,39 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
74257448
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
74267449
}
74277450

7451+
let (funding_transaction, funding_txo, is_batch_funding) = match transaction {
7452+
TransactionEnum::New(tx) => {
7453+
self.outbound_context.created_funding_transaction = Some(tx.clone());
7454+
(tx.funding_transaction, tx.outpoint, tx.is_batch_funding)
7455+
},
7456+
TransactionEnum::Old(tx) => {
7457+
// Sanity checks
7458+
if self.context.channel_id != ChannelId::v1_from_funding_outpoint(tx.outpoint) {
7459+
panic!("Previously saved funding_transaction in channel parameter does not match funding_txo saved in outbound channel parameters.")
7460+
}
7461+
if self.context.funding_transaction != Some(tx.funding_transaction) {
7462+
panic!("Previously saved funding_transaction in channel parameter does not match funding_transaction saved in outbound channel parameters.")
7463+
}
7464+
if self.context.is_batch_funding != Some(()).filter(|_| tx.is_batch_funding) {
7465+
panic!("Previously saved funding_transaction in channel parameter does not match is_batch_funding saved in outbound channel parameters.")
7466+
}
7467+
7468+
let funding_created = self.get_funding_created_msg(logger);
7469+
if funding_created.is_none() {
7470+
#[cfg(not(async_signing))] {
7471+
panic!("Failed to get signature for new funding creation");
7472+
}
7473+
#[cfg(async_signing)] {
7474+
if !self.context.signer_pending_funding {
7475+
log_trace!(logger, "funding_created awaiting signer; setting signer_pending_funding");
7476+
self.context.signer_pending_funding = true;
7477+
}
7478+
}
7479+
}
7480+
return Ok(funding_created);
7481+
}
7482+
};
7483+
74287484
self.context.channel_transaction_parameters.funding_outpoint = Some(funding_txo);
74297485
self.context.holder_signer.as_mut().provide_channel_parameters(&self.context.channel_transaction_parameters);
74307486

@@ -9382,7 +9438,7 @@ mod tests {
93829438
use crate::ln::{PaymentHash, PaymentPreimage};
93839439
use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
93849440
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
9385-
use crate::ln::channel::InitFeatures;
9441+
use crate::ln::channel::{InitFeatures, TransactionEnum};
93869442
use crate::ln::channel::{AwaitingChannelReadyFlags, Channel, ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK, commit_tx_fee_msat};
93879443
use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
93889444
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
@@ -9568,7 +9624,9 @@ mod tests {
95689624
value: 10000000, script_pubkey: output_script.clone(),
95699625
}]};
95709626
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
9571-
let funding_created_msg = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap();
9627+
9628+
let funding_transaction = TransactionEnum::new_funding_transaction(tx, funding_outpoint, false);
9629+
let funding_created_msg = node_a_chan.get_funding_created(funding_transaction, &&logger).map_err(|_| ()).unwrap();
95729630
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
95739631

95749632
// Node B --> Node A: funding signed
@@ -9697,7 +9755,8 @@ mod tests {
96979755
value: 10000000, script_pubkey: output_script.clone(),
96989756
}]};
96999757
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
9700-
let funding_created_msg = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap();
9758+
let transaction = TransactionEnum::new_funding_transaction(tx, funding_outpoint, false);
9759+
let funding_created_msg = node_a_chan.get_funding_created(transaction, &&logger).map_err(|_| ()).unwrap();
97019760
let (mut node_b_chan, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
97029761

97039762
// Node B --> Node A: funding signed
@@ -9886,7 +9945,8 @@ mod tests {
98869945
value: 10000000, script_pubkey: output_script.clone(),
98879946
}]};
98889947
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
9889-
let funding_created_msg = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap();
9948+
let transaction = TransactionEnum::new_funding_transaction(tx.clone(), funding_outpoint, false);
9949+
let funding_created_msg = node_a_chan.get_funding_created(transaction, &&logger).map_err(|_| ()).unwrap();
98909950
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
98919951

98929952
// Node B --> Node A: funding signed
@@ -9953,7 +10013,8 @@ mod tests {
995310013
value: 10000000, script_pubkey: outbound_chan.context.get_funding_redeemscript(),
995410014
}]};
995510015
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
9956-
let funding_created = outbound_chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap().unwrap();
10016+
let transaction = TransactionEnum::new_funding_transaction(tx.clone(), funding_outpoint, false);
10017+
let funding_created = outbound_chan.get_funding_created(transaction, &&logger).map_err(|_| ()).unwrap().unwrap();
995710018
let mut chan = match inbound_chan.funding_created(&funding_created, best_block, &&keys_provider, &&logger) {
995810019
Ok((chan, _, _)) => chan,
995910020
Err((_, e)) => panic!("{}", e),
@@ -11085,8 +11146,9 @@ mod tests {
1108511146
},
1108611147
]};
1108711148
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
11149+
let transaction = TransactionEnum::new_funding_transaction(tx.clone(), funding_outpoint, true);
1108811150
let funding_created_msg = node_a_chan.get_funding_created(
11089-
tx.clone(), funding_outpoint, true, &&logger,
11151+
transaction, &&logger,
1109011152
).map_err(|_| ()).unwrap();
1109111153
let (mut node_b_chan, funding_signed_msg, _) = node_b_chan.funding_created(
1109211154
&funding_created_msg.unwrap(),

lightning/src/ln/channelmanager.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ use crate::util::string::UntrustedString;
7575
use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
7676
use crate::util::logger::{Level, Logger, WithContext};
7777
use crate::util::errors::APIError;
78+
use super::channel::TransactionEnum;
79+
7880
#[cfg(not(c_bindings))]
7981
use {
8082
crate::offers::offer::DerivedMetadata,
@@ -4500,8 +4502,9 @@ where
45004502
Some(ChannelPhase::UnfundedOutboundV1(mut chan)) => {
45014503
funding_txo = find_funding_output(&chan, &funding_transaction)?;
45024504

4503-
let logger = WithChannelContext::from(&self.logger, &chan.context);
4504-
let funding_res = chan.get_funding_created(funding_transaction, funding_txo, is_batch_funding, &&logger)
4505+
let logger: WithChannelContext<'_, L> = WithChannelContext::from(&self.logger, &chan.context);
4506+
let transaction = TransactionEnum::new_funding_transaction(funding_transaction, funding_txo, is_batch_funding);
4507+
let funding_res = chan.get_funding_created(transaction, &&logger)
45054508
.map_err(|(mut chan, e)| if let ChannelError::Close(msg) = e {
45064509
let channel_id = chan.context.channel_id();
45074510
let reason = ClosureReason::ProcessingError { err: msg.clone() };

lightning/src/ln/functional_tests.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::chain::transaction::OutPoint;
2020
use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, OutputSpender, SignerProvider};
2121
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination, PaymentFailureReason};
2222
use crate::ln::{ChannelId, PaymentPreimage, PaymentSecret, PaymentHash};
23-
use crate::ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT, get_holder_selected_channel_reserve_satoshis, OutboundV1Channel, InboundV1Channel, COINBASE_MATURITY, ChannelPhase};
23+
use crate::ln::channel::{commitment_tx_base_weight, get_holder_selected_channel_reserve_satoshis, ChannelPhase, InboundV1Channel, OutboundV1Channel, TransactionEnum, COINBASE_MATURITY, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT};
2424
use crate::ln::channelmanager::{self, PaymentId, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, BREAKDOWN_TIMEOUT, ENABLE_GOSSIP_TICKS, DISABLE_GOSSIP_TICKS, MIN_CLTV_EXPIRY_DELTA};
2525
use crate::ln::channel::{DISCONNECT_PEER_AWAITING_RESPONSE_TICKS, ChannelError};
2626
use crate::ln::{chan_utils, onion_utils};
@@ -9235,7 +9235,8 @@ fn test_duplicate_chan_id() {
92359235
match a_peer_state.channel_by_id.remove(&open_chan_2_msg.common_fields.temporary_channel_id).unwrap() {
92369236
ChannelPhase::UnfundedOutboundV1(mut chan) => {
92379237
let logger = test_utils::TestLogger::new();
9238-
chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap()
9238+
let transaction = TransactionEnum::new_funding_transaction(tx.clone(), funding_outpoint, false);
9239+
chan.get_funding_created(transaction, &&logger).map_err(|_| ()).unwrap()
92399240
},
92409241
_ => panic!("Unexpected ChannelPhase variant"),
92419242
}.unwrap()

0 commit comments

Comments
 (0)