diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index a9e463a99eb..f2da485b67a 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -2056,7 +2056,7 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { holding_cell_update_fee: Option, next_holder_htlc_id: u64, pub(super) next_counterparty_htlc_id: u64, - feerate_per_kw: u32, + pub(super) feerate_per_kw: u32, /// The timestamp set on our latest `channel_update` message for this channel. It is updated /// when the channel is updated in ways which may impact the `channel_update` message or when a @@ -10705,7 +10705,7 @@ impl PendingV2Channel where SP::Target: SignerProvider { // Unfunded channel utilities -fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures { +pub(super) fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures { // The default channel type (ie the first one we try) depends on whether the channel is // public - if it is, we just go with `only_static_remotekey` as it's the only option // available. If it's private, we first try `scid_privacy` as it provides better privacy @@ -11844,24 +11844,24 @@ mod tests { use crate::types::payment::{PaymentHash, PaymentPreimage}; use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint}; use crate::ln::channelmanager::{self, HTLCSource, PaymentId}; - use crate::ln::channel::InitFeatures; use crate::ln::channel::{AwaitingChannelReadyFlags, ChannelState, FundedChannel, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK, commit_tx_fee_sat}; use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS}; - use crate::types::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures}; + use crate::types::features::{ChannelFeatures, NodeFeatures}; + #[cfg(ldk_test_vectors)] + use crate::types::features::ChannelTypeFeatures; use crate::ln::msgs; use crate::ln::msgs::{ChannelUpdate, 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::chain::chaininterface::LowerBoundedFeeEstimator; use crate::sign::{ChannelSigner, InMemorySigner, EntropySource, SignerProvider}; use crate::chain::transaction::OutPoint; 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 crate::util::test_utils::{self, OnGetShutdownScriptpubkey, TestKeysInterface, TestFeeEstimator, TestLogger}; use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature}; use bitcoin::secp256k1::ffi::Signature as FFISignature; use bitcoin::secp256k1::{SecretKey,PublicKey}; @@ -11885,15 +11885,6 @@ mod tests { assert!(ChannelState::ChannelReady(ChannelReadyFlags::new()) < ChannelState::ShutdownComplete); } - struct TestFeeEstimator { - fee_est: u32 - } - impl FeeEstimator for TestFeeEstimator { - fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u32 { - self.fee_est - } - } - #[test] fn test_max_funding_satoshis_no_wumbo() { assert_eq!(TOTAL_BITCOIN_SUPPLY_SATOSHIS, 21_000_000 * 100_000_000); @@ -11952,16 +11943,16 @@ mod tests { let seed = [42; 32]; let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); + let keys_provider = TestKeysInterface::new(&seed, network); keys_provider.expect(OnGetShutdownScriptpubkey { returns: non_v0_segwit_shutdown_script.clone(), }); - let logger = test_utils::TestLogger::new(); + let logger = TestLogger::new(); let secp_ctx = Secp256k1::new(); let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - match OutboundV1Channel::<&TestKeysInterface>::new(&LowerBoundedFeeEstimator::new(&TestFeeEstimator { fee_est: 253 }), &&keys_provider, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0, 42, None, &logger) { + match OutboundV1Channel::<&TestKeysInterface>::new(&LowerBoundedFeeEstimator::new(&TestFeeEstimator::new(253)), &&keys_provider, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0, 42, None, &logger) { Err(APIError::IncompatibleShutdownScript { script }) => { assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner()); }, @@ -11975,13 +11966,13 @@ mod tests { #[test] fn test_open_channel_msg_fee() { let original_fee = 253; - let mut fee_est = TestFeeEstimator{fee_est: original_fee }; + let fee_est = TestFeeEstimator::new(original_fee); let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_est); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); - let logger = test_utils::TestLogger::new(); + let keys_provider = TestKeysInterface::new(&seed, network); + let logger = TestLogger::new(); let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); @@ -11989,7 +11980,7 @@ mod tests { // Now change the fee so we can check that the fee in the open_channel message is the // same as the old fee. - fee_est.fee_est = 500; + *fee_est.sat_per_kw.lock().unwrap() = 500; let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); assert_eq!(open_channel_msg.common_fields.commitment_feerate_sat_per_1000_weight, original_fee); } @@ -11998,12 +11989,13 @@ mod tests { fn test_holder_vs_counterparty_dust_limit() { // Test that when calculating the local and remote commitment transaction fees, the correct // dust limits are used. - let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); + let test_est = TestFeeEstimator::new(15000); + let feeest = LowerBoundedFeeEstimator::new(&test_est); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); - let logger = test_utils::TestLogger::new(); + let keys_provider = TestKeysInterface::new(&seed, network); + let logger = TestLogger::new(); let best_block = BestBlock::from_network(network); // Go through the flow of opening a channel between two nodes, making sure @@ -12089,12 +12081,13 @@ mod tests { // calculate the real dust limits for HTLCs (i.e. the dust limit given by the counterparty // *plus* the fees paid for the HTLC) they don't swap `HTLC_SUCCESS_TX_WEIGHT` for // `HTLC_TIMEOUT_TX_WEIGHT`, and vice versa. - let fee_est = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 253 }); + let test_est = TestFeeEstimator::new(253); + let fee_est = LowerBoundedFeeEstimator::new(&test_est); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); - let logger = test_utils::TestLogger::new(); + let keys_provider = TestKeysInterface::new(&seed, network); + let logger = TestLogger::new(); let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); @@ -12133,14 +12126,15 @@ mod tests { #[test] fn channel_reestablish_no_updates() { - let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); - let logger = test_utils::TestLogger::new(); + let test_est = TestFeeEstimator::new(15000); + let feeest = LowerBoundedFeeEstimator::new(&test_est); + let logger = TestLogger::new(); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; let best_block = BestBlock::from_network(network); let chain_hash = ChainHash::using_genesis_block(network); - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); + let keys_provider = TestKeysInterface::new(&seed, network); // Go through the flow of opening a channel between two nodes. @@ -12190,12 +12184,13 @@ mod tests { #[test] fn test_configured_holder_max_htlc_value_in_flight() { - let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); - let logger = test_utils::TestLogger::new(); + let test_est = TestFeeEstimator::new(15000); + let feeest = LowerBoundedFeeEstimator::new(&test_est); + let logger = TestLogger::new(); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); + let keys_provider = TestKeysInterface::new(&seed, network); let outbound_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let inbound_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); @@ -12284,12 +12279,13 @@ mod tests { } fn test_self_and_counterparty_channel_reserve(channel_value_satoshis: u64, outbound_selected_channel_reserve_perc: f64, inbound_selected_channel_reserve_perc: f64) { - let fee_est = LowerBoundedFeeEstimator::new(&TestFeeEstimator { fee_est: 15_000 }); - let logger = test_utils::TestLogger::new(); + let test_est = TestFeeEstimator::new(15000); + let fee_est = LowerBoundedFeeEstimator::new(&test_est); + let logger = TestLogger::new(); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); + let keys_provider = TestKeysInterface::new(&seed, network); let outbound_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let inbound_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); @@ -12321,14 +12317,15 @@ mod tests { #[test] fn channel_update() { - let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); - let logger = test_utils::TestLogger::new(); + let test_est = TestFeeEstimator::new(15000); + let feeest = LowerBoundedFeeEstimator::new(&test_est); + let logger = TestLogger::new(); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; let best_block = BestBlock::from_network(network); let chain_hash = ChainHash::using_genesis_block(network); - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); + let keys_provider = TestKeysInterface::new(&seed, network); // Create Node A's channel pointing to Node B's pubkey let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); @@ -12398,13 +12395,14 @@ mod tests { fn blinding_point_skimmed_fee_malformed_ser() { // Ensure that channel blinding points, skimmed fees, and malformed HTLCs are (de)serialized // properly. - let logger = test_utils::TestLogger::new(); - let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); + let logger = TestLogger::new(); + let test_est = TestFeeEstimator::new(15000); + let feeest = LowerBoundedFeeEstimator::new(&test_est); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; let best_block = BestBlock::from_network(network); - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); + let keys_provider = 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(); @@ -12543,8 +12541,8 @@ mod tests { use core::str::FromStr; // Test vectors from BOLT 3 Appendices C and F (anchors): - let feeest = TestFeeEstimator{fee_est: 15000}; - let logger : Arc = Arc::new(test_utils::TestLogger::new()); + let feeest = TestFeeEstimator::new(15000); + let logger : Arc = Arc::new(TestLogger::new()); let secp_ctx = Secp256k1::new(); let signer = InMemorySigner::new( @@ -13302,237 +13300,17 @@ mod tests { SecretKey::from_slice(&>::from_hex("d09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110").unwrap()[..]).unwrap()); } - #[test] - fn test_zero_conf_channel_type_support() { - 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 logger = test_utils::TestLogger::new(); - - let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); - let config = UserConfig::default(); - let mut node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, - node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, None, &logger).unwrap(); - - let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key(); - channel_type_features.set_zero_conf_required(); - - let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); - open_channel_msg.common_fields.channel_type = Some(channel_type_features); - let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); - let res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, - node_b_node_id, &channelmanager::provided_channel_type_features(&config), - &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false); - assert!(res.is_ok()); - } - - #[test] - fn test_supports_anchors_zero_htlc_tx_fee() { - // Tests that if both sides support and negotiate `anchors_zero_fee_htlc_tx`, it is the - // resulting `channel_type`. - let mut config = UserConfig::default(); - config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; - - let mut expected_channel_type = ChannelTypeFeatures::empty(); - expected_channel_type.set_static_remote_key_required(); - expected_channel_type.set_anchors_zero_fee_htlc_tx_required(); - - do_test_supports_channel_type(config, expected_channel_type) - } - - #[test] - fn test_supports_zero_fee_commitments() { - // Tests that if both sides support and negotiate `anchors_zero_fee_commitments`, it is - // the resulting `channel_type`. - let mut config = UserConfig::default(); - config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true; - - let mut expected_channel_type = ChannelTypeFeatures::empty(); - expected_channel_type.set_anchor_zero_fee_commitments_required(); - - do_test_supports_channel_type(config, expected_channel_type) - } - - #[test] - fn test_supports_zero_fee_commitments_and_htlc_tx_fee() { - // Tests that if both sides support and negotiate `anchors_zero_fee_commitments` and - // `anchors_zero_fee_htlc_tx`, the resulting `channel_type` is - // `anchors_zero_fee_commitments`. - let mut config = UserConfig::default(); - config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; - config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true; - - let mut expected_channel_type = ChannelTypeFeatures::empty(); - expected_channel_type.set_anchor_zero_fee_commitments_required(); - - do_test_supports_channel_type(config, expected_channel_type) - } - - fn do_test_supports_channel_type(config: UserConfig, expected_channel_type: ChannelTypeFeatures) { - let secp_ctx = Secp256k1::new(); - let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); - let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network); - let logger = test_utils::TestLogger::new(); - - let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap()); - let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap()); - - // Assert that we get `static_remotekey` when no custom config is negotiated. - let channel_a = OutboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_b, - &channelmanager::provided_init_features(&UserConfig::default()), 10000000, 100000, 42, - &config, 0, 42, None, &logger - ).unwrap(); - assert_eq!(channel_a.funding.get_channel_type(), &ChannelTypeFeatures::only_static_remote_key()); - - let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_b, - &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, - None, &logger - ).unwrap(); - - let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); - let channel_b = InboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_a, - &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), - &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false - ).unwrap(); - - assert_eq!(channel_a.funding.get_channel_type(), &expected_channel_type); - assert_eq!(channel_b.funding.get_channel_type(), &expected_channel_type); - - if expected_channel_type.supports_anchor_zero_fee_commitments() { - assert_eq!(channel_a.context.feerate_per_kw, 0); - assert_eq!(channel_b.context.feerate_per_kw, 0); - } else { - assert_ne!(channel_a.context.feerate_per_kw, 0); - assert_ne!(channel_b.context.feerate_per_kw, 0); - } - } - - #[test] - fn test_rejects_implicit_simple_anchors() { - // Tests that if `option_anchors` is being negotiated implicitly through the intersection of - // each side's `InitFeatures`, it is rejected. - let secp_ctx = Secp256k1::new(); - let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); - let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network); - let logger = test_utils::TestLogger::new(); - - let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap()); - let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap()); - - let config = UserConfig::default(); - - // See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md - let static_remote_key_required: u64 = 1 << 12; - let simple_anchors_required: u64 = 1 << 20; - let raw_init_features = static_remote_key_required | simple_anchors_required; - let init_features_with_simple_anchors = InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec()); - - let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_b, - &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, - None, &logger - ).unwrap(); - - // Set `channel_type` to `None` to force the implicit feature negotiation. - let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); - open_channel_msg.common_fields.channel_type = None; - - // Since A supports both `static_remote_key` and `option_anchors`, but B only accepts - // `static_remote_key`, it will fail the channel. - let channel_b = InboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_a, - &channelmanager::provided_channel_type_features(&config), &init_features_with_simple_anchors, - &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false - ); - assert!(channel_b.is_err()); - } - - #[test] - fn test_rejects_simple_anchors_channel_type() { - // Tests that if `option_anchors` is being negotiated through the `channel_type` feature, - // it is rejected. - let secp_ctx = Secp256k1::new(); - let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); - let network = Network::Testnet; - let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network); - let logger = test_utils::TestLogger::new(); - - let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap()); - let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap()); - - let config = UserConfig::default(); - - // See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md - let static_remote_key_required: u64 = 1 << 12; - let simple_anchors_required: u64 = 1 << 20; - let simple_anchors_raw_features = static_remote_key_required | simple_anchors_required; - let simple_anchors_init = InitFeatures::from_le_bytes(simple_anchors_raw_features.to_le_bytes().to_vec()); - let simple_anchors_channel_type = ChannelTypeFeatures::from_le_bytes(simple_anchors_raw_features.to_le_bytes().to_vec()); - assert!(!simple_anchors_init.requires_unknown_bits()); - assert!(!simple_anchors_channel_type.requires_unknown_bits()); - - // First, we'll try to open a channel between A and B where A requests a channel type for - // the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by - // B as it's not supported by LDK. - let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_b, - &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, - None, &logger - ).unwrap(); - - let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); - open_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone()); - - let res = InboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_a, - &channelmanager::provided_channel_type_features(&config), &simple_anchors_init, - &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false - ); - assert!(res.is_err()); - - // Then, we'll try to open another channel where A requests a channel type for - // `anchors_zero_fee_htlc_tx`. B is malicious and tries to downgrade the channel type to the - // original `option_anchors` feature, which should be rejected by A as it's not supported by - // LDK. - let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_b, &simple_anchors_init, - 10000000, 100000, 42, &config, 0, 42, None, &logger - ).unwrap(); - - let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); - - let mut channel_b = InboundV1Channel::<&TestKeysInterface>::new( - &fee_estimator, &&keys_provider, &&keys_provider, node_id_a, - &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), - &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false - ).unwrap(); - - let mut accept_channel_msg = channel_b.get_accept_channel_message(&&logger).unwrap(); - accept_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone()); - - let res = channel_a.accept_channel( - &accept_channel_msg, &config.channel_handshake_limits, &simple_anchors_init - ); - assert!(res.is_err()); - } - #[test] fn test_waiting_for_batch() { - let feeest = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000}); - let logger = test_utils::TestLogger::new(); + let test_est = TestFeeEstimator::new(15000); + let feeest = LowerBoundedFeeEstimator::new(&test_est); + let logger = TestLogger::new(); let secp_ctx = Secp256k1::new(); let seed = [42; 32]; let network = Network::Testnet; let best_block = BestBlock::from_network(network); let chain_hash = ChainHash::using_genesis_block(network); - let keys_provider = test_utils::TestKeysInterface::new(&seed, network); + let keys_provider = TestKeysInterface::new(&seed, network); let mut config = UserConfig::default(); // Set trust_own_funding_0conf while ensuring we don't send channel_ready for a diff --git a/lightning/src/ln/channel_type_tests.rs b/lightning/src/ln/channel_type_tests.rs new file mode 100644 index 00000000000..97eb7e06b55 --- /dev/null +++ b/lightning/src/ln/channel_type_tests.rs @@ -0,0 +1,481 @@ +use crate::chain::chaininterface::LowerBoundedFeeEstimator; +use crate::ln::channel::{get_initial_channel_type, InboundV1Channel, OutboundV1Channel}; +use crate::ln::channelmanager; +use crate::prelude::*; +use crate::util::config::UserConfig; +use crate::util::test_utils::{TestFeeEstimator, TestKeysInterface, TestLogger}; +use bitcoin::constants::ChainHash; +use bitcoin::network::Network; +use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use lightning_types::features::{ChannelTypeFeatures, InitFeatures}; + +#[test] +fn test_option_scid_privacy_initial() { + let mut expected_type = ChannelTypeFeatures::only_static_remote_key(); + expected_type.set_scid_privacy_required(); + + do_test_get_initial_channel_type( + UserConfig::default(), + InitFeatures::empty(), + ChannelTypeFeatures::only_static_remote_key(), + |cfg: &mut UserConfig| { + // announce_for_forwarding = false is required, but set by UserConfig::default(). + cfg.channel_handshake_config.negotiate_scid_privacy = true; + }, + |their_features: &mut InitFeatures| { + their_features.set_scid_privacy_optional(); + }, + expected_type, + ) +} + +#[test] +fn test_option_anchors_zero_fee_initial() { + let mut expected_type = ChannelTypeFeatures::only_static_remote_key(); + expected_type.set_anchors_zero_fee_htlc_tx_required(); + + do_test_get_initial_channel_type( + UserConfig::default(), + InitFeatures::empty(), + ChannelTypeFeatures::only_static_remote_key(), + |cfg: &mut UserConfig| { + cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; + }, + |their_features: &mut InitFeatures| { + their_features.set_anchors_zero_fee_htlc_tx_optional(); + }, + expected_type, + ) +} + +#[test] +fn test_option_zero_fee_commitments_initial() { + let mut expected_type = ChannelTypeFeatures::empty(); + expected_type.set_anchor_zero_fee_commitments_required(); + + do_test_get_initial_channel_type( + UserConfig::default(), + InitFeatures::empty(), + ChannelTypeFeatures::only_static_remote_key(), + |cfg: &mut UserConfig| { + cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true; + }, + |their_features: &mut InitFeatures| { + their_features.set_anchor_zero_fee_commitments_optional(); + }, + expected_type, + ) +} + +#[test] +fn test_option_zero_fee_commitments_from_zero_htlc_anchors_initial() { + let mut start_cfg = UserConfig::default(); + start_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; + + let mut start_features = InitFeatures::empty(); + start_features.set_anchors_zero_fee_htlc_tx_optional(); + + let mut start_type = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(); + + let mut expected_type = ChannelTypeFeatures::empty(); + expected_type.set_anchor_zero_fee_commitments_required(); + + do_test_get_initial_channel_type( + start_cfg, + start_features, + start_type, + |cfg: &mut UserConfig| { + cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true; + }, + |their_features: &mut InitFeatures| { + their_features.set_anchor_zero_fee_commitments_optional(); + }, + expected_type, + ) +} + +fn do_test_get_initial_channel_type( + start_cfg: UserConfig, start_features: InitFeatures, start_type: ChannelTypeFeatures, + mut local_cfg_mod: F1, mut remote_features_mod: F2, channel_type: ChannelTypeFeatures, +) where + F1: FnOnce(&mut UserConfig), + F2: FnOnce(&mut InitFeatures), +{ + // Local node supports feature, remote does not. + let mut config = start_cfg.clone(); + local_cfg_mod(&mut config); + assert_eq!(get_initial_channel_type(&config, &start_features), start_type); + + // Remote node supports feature, local does not. + let mut their_features = start_features.clone(); + remote_features_mod(&mut their_features); + assert_eq!(get_initial_channel_type(&start_cfg, &their_features), start_type); + + // Both support feature. + assert_eq!(get_initial_channel_type(&config, &their_features), channel_type) +} + +#[test] +fn test_zero_conf_channel_type_support() { + let test_est = TestFeeEstimator::new(15000); + let feeest = LowerBoundedFeeEstimator::new(&test_est); + let secp_ctx = Secp256k1::new(); + let seed = [42; 32]; + let network = Network::Testnet; + let keys_provider = TestKeysInterface::new(&seed, network); + let logger = TestLogger::new(); + + let node_b_node_id = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); + let config = UserConfig::default(); + let mut node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new( + &feeest, + &&keys_provider, + &&keys_provider, + node_b_node_id, + &channelmanager::provided_init_features(&config), + 10000000, + 100000, + 42, + &config, + 0, + 42, + None, + &logger, + ) + .unwrap(); + + let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key(); + channel_type_features.set_zero_conf_required(); + + let mut open_channel_msg = + node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); + open_channel_msg.common_fields.channel_type = Some(channel_type_features); + let node_b_node_id = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); + let res = InboundV1Channel::<&TestKeysInterface>::new( + &feeest, + &&keys_provider, + &&keys_provider, + node_b_node_id, + &channelmanager::provided_channel_type_features(&config), + &channelmanager::provided_init_features(&config), + &open_channel_msg, + 7, + &config, + 0, + &&logger, + /*is_0conf=*/ false, + ); + assert!(res.is_ok()); +} + +#[test] +fn test_supports_anchors_zero_htlc_tx_fee() { + // Tests that if both sides support and negotiate `anchors_zero_fee_htlc_tx`, it is the + // resulting `channel_type`. + let mut config = UserConfig::default(); + config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; + + let mut expected_channel_type = ChannelTypeFeatures::empty(); + expected_channel_type.set_static_remote_key_required(); + expected_channel_type.set_anchors_zero_fee_htlc_tx_required(); + + do_test_supports_channel_type(config, expected_channel_type) +} + +#[test] +fn test_supports_zero_fee_commitments() { + // Tests that if both sides support and negotiate `anchors_zero_fee_commitments`, it is + // the resulting `channel_type`. + let mut config = UserConfig::default(); + config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true; + + let mut expected_channel_type = ChannelTypeFeatures::empty(); + expected_channel_type.set_anchor_zero_fee_commitments_required(); + + do_test_supports_channel_type(config, expected_channel_type) +} + +#[test] +fn test_supports_zero_fee_commitments_and_htlc_tx_fee() { + // Tests that if both sides support and negotiate `anchors_zero_fee_commitments` and + // `anchors_zero_fee_htlc_tx`, the resulting `channel_type` is + // `anchors_zero_fee_commitments`. + let mut config = UserConfig::default(); + config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; + config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true; + + let mut expected_channel_type = ChannelTypeFeatures::empty(); + expected_channel_type.set_anchor_zero_fee_commitments_required(); + + do_test_supports_channel_type(config, expected_channel_type) +} + +fn do_test_supports_channel_type(config: UserConfig, expected_channel_type: ChannelTypeFeatures) { + let secp_ctx = Secp256k1::new(); + let test_est = TestFeeEstimator::new(15000); + let fee_estimator = LowerBoundedFeeEstimator::new(&test_est); + let network = Network::Testnet; + let keys_provider = TestKeysInterface::new(&[42; 32], network); + let logger = TestLogger::new(); + + let node_id_a = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap()); + let node_id_b = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap()); + + // Assert that we get `static_remotekey` when no custom config is negotiated. + let channel_a = OutboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_b, + &channelmanager::provided_init_features(&UserConfig::default()), + 10000000, + 100000, + 42, + &config, + 0, + 42, + None, + &logger, + ) + .unwrap(); + assert_eq!( + channel_a.funding.get_channel_type(), + &ChannelTypeFeatures::only_static_remote_key() + ); + + let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_b, + &channelmanager::provided_init_features(&config), + 10000000, + 100000, + 42, + &config, + 0, + 42, + None, + &logger, + ) + .unwrap(); + + let open_channel_msg = + channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); + let channel_b = InboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_a, + &channelmanager::provided_channel_type_features(&config), + &channelmanager::provided_init_features(&config), + &open_channel_msg, + 7, + &config, + 0, + &&logger, + /*is_0conf=*/ false, + ) + .unwrap(); + + assert_eq!(channel_a.funding.get_channel_type(), &expected_channel_type); + assert_eq!(channel_b.funding.get_channel_type(), &expected_channel_type); + + if expected_channel_type.supports_anchor_zero_fee_commitments() { + assert_eq!(channel_a.context.feerate_per_kw, 0); + assert_eq!(channel_b.context.feerate_per_kw, 0); + } else { + assert_ne!(channel_a.context.feerate_per_kw, 0); + assert_ne!(channel_b.context.feerate_per_kw, 0); + } +} + +#[test] +fn test_rejects_implicit_simple_anchors() { + // Tests that if `option_anchors` is being negotiated implicitly through the intersection of + // each side's `InitFeatures`, it is rejected. + let secp_ctx = Secp256k1::new(); + let test_est = TestFeeEstimator::new(15000); + let fee_estimator = LowerBoundedFeeEstimator::new(&test_est); + let network = Network::Testnet; + let keys_provider = TestKeysInterface::new(&[42; 32], network); + let logger = TestLogger::new(); + + let node_id_a = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap()); + let node_id_b = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap()); + + let config = UserConfig::default(); + + // See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md + let static_remote_key_required: u64 = 1 << 12; + let simple_anchors_required: u64 = 1 << 20; + let raw_init_features = static_remote_key_required | simple_anchors_required; + let init_features_with_simple_anchors = + InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec()); + + let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_b, + &channelmanager::provided_init_features(&config), + 10000000, + 100000, + 42, + &config, + 0, + 42, + None, + &logger, + ) + .unwrap(); + + // Set `channel_type` to `None` to force the implicit feature negotiation. + let mut open_channel_msg = + channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); + open_channel_msg.common_fields.channel_type = None; + + // Since A supports both `static_remote_key` and `option_anchors`, but B only accepts + // `static_remote_key`, it will fail the channel. + let channel_b = InboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_a, + &channelmanager::provided_channel_type_features(&config), + &init_features_with_simple_anchors, + &open_channel_msg, + 7, + &config, + 0, + &&logger, + /*is_0conf=*/ false, + ); + assert!(channel_b.is_err()); +} + +#[test] +fn test_rejects_simple_anchors_channel_type() { + // Tests that if `option_anchors` is being negotiated through the `channel_type` feature, + // it is rejected. + let secp_ctx = Secp256k1::new(); + let test_est = TestFeeEstimator::new(15000); + let fee_estimator = LowerBoundedFeeEstimator::new(&test_est); + let network = Network::Testnet; + let keys_provider = TestKeysInterface::new(&[42; 32], network); + let logger = TestLogger::new(); + + let node_id_a = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap()); + let node_id_b = + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap()); + + let config = UserConfig::default(); + + // See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md + let static_remote_key_required: u64 = 1 << 12; + let simple_anchors_required: u64 = 1 << 20; + let simple_anchors_raw_features = static_remote_key_required | simple_anchors_required; + let simple_anchors_init = + InitFeatures::from_le_bytes(simple_anchors_raw_features.to_le_bytes().to_vec()); + let simple_anchors_channel_type = + ChannelTypeFeatures::from_le_bytes(simple_anchors_raw_features.to_le_bytes().to_vec()); + assert!(!simple_anchors_init.requires_unknown_bits()); + assert!(!simple_anchors_channel_type.requires_unknown_bits()); + + // First, we'll try to open a channel between A and B where A requests a channel type for + // the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by + // B as it's not supported by LDK. + let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_b, + &channelmanager::provided_init_features(&config), + 10000000, + 100000, + 42, + &config, + 0, + 42, + None, + &logger, + ) + .unwrap(); + + let mut open_channel_msg = + channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); + open_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone()); + + let res = InboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_a, + &channelmanager::provided_channel_type_features(&config), + &simple_anchors_init, + &open_channel_msg, + 7, + &config, + 0, + &&logger, + /*is_0conf=*/ false, + ); + assert!(res.is_err()); + + // Then, we'll try to open another channel where A requests a channel type for + // `anchors_zero_fee_htlc_tx`. B is malicious and tries to downgrade the channel type to the + // original `option_anchors` feature, which should be rejected by A as it's not supported by + // LDK. + let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_b, + &simple_anchors_init, + 10000000, + 100000, + 42, + &config, + 0, + 42, + None, + &logger, + ) + .unwrap(); + + let open_channel_msg = + channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(); + + let mut channel_b = InboundV1Channel::<&TestKeysInterface>::new( + &fee_estimator, + &&keys_provider, + &&keys_provider, + node_id_a, + &channelmanager::provided_channel_type_features(&config), + &channelmanager::provided_init_features(&config), + &open_channel_msg, + 7, + &config, + 0, + &&logger, + /*is_0conf=*/ false, + ) + .unwrap(); + + let mut accept_channel_msg = channel_b.get_accept_channel_message(&&logger).unwrap(); + accept_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone()); + + let res = channel_a.accept_channel( + &accept_channel_msg, + &config.channel_handshake_limits, + &simple_anchors_init, + ); + assert!(res.is_err()); +} diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 8d741f2954d..997a3b02e1a 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -74,6 +74,9 @@ pub mod bolt11_payment_tests; mod chanmon_update_fail_tests; #[cfg(test)] #[allow(unused_mut)] +mod channel_type_tests; +#[cfg(test)] +#[allow(unused_mut)] mod dual_funding_tests; #[cfg(any(test, feature = "_externalize_tests"))] #[allow(unused_mut)]