Skip to content

Commit b54fe5f

Browse files
committed
Avoid overflow in addition when checking counterparty feerates
This is harmless outside of debug builds - the feerate will overflow causing it to either spuriously fail the first check, or correctly pass it and fail the second check. In debug builds, however, it panics due to integer overflow. Found by the `full_stack_target` fuzz test in the Chaincode-provided continuous fuzzing. Thanks Chaincode!
1 parent 35d4ebb commit b54fe5f

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

lightning/src/ln/channel.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -870,14 +870,6 @@ impl<Signer: Sign> Channel<Signer> {
870870
fn check_remote_fee<F: Deref>(fee_estimator: &F, feerate_per_kw: u32) -> Result<(), ChannelError>
871871
where F::Target: FeeEstimator
872872
{
873-
let lower_limit = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
874-
// Some fee estimators round up to the next full sat/vbyte (ie 250 sats per kw), causing
875-
// occasional issues with feerate disagreements between an initiator that wants a feerate
876-
// of 1.1 sat/vbyte and a receiver that wants 1.1 rounded up to 2. Thus, we always add 250
877-
// sat/kw before the comparison here.
878-
if feerate_per_kw + 250 < lower_limit {
879-
return Err(ChannelError::Close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {} (- 250)", feerate_per_kw, lower_limit)));
880-
}
881873
// We only bound the fee updates on the upper side to prevent completely absurd feerates,
882874
// always accepting up to 25 sat/vByte or 10x our fee estimator's "High Priority" fee.
883875
// We generally don't care too much if they set the feerate to something very high, but it
@@ -887,6 +879,14 @@ impl<Signer: Sign> Channel<Signer> {
887879
if feerate_per_kw as u64 > upper_limit {
888880
return Err(ChannelError::Close(format!("Peer's feerate much too high. Actual: {}. Our expected upper limit: {}", feerate_per_kw, upper_limit)));
889881
}
882+
let lower_limit = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
883+
// Some fee estimators round up to the next full sat/vbyte (ie 250 sats per kw), causing
884+
// occasional issues with feerate disagreements between an initiator that wants a feerate
885+
// of 1.1 sat/vbyte and a receiver that wants 1.1 rounded up to 2. Thus, we always add 250
886+
// sat/kw before the comparison here.
887+
if feerate_per_kw + 250 < lower_limit {
888+
return Err(ChannelError::Close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {} (- 250)", feerate_per_kw, lower_limit)));
889+
}
890890
Ok(())
891891
}
892892

@@ -5859,6 +5859,13 @@ mod tests {
58595859
"MAX_FUNDING_SATOSHIS is greater than all satoshis in existence");
58605860
}
58615861

5862+
#[test]
5863+
fn test_no_fee_check_overflow() {
5864+
// Previously, calling `check_remote_fee` with a fee of 0xffffffff would overflow in
5865+
// arithmetic, causing a panic with debug assertions enabled.
5866+
assert!(Channel::<InMemorySigner>::check_remote_fee(&&TestFeeEstimator { fee_est: 42 }, u32::max_value()).is_err());
5867+
}
5868+
58625869
struct Keys {
58635870
signer: InMemorySigner,
58645871
}

0 commit comments

Comments
 (0)