@@ -63,6 +63,8 @@ pub fn scid_from_parts(block: u64, tx_index: u64, vout_index: u64) -> Result<u64
6363/// LDK has multiple reasons to generate fake short channel ids:
6464/// 1) outbound SCID aliases we use for private channels
6565/// 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)
6668pub ( crate ) mod fake_scid {
6769 use bitcoin:: hash_types:: BlockHash ;
6870 use bitcoin:: hashes:: hex:: FromHex ;
@@ -91,6 +93,7 @@ pub(crate) mod fake_scid {
9193 pub ( crate ) enum Namespace {
9294 Phantom ,
9395 OutboundAlias ,
96+ Intercept
9497 }
9598
9699 impl Namespace {
@@ -150,7 +153,7 @@ pub(crate) mod fake_scid {
150153 }
151154 }
152155
153- /// Returns whether the given fake scid falls into the given namespace.
156+ /// Returns whether the given fake scid falls into the phantom namespace.
154157 pub fn is_valid_phantom ( fake_scid_rand_bytes : & [ u8 ; 32 ] , scid : u64 , genesis_hash : & BlockHash ) -> bool {
155158 let block_height = scid_utils:: block_from_scid ( & scid) ;
156159 let tx_index = scid_utils:: tx_index_from_scid ( & scid) ;
@@ -160,11 +163,21 @@ pub(crate) mod fake_scid {
160163 && valid_vout == scid_utils:: vout_from_scid ( & scid) as u8
161164 }
162165
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+
163176 #[ cfg( test) ]
164177 mod tests {
165178 use bitcoin:: blockdata:: constants:: genesis_block;
166179 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 } ;
168181 use crate :: util:: scid_utils;
169182 use crate :: util:: test_utils;
170183 use crate :: sync:: Arc ;
@@ -174,6 +187,10 @@ pub(crate) mod fake_scid {
174187 let phantom_namespace = Namespace :: Phantom ;
175188 assert ! ( ( phantom_namespace as u8 ) < MAX_NAMESPACES ) ;
176189 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 ) ;
177194 }
178195
179196 #[ test]
@@ -203,6 +220,18 @@ pub(crate) mod fake_scid {
203220 assert ! ( !is_valid_phantom( & fake_scid_rand_bytes, invalid_fake_scid, & testnet_genesis) ) ;
204221 }
205222
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+
206235 #[ test]
207236 fn test_get_fake_scid ( ) {
208237 let mainnet_genesis = genesis_block ( Network :: Bitcoin ) . header . block_hash ( ) ;
0 commit comments