Skip to content

Commit 7aa9a94

Browse files
Add would_broadcast_at_height functionality to Channel
In service to the larger refactor of removing the Channel's reference to its ChannelMonitor.
1 parent 7dca3a9 commit 7aa9a94

File tree

3 files changed

+164
-64
lines changed

3 files changed

+164
-64
lines changed

lightning/src/ln/channel.rs

Lines changed: 137 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use ln::chan_utils;
3333
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
3434
use chain::transaction::OutPoint;
3535
use chain::keysinterface::{ChannelKeys, KeysInterface};
36-
use util::transaction_utils;
36+
use util::{byte_utils, transaction_utils};
3737
use util::ser::{Readable, Writeable, Writer};
3838
use util::logger::Logger;
3939
use util::errors::APIError;
@@ -43,6 +43,7 @@ use std;
4343
use std::default::Default;
4444
use std::{cmp,mem,fmt};
4545
use std::ops::Deref;
46+
use std::collections::HashMap;
4647
use bitcoin::hashes::hex::ToHex;
4748

4849
#[cfg(test)]
@@ -109,11 +110,8 @@ enum InboundHTLCState {
109110
/// Note that we have to keep an eye on the HTLC until we've received a broadcastable
110111
/// commitment transaction without it as otherwise we'll have to force-close the channel to
111112
/// claim it before the timeout (obviously doesn't apply to revoked HTLCs that we can't claim
112-
/// anyway). That said, ChannelMonitor does this for us (see
113-
/// ChannelMonitor::would_broadcast_at_height) so we actually remove the HTLC from our own
114-
/// local state before then, once we're sure that the next commitment_signed and
115-
/// ChannelMonitor::provide_latest_local_commitment_tx_info will not include this HTLC.
116-
LocalRemoved(InboundHTLCRemovalReason),
113+
/// anyway).
114+
LocalRemoved(bool, InboundHTLCRemovalReason),
117115
}
118116

119117
struct InboundHTLCOutput {
@@ -293,6 +291,7 @@ pub(super) struct Channel<ChanSigner: ChannelKeys> {
293291
pending_inbound_htlcs: Vec<InboundHTLCOutput>,
294292
pending_outbound_htlcs: Vec<OutboundHTLCOutput>,
295293
holding_cell_htlc_updates: Vec<HTLCUpdateAwaitingACK>,
294+
payment_preimages: HashMap<PaymentHash, PaymentPreimage>,
296295

297296
/// When resending CS/RAA messages on channel monitor restoration or on reconnect, we always
298297
/// need to ensure we resend them in the order we originally generated them. Note that because
@@ -510,6 +509,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
510509
pending_inbound_htlcs: Vec::new(),
511510
pending_outbound_htlcs: Vec::new(),
512511
holding_cell_htlc_updates: Vec::new(),
512+
payment_preimages: HashMap::new(),
513513
pending_update_fee: None,
514514
holding_cell_update_fee: None,
515515
next_local_htlc_id: 0,
@@ -738,6 +738,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
738738
pending_inbound_htlcs: Vec::new(),
739739
pending_outbound_htlcs: Vec::new(),
740740
holding_cell_htlc_updates: Vec::new(),
741+
payment_preimages: HashMap::new(),
741742
pending_update_fee: None,
742743
holding_cell_update_fee: None,
743744
next_local_htlc_id: 0,
@@ -795,6 +796,71 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
795796
Ok(chan)
796797
}
797798

799+
pub(super) fn monitor_would_broadcast_at_height<L: Deref>(&self, height: u32, logger: &L) -> bool where L::Target: Logger {
800+
macro_rules! add_htlc_output {
801+
($htlc: expr, $offered: expr, $list: expr) => {
802+
$list.push(HTLCOutputInCommitment{
803+
offered: $offered,
804+
amount_msat: $htlc.amount_msat,
805+
cltv_expiry: $htlc.cltv_expiry,
806+
payment_hash: $htlc.payment_hash,
807+
transaction_output_index: None
808+
});
809+
}
810+
}
811+
812+
let cap = self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len();
813+
let mut remote_outputs = Vec::with_capacity(cap);
814+
let mut local_outputs = Vec::with_capacity(cap);
815+
let awaiting_raa = (self.channel_state & ChannelState::AwaitingRemoteRevoke as u32) != 0;
816+
for ref htlc in self.pending_inbound_htlcs.iter() {
817+
match htlc.state {
818+
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => {
819+
add_htlc_output!(htlc, false, local_outputs);
820+
add_htlc_output!(htlc, true, remote_outputs);
821+
},
822+
InboundHTLCState::Committed => {
823+
add_htlc_output!(htlc, false, local_outputs);
824+
add_htlc_output!(htlc, true, remote_outputs);
825+
},
826+
InboundHTLCState::LocalRemoved(revoked, _) => {
827+
add_htlc_output!(htlc, false, local_outputs);
828+
if awaiting_raa && !revoked {
829+
add_htlc_output!(htlc, true, remote_outputs)
830+
}
831+
},
832+
_ => {},
833+
}
834+
}
835+
for ref htlc in self.pending_outbound_htlcs.iter() {
836+
match htlc.state {
837+
OutboundHTLCState::LocalAnnounced(_) => {
838+
add_htlc_output!(htlc, true, local_outputs);
839+
add_htlc_output!(htlc, false, remote_outputs);
840+
},
841+
OutboundHTLCState::Committed => {
842+
add_htlc_output!(htlc, true, local_outputs);
843+
add_htlc_output!(htlc, false, remote_outputs);
844+
},
845+
OutboundHTLCState::RemoteRemoved(_) => {
846+
add_htlc_output!(htlc, true, local_outputs);
847+
add_htlc_output!(htlc, false, remote_outputs)
848+
},
849+
OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => {
850+
add_htlc_output!(htlc, true, local_outputs);
851+
add_htlc_output!(htlc, false, remote_outputs);
852+
},
853+
OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => {
854+
if awaiting_raa {
855+
add_htlc_output!(htlc, false, remote_outputs)
856+
}
857+
},
858+
}
859+
}
860+
861+
ChannelMonitor::<ChanSigner>::would_broadcast_at_height_given_htlcs(local_outputs.iter(), remote_outputs.iter(), height, &self.payment_preimages, logger)
862+
}
863+
798864
// Utilities to build transactions:
799865

800866
fn get_commitment_transaction_number_obscure_factor(&self) -> u64 {
@@ -908,7 +974,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
908974
InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => (!generated_by_local, "AwaitingRemoteRevokeToAnnounce"),
909975
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => (true, "AwaitingAnnouncedRemoteRevoke"),
910976
InboundHTLCState::Committed => (true, "Committed"),
911-
InboundHTLCState::LocalRemoved(_) => (!generated_by_local, "LocalRemoved"),
977+
InboundHTLCState::LocalRemoved(revoked, _) => (!generated_by_local && !revoked, "LocalRemoved"),
912978
};
913979

914980
if include {
@@ -917,7 +983,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
917983
} else {
918984
log_trace!(logger, " ...not including inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, log_bytes!(htlc.payment_hash.0), htlc.amount_msat, state_name);
919985
match &htlc.state {
920-
&InboundHTLCState::LocalRemoved(ref reason) => {
986+
&InboundHTLCState::LocalRemoved(false, ref reason) => {
921987
if generated_by_local {
922988
if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
923989
value_to_self_msat_offset += htlc.amount_msat as i64;
@@ -1190,7 +1256,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
11901256
assert_eq!(htlc.payment_hash, payment_hash_calc);
11911257
match htlc.state {
11921258
InboundHTLCState::Committed => {},
1193-
InboundHTLCState::LocalRemoved(ref reason) => {
1259+
InboundHTLCState::LocalRemoved(_, ref reason) => {
11941260
if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
11951261
} else {
11961262
log_warn!(logger, "Have preimage and want to fulfill HTLC with payment hash {} we already failed against channel {}", log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id()));
@@ -1216,6 +1282,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
12161282
// We have to put the payment_preimage in the channel_monitor right away here to ensure we
12171283
// can claim it even if the channel hits the chain before we see their next commitment.
12181284
self.latest_monitor_update_id += 1;
1285+
self.payment_preimages.insert(payment_hash_calc, payment_preimage_arg.clone());
12191286
let monitor_update = ChannelMonitorUpdate {
12201287
update_id: self.latest_monitor_update_id,
12211288
updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
@@ -1262,7 +1329,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
12621329
return Ok((None, Some(monitor_update)));
12631330
}
12641331
log_trace!(logger, "Upgrading HTLC {} to LocalRemoved with a Fulfill!", log_bytes!(htlc.payment_hash.0));
1265-
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(payment_preimage_arg.clone()));
1332+
htlc.state = InboundHTLCState::LocalRemoved(false, InboundHTLCRemovalReason::Fulfill(payment_preimage_arg.clone()));
12661333
}
12671334

12681335
Ok((Some(msgs::UpdateFulfillHTLC {
@@ -1312,7 +1379,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
13121379
if htlc.htlc_id == htlc_id_arg {
13131380
match htlc.state {
13141381
InboundHTLCState::Committed => {},
1315-
InboundHTLCState::LocalRemoved(_) => {
1382+
InboundHTLCState::LocalRemoved(_, _) => {
13161383
debug_assert!(false, "Tried to fail an HTLC that was already fail/fulfilled");
13171384
return Ok(None);
13181385
},
@@ -1356,7 +1423,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
13561423

13571424
{
13581425
let htlc = &mut self.pending_inbound_htlcs[pending_idx];
1359-
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(err_packet.clone()));
1426+
htlc.state = InboundHTLCState::LocalRemoved(false, InboundHTLCRemovalReason::FailRelay(err_packet.clone()));
13601427
}
13611428

13621429
Ok(Some(msgs::UpdateFailHTLC {
@@ -2011,6 +2078,17 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
20112078
return Err((None, ChannelError::Close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), local_commitment_tx.1))));
20122079
}
20132080

2081+
// A LocalRemoved HTLC need to be monitored for expiration until we receive a
2082+
// broadcastable commitment tx without said HTLC. Now that we've confirmed that
2083+
// this commitment signed message provides said commitment tx, we can drop the
2084+
// LocalRemoved HTLCs we were previously watching for.
2085+
self.pending_inbound_htlcs.retain(|htlc| {
2086+
log_trace!(logger, "Removing inbound LocalRemoved {}", log_bytes!(htlc.payment_hash.0));
2087+
if let &InboundHTLCState::LocalRemoved(true, _) = &htlc.state {
2088+
false
2089+
} else { true }
2090+
});
2091+
20142092
// TODO: Merge these two, sadly they are currently both required to be passed separately to
20152093
// ChannelMonitor:
20162094
let mut htlcs_without_source = Vec::with_capacity(local_commitment_tx.2.len());
@@ -2303,30 +2381,16 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
23032381
// Take references explicitly so that we can hold multiple references to self.
23042382
let pending_inbound_htlcs: &mut Vec<_> = &mut self.pending_inbound_htlcs;
23052383
let pending_outbound_htlcs: &mut Vec<_> = &mut self.pending_outbound_htlcs;
2306-
2307-
// We really shouldnt have two passes here, but retain gives a non-mutable ref (Rust bug)
2308-
pending_inbound_htlcs.retain(|htlc| {
2309-
if let &InboundHTLCState::LocalRemoved(ref reason) = &htlc.state {
2310-
log_trace!(logger, " ...removing inbound LocalRemoved {}", log_bytes!(htlc.payment_hash.0));
2384+
for htlc in pending_inbound_htlcs.iter_mut() {
2385+
if let &mut InboundHTLCState::LocalRemoved(ref mut revoked, ref reason) = &mut htlc.state {
23112386
if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
2312-
value_to_self_msat_diff += htlc.amount_msat as i64;
2313-
}
2314-
false
2315-
} else { true }
2316-
});
2317-
pending_outbound_htlcs.retain(|htlc| {
2318-
if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref fail_reason) = &htlc.state {
2319-
log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", log_bytes!(htlc.payment_hash.0));
2320-
if let Some(reason) = fail_reason.clone() { // We really want take() here, but, again, non-mut ref :(
2321-
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
2322-
} else {
2323-
// They fulfilled, so we sent them money
2324-
value_to_self_msat_diff -= htlc.amount_msat as i64;
2387+
if !*revoked {
2388+
value_to_self_msat_diff += htlc.amount_msat as i64;
2389+
}
23252390
}
2326-
false
2327-
} else { true }
2328-
});
2329-
for htlc in pending_inbound_htlcs.iter_mut() {
2391+
*revoked = true;
2392+
continue
2393+
}
23302394
let swap = if let &InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) = &htlc.state {
23312395
log_trace!(logger, " ...promoting inbound AwaitingRemoteRevokeToAnnounce {} to Committed", log_bytes!(htlc.payment_hash.0));
23322396
true
@@ -2347,11 +2411,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
23472411
require_commitment = true;
23482412
match fail_msg {
23492413
HTLCFailureMsg::Relay(msg) => {
2350-
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(msg.reason.clone()));
2414+
htlc.state = InboundHTLCState::LocalRemoved(false, InboundHTLCRemovalReason::FailRelay(msg.reason.clone()));
23512415
update_fail_htlcs.push(msg)
23522416
},
23532417
HTLCFailureMsg::Malformed(msg) => {
2354-
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailMalformed((msg.sha256_of_onion, msg.failure_code)));
2418+
htlc.state = InboundHTLCState::LocalRemoved(false, InboundHTLCRemovalReason::FailMalformed((msg.sha256_of_onion, msg.failure_code)));
23552419
update_fail_malformed_htlcs.push(msg)
23562420
},
23572421
}
@@ -2364,6 +2428,19 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
23642428
}
23652429
}
23662430
}
2431+
// We really shouldnt have two passes here, but retain gives a non-mutable ref (Rust bug)
2432+
pending_outbound_htlcs.retain(|htlc| {
2433+
if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref fail_reason) = &htlc.state {
2434+
log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", log_bytes!(htlc.payment_hash.0));
2435+
if let Some(reason) = fail_reason.clone() { // We really want take() here, but, again, non-mut ref :(
2436+
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
2437+
} else {
2438+
// They fulfilled, so we sent them money
2439+
value_to_self_msat_diff -= htlc.amount_msat as i64;
2440+
}
2441+
false
2442+
} else { true }
2443+
});
23672444
for htlc in pending_outbound_htlcs.iter_mut() {
23682445
if let OutboundHTLCState::LocalAnnounced(_) = htlc.state {
23692446
log_trace!(logger, " ...promoting outbound LocalAnnounced {} to Committed", log_bytes!(htlc.payment_hash.0));
@@ -2533,7 +2610,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
25332610
true
25342611
},
25352612
InboundHTLCState::Committed => true,
2536-
InboundHTLCState::LocalRemoved(_) => {
2613+
InboundHTLCState::LocalRemoved(_, _) => {
25372614
// We (hopefully) sent a commitment_signed updating this HTLC (which we can
25382615
// re-transmit if needed) and they may have even sent a revoke_and_ack back
25392616
// (that we missed). Keep this around for now and if they tell us they missed
@@ -2688,7 +2765,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
26882765
}
26892766

26902767
for htlc in self.pending_inbound_htlcs.iter() {
2691-
if let &InboundHTLCState::LocalRemoved(ref reason) = &htlc.state {
2768+
if let &InboundHTLCState::LocalRemoved(false, ref reason) = &htlc.state {
26922769
match reason {
26932770
&InboundHTLCRemovalReason::FailRelay(ref err_packet) => {
26942771
update_fail_htlcs.push(msgs::UpdateFailHTLC {
@@ -3115,14 +3192,6 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
31153192
self.user_id
31163193
}
31173194

3118-
/// May only be called after funding has been initiated (ie is_funding_initiated() is true)
3119-
pub fn channel_monitor(&mut self) -> &mut ChannelMonitor<ChanSigner> {
3120-
if self.channel_state < ChannelState::FundingSent as u32 {
3121-
panic!("Can't get a channel monitor until funding has been created");
3122-
}
3123-
self.channel_monitor.as_mut().unwrap()
3124-
}
3125-
31263195
/// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
31273196
/// is_usable() returns true).
31283197
/// Allowed in any state (including after shutdown)
@@ -3819,7 +3888,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
38193888
if have_updates { break; }
38203889
}
38213890
for htlc in self.pending_inbound_htlcs.iter() {
3822-
if let InboundHTLCState::LocalRemoved(_) = htlc.state {
3891+
if let InboundHTLCState::LocalRemoved(false, _) = htlc.state {
38233892
have_updates = true;
38243893
}
38253894
if have_updates { break; }
@@ -4114,8 +4183,9 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
41144183
&InboundHTLCState::Committed => {
41154184
3u8.write(writer)?;
41164185
},
4117-
&InboundHTLCState::LocalRemoved(ref removal_reason) => {
4186+
&InboundHTLCState::LocalRemoved(ref revoked, ref removal_reason) => {
41184187
4u8.write(writer)?;
4188+
revoked.write(writer)?;
41194189
removal_reason.write(writer)?;
41204190
},
41214191
}
@@ -4151,6 +4221,11 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
41514221
}
41524222
}
41534223

4224+
writer.write_all(&byte_utils::be64_to_array(self.payment_preimages.len() as u64))?;
4225+
for payment_preimage in self.payment_preimages.values() {
4226+
writer.write_all(&payment_preimage.0[..])?;
4227+
}
4228+
41544229
(self.holding_cell_htlc_updates.len() as u64).write(writer)?;
41554230
for update in self.holding_cell_htlc_updates.iter() {
41564231
match update {
@@ -4248,6 +4323,8 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
42484323
}
42494324
}
42504325

4326+
const MAX_ALLOC_SIZE: usize = 64*1024;
4327+
42514328
impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
42524329
fn read<R : ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
42534330
let _ver: u8 = Readable::read(reader)?;
@@ -4286,7 +4363,7 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
42864363
1 => InboundHTLCState::AwaitingRemoteRevokeToAnnounce(Readable::read(reader)?),
42874364
2 => InboundHTLCState::AwaitingAnnouncedRemoteRevoke(Readable::read(reader)?),
42884365
3 => InboundHTLCState::Committed,
4289-
4 => InboundHTLCState::LocalRemoved(Readable::read(reader)?),
4366+
4 => InboundHTLCState::LocalRemoved(Readable::read(reader)?, Readable::read(reader)?),
42904367
_ => return Err(DecodeError::InvalidValue),
42914368
},
42924369
});
@@ -4312,6 +4389,16 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
43124389
});
43134390
}
43144391

4392+
let payment_preimages_len: u64 = Readable::read(reader)?;
4393+
let mut payment_preimages = HashMap::with_capacity(cmp::min(payment_preimages_len as usize, MAX_ALLOC_SIZE / 32));
4394+
for _ in 0..payment_preimages_len {
4395+
let preimage: PaymentPreimage = Readable::read(reader)?;
4396+
let hash = PaymentHash(Sha256::hash(&preimage.0[..]).into_inner());
4397+
if let Some(_) = payment_preimages.insert(hash, preimage) {
4398+
return Err(DecodeError::InvalidValue);
4399+
}
4400+
}
4401+
43154402
let holding_cell_htlc_update_count: u64 = Readable::read(reader)?;
43164403
let mut holding_cell_htlc_updates = Vec::with_capacity(cmp::min(holding_cell_htlc_update_count as usize, OUR_MAX_HTLCS as usize*2));
43174404
for _ in 0..holding_cell_htlc_update_count {
@@ -4428,6 +4515,7 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
44284515
pending_inbound_htlcs,
44294516
pending_outbound_htlcs,
44304517
holding_cell_htlc_updates,
4518+
payment_preimages,
44314519

44324520
resend_order,
44334521

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3104,7 +3104,7 @@ impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send, T: Deref + Sync + Send, K:
31043104
}
31053105
}
31063106
}
3107-
if channel.is_funding_initiated() && channel.channel_monitor().would_broadcast_at_height(height, &self.logger) {
3107+
if channel.is_funding_initiated() && channel.monitor_would_broadcast_at_height(height, &self.logger) {
31083108
if let Some(short_id) = channel.get_short_channel_id() {
31093109
short_to_id.remove(&short_id);
31103110
}

0 commit comments

Comments
 (0)