Skip to content

Commit

Permalink
bkpr: separate the invoice_fees from the invoice paid
Browse files Browse the repository at this point in the history
For income events, break out the amount paid in routing fees vs the
total amount of the *invoice* that is paid.

Also printout these fees, when available, on listaccountevents
  • Loading branch information
niftynei authored and rustyrussell committed Jul 28, 2022
1 parent aa7ffb7 commit e7ed196
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 2 deletions.
1 change: 1 addition & 0 deletions plugins/bkpr/account_entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
static const char *tags[] = {
"journal_entry",
"penalty_adj",
"invoice_fee",
};

const char *account_entry_tag_str(enum account_entry_tag tag)
Expand Down
3 changes: 2 additions & 1 deletion plugins/bkpr/account_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
#define LIGHTNING_PLUGINS_BKPR_ACCOUNT_ENTRY_H
#include "config.h"

#define NUM_ACCOUNT_ENTRY_TAGS (JOURNAL_ENTRY + 1)
#define NUM_ACCOUNT_ENTRY_TAGS (INVOICEFEE + 1)
enum account_entry_tag {
JOURNAL_ENTRY = 0,
PENALTY_ADJ = 1,
INVOICEFEE = 2,
};

/* Convert an enum into a string */
Expand Down
2 changes: 2 additions & 0 deletions plugins/bkpr/channel_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ void json_add_channel_event(struct json_stream *out,
json_add_string(out, "tag", ev->tag);
json_add_amount_msat_only(out, "credit", ev->credit);
json_add_amount_msat_only(out, "debit", ev->debit);
if (!amount_msat_zero(ev->fees))
json_add_amount_msat_only(out, "fees", ev->fees);
json_add_string(out, "currency", ev->currency);
if (ev->payment_id)
json_add_sha256(out, "payment_id", ev->payment_id);
Expand Down
29 changes: 28 additions & 1 deletion plugins/bkpr/incomestmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,16 @@ static struct income_event *maybe_chain_income(const tal_t *ctx,
return NULL;
}

static struct income_event *paid_invoice_fee(const tal_t *ctx,
struct channel_event *ev)
{
struct income_event *iev;
iev = channel_to_income(ctx, ev, AMOUNT_MSAT(0), ev->fees);
iev->tag = tal_free(ev->tag);
iev->tag = (char *)account_entry_tag_str(INVOICEFEE);
return iev;
}

static struct income_event *maybe_channel_income(const tal_t *ctx,
struct channel_event *ev)
{
Expand All @@ -203,7 +213,17 @@ static struct income_event *maybe_channel_income(const tal_t *ctx,
}

if (streq(ev->tag, "invoice")) {
/* FIXME: add a sub-category for fees paid */
/* If it's a payment, we note fees separately */
if (!amount_msat_zero(ev->debit)) {
struct amount_msat paid;
bool ok;
ok = amount_msat_sub(&paid, ev->debit, ev->fees);
assert(ok);
return channel_to_income(ctx, ev,
ev->credit,
paid);
}

return channel_to_income(ctx, ev,
ev->credit,
ev->debit);
Expand Down Expand Up @@ -338,6 +358,13 @@ struct income_event **list_income_events(const tal_t *ctx,
if (ev)
tal_arr_expand(&evs, ev);

/* Breakout fees on sent payments */
if (streq(chan->tag, "invoice")
&& !amount_msat_zero(chan->debit)) {
ev = paid_invoice_fee(evs, chan);
tal_arr_expand(&evs, ev);
}

j++;
continue;
}
Expand Down
15 changes: 15 additions & 0 deletions tests/test_pay.py
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,21 @@ def test_forward_pad_fees_and_cltv(node_factory, bitcoind):
l1.rpc.waitsendpay(rhash)
assert only_one(l3.rpc.listinvoices('test_forward_pad_fees_and_cltv')['invoices'])['status'] == 'paid'

# Do some checks of the bookkeeper's records
def _income_tagset(node, tagset):
incomes = node.rpc.listincome()['income_events']
return [e for e in incomes if e['tag'] in tagset]

tags = ['invoice', 'invoice_fee']
wait_for(lambda: len(_income_tagset(l1, tags)) == 2)
incomes = _income_tagset(l1, tags)
# the balance on l3 should equal the invoice
bal = only_one(only_one(l3.rpc.listbalances()['accounts'])['balances'])['balance']
assert incomes[0]['tag'] == 'invoice'
assert bal == incomes[0]['debit']
inve = only_one([e for e in l1.rpc.listaccountevents()['events'] if e['tag'] == 'invoice'])
assert Millisatoshi(inve['debit']) == Millisatoshi(incomes[0]['debit']) + Millisatoshi(incomes[1]['debit'])


@pytest.mark.developer("needs DEVELOPER=1 for dev_ignore_htlcs")
def test_forward_stats(node_factory, bitcoind):
Expand Down

0 comments on commit e7ed196

Please sign in to comment.