@@ -107,19 +107,19 @@ enum OutboundHTLCState {
107
107
Committed ,
108
108
/// Remote removed this (outbound) HTLC. We're waiting on their commitment_signed to finalize
109
109
/// the change (though they'll need to revoke before we fail the payment).
110
- RemoteRemoved ,
110
+ RemoteRemoved ( Option < HTLCFailReason > ) ,
111
111
/// Remote removed this and sent a commitment_signed (implying we've revoke_and_ack'ed it), but
112
112
/// the remote side hasn't yet revoked their previous state, which we need them to do before we
113
113
/// can do any backwards failing. Implies AwaitingRemoteRevoke.
114
114
/// We also have not yet removed this HTLC in a commitment_signed message, and are waiting on a
115
115
/// remote revoke_and_ack on a previous state before we can do so.
116
- AwaitingRemoteRevokeToRemove ,
116
+ AwaitingRemoteRevokeToRemove ( Option < HTLCFailReason > ) ,
117
117
/// Remote removed this and sent a commitment_signed (implying we've revoke_and_ack'ed it), but
118
118
/// the remote side hasn't yet revoked their previous state, which we need them to do before we
119
119
/// can do any backwards failing. Implies AwaitingRemoteRevoke.
120
120
/// We have removed this HTLC in our latest commitment_signed and are now just waiting on a
121
121
/// revoke_and_ack to drop completely.
122
- AwaitingRemovedRemoteRevoke ,
122
+ AwaitingRemovedRemoteRevoke ( Option < HTLCFailReason > ) ,
123
123
}
124
124
125
125
struct OutboundHTLCOutput {
@@ -129,8 +129,6 @@ struct OutboundHTLCOutput {
129
129
payment_hash : PaymentHash ,
130
130
state : OutboundHTLCState ,
131
131
source : HTLCSource ,
132
- /// If we're in a removed state, set if they failed, otherwise None
133
- fail_reason : Option < HTLCFailReason > ,
134
132
}
135
133
136
134
/// See AwaitingRemoteRevoke ChannelState for more info
@@ -859,9 +857,9 @@ impl Channel {
859
857
let ( include, state_name) = match htlc. state {
860
858
OutboundHTLCState :: LocalAnnounced ( _) => ( generated_by_local, "LocalAnnounced" ) ,
861
859
OutboundHTLCState :: Committed => ( true , "Committed" ) ,
862
- OutboundHTLCState :: RemoteRemoved => ( generated_by_local, "RemoteRemoved" ) ,
863
- OutboundHTLCState :: AwaitingRemoteRevokeToRemove => ( generated_by_local, "AwaitingRemoteRevokeToRemove" ) ,
864
- OutboundHTLCState :: AwaitingRemovedRemoteRevoke => ( false , "AwaitingRemovedRemoteRevoke" ) ,
860
+ OutboundHTLCState :: RemoteRemoved ( _ ) => ( generated_by_local, "RemoteRemoved" ) ,
861
+ OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( _ ) => ( generated_by_local, "AwaitingRemoteRevokeToRemove" ) ,
862
+ OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( _ ) => ( false , "AwaitingRemovedRemoteRevoke" ) ,
865
863
} ;
866
864
867
865
if include {
@@ -870,13 +868,11 @@ impl Channel {
870
868
} else {
871
869
log_trace ! ( self , " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})" , htlc. htlc_id, log_bytes!( htlc. payment_hash. 0 ) , htlc. amount_msat, state_name) ;
872
870
match htlc. state {
873
- OutboundHTLCState :: AwaitingRemoteRevokeToRemove |OutboundHTLCState :: AwaitingRemovedRemoteRevoke => {
874
- if htlc. fail_reason . is_none ( ) {
875
- value_to_self_msat_offset -= htlc. amount_msat as i64 ;
876
- }
871
+ OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( None ) |OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( None ) => {
872
+ value_to_self_msat_offset -= htlc. amount_msat as i64 ;
877
873
} ,
878
- OutboundHTLCState :: RemoteRemoved => {
879
- if !generated_by_local && htlc . fail_reason . is_none ( ) {
874
+ OutboundHTLCState :: RemoteRemoved ( None ) => {
875
+ if !generated_by_local {
880
876
value_to_self_msat_offset -= htlc. amount_msat as i64 ;
881
877
}
882
878
} ,
@@ -1645,10 +1641,9 @@ impl Channel {
1645
1641
OutboundHTLCState :: LocalAnnounced ( _) =>
1646
1642
return Err ( ChannelError :: Close ( "Remote tried to fulfill/fail HTLC before it had been committed" ) ) ,
1647
1643
OutboundHTLCState :: Committed => {
1648
- htlc. state = OutboundHTLCState :: RemoteRemoved ;
1649
- htlc. fail_reason = fail_reason;
1644
+ htlc. state = OutboundHTLCState :: RemoteRemoved ( fail_reason) ;
1650
1645
} ,
1651
- OutboundHTLCState :: AwaitingRemoteRevokeToRemove | OutboundHTLCState :: AwaitingRemovedRemoteRevoke | OutboundHTLCState :: RemoteRemoved =>
1646
+ OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( _ ) | OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( _ ) | OutboundHTLCState :: RemoteRemoved ( _ ) =>
1652
1647
return Err ( ChannelError :: Close ( "Remote tried to fulfill/fail HTLC that they'd already fulfilled/failed" ) ) ,
1653
1648
}
1654
1649
return Ok ( & htlc. source ) ;
@@ -1801,8 +1796,10 @@ impl Channel {
1801
1796
}
1802
1797
}
1803
1798
for htlc in self . pending_outbound_htlcs . iter_mut ( ) {
1804
- if let OutboundHTLCState :: RemoteRemoved = htlc. state {
1805
- htlc. state = OutboundHTLCState :: AwaitingRemoteRevokeToRemove ;
1799
+ if let Some ( fail_reason) = if let & mut OutboundHTLCState :: RemoteRemoved ( ref mut fail_reason) = & mut htlc. state {
1800
+ Some ( fail_reason. take ( ) )
1801
+ } else { None } {
1802
+ htlc. state = OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( fail_reason) ;
1806
1803
need_our_commitment = true ;
1807
1804
}
1808
1805
}
@@ -1855,6 +1852,8 @@ impl Channel {
1855
1852
fn free_holding_cell_htlcs ( & mut self ) -> Result < Option < ( msgs:: CommitmentUpdate , ChannelMonitor ) > , ChannelError > {
1856
1853
assert_eq ! ( self . channel_state & ChannelState :: MonitorUpdateFailed as u32 , 0 ) ;
1857
1854
if self . holding_cell_htlc_updates . len ( ) != 0 || self . holding_cell_update_fee . is_some ( ) {
1855
+ log_trace ! ( self , "Freeing holding cell with {} HTLC updates{}" , self . holding_cell_htlc_updates. len( ) , if self . holding_cell_update_fee. is_some( ) { " and a fee update" } else { "" } ) ;
1856
+
1858
1857
let mut htlc_updates = Vec :: new ( ) ;
1859
1858
mem:: swap ( & mut htlc_updates, & mut self . holding_cell_htlc_updates ) ;
1860
1859
let mut update_add_htlcs = Vec :: with_capacity ( htlc_updates. len ( ) ) ;
@@ -2020,9 +2019,9 @@ impl Channel {
2020
2019
} else { true }
2021
2020
} ) ;
2022
2021
pending_outbound_htlcs. retain ( |htlc| {
2023
- if let OutboundHTLCState :: AwaitingRemovedRemoteRevoke = htlc. state {
2022
+ if let & OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( ref fail_reason ) = & htlc. state {
2024
2023
log_trace ! ( logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}" , log_bytes!( htlc. payment_hash. 0 ) ) ;
2025
- if let Some ( reason) = htlc . fail_reason . clone ( ) { // We really want take() here, but, again, non-mut ref :(
2024
+ if let Some ( reason) = fail_reason. clone ( ) { // We really want take() here, but, again, non-mut ref :(
2026
2025
revoked_htlcs. push ( ( htlc. source . clone ( ) , htlc. payment_hash , reason) ) ;
2027
2026
} else {
2028
2027
// They fulfilled, so we sent them money
@@ -2073,9 +2072,12 @@ impl Channel {
2073
2072
if let OutboundHTLCState :: LocalAnnounced ( _) = htlc. state {
2074
2073
log_trace ! ( logger, " ...promoting outbound LocalAnnounced {} to Committed" , log_bytes!( htlc. payment_hash. 0 ) ) ;
2075
2074
htlc. state = OutboundHTLCState :: Committed ;
2076
- } else if let OutboundHTLCState :: AwaitingRemoteRevokeToRemove = htlc. state {
2075
+ }
2076
+ if let Some ( fail_reason) = if let & mut OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref mut fail_reason) = & mut htlc. state {
2077
+ Some ( fail_reason. take ( ) )
2078
+ } else { None } {
2077
2079
log_trace ! ( logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke" , log_bytes!( htlc. payment_hash. 0 ) ) ;
2078
- htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ;
2080
+ htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( fail_reason ) ;
2079
2081
require_commitment = true ;
2080
2082
}
2081
2083
}
@@ -2231,7 +2233,7 @@ impl Channel {
2231
2233
self . next_remote_htlc_id -= inbound_drop_count;
2232
2234
2233
2235
for htlc in self . pending_outbound_htlcs . iter_mut ( ) {
2234
- if let OutboundHTLCState :: RemoteRemoved = htlc. state {
2236
+ if let OutboundHTLCState :: RemoteRemoved ( _ ) = htlc. state {
2235
2237
// They sent us an update to remove this but haven't yet sent the corresponding
2236
2238
// commitment_signed, we need to move it back to Committed and they can re-send
2237
2239
// the update upon reconnection.
@@ -3249,7 +3251,6 @@ impl Channel {
3249
3251
cltv_expiry : cltv_expiry,
3250
3252
state : OutboundHTLCState :: LocalAnnounced ( Box :: new ( onion_routing_packet. clone ( ) ) ) ,
3251
3253
source,
3252
- fail_reason : None ,
3253
3254
} ) ;
3254
3255
3255
3256
let res = msgs:: UpdateAddHTLC {
@@ -3314,8 +3315,10 @@ impl Channel {
3314
3315
}
3315
3316
}
3316
3317
for htlc in self . pending_outbound_htlcs . iter_mut ( ) {
3317
- if let OutboundHTLCState :: AwaitingRemoteRevokeToRemove = htlc. state {
3318
- htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ;
3318
+ if let Some ( fail_reason) = if let & mut OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref mut fail_reason) = & mut htlc. state {
3319
+ Some ( fail_reason. take ( ) )
3320
+ } else { None } {
3321
+ htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( fail_reason) ;
3319
3322
}
3320
3323
}
3321
3324
@@ -3581,7 +3584,6 @@ impl Writeable for Channel {
3581
3584
htlc. cltv_expiry . write ( writer) ?;
3582
3585
htlc. payment_hash . write ( writer) ?;
3583
3586
htlc. source . write ( writer) ?;
3584
- write_option ! ( htlc. fail_reason) ;
3585
3587
match & htlc. state {
3586
3588
& OutboundHTLCState :: LocalAnnounced ( ref onion_packet) => {
3587
3589
0u8 . write ( writer) ?;
@@ -3590,14 +3592,17 @@ impl Writeable for Channel {
3590
3592
& OutboundHTLCState :: Committed => {
3591
3593
1u8 . write ( writer) ?;
3592
3594
} ,
3593
- & OutboundHTLCState :: RemoteRemoved => {
3595
+ & OutboundHTLCState :: RemoteRemoved ( ref fail_reason ) => {
3594
3596
2u8 . write ( writer) ?;
3597
+ write_option ! ( * fail_reason) ;
3595
3598
} ,
3596
- & OutboundHTLCState :: AwaitingRemoteRevokeToRemove => {
3599
+ & OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref fail_reason ) => {
3597
3600
3u8 . write ( writer) ?;
3601
+ write_option ! ( * fail_reason) ;
3598
3602
} ,
3599
- & OutboundHTLCState :: AwaitingRemovedRemoteRevoke => {
3603
+ & OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( ref fail_reason ) => {
3600
3604
4u8 . write ( writer) ?;
3605
+ write_option ! ( * fail_reason) ;
3601
3606
} ,
3602
3607
}
3603
3608
}
@@ -3760,13 +3765,12 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
3760
3765
cltv_expiry : Readable :: read ( reader) ?,
3761
3766
payment_hash : Readable :: read ( reader) ?,
3762
3767
source : Readable :: read ( reader) ?,
3763
- fail_reason : Readable :: read ( reader) ?,
3764
3768
state : match <u8 as Readable < R > >:: read ( reader) ? {
3765
3769
0 => OutboundHTLCState :: LocalAnnounced ( Box :: new ( Readable :: read ( reader) ?) ) ,
3766
3770
1 => OutboundHTLCState :: Committed ,
3767
- 2 => OutboundHTLCState :: RemoteRemoved ,
3768
- 3 => OutboundHTLCState :: AwaitingRemoteRevokeToRemove ,
3769
- 4 => OutboundHTLCState :: AwaitingRemovedRemoteRevoke ,
3771
+ 2 => OutboundHTLCState :: RemoteRemoved ( Readable :: read ( reader ) ? ) ,
3772
+ 3 => OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( Readable :: read ( reader ) ? ) ,
3773
+ 4 => OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( Readable :: read ( reader ) ? ) ,
3770
3774
_ => return Err ( DecodeError :: InvalidValue ) ,
3771
3775
} ,
3772
3776
} ) ;
@@ -4161,7 +4165,6 @@ mod tests {
4161
4165
payment_hash : PaymentHash ( [ 0 ; 32 ] ) ,
4162
4166
state : OutboundHTLCState :: Committed ,
4163
4167
source : HTLCSource :: dummy ( ) ,
4164
- fail_reason : None ,
4165
4168
} ;
4166
4169
out. payment_hash . 0 = Sha256 :: hash ( & hex:: decode ( "0202020202020202020202020202020202020202020202020202020202020202" ) . unwrap ( ) ) . into_inner ( ) ;
4167
4170
out
@@ -4174,7 +4177,6 @@ mod tests {
4174
4177
payment_hash : PaymentHash ( [ 0 ; 32 ] ) ,
4175
4178
state : OutboundHTLCState :: Committed ,
4176
4179
source : HTLCSource :: dummy ( ) ,
4177
- fail_reason : None ,
4178
4180
} ;
4179
4181
out. payment_hash . 0 = Sha256 :: hash ( & hex:: decode ( "0303030303030303030303030303030303030303030303030303030303030303" ) . unwrap ( ) ) . into_inner ( ) ;
4180
4182
out
0 commit comments