Skip to content

Commit

Permalink
Test blinding point serialization in Channel.
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinewallace committed Nov 30, 2023
1 parent e510e3c commit 6af786a
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 5 deletions.
106 changes: 101 additions & 5 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ struct InboundHTLCOutput {
state: InboundHTLCState,
}

#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
enum OutboundHTLCState {
/// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we
/// created it we would have put it in the holding cell instead). When they next revoke_and_ack
Expand Down Expand Up @@ -199,6 +200,7 @@ enum OutboundHTLCState {
}

#[derive(Clone)]
#[cfg_attr(test, derive(Debug, PartialEq))]
enum OutboundHTLCOutcome {
/// LDK version 0.0.105+ will always fill in the preimage here.
Success(Option<PaymentPreimage>),
Expand All @@ -223,6 +225,7 @@ impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
}
}

#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
struct OutboundHTLCOutput {
htlc_id: u64,
amount_msat: u64,
Expand All @@ -235,6 +238,7 @@ struct OutboundHTLCOutput {
}

/// See AwaitingRemoteRevoke ChannelState for more info
#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
enum HTLCUpdateAwaitingACK {
AddHTLC { // TODO: Time out if we're getting close to cltv_expiry
// always outbound
Expand Down Expand Up @@ -7889,23 +7893,25 @@ mod tests {
use bitcoin::blockdata::transaction::{Transaction, TxOut};
use bitcoin::blockdata::opcodes;
use bitcoin::network::constants::Network;
use crate::ln::PaymentHash;
use crate::ln::{PaymentHash, PaymentPreimage};
use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
use crate::ln::channel::InitFeatures;
use crate::ln::channel::{ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, commit_tx_fee_msat};
use crate::ln::channel::{Channel, ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK, commit_tx_fee_msat};
use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
use crate::ln::features::ChannelTypeFeatures;
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
use crate::ln::msgs;
use crate::ln::msgs::{ChannelUpdate, DecodeError, UnsignedChannelUpdate, MAX_VALUE_MSAT};
use crate::ln::script::ShutdownScript;
use crate::ln::chan_utils::{self, htlc_success_tx_weight, htlc_timeout_tx_weight};
use crate::chain::BestBlock;
use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget};
use crate::sign::{ChannelSigner, InMemorySigner, EntropySource, SignerProvider};
use crate::chain::transaction::OutPoint;
use crate::routing::router::Path;
use crate::routing::router::{Path, RouteHop};
use crate::util::config::UserConfig;
use crate::util::errors::APIError;
use crate::util::ser::{ReadableArgs, Writeable};
use crate::util::test_utils;
use crate::util::test_utils::{OnGetShutdownScriptpubkey, TestKeysInterface};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
Expand Down Expand Up @@ -8419,6 +8425,96 @@ use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
assert!(!node_a_chan.channel_update(&update).unwrap());
}

#[test]
fn blinding_point_ser() {
// Ensure that channel blinding points are (de)serialized properly.
let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
let secp_ctx = Secp256k1::new();
let seed = [42; 32];
let network = Network::Testnet;
let keys_provider = test_utils::TestKeysInterface::new(&seed, network);

let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
let config = UserConfig::default();
let features = channelmanager::provided_init_features(&config);
let outbound_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &features, 10000000, 100000, 42, &config, 0, 42, None).unwrap();
let mut chan = Channel { context: outbound_chan.context };

let dummy_htlc_source = HTLCSource::OutboundRoute {
path: Path {
hops: vec![RouteHop {
pubkey: test_utils::pubkey(2), channel_features: ChannelFeatures::empty(),
node_features: NodeFeatures::empty(), short_channel_id: 0, fee_msat: 0,
cltv_expiry_delta: 0, maybe_announced_channel: false,
}],
blinded_tail: None
},
session_priv: test_utils::privkey(42),
first_hop_htlc_msat: 0,
payment_id: PaymentId([42; 32]),
};
let dummy_outbound_output = OutboundHTLCOutput {
htlc_id: 0,
amount_msat: 0,
payment_hash: PaymentHash([43; 32]),
cltv_expiry: 0,
state: OutboundHTLCState::Committed,
source: dummy_htlc_source.clone(),
skimmed_fee_msat: None,
blinding_point: None,
};
let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
if idx % 2 == 0 {
htlc.blinding_point = Some(test_utils::pubkey(42 + idx as u8));
}
}
chan.context.pending_outbound_htlcs = pending_outbound_htlcs.clone();

let dummy_holding_cell_add_htlc = HTLCUpdateAwaitingACK::AddHTLC {
amount_msat: 0,
cltv_expiry: 0,
payment_hash: PaymentHash([43; 32]),
source: dummy_htlc_source.clone(),
onion_routing_packet: msgs::OnionPacket {
version: 0,
public_key: Ok(test_utils::pubkey(1)),
hop_data: [0; 20*65],
hmac: [0; 32]
},
skimmed_fee_msat: None,
blinding_point: None,
};
let dummy_holding_cell_claim_htlc = HTLCUpdateAwaitingACK::ClaimHTLC {
payment_preimage: PaymentPreimage([42; 32]),
htlc_id: 0,
};
let mut holding_cell_htlc_updates = Vec::with_capacity(10);
for i in 0..10 {
if i % 3 == 0 {
holding_cell_htlc_updates.push(dummy_holding_cell_add_htlc.clone());
} else if i % 3 == 1 {
holding_cell_htlc_updates.push(dummy_holding_cell_claim_htlc.clone());
} else {
let mut dummy_add = dummy_holding_cell_add_htlc.clone();
if let HTLCUpdateAwaitingACK::AddHTLC { ref mut blinding_point, .. } = &mut dummy_add {
*blinding_point = Some(test_utils::pubkey(42 + i));
} else { panic!() }
holding_cell_htlc_updates.push(dummy_add);
}
}
chan.context.holding_cell_htlc_updates = holding_cell_htlc_updates.clone();

// Encode and decode the channel and ensure that the HTLCs within are the same.
let encoded_chan = chan.encode();
let mut s = crate::io::Cursor::new(&encoded_chan);
let mut reader = crate::util::ser::FixedLengthReader::new(&mut s, encoded_chan.len() as u64);
let features = channelmanager::provided_channel_type_features(&config);
let decoded_chan = Channel::read(&mut reader, (&&keys_provider, &&keys_provider, 0, &features)).unwrap();
assert_eq!(decoded_chan.context.pending_outbound_htlcs, pending_outbound_htlcs);
assert_eq!(decoded_chan.context.holding_cell_htlc_updates, holding_cell_htlc_updates);
}

#[cfg(feature = "_test_vectors")]
#[test]
fn outbound_commitment_test() {
Expand Down
2 changes: 2 additions & 0 deletions lightning/src/ln/onion_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -740,9 +740,11 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
}

#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
#[cfg_attr(test, derive(PartialEq))]
pub(super) struct HTLCFailReason(HTLCFailReasonRepr);

#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
#[cfg_attr(test, derive(PartialEq))]
enum HTLCFailReasonRepr {
LightningError {
err: msgs::OnionErrorPacket,
Expand Down

0 comments on commit 6af786a

Please sign in to comment.