10
10
//! Creating blinded paths and related utilities live here.
11
11
12
12
pub mod payment;
13
- pub ( crate ) mod message;
13
+ pub mod message;
14
14
pub ( crate ) mod utils;
15
15
16
16
use bitcoin:: secp256k1:: { self , PublicKey , Secp256k1 , SecretKey } ;
@@ -21,6 +21,7 @@ use crate::offers::invoice::BlindedPayInfo;
21
21
use crate :: routing:: gossip:: { NodeId , ReadOnlyNetworkGraph } ;
22
22
use crate :: sign:: EntropySource ;
23
23
use crate :: util:: ser:: { Readable , Writeable , Writer } ;
24
+ use crate :: util:: scid_utils;
24
25
25
26
use crate :: io;
26
27
use crate :: prelude:: * ;
@@ -124,7 +125,7 @@ impl BlindedPath {
124
125
pub fn one_hop_for_message < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
125
126
recipient_node_id : PublicKey , entropy_source : ES , secp_ctx : & Secp256k1 < T >
126
127
) -> Result < Self , ( ) > where ES :: Target : EntropySource {
127
- Self :: new_for_message ( & [ recipient_node_id ] , entropy_source, secp_ctx)
128
+ Self :: new_for_message ( & [ ] , recipient_node_id , entropy_source, secp_ctx)
128
129
}
129
130
130
131
/// Create a blinded path for an onion message, to be forwarded along `node_pks`. The last node
@@ -133,17 +134,21 @@ impl BlindedPath {
133
134
/// Errors if no hops are provided or if `node_pk`(s) are invalid.
134
135
// TODO: make all payloads the same size with padding + add dummy hops
135
136
pub fn new_for_message < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
136
- node_pks : & [ PublicKey ] , entropy_source : ES , secp_ctx : & Secp256k1 < T >
137
+ intermediate_nodes : & [ message:: ForwardNode ] , recipient_node_id : PublicKey ,
138
+ entropy_source : ES , secp_ctx : & Secp256k1 < T >
137
139
) -> Result < Self , ( ) > where ES :: Target : EntropySource {
138
- if node_pks. is_empty ( ) { return Err ( ( ) ) }
140
+ let introduction_node = IntroductionNode :: NodeId (
141
+ intermediate_nodes. first ( ) . map_or ( recipient_node_id, |n| n. node_id )
142
+ ) ;
139
143
let blinding_secret_bytes = entropy_source. get_secure_random_bytes ( ) ;
140
144
let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
141
- let introduction_node = IntroductionNode :: NodeId ( node_pks[ 0 ] ) ;
142
145
143
146
Ok ( BlindedPath {
144
147
introduction_node,
145
148
blinding_point : PublicKey :: from_secret_key ( secp_ctx, & blinding_secret) ,
146
- blinded_hops : message:: blinded_hops ( secp_ctx, node_pks, & blinding_secret) . map_err ( |_| ( ) ) ?,
149
+ blinded_hops : message:: blinded_hops (
150
+ secp_ctx, intermediate_nodes, recipient_node_id, & blinding_secret,
151
+ ) . map_err ( |_| ( ) ) ?,
147
152
} )
148
153
}
149
154
@@ -213,6 +218,35 @@ impl BlindedPath {
213
218
} ,
214
219
}
215
220
}
221
+
222
+ /// Attempts to a use a compact representation for the [`IntroductionNode`] by using a directed
223
+ /// short channel id from a channel in `network_graph` leading to the introduction node.
224
+ ///
225
+ /// While this may result in a smaller encoding, there is a trade off in that the path may
226
+ /// become invalid if the channel is closed or hasn't been propagated via gossip. Therefore,
227
+ /// calling this may not be suitable for long-lived blinded paths.
228
+ pub fn use_compact_introduction_node ( & mut self , network_graph : & ReadOnlyNetworkGraph ) {
229
+ if let IntroductionNode :: NodeId ( pubkey) = & self . introduction_node {
230
+ let node_id = NodeId :: from_pubkey ( pubkey) ;
231
+ if let Some ( node_info) = network_graph. node ( & node_id) {
232
+ if let Some ( ( scid, channel_info) ) = node_info
233
+ . channels
234
+ . iter ( )
235
+ . filter_map ( |scid| network_graph. channel ( * scid) . map ( |info| ( * scid, info) ) )
236
+ . min_by_key ( |( scid, _) | scid_utils:: block_from_scid ( * scid) )
237
+ {
238
+ let direction = if node_id == channel_info. node_one {
239
+ Direction :: NodeOne
240
+ } else {
241
+ debug_assert_eq ! ( node_id, channel_info. node_two) ;
242
+ Direction :: NodeTwo
243
+ } ;
244
+ self . introduction_node =
245
+ IntroductionNode :: DirectedShortChannelId ( direction, scid) ;
246
+ }
247
+ }
248
+ }
249
+ }
216
250
}
217
251
218
252
impl Writeable for BlindedPath {
0 commit comments