@@ -782,15 +782,47 @@ impl Channel {
782782 return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given payment preimage" , msg : None } ) ;
783783 }
784784
785+ //TODO: This is racy af, they may have pending messages in flight to us that will not have
786+ //received this yet!
785787 self . value_to_self_msat += htlc_amount_msat;
786-
787788 Ok ( msgs:: UpdateFulfillHTLC {
788789 channel_id : self . channel_id ( ) ,
789790 htlc_id : htlc_id,
790791 payment_preimage : payment_preimage,
791792 } )
792793 }
793794
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+
794826 // Message handlers:
795827
796828 pub fn accept_channel ( & mut self , msg : & msgs:: AcceptChannel ) -> Result < ( ) , HandleError > {
@@ -1010,7 +1042,7 @@ impl Channel {
10101042 }
10111043
10121044 /// 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 > {
10141046 let mut found_idx = None ;
10151047 for ( idx, ref htlc) in self . pending_htlcs . iter ( ) . enumerate ( ) {
10161048 if htlc. outbound && htlc. htlc_id == htlc_id {
@@ -1026,7 +1058,7 @@ impl Channel {
10261058 }
10271059 }
10281060 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 } ) ,
10301062 Some ( idx) => {
10311063 Ok ( self . pending_htlcs . swap_remove ( idx) )
10321064 }
@@ -1096,9 +1128,7 @@ impl Channel {
10961128 let mut payment_hash = [ 0 ; 32 ] ;
10971129 sha. result ( & mut payment_hash) ;
10981130
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) ) {
11021132 Err ( e) => return Err ( e) ,
11031133 Ok ( htlc) => {
11041134 //TODO: Double-check that we didn't exceed some limits (or value_to_self went
@@ -1110,43 +1140,40 @@ impl Channel {
11101140 self . check_and_free_holding_cell_htlcs ( )
11111141 }
11121142
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 > {
11151144 if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
11161145 return Err ( HandleError { err : "Got add HTLC message when channel was not in an operational state" , msg : None } ) ;
11171146 }
11181147
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 ) {
11221149 Err ( e) => return Err ( e) ,
1123- Ok ( _htlc ) => {
1150+ Ok ( htlc ) => {
11241151 //TODO: Double-check that we didn't exceed some limits (or value_to_self went
11251152 //negative here?)
1126- ////TODO: Something?
1153+ htlc . payment_hash
11271154 }
1128- }
1155+ } ;
11291156
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) )
11311159 }
11321160
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 > {
11341162 if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
11351163 return Err ( HandleError { err : "Got add HTLC message when channel was not in an operational state" , msg : None } ) ;
11361164 }
11371165
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 ) {
11411167 Err ( e) => return Err ( e) ,
1142- Ok ( _htlc ) => {
1168+ Ok ( htlc ) => {
11431169 //TODO: Double-check that we didn't exceed some limits (or value_to_self went
11441170 //negative here?)
1145- ////TODO: Something?
1171+ htlc . payment_hash
11461172 }
1147- }
1173+ } ;
11481174
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) )
11501177 }
11511178
11521179 pub fn commitment_signed ( & mut self , msg : & msgs:: CommitmentSigned ) -> Result < ( msgs:: RevokeAndACK , Vec < PendingForwardHTLCInfo > ) , HandleError > {
0 commit comments