bkpr: exclude non-wallet events in the balance snapshot

Anchor outputs are ignored by the clightning wallet, but we keep track
of them in the bookkeeper. This causes problems when we do the balance
checks on restart w/ the balance_snapshot -- it results in us printing
out a journal_entry to 'get rid of' the anchors that the clightning node
doesnt know about.

Instead, we mark some outputs as 'ignored' and exclude these from our
account balance sums when we're comparing to the clightning snapshot.
This commit is contained in:
niftynei
2022-07-19 17:04:38 +09:30
committed by Rusty Russell
parent fec8186413
commit a3d82d5a01
12 changed files with 128 additions and 51 deletions

View File

@@ -471,6 +471,7 @@ static struct command_result *json_list_balances(struct command *cmd,
err = account_get_balance(cmd, db,
accts[i]->name,
true,
false, /* don't skip ignored */
&balances);
if (err)
@@ -596,6 +597,7 @@ static bool new_missed_channel_account(struct command *cmd,
chain_ev->outpoint = opt;
chain_ev->spending_txid = NULL;
chain_ev->payment_id = NULL;
chain_ev->ignored = false;
/* Update the account info too */
tags = tal_arr(chain_ev, enum mvt_tag, 1);
@@ -799,7 +801,7 @@ listpeers_multi_done(struct command *cmd,
db_begin_transaction(db);
err = account_get_balance(tmpctx, db, info->acct->name,
false, &balances);
false, false, &balances);
db_commit_transaction(db);
if (err)
@@ -880,7 +882,7 @@ listpeers_done(struct command *cmd, const char *buf,
info->ev->timestamp)) {
db_begin_transaction(db);
err = account_get_balance(tmpctx, db, info->acct->name,
false, &balances);
false, false, &balances);
db_commit_transaction(db);
if (err)
@@ -993,6 +995,9 @@ static struct command_result *json_balance_snapshot(struct command *cmd,
err = account_get_balance(cmd, db, acct_name,
/* Don't error if negative */
false,
/* Ignore non-clightning
* balances items */
true,
&balances);
if (err)
@@ -1193,6 +1198,10 @@ parse_and_log_chain_move(struct command *cmd,
e->timestamp = timestamp;
e->tag = mvt_tag_str(tags[0]);
e->ignored = false;
for (size_t i = 0; i < tal_count(tags); i++)
e->ignored |= tags[i] == IGNORED;
db_begin_transaction(db);
acct = find_account(cmd, db, acct_name);

View File

@@ -27,6 +27,9 @@ struct chain_event {
/* Tag describing the event */
const char *tag;
/* Is the node's wallet ignoring this? */
bool ignored;
/* Amount we received in this event */
struct amount_msat credit;

View File

@@ -94,6 +94,7 @@ static struct migration db_migrations[] = {
NULL},
{SQL("ALTER TABLE chain_events ADD origin TEXT;"), NULL},
{SQL("ALTER TABLE accounts ADD closed_count INTEGER DEFAULT 0;"), NULL},
{SQL("ALTER TABLE chain_events ADD ignored INTEGER;"), NULL},
};
static bool db_migrate(struct plugin *p, struct db *db)

View File

@@ -55,6 +55,8 @@ static struct chain_event *stmt2chain_event(const tal_t *ctx, struct db_stmt *st
} else
e->spending_txid = NULL;
e->ignored = db_col_int(stmt, "e.ignored") == 1;
return e;
}
@@ -125,6 +127,7 @@ struct chain_event **list_chain_events_timebox(const tal_t *ctx,
", e.outnum"
", e.spending_txid"
", e.payment_id"
", e.ignored"
" FROM chain_events e"
" LEFT OUTER JOIN accounts a"
" ON e.account_id = a.id"
@@ -164,6 +167,7 @@ struct chain_event **account_get_chain_events(const tal_t *ctx,
", e.outnum"
", e.spending_txid"
", e.payment_id"
", e.ignored"
" FROM chain_events e"
" LEFT OUTER JOIN accounts a"
" ON e.account_id = a.id"
@@ -196,6 +200,7 @@ static struct chain_event **find_txos_for_tx(const tal_t *ctx,
", e.outnum"
", e.spending_txid"
", e.payment_id"
", e.ignored"
" FROM chain_events e"
" LEFT OUTER JOIN accounts a"
" ON e.account_id = a.id"
@@ -591,6 +596,7 @@ struct chain_event *find_chain_event_by_id(const tal_t *ctx,
", e.outnum"
", e.spending_txid"
", e.payment_id"
", e.ignored"
" FROM chain_events e"
" LEFT OUTER JOIN accounts a"
" ON e.account_id = a.id"
@@ -635,6 +641,7 @@ static struct chain_event *find_chain_event(const tal_t *ctx,
", e.outnum"
", e.spending_txid"
", e.payment_id"
", e.ignored"
" FROM chain_events e"
" LEFT OUTER JOIN accounts a"
" ON e.account_id = a.id"
@@ -661,6 +668,7 @@ static struct chain_event *find_chain_event(const tal_t *ctx,
", e.outnum"
", e.spending_txid"
", e.payment_id"
", e.ignored"
" FROM chain_events e"
" LEFT OUTER JOIN accounts a"
" ON e.account_id = a.id"
@@ -689,6 +697,7 @@ char *account_get_balance(const tal_t *ctx,
struct db *db,
const char *acct_name,
bool calc_sum,
bool skip_ignored,
struct acct_balance ***balances)
{
struct db_stmt *stmt;
@@ -701,9 +710,13 @@ char *account_get_balance(const tal_t *ctx,
" LEFT OUTER JOIN accounts a"
" ON a.id = ce.account_id"
" WHERE a.name = ?"
" AND ce.ignored != ?"
" GROUP BY ce.currency"));
db_bind_text(stmt, 0, acct_name);
/* We populate ignored with a 0 or 1,
* if we want both 0+1, we just ignore everything with a 2 */
db_bind_int(stmt, 1, skip_ignored ? 1 : 2);
db_query_prepared(stmt);
*balances = tal_arr(ctx, struct acct_balance *, 0);
@@ -1287,6 +1300,7 @@ static struct chain_event **find_chain_events_bytxid(const tal_t *ctx, struct db
", e.outnum"
", e.spending_txid"
", e.payment_id"
", e.ignored"
" FROM chain_events e"
" LEFT OUTER JOIN accounts a"
" ON a.id = e.account_id"
@@ -1775,9 +1789,10 @@ bool log_chain_event(struct db *db,
", outnum"
", payment_id"
", spending_txid"
", ignored"
")"
" VALUES"
" (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
" VALUES "
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
db_bind_u64(stmt, 0, acct->db_id);
if (e->origin_acct)
@@ -1804,6 +1819,7 @@ bool log_chain_event(struct db *db,
else
db_bind_null(stmt, 12);
db_bind_int(stmt, 13, e->ignored ? 1 : 0);
db_exec_prepared_v2(stmt);
e->db_id = db_last_insert_id_v2(stmt);
e->acct_db_id = acct->db_id;

View File

@@ -91,12 +91,14 @@ struct chain_event **list_chain_events_timebox(const tal_t *ctx,
/* Calculate the balances for an account
*
* @calc_sum - compute the total balance. error if negative
* @calc_sum - compute the total balance. error if negative
* @skip_ignored - don't include ignored payments in the balance sum
* */
char *account_get_balance(const tal_t *ctx,
struct db *db,
const char *acct_name,
bool calc_sum,
bool skip_ignored,
struct acct_balance ***balances);
/* Get chain fees for account */

View File

@@ -360,6 +360,7 @@ static struct chain_event *make_chain_event(const tal_t *ctx,
ev->currency = "btc";
ev->timestamp = 1919191;
ev->blockheight = blockheight;
ev->ignored = false;
memset(&ev->outpoint.txid, outpoint_char, sizeof(struct bitcoin_txid));
ev->outpoint.n = outnum;
@@ -961,6 +962,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p)
ev1->currency = "btc";
ev1->timestamp = 1919191;
ev1->blockheight = 1919191;
ev1->ignored = false;
memset(&ev1->outpoint.txid, 'D', sizeof(struct bitcoin_txid));
ev1->outpoint.n = 1;
ev1->spending_txid = tal(ctx, struct bitcoin_txid);
@@ -980,6 +982,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p)
ev2->currency = "btc";
ev2->timestamp = 1919191;
ev2->blockheight = 1919191;
ev2->ignored = false;
memset(&ev2->outpoint.txid, 'D', sizeof(struct bitcoin_txid));
ev2->outpoint.n = 1;
ev2->spending_txid = NULL;
@@ -996,6 +999,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p)
ev3->currency = "btc";
ev3->timestamp = 3939393;
ev3->blockheight = 3939393;
ev3->ignored = false;
memset(&ev3->outpoint.txid, 'E', sizeof(struct bitcoin_txid));
ev3->outpoint.n = 1;
ev3->spending_txid = tal(ctx, struct bitcoin_txid);
@@ -1083,15 +1087,16 @@ static bool test_account_balances(const tal_t *ctx, struct plugin *p)
AMOUNT_MSAT(1000),
1019,
'A', 1, '*'));
ev1 = make_chain_event(ctx, "two",
AMOUNT_MSAT(0), AMOUNT_MSAT(999),
AMOUNT_MSAT(999),
1020, 'A', 2, '*');
/* Make this an ignored event */
ev1->ignored = true;
/* -999btc */
log_chain_event(db, acct,
make_chain_event(ctx, "two",
AMOUNT_MSAT(0),
AMOUNT_MSAT(999),
AMOUNT_MSAT(999),
1020,
'A', 2, '*'));
log_chain_event(db, acct, ev1);
/* -440btc */
log_channel_event(db, acct,
@@ -1118,7 +1123,7 @@ static bool test_account_balances(const tal_t *ctx, struct plugin *p)
/* Add same chain event to a different account, shouldn't show */
log_chain_event(db, acct2, ev1);
err = account_get_balance(ctx, db, acct->name, true,
err = account_get_balance(ctx, db, acct->name, true, false,
&balances);
CHECK_MSG(!err, err);
db_commit_transaction(db);
@@ -1141,14 +1146,21 @@ static bool test_account_balances(const tal_t *ctx, struct plugin *p)
ev1->currency = "chf";
log_chain_event(db, acct, ev1);
err = account_get_balance(ctx, db, acct->name, true,
err = account_get_balance(ctx, db, acct->name, true, false,
&balances);
CHECK_MSG(err != NULL, "Expected err message");
CHECK(streq(err, "chf channel balance is negative? 5000msat - 5001msat"));
err = account_get_balance(ctx, db, acct->name, false,
err = account_get_balance(ctx, db, acct->name, false, false,
&balances);
CHECK_MSG(!err, err);
/* Now with ignored events */
err = account_get_balance(ctx, db, acct->name, true, true,
&balances);
CHECK(streq(balances[0]->currency, "btc"));
CHECK(amount_msat_eq(balances[0]->balance,
AMOUNT_MSAT(500 - 440 + 1000)));
db_commit_transaction(db);
return true;
@@ -1212,6 +1224,7 @@ static bool test_account_crud(const tal_t *ctx, struct plugin *p)
ev1->currency = "btc";
ev1->timestamp = 1919191;
ev1->blockheight = 1919191;
ev1->ignored = false;
memset(&ev1->outpoint.txid, 'D', sizeof(struct bitcoin_txid));
ev1->outpoint.n = 1;
ev1->spending_txid = tal(ctx, struct bitcoin_txid);