From a45da6328010c3bdc441e51f8f9fbbe035ce6266 Mon Sep 17 00:00:00 2001 From: niftynei Date: Tue, 19 Jul 2022 17:04:38 +0930 Subject: [PATCH] bkpr: pass the node_id over for channel_opens, add to account it's nice to know what node your channel was opened with. in theory we could use listpeers to merge the data after the fact, except that channels disappear after they've been closed for a bit. it's better to just save the info. we print it out in `listbalances`, as that's a great place account level information --- common/coin_mvt.c | 20 +++++++++++++++++ common/coin_mvt.h | 8 +++++++ lightningd/channel_control.c | 1 + lightningd/notification.c | 2 ++ plugins/bkpr/bookkeeper.c | 38 +++++++++++++++++++++++++++++--- plugins/bkpr/recorder.c | 15 +++++++++++-- plugins/bkpr/recorder.h | 3 ++- plugins/bkpr/test/run-recorder.c | 23 ++++++++++--------- 8 files changed, 94 insertions(+), 16 deletions(-) diff --git a/common/coin_mvt.c b/common/coin_mvt.c index 9680b873f..4893d0e55 100644 --- a/common/coin_mvt.c +++ b/common/coin_mvt.c @@ -105,6 +105,9 @@ static struct chain_coin_mvt *new_chain_coin_mvt(const tal_t *ctx, mvt->outpoint = outpoint; mvt->originating_acct = NULL; + /* Most chain event's don't have a peer (only channel_opens) */ + mvt->peer_id = NULL; + /* for htlc's that are filled onchain, we also have a * preimage, NULL otherwise */ mvt->payment_hash = tal_dup_or_null(mvt, struct sha256, payment_hash); @@ -195,6 +198,7 @@ struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx, struct chain_coin_mvt *new_coin_channel_open(const tal_t *ctx, const struct channel_id *chan_id, const struct bitcoin_outpoint *out, + const struct node_id *peer_id, u32 blockheight, const struct amount_msat amount, const struct amount_sat output_val, @@ -207,6 +211,7 @@ struct chain_coin_mvt *new_coin_channel_open(const tal_t *ctx, take(new_tag_arr(NULL, CHANNEL_OPEN)), amount, true, output_val, 0); mvt->account_name = type_to_string(mvt, struct channel_id, chan_id); + mvt->peer_id = tal_dup(mvt, struct node_id, peer_id); /* If we're the opener, add to the tag list */ if (is_opener) @@ -359,6 +364,7 @@ struct coin_mvt *finalize_chain_mvt(const tal_t *ctx, mvt->blockheight = chain_mvt->blockheight; mvt->version = COIN_MVT_VERSION; mvt->node_id = node_id; + mvt->peer_id = chain_mvt->peer_id; return mvt; } @@ -391,6 +397,7 @@ struct coin_mvt *finalize_channel_mvt(const tal_t *ctx, mvt->timestamp = timestamp; mvt->version = COIN_MVT_VERSION; mvt->node_id = tal_dup(mvt, struct node_id, node_id); + mvt->peer_id = NULL; return mvt; } @@ -432,6 +439,12 @@ void towire_chain_coin_mvt(u8 **pptr, const struct chain_coin_mvt *mvt) towire_amount_msat(pptr, mvt->debit); towire_amount_sat(pptr, mvt->output_val); towire_u32(pptr, mvt->output_count); + + if (mvt->peer_id) { + towire_bool(pptr, true); + towire_node_id(pptr, mvt->peer_id); + } else + towire_bool(pptr, false); } void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_mvt *mvt) @@ -475,4 +488,11 @@ void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_m mvt->debit = fromwire_amount_msat(cursor, max); mvt->output_val = fromwire_amount_sat(cursor, max); mvt->output_count = fromwire_u32(cursor, max); + + if (fromwire_bool(cursor, max)) { + struct node_id peer_id; + fromwire_node_id(cursor, max, &peer_id); + mvt->peer_id = tal_dup(mvt, struct node_id, &peer_id); + } else + mvt->peer_id = NULL; } diff --git a/common/coin_mvt.h b/common/coin_mvt.h index 760d848bc..aaecb3f86 100644 --- a/common/coin_mvt.h +++ b/common/coin_mvt.h @@ -68,6 +68,10 @@ struct chain_coin_mvt { const struct bitcoin_txid *tx_txid; const struct bitcoin_outpoint *outpoint; + /* The id of the peer we have this channel with. + * Only on our channel_open events */ + const struct node_id *peer_id; + /* some on-chain movements have a payment hash */ struct sha256 *payment_hash; @@ -105,6 +109,9 @@ struct coin_mvt { /* name of 'account': wallet, external, */ const char *account_id; + /* Peer that this event occurred with */ + const struct node_id *peer_id; + /* if account_id is external, the account this 'impacted' */ const char *originating_acct; @@ -183,6 +190,7 @@ struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx, struct chain_coin_mvt *new_coin_channel_open(const tal_t *ctx, const struct channel_id *chan_id, const struct bitcoin_outpoint *out, + const struct node_id *peer_id, u32 blockheight, const struct amount_msat amount, const struct amount_sat output_val, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 52eef8c22..67a56b853 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -156,6 +156,7 @@ void channel_record_open(struct channel *channel, u32 blockheight) mvt = new_coin_channel_open(tmpctx, &channel->cid, &channel->funding, + &channel->peer->id, blockheight, start_balance, channel->funding_sats, diff --git a/lightningd/notification.c b/lightningd/notification.c index a11602c72..1b28a08ab 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -478,6 +478,8 @@ static void coin_movement_notification_serialize(struct json_stream *stream, json_object_start(stream, "coin_movement"); json_add_num(stream, "version", mvt->version); json_add_node_id(stream, "node_id", mvt->node_id); + if (mvt->peer_id) + json_add_node_id(stream, "peer_id", mvt->peer_id); json_add_string(stream, "type", mvt_type_str(mvt->type)); json_add_string(stream, "account_id", mvt->account_id); if (mvt->originating_acct) diff --git a/plugins/bkpr/bookkeeper.c b/plugins/bkpr/bookkeeper.c index 4fa323885..8c2a79208 100644 --- a/plugins/bkpr/bookkeeper.c +++ b/plugins/bkpr/bookkeeper.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -489,6 +490,12 @@ static struct command_result *json_list_balances(struct command *cmd, json_object_start(res, NULL); json_add_string(res, "account", accts[i]->name); + if (accts[i]->peer_id) { + json_add_node_id(res, "peer_id", accts[i]->peer_id); + json_add_bool(res, "account_resolved", + accts[i]->onchain_resolved_block > 0); + } + json_array_start(res, "balances"); for (size_t j = 0; j < tal_count(balances); j++) { json_object_start(res, NULL); @@ -549,6 +556,18 @@ static bool new_missed_channel_account(struct command *cmd, assert(peer_arr_tok->type == JSMN_ARRAY); /* There should only be one peer */ json_for_each_arr(i, curr_peer, peer_arr_tok) { + const char *err; + struct node_id peer_id; + + err = json_scan(cmd, buf, curr_peer, "{id:%}", + JSON_SCAN(json_to_node_id, &peer_id)); + + if (err) + plugin_err(cmd->plugin, + "failure scanning listpeer" + " result: %s", err); + + json_get_member(buf, curr_peer, "id"); chan_arr_tok = json_get_member(buf, curr_peer, "channels"); assert(chan_arr_tok->type == JSMN_ARRAY); @@ -557,7 +576,6 @@ static bool new_missed_channel_account(struct command *cmd, struct amount_msat amt, remote_amt, push_amt, push_credit, push_debit; char *opener, *chan_id; - const char *err; enum mvt_tag *tags; bool ok; @@ -624,7 +642,8 @@ static bool new_missed_channel_account(struct command *cmd, chain_ev->credit = amt; db_begin_transaction(db); log_chain_event(db, acct, chain_ev); - maybe_update_account(db, acct, chain_ev, tags, 0); + maybe_update_account(db, acct, chain_ev, + tags, 0, &peer_id); maybe_update_onchain_fees(cmd, db, &opt.txid); /* We won't count the close's fees if we're @@ -1120,6 +1139,7 @@ parse_and_log_chain_move(struct command *cmd, struct chain_event *e = tal(cmd, struct chain_event); struct sha256 *payment_hash = tal(cmd, struct sha256); struct bitcoin_txid *spending_txid = tal(cmd, struct bitcoin_txid); + struct node_id *peer_id; struct account *acct; u32 closed_count; const char *err; @@ -1180,6 +1200,17 @@ parse_and_log_chain_move(struct command *cmd, err = tal_free(err); } + peer_id = tal(cmd, struct node_id); + err = json_scan(tmpctx, buf, params, + "{coin_movement:" + "{peer_id:%}}", + JSON_SCAN(json_to_node_id, peer_id)); + + if (err) { + peer_id = tal_free(peer_id); + err = tal_free(err); + } + err = json_scan(tmpctx, buf, params, "{coin_movement:" "{output_count:%}}", @@ -1219,7 +1250,8 @@ parse_and_log_chain_move(struct command *cmd, /* This event *might* have implications for account; * update as necessary */ - maybe_update_account(db, acct, e, tags, closed_count); + maybe_update_account(db, acct, e, tags, closed_count, + peer_id); /* Can we calculate any onchain fees now? */ err = maybe_update_onchain_fees(cmd, db, diff --git a/plugins/bkpr/recorder.c b/plugins/bkpr/recorder.c index baccbf230..3fc57fa63 100644 --- a/plugins/bkpr/recorder.c +++ b/plugins/bkpr/recorder.c @@ -1152,7 +1152,8 @@ void maybe_update_account(struct db *db, struct account *acct, struct chain_event *e, const enum mvt_tag *tags, - u32 closed_count) + u32 closed_count, + struct node_id *peer_id) { struct db_stmt *stmt; bool updated = false; @@ -1200,6 +1201,11 @@ void maybe_update_account(struct db *db, } } + if (peer_id) { + updated = true; + acct->peer_id = tal_dup(acct, struct node_id, peer_id); + } + if (closed_count > 0) { updated = true; acct->closed_count = closed_count; @@ -1216,6 +1222,7 @@ void maybe_update_account(struct db *db, ", we_opened = ?" ", leased = ?" ", closed_count = ?" + ", peer_id = ?" " WHERE" " name = ?")); @@ -1232,8 +1239,12 @@ void maybe_update_account(struct db *db, db_bind_int(stmt, 2, acct->we_opened ? 1 : 0); db_bind_int(stmt, 3, acct->leased ? 1 : 0); db_bind_int(stmt, 4, acct->closed_count); + if (acct->peer_id) + db_bind_node_id(stmt, 5, acct->peer_id); + else + db_bind_null(stmt, 5); - db_bind_text(stmt, 5, acct->name); + db_bind_text(stmt, 6, acct->name); db_exec_prepared_v2(take(stmt)); } diff --git a/plugins/bkpr/recorder.h b/plugins/bkpr/recorder.h index b29d69d06..c7c4209ca 100644 --- a/plugins/bkpr/recorder.h +++ b/plugins/bkpr/recorder.h @@ -164,7 +164,8 @@ void maybe_update_account(struct db *db, struct account *acct, struct chain_event *e, const enum mvt_tag *tags, - u32 closed_count); + u32 closed_count, + struct node_id *peer_id); /* Update our onchain fees now? */ char *maybe_update_onchain_fees(const tal_t *ctx, diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c index f76078185..3c5fbffb2 100644 --- a/plugins/bkpr/test/run-recorder.c +++ b/plugins/bkpr/test/run-recorder.c @@ -251,7 +251,9 @@ static bool accountseq(struct account *a1, struct account *a2) { CHECK(a1->db_id == a2->db_id); CHECK(streq(a1->name, a2->name)); - CHECK(node_id_eq(a1->peer_id, a2->peer_id)); + CHECK((a1->peer_id != NULL) == (a2->peer_id != NULL)); + if (a1->peer_id) + CHECK(node_id_eq(a1->peer_id, a2->peer_id)); CHECK(a1->is_wallet == a2->is_wallet); CHECK(a1->we_opened == a2->we_opened); CHECK(a1->leased == a2->leased); @@ -507,7 +509,7 @@ static bool test_onchain_fee_chan_close(const tal_t *ctx, struct plugin *p) 'X', 0, '*'); log_chain_event(db, acct, ev); tags[0] = CHANNEL_OPEN; - maybe_update_account(db, acct, ev, tags, 0); + maybe_update_account(db, acct, ev, tags, 0, NULL); ev = make_chain_event(ctx, "channel_close", AMOUNT_MSAT(0), @@ -519,7 +521,7 @@ static bool test_onchain_fee_chan_close(const tal_t *ctx, struct plugin *p) /* Update the account to have the right info! */ tags[0] = CHANNEL_CLOSE; - maybe_update_account(db, acct, ev, tags, close_output_count); + maybe_update_account(db, acct, ev, tags, close_output_count, NULL); log_chain_event(db, acct, make_chain_event(ctx, "delayed_to_us", @@ -1169,15 +1171,16 @@ static bool test_account_balances(const tal_t *ctx, struct plugin *p) static bool test_account_crud(const tal_t *ctx, struct plugin *p) { struct db *db = db_setup(ctx, p, tmp_dsn(ctx)); - struct node_id peer_id; + struct node_id *peer_id; struct account *acct, *acct2, **acct_list; struct chain_event *ev1; enum mvt_tag *tags; char *name = tal_fmt(ctx, "example"); - memset(&peer_id, 3, sizeof(struct node_id)); + peer_id = tal(ctx, struct node_id); + memset(peer_id, 3, sizeof(struct node_id)); - acct = new_account(ctx, name, &peer_id); + acct = new_account(ctx, name, NULL); CHECK(!acct->is_wallet); db_begin_transaction(db); @@ -1192,7 +1195,7 @@ static bool test_account_crud(const tal_t *ctx, struct plugin *p) CHECK(tal_count(acct_list) == 1); accountseq(acct_list[0], acct); - acct = new_account(ctx, tal_fmt(ctx, "wallet"), &peer_id); + acct = new_account(ctx, tal_fmt(ctx, "wallet"), NULL); CHECK(acct->is_wallet); db_begin_transaction(db); @@ -1239,7 +1242,7 @@ static bool test_account_crud(const tal_t *ctx, struct plugin *p) /* should not update the account info */ tags[0] = PUSHED; tags[1] = PENALTY; - maybe_update_account(db, acct, ev1, tags, 0); + maybe_update_account(db, acct, ev1, tags, 0, peer_id); acct2 = find_account(ctx, db, "wallet"); accountseq(acct, acct2); @@ -1248,7 +1251,7 @@ static bool test_account_crud(const tal_t *ctx, struct plugin *p) CHECK(acct->open_event_db_id == NULL); tags[0] = CHANNEL_OPEN; tags[1] = LEASED; - maybe_update_account(db, acct, ev1, tags, 2); + maybe_update_account(db, acct, ev1, tags, 2, peer_id); acct2 = find_account(ctx, db, "wallet"); accountseq(acct, acct2); CHECK(acct->leased); @@ -1259,7 +1262,7 @@ static bool test_account_crud(const tal_t *ctx, struct plugin *p) tags[1] = OPENER; CHECK(acct->closed_event_db_id == NULL); CHECK(!acct->we_opened); - maybe_update_account(db, acct, ev1, tags, 0); + maybe_update_account(db, acct, ev1, tags, 0, NULL); acct2 = find_account(ctx, db, "wallet"); accountseq(acct, acct2); CHECK(acct->closed_event_db_id != NULL);