Skip to content

Commit c587612

Browse files
author
Chandra Pratap
committed
fuzz-tests: Add a test to trigger the break in amount_msat_sub_fee
An assertion failure occurs in amount_msat_sub_fee() due to overlow of parameters. Add a test in tests/test_askrene.py to try and trigger this failure through a user-level command.
1 parent 108f7a6 commit c587612

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

common/amount.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <common/overflows.h>
88
#include <common/utils.h>
99
#include <inttypes.h>
10+
#include <stdio.h>
1011
#include <wire/wire.h>
1112

1213
bool amount_sat_to_msat(struct amount_msat *msat,
@@ -616,6 +617,12 @@ struct amount_msat amount_msat_sub_fee(struct amount_msat in,
616617
* Since we round the fee down, out can be a bit bigger than
617618
* expected, so we iterate upwards.
618619
*/
620+
FILE *logf = fopen("/tmp/amount_msat_sub_fee.log", "a");
621+
if (logf) {
622+
fprintf(logf, "CALL: in=%" PRIu64 "msat, fee_base_msat=%u, fee_ppm=%u\n",
623+
in.millisatoshis, fee_base_msat, fee_proportional_millionths);
624+
fclose(logf);
625+
}
619626
if (!amount_msat_sub(&out, in, amount_msat(fee_base_msat)))
620627
return AMOUNT_MSAT(0);
621628
if (!amount_msat_mul_div(&out, out, 1000000,

tests/test_askrene.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,44 @@ def direction(src, dst):
2020
return 1
2121

2222

23+
def test_fee_overflow(node_factory):
24+
"""Test for integer overflow in fee calculation with extreme parameters"""
25+
input = 1000
26+
fee_base = 8
27+
fee_prop = 4295000
28+
29+
# Setup: Create a line graph with 2 nodes
30+
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
31+
32+
# Create a new layer for fee modifications
33+
l1.rpc.askrene_create_layer('fee_update_layer')
34+
35+
# Get channel ID between l1 and l2 (example)
36+
scid = first_scid(l1, l2)
37+
scid_dir = f"{scid}/{direction(l1.info['id'], l2.info['id'])}"
38+
39+
# Update fee parameters for a specific channel direction
40+
l1.rpc.askrene_update_channel(
41+
layer='fee_update_layer',
42+
short_channel_id_dir=scid_dir,
43+
htlc_minimum_msat=100,
44+
# Any values larger than these get truncated to a set of safe values
45+
htlc_maximum_msat='9999999999999999sat',
46+
fee_base_msat=9999999,
47+
fee_proportional_millionths=999999,
48+
cltv_expiry_delta=18
49+
)
50+
51+
# Now call getroutes with the modified fee layer
52+
routes = l1.rpc.getroutes(
53+
source=l1.info['id'],
54+
destination=l2.info['id'],
55+
amount_msat=input,
56+
layers=['fee_update_layer'],
57+
maxfee_msat=0xFFFFFFFFFFFFFFFF,
58+
final_cltv=1440
59+
)
60+
2361
def test_reserve(node_factory):
2462
"""Test reserving channels"""
2563
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True)

0 commit comments

Comments
 (0)