Skip to content

Commit fccfd04

Browse files
committed
Update Default Blinded Path constructor to use Dummy Hops
Applies dummy hops by default when constructing blinded paths via `DefaultMessageRouter`, enhancing privacy by obscuring the true path length. Uses a predefined `DUMMY_HOPS_COUNT` to apply dummy hops consistently without requiring explicit user input.
1 parent add7792 commit fccfd04

File tree

8 files changed

+66
-22
lines changed

8 files changed

+66
-22
lines changed

lightning-background-processor/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,7 @@ mod tests {
16591659
let msg_router = Arc::new(DefaultMessageRouter::new(
16601660
network_graph.clone(),
16611661
Arc::clone(&keys_manager),
1662+
keys_manager.get_expanded_key(),
16621663
));
16631664
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Bitcoin));
16641665
let kv_store =

lightning-liquidity/tests/common/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#![allow(unused_macros)]
66

77
use lightning::chain::Filter;
8-
use lightning::sign::{EntropySource, NodeSigner};
98

109
use bitcoin::blockdata::constants::{genesis_block, ChainHash};
1110
use bitcoin::blockdata::transaction::Transaction;
@@ -24,7 +23,7 @@ use lightning::onion_message::messenger::DefaultMessageRouter;
2423
use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};
2524
use lightning::routing::router::{CandidateRouteHop, DefaultRouter, Path};
2625
use lightning::routing::scoring::{ChannelUsage, ScoreLookUp, ScoreUpdate};
27-
use lightning::sign::{InMemorySigner, KeysManager};
26+
use lightning::sign::{EntropySource, InMemorySigner, KeysManager, NodeSigner};
2827
use lightning::util::config::UserConfig;
2928
use lightning::util::persist::{
3029
KVStore, CHANNEL_MANAGER_PERSISTENCE_KEY, CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE,
@@ -420,8 +419,11 @@ pub(crate) fn create_liquidity_node(
420419
scorer.clone(),
421420
Default::default(),
422421
));
423-
let msg_router =
424-
Arc::new(DefaultMessageRouter::new(Arc::clone(&network_graph), Arc::clone(&keys_manager)));
422+
let msg_router = Arc::new(DefaultMessageRouter::new(
423+
Arc::clone(&network_graph),
424+
Arc::clone(&keys_manager),
425+
keys_manager.get_expanded_key(),
426+
));
425427
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Bitcoin));
426428
let kv_store =
427429
Arc::new(FilesystemStore::new(format!("{}_persister_{}", &persist_dir, i).into()));

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17055,7 +17055,7 @@ pub mod bench {
1705517055
let scorer = RwLock::new(test_utils::TestScorer::new());
1705617056
let entropy = test_utils::TestKeysInterface::new(&[0u8; 32], network);
1705717057
let router = test_utils::TestRouter::new(Arc::new(NetworkGraph::new(network, &logger_a)), &logger_a, &scorer);
17058-
let message_router = test_utils::TestMessageRouter::new(Arc::new(NetworkGraph::new(network, &logger_a)), &entropy);
17058+
let message_router = test_utils::TestMessageRouter::new(Arc::new(NetworkGraph::new(network, &logger_a)), &keys_manager, keys_manager.get_expanded_key());
1705917059

1706017060
let mut config: UserConfig = Default::default();
1706117061
config.channel_config.max_dust_htlc_exposure = MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253);

lightning/src/ln/functional_test_utils.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::onion_message::messenger::OnionMessenger;
3232
use crate::ln::onion_utils::LocalHTLCFailureReason;
3333
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
3434
use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
35-
use crate::sign::{EntropySource, RandomBytes};
35+
use crate::sign::{EntropySource, NodeSigner, RandomBytes};
3636
use crate::util::config::{MaxDustHTLCExposure, UserConfig};
3737
use crate::util::logger::Logger;
3838
use crate::util::scid_utils;
@@ -728,7 +728,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
728728
signer_provider: self.keys_manager,
729729
fee_estimator: &test_utils::TestFeeEstimator::new(253),
730730
router: &test_utils::TestRouter::new(Arc::clone(&network_graph), &self.logger, &scorer),
731-
message_router: &test_utils::TestMessageRouter::new(network_graph, self.keys_manager),
731+
message_router: &test_utils::TestMessageRouter::new(network_graph, self.keys_manager, self.keys_manager.get_expanded_key()),
732732
chain_monitor: self.chain_monitor,
733733
tx_broadcaster: &broadcaster,
734734
logger: &self.logger,
@@ -3350,13 +3350,14 @@ pub fn create_node_cfgs_with_persisters<'a>(node_count: usize, chanmon_cfgs: &'a
33503350
let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[i].chain_source), &chanmon_cfgs[i].tx_broadcaster, &chanmon_cfgs[i].logger, &chanmon_cfgs[i].fee_estimator, persisters[i], &chanmon_cfgs[i].keys_manager);
33513351
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[i].logger));
33523352
let seed = [i as u8; 32];
3353+
let expanded_key = chanmon_cfgs[i].keys_manager.get_expanded_key();
33533354
nodes.push(NodeCfg {
33543355
chain_source: &chanmon_cfgs[i].chain_source,
33553356
logger: &chanmon_cfgs[i].logger,
33563357
tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster,
33573358
fee_estimator: &chanmon_cfgs[i].fee_estimator,
33583359
router: test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[i].logger, &chanmon_cfgs[i].scorer),
3359-
message_router: test_utils::TestMessageRouter::new(network_graph.clone(), &chanmon_cfgs[i].keys_manager),
3360+
message_router: test_utils::TestMessageRouter::new(network_graph.clone(), &chanmon_cfgs[i].keys_manager, expanded_key),
33603361
chain_monitor,
33613362
keys_manager: &chanmon_cfgs[i].keys_manager,
33623363
node_seed: seed,

lightning/src/ln/functional_tests.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use crate::routing::gossip::{NetworkGraph, NetworkUpdate};
4949
use crate::routing::router::{
5050
get_route, Path, PaymentParameters, Route, RouteHop, RouteParameters,
5151
};
52-
use crate::sign::{EntropySource, OutputSpender, SignerProvider};
52+
use crate::sign::{EntropySource, NodeSigner, OutputSpender, SignerProvider};
5353
use crate::types::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
5454
use crate::types::payment::{PaymentHash, PaymentSecret};
5555
use crate::util::config::{
@@ -5173,7 +5173,11 @@ pub fn test_key_derivation_params() {
51735173
let scorer = RwLock::new(test_utils::TestScorer::new());
51745174
let router =
51755175
test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[0].logger, &scorer);
5176-
let message_router = test_utils::TestMessageRouter::new(network_graph.clone(), &keys_manager);
5176+
let message_router = test_utils::TestMessageRouter::new(
5177+
network_graph.clone(),
5178+
&keys_manager,
5179+
keys_manager.get_expanded_key(),
5180+
);
51775181
let node = NodeCfg {
51785182
chain_source: &chanmon_cfgs[0].chain_source,
51795183
logger: &chanmon_cfgs[0].logger,

lightning/src/onion_message/functional_tests.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,11 @@ fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
279279
let node_signer = Arc::new(TestNodeSigner::new(secret_key));
280280

281281
let node_id_lookup = Arc::new(EmptyNodeIdLookUp {});
282-
let message_router =
283-
Arc::new(DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone()));
282+
let message_router = Arc::new(DefaultMessageRouter::new(
283+
network_graph.clone(),
284+
entropy_source.clone(),
285+
node_signer.get_expanded_key(),
286+
));
284287
let offers_message_handler = Arc::new(TestOffersMessageHandler {});
285288
let async_payments_message_handler = Arc::new(TestAsyncPaymentsMessageHandler {});
286289
let dns_resolver_message_handler = Arc::new(TestDNSResolverMessageHandler {});

lightning/src/onion_message/messenger.rs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::ln::channelmanager::Verification;
4040
use crate::ln::msgs::{
4141
self, BaseMessageHandler, MessageSendEvent, OnionMessage, OnionMessageHandler, SocketAddress,
4242
};
43-
use crate::ln::onion_utils;
43+
use crate::ln::{inbound_payment, onion_utils};
4444
use crate::routing::gossip::{NetworkGraph, NodeId, ReadOnlyNetworkGraph};
4545
use crate::sign::{EntropySource, NodeSigner, Recipient};
4646
use crate::types::features::{InitFeatures, NodeFeatures};
@@ -541,6 +541,7 @@ where
541541
{
542542
network_graph: G,
543543
entropy_source: ES,
544+
expanded_key: inbound_payment::ExpandedKey,
544545
}
545546

546547
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref> DefaultMessageRouter<G, L, ES>
@@ -549,16 +550,19 @@ where
549550
ES::Target: EntropySource,
550551
{
551552
/// Creates a [`DefaultMessageRouter`] using the given [`NetworkGraph`].
552-
pub fn new(network_graph: G, entropy_source: ES) -> Self {
553-
Self { network_graph, entropy_source }
553+
pub fn new(
554+
network_graph: G, entropy_source: ES, expanded_key: inbound_payment::ExpandedKey,
555+
) -> Self {
556+
Self { network_graph, entropy_source, expanded_key }
554557
}
555558

556559
fn create_blinded_paths_from_iter<
557560
I: ExactSizeIterator<Item = MessageForwardNode>,
558561
T: secp256k1::Signing + secp256k1::Verification,
559562
>(
560563
network_graph: &G, recipient: PublicKey, context: MessageContext, peers: I,
561-
entropy_source: &ES, secp_ctx: &Secp256k1<T>, compact_paths: bool,
564+
entropy_source: &ES, expanded_key: &inbound_payment::ExpandedKey, secp_ctx: &Secp256k1<T>,
565+
compact_paths: bool,
562566
) -> Result<Vec<BlindedMessagePath>, ()> {
563567
// Limit the number of blinded paths that are computed.
564568
const MAX_PATHS: usize = 3;
@@ -567,6 +571,21 @@ where
567571
// recipient's node_id.
568572
const MIN_PEER_CHANNELS: usize = 3;
569573

574+
// Add a random number (0 to 5) of dummy hops to each non-compact blinded path
575+
// to make it harder to infer the recipient's position.
576+
//
577+
// # Note on compact paths:
578+
//
579+
// Compact paths are optimized for minimal size. Adding dummy hops to them
580+
// would increase their size and negate their primary advantage.
581+
// Therefore, we avoid adding dummy hops to compact paths.
582+
let dummy_hops_count = if compact_paths {
583+
0
584+
} else {
585+
let random_byte = entropy_source.get_secure_random_bytes()[0];
586+
random_byte % 6
587+
};
588+
570589
let network_graph = network_graph.deref().read_only();
571590
let is_recipient_announced =
572591
network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient));
@@ -597,7 +616,15 @@ where
597616
let paths = peer_info
598617
.into_iter()
599618
.map(|(peer, _, _)| {
600-
BlindedMessagePath::new(&[peer], recipient, context.clone(), entropy, secp_ctx)
619+
BlindedMessagePath::new_with_dummy_hops(
620+
&[peer],
621+
dummy_hops_count,
622+
recipient,
623+
context.clone(),
624+
entropy,
625+
expanded_key,
626+
secp_ctx,
627+
)
601628
})
602629
.take(MAX_PATHS)
603630
.collect::<Result<Vec<_>, _>>();
@@ -666,7 +693,7 @@ where
666693

667694
pub(crate) fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
668695
network_graph: &G, recipient: PublicKey, context: MessageContext, peers: Vec<PublicKey>,
669-
entropy_source: &ES, secp_ctx: &Secp256k1<T>,
696+
entropy_source: &ES, expanded_key: &inbound_payment::ExpandedKey, secp_ctx: &Secp256k1<T>,
670697
) -> Result<Vec<BlindedMessagePath>, ()> {
671698
let peers =
672699
peers.into_iter().map(|node_id| MessageForwardNode { node_id, short_channel_id: None });
@@ -676,21 +703,24 @@ where
676703
context,
677704
peers.into_iter(),
678705
entropy_source,
706+
expanded_key,
679707
secp_ctx,
680708
false,
681709
)
682710
}
683711

684712
pub(crate) fn create_compact_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
685713
network_graph: &G, recipient: PublicKey, context: MessageContext,
686-
peers: Vec<MessageForwardNode>, entropy_source: &ES, secp_ctx: &Secp256k1<T>,
714+
peers: Vec<MessageForwardNode>, entropy_source: &ES,
715+
expanded_key: &inbound_payment::ExpandedKey, secp_ctx: &Secp256k1<T>,
687716
) -> Result<Vec<BlindedMessagePath>, ()> {
688717
Self::create_blinded_paths_from_iter(
689718
network_graph,
690719
recipient,
691720
context,
692721
peers.into_iter(),
693722
entropy_source,
723+
expanded_key,
694724
secp_ctx,
695725
true,
696726
)
@@ -719,6 +749,7 @@ where
719749
context,
720750
peers,
721751
&self.entropy_source,
752+
&self.expanded_key,
722753
secp_ctx,
723754
)
724755
}
@@ -733,6 +764,7 @@ where
733764
context,
734765
peers,
735766
&self.entropy_source,
767+
&self.expanded_key,
736768
secp_ctx,
737769
)
738770
}

lightning/src/util/test_utils.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ use crate::events::bump_transaction::Utxo;
2626
#[cfg(any(test, feature = "_externalize_tests"))]
2727
use crate::ln::chan_utils::CommitmentTransaction;
2828
use crate::ln::channel_state::ChannelDetails;
29-
use crate::ln::channelmanager;
3029
use crate::ln::inbound_payment::ExpandedKey;
3130
use crate::ln::msgs::{BaseMessageHandler, MessageSendEvent};
3231
use crate::ln::script::ShutdownScript;
3332
use crate::ln::types::ChannelId;
33+
use crate::ln::{channelmanager, inbound_payment};
3434
use crate::ln::{msgs, wire};
3535
use crate::offers::invoice::UnsignedBolt12Invoice;
3636
use crate::onion_message::messenger::{
@@ -322,8 +322,9 @@ pub struct TestMessageRouter<'a> {
322322
impl<'a> TestMessageRouter<'a> {
323323
pub fn new(
324324
network_graph: Arc<NetworkGraph<&'a TestLogger>>, entropy_source: &'a TestKeysInterface,
325+
expanded_key: inbound_payment::ExpandedKey,
325326
) -> Self {
326-
Self { inner: DefaultMessageRouter::new(network_graph, entropy_source) }
327+
Self { inner: DefaultMessageRouter::new(network_graph, entropy_source, expanded_key) }
327328
}
328329
}
329330

@@ -1488,7 +1489,7 @@ impl TestNodeSigner {
14881489

14891490
impl NodeSigner for TestNodeSigner {
14901491
fn get_expanded_key(&self) -> ExpandedKey {
1491-
unreachable!()
1492+
ExpandedKey::new([42; 32])
14921493
}
14931494

14941495
fn get_peer_storage_key(&self) -> PeerStorageKey {

0 commit comments

Comments
 (0)