Skip to content

Commit 068543e

Browse files
Ensure build_commitment_tx and next_local/remote_tx_fee agree on the fee
... when possible. Sometimes they'll inevitably count different HTLCs, so we skip those cases.
1 parent ca680d1 commit 068543e

File tree

1 file changed

+149
-9
lines changed

1 file changed

+149
-9
lines changed

lightning/src/ln/channel.rs

Lines changed: 149 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ use std;
4242
use std::default::Default;
4343
use std::{cmp,mem,fmt};
4444
use std::ops::Deref;
45+
#[cfg(test)]
46+
use std::sync::Mutex;
4547
use bitcoin::hashes::hex::ToHex;
4648

4749
#[cfg(test)]
@@ -391,6 +393,15 @@ pub(super) struct Channel<ChanSigner: ChannelKeys> {
391393
commitment_secrets: CounterpartyCommitmentSecrets,
392394

393395
network_sync: UpdateStatus,
396+
397+
// We save these values so we can make sure `next_local_commit_tx_fee_msat` and
398+
// `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
399+
// be, by comparing the cached values to the fee of the tranaction generated by
400+
// `build_commitment_transaction`.
401+
#[cfg(test)]
402+
next_local_commitment_tx_fee_cached: Mutex<Option<u64>>,
403+
#[cfg(test)]
404+
next_remote_commitment_tx_fee_cached: Mutex<Option<u64>>,
394405
}
395406

396407
pub const OUR_MAX_HTLCS: u16 = 50; //TODO
@@ -559,6 +570,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
559570
commitment_secrets: CounterpartyCommitmentSecrets::new(),
560571

561572
network_sync: UpdateStatus::Fresh,
573+
574+
#[cfg(test)]
575+
next_local_commitment_tx_fee_cached: Mutex::new(None),
576+
#[cfg(test)]
577+
next_remote_commitment_tx_fee_cached: Mutex::new(None),
562578
})
563579
}
564580

@@ -787,6 +803,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
787803
commitment_secrets: CounterpartyCommitmentSecrets::new(),
788804

789805
network_sync: UpdateStatus::Fresh,
806+
807+
#[cfg(test)]
808+
next_local_commitment_tx_fee_cached: Mutex::new(None),
809+
#[cfg(test)]
810+
next_remote_commitment_tx_fee_cached: Mutex::new(None),
790811
};
791812

792813
Ok(chan)
@@ -905,7 +926,21 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
905926
InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => (!generated_by_local, "AwaitingRemoteRevokeToAnnounce"),
906927
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => (true, "AwaitingAnnouncedRemoteRevoke"),
907928
InboundHTLCState::Committed => (true, "Committed"),
908-
InboundHTLCState::LocalRemoved(_) => (!generated_by_local, "LocalRemoved"),
929+
InboundHTLCState::LocalRemoved(_) => {
930+
#[cfg(test)]
931+
{
932+
// Remote commitment transactions generated by us won't include our locally removed
933+
// HTLCs, even though we include them when deciding whether to accept/send new HTLCs and
934+
// setting these cached values. Therefore, set these values to None here so we don't
935+
// assert that the transaction generated in this function has the same fee as the cached
936+
// fee. Similar reasoning applies to LocalAnnounced and RemoveRemoved HTLCs below.
937+
if !local && generated_by_local {
938+
*self.next_local_commitment_tx_fee_cached.lock().unwrap() = None;
939+
*self.next_remote_commitment_tx_fee_cached.lock().unwrap() = None;
940+
}
941+
}
942+
(!generated_by_local, "LocalRemoved")
943+
},
909944
};
910945

911946
if include {
@@ -928,9 +963,27 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
928963

929964
for ref htlc in self.pending_outbound_htlcs.iter() {
930965
let (include, state_name) = match htlc.state {
931-
OutboundHTLCState::LocalAnnounced(_) => (generated_by_local, "LocalAnnounced"),
966+
OutboundHTLCState::LocalAnnounced(_) => {
967+
#[cfg(test)]
968+
{
969+
if local && !generated_by_local {
970+
*self.next_local_commitment_tx_fee_cached.lock().unwrap() = None;
971+
*self.next_remote_commitment_tx_fee_cached.lock().unwrap() = None;
972+
}
973+
}
974+
(generated_by_local, "LocalAnnounced")
975+
},
932976
OutboundHTLCState::Committed => (true, "Committed"),
933-
OutboundHTLCState::RemoteRemoved(_) => (generated_by_local, "RemoteRemoved"),
977+
OutboundHTLCState::RemoteRemoved(_) => {
978+
#[cfg(test)]
979+
{
980+
if local && !generated_by_local {
981+
*self.next_local_commitment_tx_fee_cached.lock().unwrap() = None;
982+
*self.next_remote_commitment_tx_fee_cached.lock().unwrap() = None;
983+
}
984+
}
985+
(generated_by_local, "RemoteRemoved")
986+
},
934987
OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => (generated_by_local, "AwaitingRemoteRevokeToRemove"),
935988
OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => (false, "AwaitingRemovedRemoteRevoke"),
936989
};
@@ -1780,7 +1833,18 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
17801833
}
17811834
}
17821835

1783-
self.commit_tx_fee_msat(included_htlcs + addl_htlcs)
1836+
let num_htlcs = included_htlcs + addl_htlcs;
1837+
let res = self.commit_tx_fee_msat(num_htlcs);
1838+
#[cfg(test)]
1839+
{
1840+
if fee_spike_buffer_htlc.is_none() {
1841+
*self.next_local_commitment_tx_fee_cached.lock().unwrap() = Some(res);
1842+
} else {
1843+
let fee = self.commit_tx_fee_msat(num_htlcs - 1);
1844+
*self.next_local_commitment_tx_fee_cached.lock().unwrap() = Some(fee);
1845+
}
1846+
}
1847+
res
17841848
}
17851849

17861850
// Get the commitment tx fee for the remote's next commitment transaction based on the number of
@@ -1825,10 +1889,38 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18251889
}
18261890
}
18271891

1828-
self.commit_tx_fee_msat(included_htlcs + addl_htlcs)
1892+
let num_htlcs = included_htlcs + addl_htlcs;
1893+
let res = self.commit_tx_fee_msat(num_htlcs);
1894+
#[cfg(test)]
1895+
{
1896+
if fee_spike_buffer_htlc.is_none() {
1897+
*self.next_remote_commitment_tx_fee_cached.lock().unwrap() = Some(res);
1898+
} else {
1899+
let fee = self.commit_tx_fee_msat(num_htlcs - 1);
1900+
*self.next_remote_commitment_tx_fee_cached.lock().unwrap() = Some(fee);
1901+
}
1902+
}
1903+
res
1904+
}
1905+
1906+
1907+
pub fn update_add_htlc<F, L: Deref>(&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_status: PendingHTLCStatus, create_pending_htlc_status: F, logger: &L) -> Result<(), ChannelError>
1908+
where F: for<'a> Fn(&'a Self, PendingHTLCStatus, u16) -> PendingHTLCStatus, L::Target: Logger {
1909+
match self.update_add_htlc_internal(msg, pending_forward_status, create_pending_htlc_status, logger) {
1910+
Ok(()) => return Ok(()),
1911+
Err(e) => {
1912+
#[cfg(test)]
1913+
{
1914+
// If we errored, one of these fields still might've been set, so re-set them to None.
1915+
*self.next_local_commitment_tx_fee_cached.lock().unwrap() = None;
1916+
*self.next_remote_commitment_tx_fee_cached.lock().unwrap() = None;
1917+
}
1918+
return Err(e);
1919+
},
1920+
}
18291921
}
18301922

1831-
pub fn update_add_htlc<F, L: Deref>(&mut self, msg: &msgs::UpdateAddHTLC, mut pending_forward_status: PendingHTLCStatus, create_pending_htlc_status: F, logger: &L) -> Result<(), ChannelError>
1923+
fn update_add_htlc_internal<F, L: Deref>(&mut self, msg: &msgs::UpdateAddHTLC, mut pending_forward_status: PendingHTLCStatus, create_pending_htlc_status: F, logger: &L) -> Result<(), ChannelError>
18321924
where F: for<'a> Fn(&'a Self, PendingHTLCStatus, u16) -> PendingHTLCStatus, L::Target: Logger {
18331925
// We can't accept HTLCs sent after we've sent a shutdown.
18341926
let local_sent_shutdown = (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::LocalShutdownSent as u32)) != (ChannelState::ChannelFunded as u32);
@@ -2054,16 +2146,25 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
20542146
return Err((None, ChannelError::Close("Invalid commitment tx signature from peer".to_owned())));
20552147
}
20562148

2149+
let num_htlcs = commitment_tx.1;
2150+
let total_fee = feerate_per_kw as u64 * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000;
20572151
//If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction
20582152
if update_fee {
2059-
let num_htlcs = commitment_tx.1;
2060-
let total_fee = feerate_per_kw as u64 * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000;
2061-
20622153
let counterparty_reserve_we_require = Channel::<ChanSigner>::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis);
20632154
if self.channel_value_satoshis - self.value_to_self_msat / 1000 < total_fee + counterparty_reserve_we_require {
20642155
return Err((None, ChannelError::Close("Funding remote cannot afford proposed new fee".to_owned())));
20652156
}
20662157
}
2158+
#[cfg(test)]
2159+
{
2160+
let projected_fee = match self.channel_outbound {
2161+
true => self.next_local_commitment_tx_fee_cached.lock().unwrap().take(),
2162+
false => self.next_remote_commitment_tx_fee_cached.lock().unwrap().take()
2163+
};
2164+
if let Some(fee) = projected_fee {
2165+
assert_eq!(total_fee, fee / 1000);
2166+
}
2167+
}
20672168

20682169
if msg.htlc_signatures.len() != commitment_tx.1 {
20692170
return Err((None, ChannelError::Close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), commitment_tx.1))));
@@ -3744,6 +3845,28 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37443845
/// You MUST call send_commitment prior to any other calls on this Channel
37453846
/// If an Err is returned, it's a ChannelError::Ignore!
37463847
pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result<Option<msgs::UpdateAddHTLC>, ChannelError> {
3848+
match self.send_htlc_internal(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet) {
3849+
Ok(res) => return Ok(res),
3850+
Err(e) => {
3851+
#[cfg(test)]
3852+
{
3853+
// If we errored, one of these fields still might've been set, so re-set them to None.
3854+
*self.next_local_commitment_tx_fee_cached.lock().unwrap() = None;
3855+
*self.next_remote_commitment_tx_fee_cached.lock().unwrap() = None;
3856+
}
3857+
return Err(e);
3858+
}
3859+
}
3860+
}
3861+
3862+
/// Adds a pending outbound HTLC to this channel, note that you probably want
3863+
/// send_htlc_and_commit instead cause you'll want both messages at once.
3864+
/// This returns an option instead of a pure UpdateAddHTLC as we may be in a state where we are
3865+
/// waiting on the remote peer to send us a revoke_and_ack during which time we cannot add new
3866+
/// HTLCs on the wire or we wouldn't be able to determine what they actually ACK'ed.
3867+
/// You MUST call send_commitment prior to any other calls on this Channel
3868+
/// If an Err is returned, it's a ChannelError::Ignore!
3869+
fn send_htlc_internal(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result<Option<msgs::UpdateAddHTLC>, ChannelError> {
37473870
if (self.channel_state & (ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelFunded as u32) {
37483871
return Err(ChannelError::Ignore("Cannot send HTLC until channel is fully established and we haven't started shutting down".to_owned()));
37493872
}
@@ -3938,6 +4061,18 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
39384061
let counterparty_commitment_tx = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, feerate_per_kw, logger);
39394062
let (signature, htlc_signatures);
39404063

4064+
#[cfg(test)]
4065+
{
4066+
let projected_fee = match self.channel_outbound {
4067+
true => self.next_local_commitment_tx_fee_cached.lock().unwrap().take(),
4068+
false => self.next_remote_commitment_tx_fee_cached.lock().unwrap().take()
4069+
};
4070+
if let Some(fee) = projected_fee {
4071+
let actual_fee = self.commit_tx_fee_msat(counterparty_commitment_tx.1);
4072+
assert_eq!(actual_fee, fee);
4073+
}
4074+
}
4075+
39414076
{
39424077
let mut htlcs = Vec::with_capacity(counterparty_commitment_tx.2.len());
39434078
for &(ref htlc, _) in counterparty_commitment_tx.2.iter() {
@@ -4524,6 +4659,11 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
45244659
commitment_secrets,
45254660

45264661
network_sync: UpdateStatus::Fresh,
4662+
4663+
#[cfg(test)]
4664+
next_local_commitment_tx_fee_cached: Mutex::new(None),
4665+
#[cfg(test)]
4666+
next_remote_commitment_tx_fee_cached: Mutex::new(None),
45274667
})
45284668
}
45294669
}

0 commit comments

Comments
 (0)