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