Skip to content

Commit 69ee486

Browse files
authored
Merge pull request #1004 from TheBlueMatt/2021-07-forward-event
Add a `PaymentForwarded` Event
2 parents 09e1670 + 50f47ec commit 69ee486

11 files changed

+249
-113
lines changed

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
# 0.0.100 - WIP
2+
3+
## Serialization Compatibility
4+
* HTLCs which were in the process of being claimed on-chain when a pre-0.0.100
5+
`ChannelMonitor` was serialized may generate `PaymentForwarded` events with
6+
spurious `fee_earned_msat` values. This only applies to payments which were
7+
unresolved at the time of the upgrade.
8+
* 0.0.100 clients with pending PaymentForwarded events at serialization-time
9+
will generate serialized `ChannelManager` objects which 0.0.99 and earlier
10+
clients cannot read. The likelihood of this can be reduced by ensuring you
11+
process all pending events immediately before serialization (as is done by
12+
the `lightning-background-processor` crate).
13+
14+
115
# 0.0.99 - 2021-07-09
216

317
## API Updates

fuzz/src/chanmon_consistency.rs

+1
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
805805
},
806806
events::Event::PaymentSent { .. } => {},
807807
events::Event::PaymentFailed { .. } => {},
808+
events::Event::PaymentForwarded { .. } if $node == 1 => {},
808809
events::Event::PendingHTLCsForwardable { .. } => {
809810
nodes[$node].process_pending_htlc_forwards();
810811
},

fuzz/src/full_stack.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,10 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
596596
//TODO: enhance by fetching random amounts from fuzz input?
597597
payments_received.push(payment_hash);
598598
},
599-
Event::PaymentSent {..} => {},
600-
Event::PaymentFailed {..} => {},
601599
Event::PendingHTLCsForwardable {..} => {
602600
should_forward = true;
603601
},
604-
Event::SpendableOutputs {..} => {},
602+
_ => {},
605603
}
606604
}
607605
}

lightning/src/chain/channelmonitor.rs

+44-34
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,12 @@ pub enum MonitorEvent {
199199
pub struct HTLCUpdate {
200200
pub(crate) payment_hash: PaymentHash,
201201
pub(crate) payment_preimage: Option<PaymentPreimage>,
202-
pub(crate) source: HTLCSource
202+
pub(crate) source: HTLCSource,
203+
pub(crate) onchain_value_satoshis: Option<u64>,
203204
}
204205
impl_writeable_tlv_based!(HTLCUpdate, {
205206
(0, payment_hash, required),
207+
(1, onchain_value_satoshis, option),
206208
(2, source, required),
207209
(4, payment_preimage, option),
208210
});
@@ -385,6 +387,7 @@ enum OnchainEvent {
385387
HTLCUpdate {
386388
source: HTLCSource,
387389
payment_hash: PaymentHash,
390+
onchain_value_satoshis: Option<u64>,
388391
},
389392
MaturingOutput {
390393
descriptor: SpendableOutputDescriptor,
@@ -400,6 +403,7 @@ impl_writeable_tlv_based!(OnchainEventEntry, {
400403
impl_writeable_tlv_based_enum!(OnchainEvent,
401404
(0, HTLCUpdate) => {
402405
(0, source, required),
406+
(1, onchain_value_satoshis, option),
403407
(2, payment_hash, required),
404408
},
405409
(1, MaturingOutput) => {
@@ -1574,6 +1578,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
15741578
event: OnchainEvent::HTLCUpdate {
15751579
source: (**source).clone(),
15761580
payment_hash: htlc.payment_hash.clone(),
1581+
onchain_value_satoshis: Some(htlc.amount_msat / 1000),
15771582
},
15781583
};
15791584
log_info!(logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of revoked counterparty commitment transaction, waiting for confirmation (at height {})", log_bytes!(htlc.payment_hash.0), $commitment_tx, entry.confirmation_threshold());
@@ -1641,6 +1646,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
16411646
event: OnchainEvent::HTLCUpdate {
16421647
source: (**source).clone(),
16431648
payment_hash: htlc.payment_hash.clone(),
1649+
onchain_value_satoshis: Some(htlc.amount_msat / 1000),
16441650
},
16451651
});
16461652
}
@@ -1779,27 +1785,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
17791785
let mut claim_requests = Vec::new();
17801786
let mut watch_outputs = Vec::new();
17811787

1782-
macro_rules! wait_threshold_conf {
1783-
($source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1784-
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
1785-
if entry.height != height { return true; }
1786-
match entry.event {
1787-
OnchainEvent::HTLCUpdate { source: ref update_source, .. } => {
1788-
*update_source != $source
1789-
},
1790-
_ => true,
1791-
}
1792-
});
1793-
let entry = OnchainEventEntry {
1794-
txid: commitment_txid,
1795-
height,
1796-
event: OnchainEvent::HTLCUpdate { source: $source, payment_hash: $payment_hash },
1797-
};
1798-
log_trace!(logger, "Failing HTLC with payment_hash {} from {} holder commitment tx due to broadcast of transaction, waiting confirmation (at height{})", log_bytes!($payment_hash.0), $commitment_tx, entry.confirmation_threshold());
1799-
self.onchain_events_awaiting_threshold_conf.push(entry);
1800-
}
1801-
}
1802-
18031788
macro_rules! append_onchain_update {
18041789
($updates: expr, $to_watch: expr) => {
18051790
claim_requests = $updates.0;
@@ -1828,21 +1813,40 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
18281813
}
18291814

18301815
macro_rules! fail_dust_htlcs_after_threshold_conf {
1831-
($holder_tx: expr) => {
1816+
($holder_tx: expr, $commitment_tx: expr) => {
18321817
for &(ref htlc, _, ref source) in &$holder_tx.htlc_outputs {
18331818
if htlc.transaction_output_index.is_none() {
18341819
if let &Some(ref source) = source {
1835-
wait_threshold_conf!(source.clone(), "lastest", htlc.payment_hash.clone());
1820+
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
1821+
if entry.height != height { return true; }
1822+
match entry.event {
1823+
OnchainEvent::HTLCUpdate { source: ref update_source, .. } => {
1824+
update_source != source
1825+
},
1826+
_ => true,
1827+
}
1828+
});
1829+
let entry = OnchainEventEntry {
1830+
txid: commitment_txid,
1831+
height,
1832+
event: OnchainEvent::HTLCUpdate {
1833+
source: source.clone(), payment_hash: htlc.payment_hash,
1834+
onchain_value_satoshis: Some(htlc.amount_msat / 1000)
1835+
},
1836+
};
1837+
log_trace!(logger, "Failing HTLC with payment_hash {} from {} holder commitment tx due to broadcast of transaction, waiting confirmation (at height{})",
1838+
log_bytes!(htlc.payment_hash.0), $commitment_tx, entry.confirmation_threshold());
1839+
self.onchain_events_awaiting_threshold_conf.push(entry);
18361840
}
18371841
}
18381842
}
18391843
}
18401844
}
18411845

18421846
if is_holder_tx {
1843-
fail_dust_htlcs_after_threshold_conf!(self.current_holder_commitment_tx);
1847+
fail_dust_htlcs_after_threshold_conf!(self.current_holder_commitment_tx, "latest");
18441848
if let &Some(ref holder_tx) = &self.prev_holder_signed_commitment_tx {
1845-
fail_dust_htlcs_after_threshold_conf!(holder_tx);
1849+
fail_dust_htlcs_after_threshold_conf!(holder_tx, "previous");
18461850
}
18471851
}
18481852

@@ -2090,7 +2094,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
20902094
// Produce actionable events from on-chain events having reached their threshold.
20912095
for entry in onchain_events_reaching_threshold_conf.drain(..) {
20922096
match entry.event {
2093-
OnchainEvent::HTLCUpdate { ref source, payment_hash } => {
2097+
OnchainEvent::HTLCUpdate { ref source, payment_hash, onchain_value_satoshis } => {
20942098
// Check for duplicate HTLC resolutions.
20952099
#[cfg(debug_assertions)]
20962100
{
@@ -2109,9 +2113,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21092113

21102114
log_debug!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!(payment_hash.0));
21112115
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
2112-
payment_hash: payment_hash,
2116+
payment_hash,
21132117
payment_preimage: None,
21142118
source: source.clone(),
2119+
onchain_value_satoshis,
21152120
}));
21162121
},
21172122
OnchainEvent::MaturingOutput { descriptor } => {
@@ -2328,7 +2333,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23282333
if pending_htlc.payment_hash == $htlc_output.payment_hash && pending_htlc.amount_msat == $htlc_output.amount_msat {
23292334
if let &Some(ref source) = pending_source {
23302335
log_claim!("revoked counterparty commitment tx", false, pending_htlc, true);
2331-
payment_data = Some(((**source).clone(), $htlc_output.payment_hash));
2336+
payment_data = Some(((**source).clone(), $htlc_output.payment_hash, $htlc_output.amount_msat));
23322337
break;
23332338
}
23342339
}
@@ -2348,7 +2353,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23482353
// transaction. This implies we either learned a preimage, the HTLC
23492354
// has timed out, or we screwed up. In any case, we should now
23502355
// resolve the source HTLC with the original sender.
2351-
payment_data = Some(((*source).clone(), htlc_output.payment_hash));
2356+
payment_data = Some(((*source).clone(), htlc_output.payment_hash, htlc_output.amount_msat));
23522357
} else if !$holder_tx {
23532358
check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid, htlc_output);
23542359
if payment_data.is_none() {
@@ -2381,7 +2386,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23812386

23822387
// Check that scan_commitment, above, decided there is some source worth relaying an
23832388
// HTLC resolution backwards to and figure out whether we learned a preimage from it.
2384-
if let Some((source, payment_hash)) = payment_data {
2389+
if let Some((source, payment_hash, amount_msat)) = payment_data {
23852390
let mut payment_preimage = PaymentPreimage([0; 32]);
23862391
if accepted_preimage_claim {
23872392
if !self.pending_monitor_events.iter().any(
@@ -2390,7 +2395,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23902395
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
23912396
source,
23922397
payment_preimage: Some(payment_preimage),
2393-
payment_hash
2398+
payment_hash,
2399+
onchain_value_satoshis: Some(amount_msat / 1000),
23942400
}));
23952401
}
23962402
} else if offered_preimage_claim {
@@ -2402,7 +2408,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
24022408
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
24032409
source,
24042410
payment_preimage: Some(payment_preimage),
2405-
payment_hash
2411+
payment_hash,
2412+
onchain_value_satoshis: Some(amount_msat / 1000),
24062413
}));
24072414
}
24082415
} else {
@@ -2418,7 +2425,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
24182425
let entry = OnchainEventEntry {
24192426
txid: tx.txid(),
24202427
height,
2421-
event: OnchainEvent::HTLCUpdate { source: source, payment_hash: payment_hash },
2428+
event: OnchainEvent::HTLCUpdate {
2429+
source, payment_hash,
2430+
onchain_value_satoshis: Some(amount_msat / 1000),
2431+
},
24222432
};
24232433
log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height {})", log_bytes!(payment_hash.0), entry.confirmation_threshold());
24242434
self.onchain_events_awaiting_threshold_conf.push(entry);

lightning/src/ln/chanmon_update_fail_tests.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,7 @@ fn test_monitor_update_fail_reestablish() {
11601160
assert!(updates.update_fee.is_none());
11611161
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
11621162
nodes[1].node.handle_update_fulfill_htlc(&nodes[2].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
1163+
expect_payment_forwarded!(nodes[1], Some(1000), false);
11631164
check_added_monitors!(nodes[1], 1);
11641165
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
11651166
commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false);
@@ -2318,6 +2319,7 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f
23182319
assert_eq!(fulfill_msg, cs_updates.update_fulfill_htlcs[0]);
23192320
}
23202321
nodes[1].node.handle_update_fulfill_htlc(&nodes[2].node.get_our_node_id(), &fulfill_msg);
2322+
expect_payment_forwarded!(nodes[1], Some(1000), false);
23212323
check_added_monitors!(nodes[1], 1);
23222324

23232325
let mut bs_updates = None;

lightning/src/ln/channel.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ pub struct CounterpartyForwardingInfo {
307307
enum UpdateFulfillFetch {
308308
NewClaim {
309309
monitor_update: ChannelMonitorUpdate,
310+
htlc_value_msat: u64,
310311
msg: Option<msgs::UpdateFulfillHTLC>,
311312
},
312313
DuplicateClaim {},
@@ -320,6 +321,8 @@ pub enum UpdateFulfillCommitFetch {
320321
NewClaim {
321322
/// The ChannelMonitorUpdate which places the new payment preimage in the channel monitor
322323
monitor_update: ChannelMonitorUpdate,
324+
/// The value of the HTLC which was claimed, in msat.
325+
htlc_value_msat: u64,
323326
/// The update_fulfill message and commitment_signed message (if the claim was not placed
324327
/// in the holding cell).
325328
msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>,
@@ -337,6 +340,9 @@ pub enum UpdateFulfillCommitFetch {
337340
// Holder designates channel data owned for the benefice of the user client.
338341
// Counterparty designates channel data owned by the another channel participant entity.
339342
pub(super) struct Channel<Signer: Sign> {
343+
#[cfg(any(test, feature = "_test_utils"))]
344+
pub(crate) config: ChannelConfig,
345+
#[cfg(not(any(test, feature = "_test_utils")))]
340346
config: ChannelConfig,
341347

342348
user_id: u64,
@@ -1276,6 +1282,7 @@ impl<Signer: Sign> Channel<Signer> {
12761282
// these, but for now we just have to treat them as normal.
12771283

12781284
let mut pending_idx = core::usize::MAX;
1285+
let mut htlc_value_msat = 0;
12791286
for (idx, htlc) in self.pending_inbound_htlcs.iter().enumerate() {
12801287
if htlc.htlc_id == htlc_id_arg {
12811288
assert_eq!(htlc.payment_hash, payment_hash_calc);
@@ -1295,6 +1302,7 @@ impl<Signer: Sign> Channel<Signer> {
12951302
}
12961303
}
12971304
pending_idx = idx;
1305+
htlc_value_msat = htlc.amount_msat;
12981306
break;
12991307
}
13001308
}
@@ -1336,7 +1344,7 @@ impl<Signer: Sign> Channel<Signer> {
13361344
// TODO: We may actually be able to switch to a fulfill here, though its
13371345
// rare enough it may not be worth the complexity burden.
13381346
debug_assert!(false, "Tried to fulfill an HTLC that was already failed");
1339-
return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
1347+
return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
13401348
}
13411349
},
13421350
_ => {}
@@ -1348,7 +1356,7 @@ impl<Signer: Sign> Channel<Signer> {
13481356
});
13491357
#[cfg(any(test, feature = "fuzztarget"))]
13501358
self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
1351-
return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
1359+
return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
13521360
}
13531361
#[cfg(any(test, feature = "fuzztarget"))]
13541362
self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
@@ -1358,14 +1366,15 @@ impl<Signer: Sign> Channel<Signer> {
13581366
if let InboundHTLCState::Committed = htlc.state {
13591367
} else {
13601368
debug_assert!(false, "Have an inbound HTLC we tried to claim before it was fully committed to");
1361-
return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
1369+
return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
13621370
}
13631371
log_trace!(logger, "Upgrading HTLC {} to LocalRemoved with a Fulfill in channel {}!", log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id));
13641372
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(payment_preimage_arg.clone()));
13651373
}
13661374

13671375
UpdateFulfillFetch::NewClaim {
13681376
monitor_update,
1377+
htlc_value_msat,
13691378
msg: Some(msgs::UpdateFulfillHTLC {
13701379
channel_id: self.channel_id(),
13711380
htlc_id: htlc_id_arg,
@@ -1376,7 +1385,7 @@ impl<Signer: Sign> Channel<Signer> {
13761385

13771386
pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> Result<UpdateFulfillCommitFetch, (ChannelError, ChannelMonitorUpdate)> where L::Target: Logger {
13781387
match self.get_update_fulfill_htlc(htlc_id, payment_preimage, logger) {
1379-
UpdateFulfillFetch::NewClaim { mut monitor_update, msg: Some(update_fulfill_htlc) } => {
1388+
UpdateFulfillFetch::NewClaim { mut monitor_update, htlc_value_msat, msg: Some(update_fulfill_htlc) } => {
13801389
let (commitment, mut additional_update) = match self.send_commitment_no_status_check(logger) {
13811390
Err(e) => return Err((e, monitor_update)),
13821391
Ok(res) => res
@@ -1385,9 +1394,10 @@ impl<Signer: Sign> Channel<Signer> {
13851394
// strictly increasing by one, so decrement it here.
13861395
self.latest_monitor_update_id = monitor_update.update_id;
13871396
monitor_update.updates.append(&mut additional_update.updates);
1388-
Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, msgs: Some((update_fulfill_htlc, commitment)) })
1397+
Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, htlc_value_msat, msgs: Some((update_fulfill_htlc, commitment)) })
13891398
},
1390-
UpdateFulfillFetch::NewClaim { monitor_update, msg: None } => Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, msgs: None }),
1399+
UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None } =>
1400+
Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, htlc_value_msat, msgs: None }),
13911401
UpdateFulfillFetch::DuplicateClaim {} => Ok(UpdateFulfillCommitFetch::DuplicateClaim {}),
13921402
}
13931403
}
@@ -2164,7 +2174,7 @@ impl<Signer: Sign> Channel<Signer> {
21642174

21652175
/// Marks an outbound HTLC which we have received update_fail/fulfill/malformed
21662176
#[inline]
2167-
fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<PaymentHash>, fail_reason: Option<HTLCFailReason>) -> Result<&HTLCSource, ChannelError> {
2177+
fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<PaymentHash>, fail_reason: Option<HTLCFailReason>) -> Result<&OutboundHTLCOutput, ChannelError> {
21682178
for htlc in self.pending_outbound_htlcs.iter_mut() {
21692179
if htlc.htlc_id == htlc_id {
21702180
match check_preimage {
@@ -2183,13 +2193,13 @@ impl<Signer: Sign> Channel<Signer> {
21832193
OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) | OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) | OutboundHTLCState::RemoteRemoved(_) =>
21842194
return Err(ChannelError::Close(format!("Remote tried to fulfill/fail HTLC ({}) that they'd already fulfilled/failed", htlc_id))),
21852195
}
2186-
return Ok(&htlc.source);
2196+
return Ok(htlc);
21872197
}
21882198
}
21892199
Err(ChannelError::Close("Remote tried to fulfill/fail an HTLC we couldn't find".to_owned()))
21902200
}
21912201

2192-
pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<HTLCSource, ChannelError> {
2202+
pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<(HTLCSource, u64), ChannelError> {
21932203
if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
21942204
return Err(ChannelError::Close("Got fulfill HTLC message when channel was not in an operational state".to_owned()));
21952205
}
@@ -2198,7 +2208,7 @@ impl<Signer: Sign> Channel<Signer> {
21982208
}
21992209

22002210
let payment_hash = PaymentHash(Sha256::hash(&msg.payment_preimage.0[..]).into_inner());
2201-
self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None).map(|source| source.clone())
2211+
self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None).map(|htlc| (htlc.source.clone(), htlc.amount_msat))
22022212
}
22032213

22042214
pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> {
@@ -2497,7 +2507,7 @@ impl<Signer: Sign> Channel<Signer> {
24972507
// in it hitting the holding cell again and we cannot change the state of a
24982508
// holding cell HTLC from fulfill to anything else.
24992509
let (update_fulfill_msg_option, mut additional_monitor_update) =
2500-
if let UpdateFulfillFetch::NewClaim { msg, monitor_update } = self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
2510+
if let UpdateFulfillFetch::NewClaim { msg, monitor_update, .. } = self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
25012511
(msg, monitor_update)
25022512
} else { unreachable!() };
25032513
update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap());

0 commit comments

Comments
 (0)