@@ -63,6 +63,8 @@ pub fn scid_from_parts(block: u64, tx_index: u64, vout_index: u64) -> Result<u64
63
63
/// LDK has multiple reasons to generate fake short channel ids:
64
64
/// 1) outbound SCID aliases we use for private channels
65
65
/// 2) phantom node payments, to get an scid for the phantom node's phantom channel
66
+ /// 3) payments intended to be intercepted will route using a fake scid (this is typically used so
67
+ /// the forwarding node can open a JIT channel to the next hop)
66
68
pub ( crate ) mod fake_scid {
67
69
use bitcoin:: hash_types:: BlockHash ;
68
70
use bitcoin:: hashes:: hex:: FromHex ;
@@ -91,6 +93,7 @@ pub(crate) mod fake_scid {
91
93
pub ( crate ) enum Namespace {
92
94
Phantom ,
93
95
OutboundAlias ,
96
+ Intercept
94
97
}
95
98
96
99
impl Namespace {
@@ -150,7 +153,7 @@ pub(crate) mod fake_scid {
150
153
}
151
154
}
152
155
153
- /// Returns whether the given fake scid falls into the given namespace.
156
+ /// Returns whether the given fake scid falls into the phantom namespace.
154
157
pub fn is_valid_phantom ( fake_scid_rand_bytes : & [ u8 ; 32 ] , scid : u64 , genesis_hash : & BlockHash ) -> bool {
155
158
let block_height = scid_utils:: block_from_scid ( & scid) ;
156
159
let tx_index = scid_utils:: tx_index_from_scid ( & scid) ;
@@ -160,11 +163,21 @@ pub(crate) mod fake_scid {
160
163
&& valid_vout == scid_utils:: vout_from_scid ( & scid) as u8
161
164
}
162
165
166
+ /// Returns whether the given fake scid falls into the intercept namespace.
167
+ pub fn is_valid_intercept ( fake_scid_rand_bytes : & [ u8 ; 32 ] , scid : u64 , genesis_hash : & BlockHash ) -> bool {
168
+ let block_height = scid_utils:: block_from_scid ( & scid) ;
169
+ let tx_index = scid_utils:: tx_index_from_scid ( & scid) ;
170
+ let namespace = Namespace :: Intercept ;
171
+ let valid_vout = namespace. get_encrypted_vout ( block_height, tx_index, fake_scid_rand_bytes) ;
172
+ block_height >= segwit_activation_height ( genesis_hash)
173
+ && valid_vout == scid_utils:: vout_from_scid ( & scid) as u8
174
+ }
175
+
163
176
#[ cfg( test) ]
164
177
mod tests {
165
178
use bitcoin:: blockdata:: constants:: genesis_block;
166
179
use bitcoin:: network:: constants:: Network ;
167
- use crate :: util:: scid_utils:: fake_scid:: { is_valid_phantom, MAINNET_SEGWIT_ACTIVATION_HEIGHT , MAX_TX_INDEX , MAX_NAMESPACES , Namespace , NAMESPACE_ID_BITMASK , segwit_activation_height, TEST_SEGWIT_ACTIVATION_HEIGHT } ;
180
+ use crate :: util:: scid_utils:: fake_scid:: { is_valid_intercept , is_valid_phantom, MAINNET_SEGWIT_ACTIVATION_HEIGHT , MAX_TX_INDEX , MAX_NAMESPACES , Namespace , NAMESPACE_ID_BITMASK , segwit_activation_height, TEST_SEGWIT_ACTIVATION_HEIGHT } ;
168
181
use crate :: util:: scid_utils;
169
182
use crate :: util:: test_utils;
170
183
use crate :: sync:: Arc ;
@@ -174,6 +187,10 @@ pub(crate) mod fake_scid {
174
187
let phantom_namespace = Namespace :: Phantom ;
175
188
assert ! ( ( phantom_namespace as u8 ) < MAX_NAMESPACES ) ;
176
189
assert ! ( ( phantom_namespace as u8 ) <= NAMESPACE_ID_BITMASK ) ;
190
+
191
+ let intercept_namespace = Namespace :: Intercept ;
192
+ assert ! ( ( intercept_namespace as u8 ) < MAX_NAMESPACES ) ;
193
+ assert ! ( ( intercept_namespace as u8 ) <= NAMESPACE_ID_BITMASK ) ;
177
194
}
178
195
179
196
#[ test]
@@ -203,6 +220,18 @@ pub(crate) mod fake_scid {
203
220
assert ! ( !is_valid_phantom( & fake_scid_rand_bytes, invalid_fake_scid, & testnet_genesis) ) ;
204
221
}
205
222
223
+ #[ test]
224
+ fn test_is_valid_intercept ( ) {
225
+ let namespace = Namespace :: Intercept ;
226
+ let fake_scid_rand_bytes = [ 0 ; 32 ] ;
227
+ let testnet_genesis = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
228
+ let valid_encrypted_vout = namespace. get_encrypted_vout ( 0 , 0 , & fake_scid_rand_bytes) ;
229
+ let valid_fake_scid = scid_utils:: scid_from_parts ( 1 , 0 , valid_encrypted_vout as u64 ) . unwrap ( ) ;
230
+ assert ! ( is_valid_intercept( & fake_scid_rand_bytes, valid_fake_scid, & testnet_genesis) ) ;
231
+ let invalid_fake_scid = scid_utils:: scid_from_parts ( 1 , 0 , 12 ) . unwrap ( ) ;
232
+ assert ! ( !is_valid_intercept( & fake_scid_rand_bytes, invalid_fake_scid, & testnet_genesis) ) ;
233
+ }
234
+
206
235
#[ test]
207
236
fn test_get_fake_scid ( ) {
208
237
let mainnet_genesis = genesis_block ( Network :: Bitcoin ) . header . block_hash ( ) ;
0 commit comments