@@ -163,6 +163,7 @@ struct InboundHTLCOutput {
163163 state: InboundHTLCState,
164164}
165165
166+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
166167enum OutboundHTLCState {
167168 /// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we
168169 /// created it we would have put it in the holding cell instead). When they next revoke_and_ack
@@ -196,6 +197,7 @@ enum OutboundHTLCState {
196197}
197198
198199#[derive(Clone)]
200+ #[cfg_attr(test, derive(Debug, PartialEq))]
199201enum OutboundHTLCOutcome {
200202 /// LDK version 0.0.105+ will always fill in the preimage here.
201203 Success(Option<PaymentPreimage>),
@@ -220,6 +222,7 @@ impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
220222 }
221223}
222224
225+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
223226struct OutboundHTLCOutput {
224227 htlc_id: u64,
225228 amount_msat: u64,
@@ -232,6 +235,7 @@ struct OutboundHTLCOutput {
232235}
233236
234237/// See AwaitingRemoteRevoke ChannelState for more info
238+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
235239enum HTLCUpdateAwaitingACK {
236240 AddHTLC { // TODO: Time out if we're getting close to cltv_expiry
237241 // always outbound
@@ -7822,12 +7826,13 @@ mod tests {
78227826 use bitcoin::blockdata::opcodes;
78237827 use bitcoin::network::constants::Network;
78247828 use hex;
7825- use crate::ln::PaymentHash;
7829+ use crate::ln::{ PaymentHash, PaymentPreimage} ;
78267830 use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
78277831 use crate::ln::channel::InitFeatures;
78287832 use crate::ln::channel::{Channel, ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, commit_tx_fee_msat};
7829- use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
7830- use crate::ln::features::ChannelTypeFeatures;
7833+ use crate::ln::channel::{HTLCUpdateAwaitingACK, MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
7834+ use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
7835+ use crate::ln::msgs;
78317836 use crate::ln::msgs::{ChannelUpdate, DecodeError, UnsignedChannelUpdate, MAX_VALUE_MSAT};
78327837 use crate::ln::script::ShutdownScript;
78337838 use crate::ln::chan_utils;
@@ -7836,9 +7841,10 @@ mod tests {
78367841 use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget};
78377842 use crate::sign::{ChannelSigner, InMemorySigner, EntropySource, SignerProvider};
78387843 use crate::chain::transaction::OutPoint;
7839- use crate::routing::router::Path;
7844+ use crate::routing::router::{ Path, RouteHop} ;
78407845 use crate::util::config::UserConfig;
78417846 use crate::util::errors::APIError;
7847+ use crate::util::ser::{ReadableArgs, Writeable};
78427848 use crate::util::test_utils;
78437849 use crate::util::test_utils::{OnGetShutdownScriptpubkey, TestKeysInterface};
78447850 use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
@@ -8359,6 +8365,96 @@ mod tests {
83598365 assert!(!node_a_chan.channel_update(&update).unwrap());
83608366 }
83618367
8368+ #[test]
8369+ fn blinding_point_ser() {
8370+ // Ensure that channel blinding points are (de)serialized properly.
8371+ let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
8372+ let secp_ctx = Secp256k1::new();
8373+ let seed = [42; 32];
8374+ let network = Network::Testnet;
8375+ let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
8376+
8377+ let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
8378+ let config = UserConfig::default();
8379+ let features = channelmanager::provided_init_features(&config);
8380+ let outbound_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &features, 10000000, 100000, 42, &config, 0, 42, None).unwrap();
8381+ let mut chan = Channel { context: outbound_chan.context };
8382+
8383+ let dummy_htlc_source = HTLCSource::OutboundRoute {
8384+ path: Path {
8385+ hops: vec![RouteHop {
8386+ pubkey: test_utils::pubkey(2), channel_features: ChannelFeatures::empty(),
8387+ node_features: NodeFeatures::empty(), short_channel_id: 0, fee_msat: 0,
8388+ cltv_expiry_delta: 0, maybe_announced_channel: false,
8389+ }],
8390+ blinded_tail: None
8391+ },
8392+ session_priv: SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
8393+ first_hop_htlc_msat: 0,
8394+ payment_id: PaymentId([42; 32]),
8395+ };
8396+ let dummy_outbound_output = OutboundHTLCOutput {
8397+ htlc_id: 0,
8398+ amount_msat: 0,
8399+ payment_hash: PaymentHash(Sha256::hash(&[43; 32]).into_inner()),
8400+ cltv_expiry: 0,
8401+ state: OutboundHTLCState::Committed,
8402+ source: dummy_htlc_source.clone(),
8403+ skimmed_fee_msat: None,
8404+ blinding_point: None,
8405+ };
8406+ let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
8407+ for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
8408+ if idx % 2 == 0 {
8409+ htlc.blinding_point = Some(test_utils::pubkey(42 + idx as u8));
8410+ }
8411+ }
8412+ chan.context.pending_outbound_htlcs = pending_outbound_htlcs.clone();
8413+
8414+ let dummy_holding_cell_add_htlc = HTLCUpdateAwaitingACK::AddHTLC {
8415+ amount_msat: 0,
8416+ cltv_expiry: 0,
8417+ payment_hash: PaymentHash(Sha256::hash(&[43; 32]).into_inner()),
8418+ source: dummy_htlc_source.clone(),
8419+ onion_routing_packet: msgs::OnionPacket {
8420+ version: 0,
8421+ public_key: Ok(test_utils::pubkey(1)),
8422+ hop_data: [0; 20*65],
8423+ hmac: [0; 32]
8424+ },
8425+ skimmed_fee_msat: None,
8426+ blinding_point: None,
8427+ };
8428+ let dummy_holding_cell_claim_htlc = HTLCUpdateAwaitingACK::ClaimHTLC {
8429+ payment_preimage: PaymentPreimage([42; 32]),
8430+ htlc_id: 0,
8431+ };
8432+ let mut holding_cell_htlc_updates = Vec::with_capacity(10);
8433+ for i in 0..10 {
8434+ if i % 3 == 0 {
8435+ holding_cell_htlc_updates.push(dummy_holding_cell_add_htlc.clone());
8436+ } else if i % 3 == 1 {
8437+ holding_cell_htlc_updates.push(dummy_holding_cell_claim_htlc.clone());
8438+ } else {
8439+ let mut dummy_add = dummy_holding_cell_add_htlc.clone();
8440+ if let HTLCUpdateAwaitingACK::AddHTLC { ref mut blinding_point, .. } = &mut dummy_add {
8441+ *blinding_point = Some(test_utils::pubkey(42 + i));
8442+ } else { panic!() }
8443+ holding_cell_htlc_updates.push(dummy_add);
8444+ }
8445+ }
8446+ chan.context.holding_cell_htlc_updates = holding_cell_htlc_updates.clone();
8447+
8448+ // Encode and decode the channel and ensure that the HTLCs within are the same.
8449+ let encoded_chan = chan.encode();
8450+ let mut s = crate::io::Cursor::new(&encoded_chan);
8451+ let mut reader = crate::util::ser::FixedLengthReader::new(&mut s, encoded_chan.len() as u64);
8452+ let features = channelmanager::provided_channel_type_features(&config);
8453+ let decoded_chan = Channel::read(&mut reader, (&&keys_provider, &&keys_provider, 0, &features)).unwrap();
8454+ assert_eq!(decoded_chan.context.pending_outbound_htlcs, pending_outbound_htlcs);
8455+ assert_eq!(decoded_chan.context.holding_cell_htlc_updates, holding_cell_htlc_updates);
8456+ }
8457+
83628458 #[cfg(feature = "_test_vectors")]
83638459 #[test]
83648460 fn outbound_commitment_test() {
0 commit comments