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);