@@ -6,9 +6,12 @@ use bitcoin::hashes::Hash;
6
6
use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
7
7
use bitcoin:: secp256k1:: { self , Secp256k1 , PublicKey } ;
8
8
9
+ use crate :: blinded_path;
10
+ use crate :: blinded_path:: payment:: { PaymentConstraints , PaymentRelay } ;
9
11
use crate :: chain:: channelmonitor:: { HTLC_FAIL_BACK_BUFFER , LATENCY_GRACE_PERIOD_BLOCKS } ;
10
12
use crate :: ln:: PaymentHash ;
11
- use crate :: ln:: channelmanager:: { CLTV_FAR_FAR_AWAY , HTLCFailureMsg , MIN_CLTV_EXPIRY_DELTA , PendingHTLCInfo , PendingHTLCRouting } ;
13
+ use crate :: ln:: channelmanager:: { BlindedForward , CLTV_FAR_FAR_AWAY , HTLCFailureMsg , MIN_CLTV_EXPIRY_DELTA , PendingHTLCInfo , PendingHTLCRouting } ;
14
+ use crate :: ln:: features:: BlindedHopFeatures ;
12
15
use crate :: ln:: msgs;
13
16
use crate :: ln:: onion_utils;
14
17
use crate :: ln:: onion_utils:: { HTLCFailReason , INVALID_ONION_BLINDING } ;
@@ -28,6 +31,23 @@ pub struct InboundOnionErr {
28
31
pub msg : & ' static str ,
29
32
}
30
33
34
+ fn check_blinded_forward (
35
+ inbound_amt_msat : u64 , inbound_cltv_expiry : u32 , payment_relay : & PaymentRelay ,
36
+ payment_constraints : & PaymentConstraints , features : & BlindedHopFeatures
37
+ ) -> Result < ( u64 , u32 ) , ( ) > {
38
+ let amt_to_forward = blinded_path:: payment:: amt_to_forward_msat (
39
+ inbound_amt_msat, payment_relay
40
+ ) . ok_or ( ( ) ) ?;
41
+ let outgoing_cltv_value = inbound_cltv_expiry. checked_sub (
42
+ payment_relay. cltv_expiry_delta as u32
43
+ ) . ok_or ( ( ) ) ?;
44
+ if inbound_amt_msat < payment_constraints. htlc_minimum_msat ||
45
+ outgoing_cltv_value > payment_constraints. max_cltv_expiry
46
+ { return Err ( ( ) ) }
47
+ if features. requires_unknown_bits_from ( & BlindedHopFeatures :: empty ( ) ) { return Err ( ( ) ) }
48
+ Ok ( ( amt_to_forward, outgoing_cltv_value) )
49
+ }
50
+
31
51
pub ( super ) fn create_fwd_pending_htlc_info (
32
52
msg : & msgs:: UpdateAddHTLC , hop_data : msgs:: InboundOnionPayload , hop_hmac : [ u8 ; 32 ] ,
33
53
new_packet_bytes : [ u8 ; onion_utils:: ONION_DATA_LEN ] , shared_secret : [ u8 ; 32 ] ,
@@ -41,10 +61,27 @@ pub(super) fn create_fwd_pending_htlc_info(
41
61
hmac : hop_hmac,
42
62
} ;
43
63
44
- let ( short_channel_id, amt_to_forward, outgoing_cltv_value) = match hop_data {
64
+ let (
65
+ short_channel_id, amt_to_forward, outgoing_cltv_value, inbound_blinding_point
66
+ ) = match hop_data {
45
67
msgs:: InboundOnionPayload :: Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } =>
46
- ( short_channel_id, amt_to_forward, outgoing_cltv_value) ,
47
- msgs:: InboundOnionPayload :: BlindedForward { .. } => todo ! ( ) ,
68
+ ( short_channel_id, amt_to_forward, outgoing_cltv_value, None ) ,
69
+ msgs:: InboundOnionPayload :: BlindedForward {
70
+ short_channel_id, payment_relay, payment_constraints, intro_node_blinding_point, features,
71
+ } => {
72
+ let ( amt_to_forward, outgoing_cltv_value) = check_blinded_forward (
73
+ msg. amount_msat , msg. cltv_expiry , & payment_relay, & payment_constraints, & features
74
+ ) . map_err ( |( ) | {
75
+ // We should be returning malformed here if `msg.blinding_point` is set, but this is
76
+ // unreachable right now since we checked it in `decode_update_add_htlc_onion`.
77
+ InboundOnionErr {
78
+ msg : "Underflow calculating outbound amount or cltv value for blinded forward" ,
79
+ err_code : INVALID_ONION_BLINDING ,
80
+ err_data : vec ! [ 0 ; 32 ] ,
81
+ }
82
+ } ) ?;
83
+ ( short_channel_id, amt_to_forward, outgoing_cltv_value, Some ( intro_node_blinding_point) )
84
+ } ,
48
85
msgs:: InboundOnionPayload :: Receive { .. } | msgs:: InboundOnionPayload :: BlindedReceive { .. } =>
49
86
return Err ( InboundOnionErr {
50
87
msg : "Final Node OnionHopData provided for us as an intermediary node" ,
@@ -57,7 +94,7 @@ pub(super) fn create_fwd_pending_htlc_info(
57
94
routing : PendingHTLCRouting :: Forward {
58
95
onion_packet : outgoing_packet,
59
96
short_channel_id,
60
- blinded : None ,
97
+ blinded : inbound_blinding_point . map ( |bp| BlindedForward { inbound_blinding_point : bp } ) ,
61
98
} ,
62
99
payment_hash : msg. payment_hash ,
63
100
incoming_shared_secret : shared_secret,
@@ -336,9 +373,25 @@ where
336
373
}
337
374
} ,
338
375
onion_utils:: Hop :: Forward {
339
- next_hop_data : msgs:: InboundOnionPayload :: BlindedForward { .. } , ..
376
+ next_hop_data : msgs:: InboundOnionPayload :: BlindedForward {
377
+ short_channel_id, ref payment_relay, ref payment_constraints, ref features, ..
378
+ } , ..
340
379
} => {
341
- todo ! ( )
380
+ let ( amt_to_forward, outgoing_cltv_value) = match check_blinded_forward (
381
+ msg. amount_msat , msg. cltv_expiry , & payment_relay, & payment_constraints, & features
382
+ ) {
383
+ Ok ( ( amt, cltv) ) => ( amt, cltv) ,
384
+ Err ( ( ) ) => {
385
+ return_err ! ( "Underflow calculating outbound amount or cltv value for blinded forward" ,
386
+ INVALID_ONION_BLINDING , & [ 0 ; 32 ] ) ;
387
+ }
388
+ } ;
389
+ let next_packet_pubkey = onion_utils:: next_hop_pubkey ( & secp_ctx,
390
+ msg. onion_routing_packet . public_key . unwrap ( ) , & shared_secret) ;
391
+ NextPacketDetails {
392
+ next_packet_pubkey, outgoing_scid : short_channel_id, outgoing_amt_msat : amt_to_forward,
393
+ outgoing_cltv_value
394
+ }
342
395
} ,
343
396
onion_utils:: Hop :: Receive { .. } => return Ok ( ( next_hop, shared_secret, None ) ) ,
344
397
onion_utils:: Hop :: Forward { next_hop_data : msgs:: InboundOnionPayload :: Receive { .. } , .. } |
0 commit comments