balance snap: first pass

This commit is contained in:
niftynei 2021-12-13 16:44:32 -06:00 committed by Rusty Russell
parent 5570c6da08
commit ec991e3af7
7 changed files with 118 additions and 1 deletions

View File

@ -7,7 +7,6 @@
#include <common/type_to_string.h>
#include <wire/wire.h>
#define WALLET "wallet"
#define EXTERNAL "external"
static const char *mvt_types[] = { "chain_mvt", "channel_mvt" };

View File

@ -7,6 +7,7 @@
#include <common/utils.h>
#define COIN_MVT_VERSION 2
#define WALLET "wallet"
enum mvt_type {
CHAIN_MVT = 0,

View File

@ -629,6 +629,10 @@ static void updates_complete(struct chain_topology *topo)
"last_processed_block", topo->tip->height);
topo->prev_tip = topo->tip->blkid;
/* Send out an account balance snapshot */
/* FIXME: only issue on first updates_complete call */
send_account_balance_snapshot(topo->ld, topo->tip->height);
}
/* If bitcoind is synced, we're now synced. */

View File

@ -1,8 +1,12 @@
#include "config.h"
#include <ccan/array_size/array_size.h>
#include <common/onion.h>
#include <common/type_to_string.h>
#include <lightningd/channel.h>
#include <lightningd/coin_mvts.h>
#include <lightningd/notification.h>
#include <lightningd/peer_control.h>
void notify_channel_mvt(struct lightningd *ld, const struct channel_coin_mvt *mvt)
{
@ -76,3 +80,55 @@ struct channel_coin_mvt *new_channel_mvt_routed_hout(const tal_t *ctx,
false,
hout->fees);
}
void send_account_balance_snapshot(struct lightningd *ld, u32 blockheight)
{
struct balance_snapshot *snap = tal(NULL, struct balance_snapshot);
struct account_balance *bal;
struct utxo **utxos;
struct channel *chan;
struct peer *p;
/* Available + reserved utxos are A+, as reserved things have not yet
* been spent */
enum output_status utxo_states[] = {OUTPUT_STATE_AVAILABLE,
OUTPUT_STATE_RESERVED};
snap->blockheight = blockheight;
snap->timestamp = time_now().ts.tv_sec;
snap->node_id = &ld->id;
/* Add the 'wallet' account balance */
snap->accts = tal_arr(snap, struct account_balance *, 1);
bal = tal(snap, struct account_balance);
bal->acct_id = WALLET;
bal->bip173_name = chainparams->lightning_hrp;
for (size_t i = 0; i < ARRAY_SIZE(utxo_states); i++) {
utxos = wallet_get_utxos(NULL, ld->wallet, utxo_states[i]);
for (size_t j = 0; j < tal_count(utxos); j++) {
if (!amount_msat_add_sat(&bal->balance,
bal->balance, utxos[j]->amount))
fatal("Overflow adding node balance");
}
tal_free(utxos);
}
snap->accts[0] = bal;
/* Add channel balances */
list_for_each(&ld->peers, p, list) {
list_for_each(&p->channels, chan, list) {
if (channel_active(chan)) {
bal = tal(snap, struct account_balance);
bal->bip173_name = chainparams->lightning_hrp;
bal->acct_id = type_to_string(bal,
struct channel_id,
&chan->cid);
bal->balance = chan->our_msat;
tal_arr_expand(&snap->accts, bal);
}
}
}
notify_balance_snapshot(ld, snap);
tal_free(snap);
}

View File

@ -5,6 +5,20 @@
#include <common/coin_mvt.h>
#include <lightningd/lightningd.h>
struct account_balance {
const char *acct_id;
const char *bip173_name;
struct amount_msat balance;
};
struct balance_snapshot {
struct node_id *node_id;
u32 blockheight;
u32 timestamp;
struct account_balance **accts;
};
void notify_channel_mvt(struct lightningd *ld, const struct channel_coin_mvt *mvt);
void notify_chain_mvt(struct lightningd *ld, const struct chain_coin_mvt *mvt);
@ -21,4 +35,5 @@ struct channel_coin_mvt *new_channel_mvt_routed_hout(const tal_t *ctx,
struct htlc_out *hout,
struct channel *channel);
void send_account_balance_snapshot(struct lightningd *ld, u32 blockheight);
#endif /* LIGHTNING_LIGHTNINGD_COIN_MVTS_H */

View File

@ -2,6 +2,7 @@
#include <common/json_helpers.h>
#include <common/type_to_string.h>
#include <lightningd/channel.h>
#include <lightningd/coin_mvts.h>
#include <lightningd/notification.h>
static struct notification *find_notification_by_topic(const char* topic)
@ -513,6 +514,43 @@ void notify_coin_mvt(struct lightningd *ld,
plugins_notify(ld->plugins, take(n));
}
static void balance_snapshot_notification_serialize(struct json_stream *stream, struct balance_snapshot *snap)
{
json_object_start(stream, "balance_snapshot");
json_add_node_id(stream, "node_id", snap->node_id);
json_add_u32(stream, "blockheight", snap->blockheight);
json_add_u32(stream, "timestamp", snap->timestamp);
json_array_start(stream, "accounts");
for (size_t i = 0; i < tal_count(snap->accts); i++) {
json_object_start(stream, NULL);
json_add_string(stream, "account_id",
snap->accts[i]->acct_id);
json_add_amount_msat_only(stream, "balance",
snap->accts[i]->balance);
json_add_string(stream, "coin_type", snap->accts[i]->bip173_name);
json_object_end(stream);
}
json_array_end(stream);
json_object_end(stream);
}
REGISTER_NOTIFICATION(balance_snapshot,
balance_snapshot_notification_serialize);
void notify_balance_snapshot(struct lightningd *ld,
const struct balance_snapshot *snap)
{
void (*serialize)(struct json_stream *,
const struct balance_snapshot *) = balance_snapshot_notification_gen.serialize;
struct jsonrpc_notification *n =
jsonrpc_notification_start(NULL, "balance_snapshot");
serialize(n->stream, snap);
jsonrpc_notification_end(n);
plugins_notify(ld->plugins, take(n));
}
static void openchannel_peer_sigs_serialize(struct json_stream *stream,
const struct channel_id *cid,
const struct wally_psbt *psbt)

View File

@ -5,6 +5,7 @@
#include <lightningd/pay.h>
#include <lightningd/plugin.h>
struct balance_snapshot;
struct onionreply;
struct wally_psbt;
@ -81,6 +82,9 @@ void notify_sendpay_failure(struct lightningd *ld,
void notify_coin_mvt(struct lightningd *ld,
const struct coin_mvt *mvt);
void notify_balance_snapshot(struct lightningd *ld,
const struct balance_snapshot *snap);
void notify_openchannel_peer_sigs(struct lightningd *ld,
const struct channel_id *cid,
const struct wally_psbt *psbt);