@@ -782,15 +782,47 @@ impl Channel {
782
782
return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given payment preimage" , msg : None } ) ;
783
783
}
784
784
785
+ //TODO: This is racy af, they may have pending messages in flight to us that will not have
786
+ //received this yet!
785
787
self . value_to_self_msat += htlc_amount_msat;
786
-
787
788
Ok ( msgs:: UpdateFulfillHTLC {
788
789
channel_id : self . channel_id ( ) ,
789
790
htlc_id : htlc_id,
790
791
payment_preimage : payment_preimage,
791
792
} )
792
793
}
793
794
795
+ pub fn get_update_fail_htlc ( & mut self , payment_hash : & [ u8 ; 32 ] , err_packet : msgs:: OnionErrorPacket ) -> Result < msgs:: UpdateFailHTLC , HandleError > {
796
+ if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
797
+ return Err ( HandleError { err : "Was asked to fail an HTLC when channel was not in an operational state" , msg : None } ) ;
798
+ }
799
+
800
+ let mut htlc_id = 0 ;
801
+ let mut htlc_amount_msat = 0 ;
802
+ self . pending_htlcs . retain ( |ref htlc| {
803
+ if !htlc. outbound && htlc. payment_hash == * payment_hash {
804
+ if htlc_id != 0 {
805
+ panic ! ( "Duplicate HTLC payment_hash, you probably re-used payment preimages, NEVER DO THIS!" ) ;
806
+ }
807
+ htlc_id = htlc. htlc_id ;
808
+ htlc_amount_msat += htlc. amount_msat ;
809
+ false
810
+ } else { true }
811
+ } ) ;
812
+ if htlc_amount_msat == 0 {
813
+ return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given payment preimage" , msg : None } ) ;
814
+ }
815
+
816
+ //TODO: This is racy af, they may have pending messages in flight to us that will not have
817
+ //received this yet!
818
+
819
+ Ok ( msgs:: UpdateFailHTLC {
820
+ channel_id : self . channel_id ( ) ,
821
+ htlc_id,
822
+ reason : err_packet
823
+ } )
824
+ }
825
+
794
826
// Message handlers:
795
827
796
828
pub fn accept_channel ( & mut self , msg : & msgs:: AcceptChannel ) -> Result < ( ) , HandleError > {
@@ -1010,7 +1042,7 @@ impl Channel {
1010
1042
}
1011
1043
1012
1044
/// Removes an outbound HTLC which has been commitment_signed by the remote end
1013
- fn remove_htlc ( & mut self , htlc_id : u64 , check_preimage : Option < [ u8 ; 32 ] > ) -> Result < HTLCOutput , HandleError > {
1045
+ fn remove_outbound_htlc ( & mut self , htlc_id : u64 , check_preimage : Option < [ u8 ; 32 ] > ) -> Result < HTLCOutput , HandleError > {
1014
1046
let mut found_idx = None ;
1015
1047
for ( idx, ref htlc) in self . pending_htlcs . iter ( ) . enumerate ( ) {
1016
1048
if htlc. outbound && htlc. htlc_id == htlc_id {
@@ -1026,7 +1058,7 @@ impl Channel {
1026
1058
}
1027
1059
}
1028
1060
match found_idx {
1029
- None => Err ( HandleError { err : "Remote tried to fulfill an HTLC we couldn't find" , msg : None } ) ,
1061
+ None => Err ( HandleError { err : "Remote tried to fulfill/fail an HTLC we couldn't find" , msg : None } ) ,
1030
1062
Some ( idx) => {
1031
1063
Ok ( self . pending_htlcs . swap_remove ( idx) )
1032
1064
}
@@ -1096,9 +1128,7 @@ impl Channel {
1096
1128
let mut payment_hash = [ 0 ; 32 ] ;
1097
1129
sha. result ( & mut payment_hash) ;
1098
1130
1099
- //TODO: Tell channel_monitor about the payment_preimage
1100
-
1101
- match self . remove_htlc ( msg. htlc_id , Some ( payment_hash) ) {
1131
+ match self . remove_outbound_htlc ( msg. htlc_id , Some ( payment_hash) ) {
1102
1132
Err ( e) => return Err ( e) ,
1103
1133
Ok ( htlc) => {
1104
1134
//TODO: Double-check that we didn't exceed some limits (or value_to_self went
@@ -1110,43 +1140,40 @@ impl Channel {
1110
1140
self . check_and_free_holding_cell_htlcs ( )
1111
1141
}
1112
1142
1113
-
1114
- pub fn update_fail_htlc ( & mut self , msg : & msgs:: UpdateFailHTLC ) -> Result < Option < ( Vec < msgs:: UpdateAddHTLC > , msgs:: CommitmentSigned ) > , HandleError > {
1143
+ pub fn update_fail_htlc ( & mut self , msg : & msgs:: UpdateFailHTLC ) -> Result < ( [ u8 ; 32 ] , Option < ( Vec < msgs:: UpdateAddHTLC > , msgs:: CommitmentSigned ) > ) , HandleError > {
1115
1144
if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
1116
1145
return Err ( HandleError { err : "Got add HTLC message when channel was not in an operational state" , msg : None } ) ;
1117
1146
}
1118
1147
1119
- //TODO: Lots of checks here (and implementation after the remove?)
1120
-
1121
- match self . remove_htlc ( msg. htlc_id , None ) {
1148
+ let payment_hash = match self . remove_outbound_htlc ( msg. htlc_id , None ) {
1122
1149
Err ( e) => return Err ( e) ,
1123
- Ok ( _htlc ) => {
1150
+ Ok ( htlc ) => {
1124
1151
//TODO: Double-check that we didn't exceed some limits (or value_to_self went
1125
1152
//negative here?)
1126
- ////TODO: Something?
1153
+ htlc . payment_hash
1127
1154
}
1128
- }
1155
+ } ;
1129
1156
1130
- self . check_and_free_holding_cell_htlcs ( )
1157
+ let holding_cell_freedom = self . check_and_free_holding_cell_htlcs ( ) ?;
1158
+ Ok ( ( payment_hash, holding_cell_freedom) )
1131
1159
}
1132
1160
1133
- pub fn update_fail_malformed_htlc ( & mut self , msg : & msgs:: UpdateFailMalformedHTLC ) -> Result < Option < ( Vec < msgs:: UpdateAddHTLC > , msgs:: CommitmentSigned ) > , HandleError > {
1161
+ pub fn update_fail_malformed_htlc ( & mut self , msg : & msgs:: UpdateFailMalformedHTLC ) -> Result < ( [ u8 ; 32 ] , Option < ( Vec < msgs:: UpdateAddHTLC > , msgs:: CommitmentSigned ) > ) , HandleError > {
1134
1162
if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
1135
1163
return Err ( HandleError { err : "Got add HTLC message when channel was not in an operational state" , msg : None } ) ;
1136
1164
}
1137
1165
1138
- //TODO: Lots of checks here (and implementation after the remove?)
1139
-
1140
- match self . remove_htlc ( msg. htlc_id , None ) {
1166
+ let payment_hash = match self . remove_outbound_htlc ( msg. htlc_id , None ) {
1141
1167
Err ( e) => return Err ( e) ,
1142
- Ok ( _htlc ) => {
1168
+ Ok ( htlc ) => {
1143
1169
//TODO: Double-check that we didn't exceed some limits (or value_to_self went
1144
1170
//negative here?)
1145
- ////TODO: Something?
1171
+ htlc . payment_hash
1146
1172
}
1147
- }
1173
+ } ;
1148
1174
1149
- self . check_and_free_holding_cell_htlcs ( )
1175
+ let holding_cell_freedom = self . check_and_free_holding_cell_htlcs ( ) ?;
1176
+ Ok ( ( payment_hash, holding_cell_freedom) )
1150
1177
}
1151
1178
1152
1179
pub fn commitment_signed ( & mut self , msg : & msgs:: CommitmentSigned ) -> Result < ( msgs:: RevokeAndACK , Vec < PendingForwardHTLCInfo > ) , HandleError > {
0 commit comments