@@ -166,6 +166,7 @@ struct InboundHTLCOutput {
166166	state: InboundHTLCState,
167167}
168168
169+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
169170enum OutboundHTLCState {
170171	/// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we
171172	/// created it we would have put it in the holding cell instead). When they next revoke_and_ack
@@ -199,6 +200,7 @@ enum OutboundHTLCState {
199200}
200201
201202#[derive(Clone)]
203+ #[cfg_attr(test, derive(Debug, PartialEq))]
202204enum OutboundHTLCOutcome {
203205	/// LDK version 0.0.105+ will always fill in the preimage here.
204206	Success(Option<PaymentPreimage>),
@@ -223,6 +225,7 @@ impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
223225	}
224226}
225227
228+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
226229struct OutboundHTLCOutput {
227230	htlc_id: u64,
228231	amount_msat: u64,
@@ -235,6 +238,7 @@ struct OutboundHTLCOutput {
235238}
236239
237240/// See AwaitingRemoteRevoke ChannelState for more info
241+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
238242enum HTLCUpdateAwaitingACK {
239243	AddHTLC { // TODO: Time out if we're getting close to cltv_expiry
240244		// always outbound
@@ -7889,23 +7893,25 @@ mod tests {
78897893	use bitcoin::blockdata::transaction::{Transaction, TxOut};
78907894	use bitcoin::blockdata::opcodes;
78917895	use bitcoin::network::constants::Network;
7892- 	use crate::ln::PaymentHash;
7896+ 	use crate::ln::{ PaymentHash, PaymentPreimage} ;
78937897	use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
7894- use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
7898+ 	 use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
78957899	use crate::ln::channel::InitFeatures;
7896- 	use crate::ln::channel::{ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, commit_tx_fee_msat};
7900+ 	use crate::ln::channel::{Channel,  ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK , commit_tx_fee_msat};
78977901	use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
7898- 	use crate::ln::features::ChannelTypeFeatures;
7902+ 	use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
7903+ 	use crate::ln::msgs;
78997904	use crate::ln::msgs::{ChannelUpdate, DecodeError, UnsignedChannelUpdate, MAX_VALUE_MSAT};
79007905	use crate::ln::script::ShutdownScript;
79017906	use crate::ln::chan_utils::{self, htlc_success_tx_weight, htlc_timeout_tx_weight};
79027907	use crate::chain::BestBlock;
79037908	use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget};
79047909	use crate::sign::{ChannelSigner, InMemorySigner, EntropySource, SignerProvider};
79057910	use crate::chain::transaction::OutPoint;
7906- 	use crate::routing::router::Path;
7911+ 	use crate::routing::router::{ Path, RouteHop} ;
79077912	use crate::util::config::UserConfig;
79087913	use crate::util::errors::APIError;
7914+ 	use crate::util::ser::{ReadableArgs, Writeable};
79097915	use crate::util::test_utils;
79107916	use crate::util::test_utils::{OnGetShutdownScriptpubkey, TestKeysInterface};
79117917	use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
@@ -8419,6 +8425,96 @@ use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
84198425		assert!(!node_a_chan.channel_update(&update).unwrap());
84208426	}
84218427
8428+ 	#[test]
8429+ 	fn blinding_point_ser() {
8430+ 		// Ensure that channel blinding points are (de)serialized properly.
8431+ 		let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
8432+ 		let secp_ctx = Secp256k1::new();
8433+ 		let seed = [42; 32];
8434+ 		let network = Network::Testnet;
8435+ 		let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
8436+ 
8437+ 		let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
8438+ 		let config = UserConfig::default();
8439+ 		let features = channelmanager::provided_init_features(&config);
8440+ 		let outbound_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &features, 10000000, 100000, 42, &config, 0, 42, None).unwrap();
8441+ 		let mut chan = Channel { context: outbound_chan.context };
8442+ 
8443+ 		let dummy_htlc_source = HTLCSource::OutboundRoute {
8444+ 			path: Path {
8445+ 				hops: vec![RouteHop {
8446+ 					pubkey: test_utils::pubkey(2), channel_features: ChannelFeatures::empty(),
8447+ 					node_features: NodeFeatures::empty(), short_channel_id: 0, fee_msat: 0,
8448+ 					cltv_expiry_delta: 0, maybe_announced_channel: false,
8449+ 				}],
8450+ 				blinded_tail: None
8451+ 			},
8452+ 			session_priv: test_utils::privkey(42),
8453+ 			first_hop_htlc_msat: 0,
8454+ 			payment_id: PaymentId([42; 32]),
8455+ 		};
8456+ 		let dummy_outbound_output = OutboundHTLCOutput {
8457+ 			htlc_id: 0,
8458+ 			amount_msat: 0,
8459+ 			payment_hash: PaymentHash([43; 32]),
8460+ 			cltv_expiry: 0,
8461+ 			state: OutboundHTLCState::Committed,
8462+ 			source: dummy_htlc_source.clone(),
8463+ 			skimmed_fee_msat: None,
8464+ 			blinding_point: None,
8465+ 		};
8466+ 		let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
8467+ 		for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
8468+ 			if idx % 2 == 0 {
8469+ 				htlc.blinding_point = Some(test_utils::pubkey(42 + idx as u8));
8470+ 			}
8471+ 		}
8472+ 		chan.context.pending_outbound_htlcs = pending_outbound_htlcs.clone();
8473+ 
8474+ 		let dummy_holding_cell_add_htlc = HTLCUpdateAwaitingACK::AddHTLC {
8475+ 			amount_msat: 0,
8476+ 			cltv_expiry: 0,
8477+ 			payment_hash: PaymentHash([43; 32]),
8478+ 			source: dummy_htlc_source.clone(),
8479+ 			onion_routing_packet: msgs::OnionPacket {
8480+ 				version: 0,
8481+ 				public_key: Ok(test_utils::pubkey(1)),
8482+ 				hop_data: [0; 20*65],
8483+ 				hmac: [0; 32]
8484+ 			},
8485+ 			skimmed_fee_msat: None,
8486+ 			blinding_point: None,
8487+ 		};
8488+ 		let dummy_holding_cell_claim_htlc = HTLCUpdateAwaitingACK::ClaimHTLC {
8489+ 			payment_preimage: PaymentPreimage([42; 32]),
8490+ 			htlc_id: 0,
8491+ 		};
8492+ 		let mut holding_cell_htlc_updates = Vec::with_capacity(10);
8493+ 		for i in 0..10 {
8494+ 			if i % 3 == 0 {
8495+ 				holding_cell_htlc_updates.push(dummy_holding_cell_add_htlc.clone());
8496+ 			} else if i % 3 == 1 {
8497+ 				holding_cell_htlc_updates.push(dummy_holding_cell_claim_htlc.clone());
8498+ 			} else {
8499+ 				let mut dummy_add = dummy_holding_cell_add_htlc.clone();
8500+ 				if let HTLCUpdateAwaitingACK::AddHTLC { ref mut blinding_point, .. } = &mut dummy_add {
8501+ 					*blinding_point = Some(test_utils::pubkey(42 + i));
8502+ 				} else { panic!() }
8503+ 				holding_cell_htlc_updates.push(dummy_add);
8504+ 			}
8505+ 		}
8506+ 		chan.context.holding_cell_htlc_updates = holding_cell_htlc_updates.clone();
8507+ 
8508+ 		// Encode and decode the channel and ensure that the HTLCs within are the same.
8509+ 		let encoded_chan = chan.encode();
8510+ 		let mut s = crate::io::Cursor::new(&encoded_chan);
8511+ 		let mut reader = crate::util::ser::FixedLengthReader::new(&mut s, encoded_chan.len() as u64);
8512+ 		let features = channelmanager::provided_channel_type_features(&config);
8513+ 		let decoded_chan = Channel::read(&mut reader, (&&keys_provider, &&keys_provider, 0, &features)).unwrap();
8514+ 		assert_eq!(decoded_chan.context.pending_outbound_htlcs, pending_outbound_htlcs);
8515+ 		assert_eq!(decoded_chan.context.holding_cell_htlc_updates, holding_cell_htlc_updates);
8516+ 	}
8517+ 
84228518	#[cfg(feature = "_test_vectors")]
84238519	#[test]
84248520	fn outbound_commitment_test() {
0 commit comments