Skip to content

Askrene: prune and cap #8332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
7 changes: 7 additions & 0 deletions common/amount.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,13 @@ struct amount_msat amount_msat_div(struct amount_msat msat, u64 div)
return msat;
}

struct amount_msat amount_msat_div_ceil(struct amount_msat msat, u64 div)
{
u64 res = msat.millisatoshis / div;
msat.millisatoshis = res + (div * res == msat.millisatoshis ? 0 : 1);
return msat;
}

struct amount_sat amount_sat_div(struct amount_sat sat, u64 div)
{
sat.satoshis /= div;
Expand Down
6 changes: 6 additions & 0 deletions common/amount.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ WARN_UNUSED_RESULT bool amount_sat_add_sat_s64(struct amount_sat *val,
WARN_UNUSED_RESULT bool amount_msat_accumulate(struct amount_msat *a,
struct amount_msat b);

/* returns floor(msat/div) */
struct amount_msat amount_msat_div(struct amount_msat msat, u64 div);

/* returns ceil(msat/div) */
struct amount_msat amount_msat_div_ceil(struct amount_msat msat, u64 div);

/* returns floor(sat/div) */
struct amount_sat amount_sat_div(struct amount_sat sat, u64 div);

bool amount_sat_mul(struct amount_sat *res, struct amount_sat sat, u64 mul);
Expand Down
70 changes: 70 additions & 0 deletions common/test/run-amount.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,75 @@ static void test_amount_with_fee(void)
2100000001234567890ULL);
}

static void test_case_amount_div(u64 input, u64 div, u64 expected)
{
struct amount_msat msat = amount_msat(input);
struct amount_msat expected_msat = amount_msat(expected);
struct amount_msat result_msat = amount_msat_div(msat, div);
assert(amount_msat_eq(result_msat, expected_msat));
}

static void test_case_amount_div_ceil(u64 input, u64 div, u64 expected)
{
struct amount_msat msat = amount_msat(input);
struct amount_msat expected_msat = amount_msat(expected);
struct amount_msat result_msat = amount_msat_div_ceil(msat, div);
assert(amount_msat_eq(result_msat, expected_msat));
}

static void test_amount_div(void)
{
test_case_amount_div(1, 1, 1);
test_case_amount_div(1, 2, 0);
test_case_amount_div(1, 3, 0);

test_case_amount_div(2, 1, 2);
test_case_amount_div(2, 2, 1);
test_case_amount_div(2, 3, 0);

test_case_amount_div(3, 1, 3);
test_case_amount_div(3, 2, 1);
test_case_amount_div(3, 3, 1);
test_case_amount_div(3, 4, 0);

test_case_amount_div(10, 1, 10);
test_case_amount_div(10, 2, 5);
test_case_amount_div(10, 3, 3);
test_case_amount_div(10, 4, 2);
test_case_amount_div(10, 5, 2);
test_case_amount_div(10, 6, 1);
test_case_amount_div(10, 7, 1);
test_case_amount_div(10, 8, 1);
test_case_amount_div(10, 9, 1);
test_case_amount_div(10, 10, 1);
test_case_amount_div(10, 11, 0);

test_case_amount_div_ceil(1, 1, 1);
test_case_amount_div_ceil(1, 2, 1);
test_case_amount_div_ceil(1, 3, 1);

test_case_amount_div_ceil(2, 1, 2);
test_case_amount_div_ceil(2, 2, 1);
test_case_amount_div_ceil(2, 3, 1);

test_case_amount_div_ceil(3, 1, 3);
test_case_amount_div_ceil(3, 2, 2);
test_case_amount_div_ceil(3, 3, 1);
test_case_amount_div_ceil(3, 4, 1);

test_case_amount_div_ceil(10, 1, 10);
test_case_amount_div_ceil(10, 2, 5);
test_case_amount_div_ceil(10, 3, 4);
test_case_amount_div_ceil(10, 4, 3);
test_case_amount_div_ceil(10, 5, 2);
test_case_amount_div_ceil(10, 6, 2);
test_case_amount_div_ceil(10, 7, 2);
test_case_amount_div_ceil(10, 8, 2);
test_case_amount_div_ceil(10, 9, 2);
test_case_amount_div_ceil(10, 10, 1);
test_case_amount_div_ceil(10, 11, 1);
}

#define FAIL_MSAT(msatp, str) \
assert(!parse_amount_msat((msatp), (str), strlen(str)))
#define PASS_MSAT(msatp, str, val) \
Expand Down Expand Up @@ -330,5 +399,6 @@ int main(int argc, char *argv[])
}

test_amount_with_fee();
test_amount_div();
common_shutdown();
}
2 changes: 1 addition & 1 deletion contrib/msggen/msggen/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -16125,7 +16125,7 @@
"",
"Layers are generally maintained by plugins, either to contain persistent information about capacities which have been discovered, or to contain transient information for this particular payment (such as blinded paths or routehints).",
"",
"There are three automatic layers: *auto.localchans* contains information on local channels from this node (including non-public ones), and their exact current spendable capacities. *auto.sourcefree* overrides all channels (including those from previous layers) leading out of the *source* to be zero fee and zero delay. These are both useful in the case where the source is the current node. And *auto.no_mpp_support* forces getroutes to return a single flow, though only basic checks are done that the result is useful."
"There are three automatic layers: *auto.localchans* contains information on local channels from this node (including non-public ones), and their exact current spendable capacities. *auto.sourcefree* overrides all channels (including those from previous layers) leading out of the *source* to be zero fee and zero delay. These are both useful in the case where the source is the current node. And *auto.no_mpp_support* forces getroutes to return a single path solution which is useful for payments for which MPP is not supported."
],
"categories": [
"readonly"
Expand Down
2 changes: 1 addition & 1 deletion doc/schemas/getroutes.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"",
"Layers are generally maintained by plugins, either to contain persistent information about capacities which have been discovered, or to contain transient information for this particular payment (such as blinded paths or routehints).",
"",
"There are three automatic layers: *auto.localchans* contains information on local channels from this node (including non-public ones), and their exact current spendable capacities. *auto.sourcefree* overrides all channels (including those from previous layers) leading out of the *source* to be zero fee and zero delay. These are both useful in the case where the source is the current node. And *auto.no_mpp_support* forces getroutes to return a single flow, though only basic checks are done that the result is useful."
"There are three automatic layers: *auto.localchans* contains information on local channels from this node (including non-public ones), and their exact current spendable capacities. *auto.sourcefree* overrides all channels (including those from previous layers) leading out of the *source* to be zero fee and zero delay. These are both useful in the case where the source is the current node. And *auto.no_mpp_support* forces getroutes to return a single path solution which is useful for payments for which MPP is not supported."
],
"categories": [
"readonly"
Expand Down
Loading
Loading