Skip to content

Commit 4cdaabd

Browse files
Store inbound committed update_adds in Channel
We have an overarching goal of (mostly) getting rid of ChannelManager persistence and rebuilding the ChannelManager's state from existing ChannelMonitors, due to issues when the two structs are out-of-sync on restart. The main issue that can arise is channel force closure. As part of this, we plan to store at least parts of Channels in ChannelMonitors, and that Channel data will be used in rebuilding the manager. Once we store update_adds in Channels, we can use them on restart when reconstructing ChannelManager maps such as forward_htlcs and pending_intercepted_htlcs. Upcoming commits will start doing this reconstruction.
1 parent 4561bc5 commit 4cdaabd

File tree

1 file changed

+50
-27
lines changed

1 file changed

+50
-27
lines changed

lightning/src/ln/channel.rs

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ enum InboundHTLCState {
211211
/// channel (before it can then get forwarded and/or removed).
212212
/// Implies AwaitingRemoteRevoke.
213213
AwaitingAnnouncedRemoteRevoke(InboundHTLCResolution),
214-
Committed,
214+
Committed {
215+
update_add_htlc_opt: Option<msgs::UpdateAddHTLC>,
216+
},
215217
/// Removed by us and a new commitment_signed was sent (if we were AwaitingRemoteRevoke when we
216218
/// created it we would have put it in the holding cell instead). When they next revoke_and_ack
217219
/// we'll drop it.
@@ -235,7 +237,7 @@ impl From<&InboundHTLCState> for Option<InboundHTLCStateDetails> {
235237
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => {
236238
Some(InboundHTLCStateDetails::AwaitingRemoteRevokeToAdd)
237239
},
238-
InboundHTLCState::Committed => Some(InboundHTLCStateDetails::Committed),
240+
InboundHTLCState::Committed { .. } => Some(InboundHTLCStateDetails::Committed),
239241
InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(_)) => {
240242
Some(InboundHTLCStateDetails::AwaitingRemoteRevokeToRemoveFail)
241243
},
@@ -256,7 +258,7 @@ impl fmt::Display for InboundHTLCState {
256258
InboundHTLCState::RemoteAnnounced(_) => write!(f, "RemoteAnnounced"),
257259
InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => write!(f, "AwaitingRemoteRevokeToAnnounce"),
258260
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => write!(f, "AwaitingAnnouncedRemoteRevoke"),
259-
InboundHTLCState::Committed => write!(f, "Committed"),
261+
InboundHTLCState::Committed { .. } => write!(f, "Committed"),
260262
InboundHTLCState::LocalRemoved(_) => write!(f, "LocalRemoved"),
261263
}
262264
}
@@ -268,7 +270,7 @@ impl InboundHTLCState {
268270
InboundHTLCState::RemoteAnnounced(_) => !generated_by_local,
269271
InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => !generated_by_local,
270272
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => true,
271-
InboundHTLCState::Committed => true,
273+
InboundHTLCState::Committed { .. } => true,
272274
InboundHTLCState::LocalRemoved(_) => !generated_by_local,
273275
}
274276
}
@@ -296,7 +298,7 @@ impl InboundHTLCState {
296298
},
297299
InboundHTLCResolution::Resolved { .. } => false,
298300
},
299-
InboundHTLCState::Committed | InboundHTLCState::LocalRemoved(_) => false,
301+
InboundHTLCState::Committed { .. } | InboundHTLCState::LocalRemoved(_) => false,
300302
}
301303
}
302304
}
@@ -4102,7 +4104,7 @@ where
41024104

41034105
if self.pending_inbound_htlcs.iter()
41044106
.any(|htlc| match htlc.state {
4105-
InboundHTLCState::Committed => false,
4107+
InboundHTLCState::Committed { .. } => false,
41064108
// An HTLC removal from the local node is pending on the remote commitment.
41074109
InboundHTLCState::LocalRemoved(_) => true,
41084110
// An HTLC add from the remote node is pending on the local commitment.
@@ -4531,7 +4533,7 @@ where
45314533
(InboundHTLCState::RemoteAnnounced(..), _) => true,
45324534
(InboundHTLCState::AwaitingRemoteRevokeToAnnounce(..), _) => true,
45334535
(InboundHTLCState::AwaitingAnnouncedRemoteRevoke(..), _) => true,
4534-
(InboundHTLCState::Committed, _) => true,
4536+
(InboundHTLCState::Committed { .. }, _) => true,
45354537
(InboundHTLCState::LocalRemoved(..), true) => true,
45364538
(InboundHTLCState::LocalRemoved(..), false) => false,
45374539
})
@@ -7320,7 +7322,7 @@ where
73207322
payment_preimage_arg
73217323
);
73227324
match htlc.state {
7323-
InboundHTLCState::Committed => {},
7325+
InboundHTLCState::Committed { .. } => {},
73247326
InboundHTLCState::LocalRemoved(ref reason) => {
73257327
if let &InboundHTLCRemovalReason::Fulfill { .. } = reason {
73267328
} else {
@@ -7413,7 +7415,7 @@ where
74137415

74147416
{
74157417
let htlc = &mut self.context.pending_inbound_htlcs[pending_idx];
7416-
if let InboundHTLCState::Committed = htlc.state {
7418+
if let InboundHTLCState::Committed { .. } = htlc.state {
74177419
} else {
74187420
debug_assert!(
74197421
false,
@@ -7548,7 +7550,7 @@ where
75487550
for (idx, htlc) in self.context.pending_inbound_htlcs.iter().enumerate() {
75497551
if htlc.htlc_id == htlc_id_arg {
75507552
match htlc.state {
7551-
InboundHTLCState::Committed => {},
7553+
InboundHTLCState::Committed { .. } => {},
75527554
InboundHTLCState::LocalRemoved(_) => {
75537555
return Err(ChannelError::Ignore(format!("HTLC {} was already resolved", htlc.htlc_id)));
75547556
},
@@ -8716,7 +8718,7 @@ where
87168718
false
87178719
};
87188720
if swap {
8719-
let mut state = InboundHTLCState::Committed;
8721+
let mut state = InboundHTLCState::Committed { update_add_htlc_opt: None };
87208722
mem::swap(&mut state, &mut htlc.state);
87218723

87228724
if let InboundHTLCState::AwaitingRemoteRevokeToAnnounce(resolution) = state {
@@ -8755,14 +8757,19 @@ where
87558757
PendingHTLCStatus::Forward(forward_info) => {
87568758
log_trace!(logger, " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to Committed, attempting to forward", &htlc.payment_hash);
87578759
to_forward_infos.push((forward_info, htlc.htlc_id));
8758-
htlc.state = InboundHTLCState::Committed;
8760+
// TODO: this is currently unreachable, so is it okay? will we lose a forward?
8761+
htlc.state = InboundHTLCState::Committed {
8762+
update_add_htlc_opt: None,
8763+
};
87598764
},
87608765
}
87618766
},
87628767
InboundHTLCResolution::Pending { update_add_htlc } => {
87638768
log_trace!(logger, " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to Committed", &htlc.payment_hash);
8764-
pending_update_adds.push(update_add_htlc);
8765-
htlc.state = InboundHTLCState::Committed;
8769+
pending_update_adds.push(update_add_htlc.clone());
8770+
htlc.state = InboundHTLCState::Committed {
8771+
update_add_htlc_opt: Some(update_add_htlc),
8772+
};
87668773
},
87678774
}
87688775
}
@@ -9297,7 +9304,7 @@ where
92979304
// in response to it yet, so don't touch it.
92989305
true
92999306
},
9300-
InboundHTLCState::Committed => true,
9307+
InboundHTLCState::Committed { .. } => true,
93019308
InboundHTLCState::LocalRemoved(_) => {
93029309
// We (hopefully) sent a commitment_signed updating this HTLC (which we can
93039310
// re-transmit if needed) and they may have even sent a revoke_and_ack back
@@ -14518,6 +14525,7 @@ where
1451814525
}
1451914526
}
1452014527
let mut removed_htlc_attribution_data: Vec<&Option<AttributionData>> = Vec::new();
14528+
let mut inbound_committed_update_adds: Vec<Option<msgs::UpdateAddHTLC>> = Vec::new();
1452114529
(self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
1452214530
for htlc in self.context.pending_inbound_htlcs.iter() {
1452314531
if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -14537,8 +14545,9 @@ where
1453714545
2u8.write(writer)?;
1453814546
htlc_resolution.write(writer)?;
1453914547
},
14540-
&InboundHTLCState::Committed => {
14548+
&InboundHTLCState::Committed { ref update_add_htlc_opt } => {
1454114549
3u8.write(writer)?;
14550+
inbound_committed_update_adds.push(update_add_htlc_opt.clone());
1454214551
},
1454314552
&InboundHTLCState::LocalRemoved(ref removal_reason) => {
1454414553
4u8.write(writer)?;
@@ -14914,6 +14923,7 @@ where
1491414923
(69, holding_cell_held_htlc_flags, optional_vec), // Added in 0.2
1491514924
(71, holder_commitment_point_previous_revoked, option), // Added in 0.3
1491614925
(73, holder_commitment_point_last_revoked, option), // Added in 0.3
14926+
(75, inbound_committed_update_adds, optional_vec),
1491714927
});
1491814928

1491914929
Ok(())
@@ -14997,7 +15007,7 @@ where
1499715007
};
1499815008
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(resolution)
1499915009
},
15000-
3 => InboundHTLCState::Committed,
15010+
3 => InboundHTLCState::Committed { update_add_htlc_opt: None },
1500115011
4 => {
1500215012
let reason = match <u8 as Readable>::read(reader)? {
1500315013
0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
@@ -15301,6 +15311,7 @@ where
1530115311

1530215312
let mut pending_outbound_held_htlc_flags_opt: Option<Vec<Option<()>>> = None;
1530315313
let mut holding_cell_held_htlc_flags_opt: Option<Vec<Option<()>>> = None;
15314+
let mut inbound_committed_update_adds_opt: Option<Vec<Option<msgs::UpdateAddHTLC>>> = None;
1530415315

1530515316
read_tlv_fields!(reader, {
1530615317
(0, announcement_sigs, option),
@@ -15350,6 +15361,7 @@ where
1535015361
(69, holding_cell_held_htlc_flags_opt, optional_vec), // Added in 0.2
1535115362
(71, holder_commitment_point_previous_revoked_opt, option), // Added in 0.3
1535215363
(73, holder_commitment_point_last_revoked_opt, option), // Added in 0.3
15364+
(75, inbound_committed_update_adds_opt, optional_vec),
1535315365
});
1535415366

1535515367
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -15473,6 +15485,17 @@ where
1547315485
return Err(DecodeError::InvalidValue);
1547415486
}
1547515487
}
15488+
if let Some(update_adds) = inbound_committed_update_adds_opt {
15489+
let mut iter = update_adds.into_iter();
15490+
for htlc in pending_inbound_htlcs.iter_mut() {
15491+
if let InboundHTLCState::Committed { ref mut update_add_htlc_opt } = htlc.state {
15492+
*update_add_htlc_opt = iter.next().ok_or(DecodeError::InvalidValue)?;
15493+
}
15494+
}
15495+
if iter.next().is_some() {
15496+
return Err(DecodeError::InvalidValue);
15497+
}
15498+
}
1547615499

1547715500
if let Some(attribution_data_list) = removed_htlc_attribution_data {
1547815501
let mut removed_htlcs = pending_inbound_htlcs.iter_mut().filter_map(|status| {
@@ -16057,7 +16080,7 @@ mod tests {
1605716080
amount_msat: htlc_amount_msat,
1605816081
payment_hash: PaymentHash(Sha256::hash(&[42; 32]).to_byte_array()),
1605916082
cltv_expiry: 300000000,
16060-
state: InboundHTLCState::Committed,
16083+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1606116084
});
1606216085

1606316086
node_a_chan.context.pending_outbound_htlcs.push(OutboundHTLCOutput {
@@ -16903,7 +16926,7 @@ mod tests {
1690316926
amount_msat: 1000000,
1690416927
cltv_expiry: 500,
1690516928
payment_hash: PaymentHash::from(payment_preimage_0),
16906-
state: InboundHTLCState::Committed,
16929+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1690716930
});
1690816931

1690916932
let payment_preimage_1 =
@@ -16913,7 +16936,7 @@ mod tests {
1691316936
amount_msat: 2000000,
1691416937
cltv_expiry: 501,
1691516938
payment_hash: PaymentHash::from(payment_preimage_1),
16916-
state: InboundHTLCState::Committed,
16939+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1691716940
});
1691816941

1691916942
let payment_preimage_2 =
@@ -16953,7 +16976,7 @@ mod tests {
1695316976
amount_msat: 4000000,
1695416977
cltv_expiry: 504,
1695516978
payment_hash: PaymentHash::from(payment_preimage_4),
16956-
state: InboundHTLCState::Committed,
16979+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1695716980
});
1695816981

1695916982
// commitment tx with all five HTLCs untrimmed (minimum feerate)
@@ -17342,7 +17365,7 @@ mod tests {
1734217365
amount_msat: 2000000,
1734317366
cltv_expiry: 501,
1734417367
payment_hash: PaymentHash::from(payment_preimage_1),
17345-
state: InboundHTLCState::Committed,
17368+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1734617369
});
1734717370

1734817371
chan.context.pending_outbound_htlcs.clear();
@@ -17593,7 +17616,7 @@ mod tests {
1759317616
amount_msat: 5000000,
1759417617
cltv_expiry: 920150,
1759517618
payment_hash: PaymentHash::from(htlc_in_preimage),
17596-
state: InboundHTLCState::Committed,
17619+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1759717620
}));
1759817621

1759917622
chan.context.pending_outbound_htlcs.extend(
@@ -17722,7 +17745,7 @@ mod tests {
1772217745
amount_msat: 100000,
1772317746
cltv_expiry: 920125,
1772417747
payment_hash: htlc_0_in_hash,
17725-
state: InboundHTLCState::Committed,
17748+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1772617749
});
1772717750

1772817751
let htlc_1_in_preimage =
@@ -17740,7 +17763,7 @@ mod tests {
1774017763
amount_msat: 49900000,
1774117764
cltv_expiry: 920125,
1774217765
payment_hash: htlc_1_in_hash,
17743-
state: InboundHTLCState::Committed,
17766+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1774417767
});
1774517768

1774617769
chan.context.pending_outbound_htlcs.extend(
@@ -17792,7 +17815,7 @@ mod tests {
1779217815
amount_msat: 30000,
1779317816
payment_hash,
1779417817
cltv_expiry: 920125,
17795-
state: InboundHTLCState::Committed,
17818+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1779617819
},
1779717820
));
1779817821

@@ -17959,7 +17982,7 @@ mod tests {
1795917982
amount_msat,
1796017983
cltv_expiry,
1796117984
payment_hash,
17962-
state: InboundHTLCState::Committed,
17985+
state: InboundHTLCState::Committed { update_add_htlc_opt: None },
1796317986
}),
1796417987
);
1796517988

0 commit comments

Comments
 (0)