Browse Source

wallet: Track some channel usage statistics.

Fixes: #1049
ppa-0.6.1
ZmnSCPxj 7 years ago
committed by Rusty Russell
parent
commit
0bb9bcc0f1
  1. 23
      lightningd/peer_control.c
  2. 27
      lightningd/peer_htlcs.c
  3. 16
      wallet/db.c
  4. 62
      wallet/wallet.c
  5. 29
      wallet/wallet.h

23
lightningd/peer_control.c

@ -625,6 +625,7 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg,
list_for_each(&gpa->cmd->ld->peers, p, list) {
bool connected;
struct channel *channel;
struct channel_stats channel_stats;
if (gpa->specific_id && !pubkey_eq(gpa->specific_id, &p->id))
continue;
@ -712,6 +713,28 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg,
json_add_string(response, NULL,
channel->billboard.transient);
json_array_end(response);
/* Provide channel statistics */
wallet_channel_stats_load(gpa->cmd->ld->wallet,
channel->dbid,
&channel_stats);
json_add_u64(response, "in_payments_offered",
channel_stats.in_payments_offered);
json_add_u64(response, "in_msatoshi_offered",
channel_stats.in_msatoshi_offered);
json_add_u64(response, "in_payments_fulfilled",
channel_stats.in_payments_fulfilled);
json_add_u64(response, "in_msatoshi_fulfilled",
channel_stats.in_msatoshi_fulfilled);
json_add_u64(response, "out_payments_offered",
channel_stats.out_payments_offered);
json_add_u64(response, "out_msatoshi_offered",
channel_stats.out_msatoshi_offered);
json_add_u64(response, "out_payments_fulfilled",
channel_stats.out_payments_fulfilled);
json_add_u64(response, "out_msatoshi_fulfilled",
channel_stats.out_msatoshi_fulfilled);
json_object_end(response);
}
json_array_end(response);

27
lightningd/peer_htlcs.c

@ -199,26 +199,32 @@ static bool check_cltv(struct htlc_in *hin,
static void fulfill_htlc(struct htlc_in *hin, const struct preimage *preimage)
{
u8 *msg;
struct channel *channel = hin->key.channel;
struct wallet *wallet = channel->peer->ld->wallet;
hin->preimage = tal_dup(hin, struct preimage, preimage);
htlc_in_check(hin, __func__);
/* We update state now to signal it's in progress, for persistence. */
htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC);
htlc_in_update_state(channel, hin, SENT_REMOVE_HTLC);
/* Update channel stats */
wallet_channel_stats_incr_in_fulfilled(wallet,
channel->dbid,
hin->msatoshi);
/* No owner? We'll either send to channeld in peer_htlcs, or
* onchaind in onchaind_tell_fulfill. */
if (!hin->key.channel->owner) {
log_debug(hin->key.channel->log, "HTLC fulfilled, but no owner.");
if (!channel->owner) {
log_debug(channel->log, "HTLC fulfilled, but no owner.");
return;
}
if (channel_on_chain(hin->key.channel)) {
if (channel_on_chain(channel)) {
msg = towire_onchain_known_preimage(hin, preimage);
} else {
msg = towire_channel_fulfill_htlc(hin, hin->key.id, preimage);
}
subd_send_msg(hin->key.channel->owner, take(msg));
subd_send_msg(channel->owner, take(msg));
}
static void handle_localpay(struct htlc_in *hin,
@ -665,6 +671,10 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout,
htlc_out_check(hout, __func__);
wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, preimage);
/* Update channel stats */
wallet_channel_stats_incr_out_fulfilled(ld->wallet,
channel->dbid,
hout->msatoshi);
if (hout->in)
fulfill_htlc(hout->in, preimage);
@ -889,6 +899,10 @@ static bool update_out_htlc(struct channel *channel,
if (!hout->dbid) {
wallet_htlc_save_out(ld->wallet, channel, hout);
/* Update channel stats */
wallet_channel_stats_incr_out_offered(ld->wallet,
channel->dbid,
hout->msatoshi);
/* For our own HTLCs, we commit payment to db lazily */
if (hout->origin_htlc_id == 0)
@ -1053,6 +1067,9 @@ static bool channel_added_their_htlc(struct channel *channel,
/* Save an incoming htlc to the wallet */
wallet_htlc_save_in(ld->wallet, channel, hin);
/* Update channel stats */
wallet_channel_stats_incr_in_offered(ld->wallet, channel->dbid,
added->amount_msat);
log_debug(channel->log, "Adding their HTLC %"PRIu64, added->id);
connect_htlc_in(&channel->peer->ld->htlcs_in, hin);

16
wallet/db.c

@ -251,6 +251,22 @@ char *dbmigrations[] = {
" , route_nodes = NULL"
" , route_channels = NULL"
" WHERE status <> 0;", /* PAYMENT_PENDING */
/* -- Routing statistics -- */
"ALTER TABLE channels ADD in_payments_offered INTEGER;",
"ALTER TABLE channels ADD in_payments_fulfilled INTEGER;",
"ALTER TABLE channels ADD in_msatoshi_offered INTEGER;",
"ALTER TABLE channels ADD in_msatoshi_fulfilled INTEGER;",
"ALTER TABLE channels ADD out_payments_offered INTEGER;",
"ALTER TABLE channels ADD out_payments_fulfilled INTEGER;",
"ALTER TABLE channels ADD out_msatoshi_offered INTEGER;",
"ALTER TABLE channels ADD out_msatoshi_fulfilled INTEGER;",
"UPDATE channels"
" SET in_payments_offered = 0, in_payments_fulfilled = 0"
" , in_msatoshi_offered = 0, in_msatoshi_fulfilled = 0"
" , out_payments_offered = 0, out_payments_fulfilled = 0"
" , out_msatoshi_offered = 0, out_msatoshi_fulfilled = 0"
" ;",
/* -- Routing statistics ends --*/
NULL,
};

62
wallet/wallet.c

@ -719,6 +719,68 @@ bool wallet_channels_load_active(const tal_t *ctx, struct wallet *w)
return ok;
}
static
void wallet_channel_stats_incr_x(struct wallet *w,
char const *dir,
char const *typ,
u64 cdbid,
u64 msatoshi)
{
char const *payments_stat = tal_fmt(tmpctx, "%s_payments_%s",
dir, typ);
char const *msatoshi_stat = tal_fmt(tmpctx, "%s_msatoshi_%s",
dir, typ);
char const *qry = tal_fmt(tmpctx,
"UPDATE channels"
" SET %s = COALESCE(%s, 0) + 1"
" , %s = COALESCE(%s, 0) + %"PRIu64""
" WHERE id = %"PRIu64";",
payments_stat, payments_stat,
msatoshi_stat, msatoshi_stat, msatoshi,
cdbid);
sqlite3_stmt *stmt = db_prepare(w->db, qry);
db_exec_prepared(w->db, stmt);
}
void wallet_channel_stats_incr_in_offered(struct wallet *w, u64 id, u64 m)
{
wallet_channel_stats_incr_x(w, "in", "offered", id, m);
}
void wallet_channel_stats_incr_in_fulfilled(struct wallet *w, u64 id, u64 m)
{
wallet_channel_stats_incr_x(w, "in", "fulfilled", id, m);
}
void wallet_channel_stats_incr_out_offered(struct wallet *w, u64 id, u64 m)
{
wallet_channel_stats_incr_x(w, "out", "offered", id, m);
}
void wallet_channel_stats_incr_out_fulfilled(struct wallet *w, u64 id, u64 m)
{
wallet_channel_stats_incr_x(w, "out", "fulfilled", id, m);
}
void wallet_channel_stats_load(struct wallet *w,
u64 id,
struct channel_stats *stats)
{
sqlite3_stmt *stmt;
stmt = db_prepare(w->db,
"SELECT in_payments_offered, in_payments_fulfilled"
" , in_msatoshi_offered, in_msatoshi_fulfilled"
" , out_payments_offered, out_payments_fulfilled"
" , out_msatoshi_offered, out_msatoshi_fulfilled"
" FROM channels"
" WHERE id = ?");
sqlite3_bind_int64(stmt, 1, id);
stats->in_payments_offered = sqlite3_column_int64(stmt, 0);
stats->in_payments_fulfilled = sqlite3_column_int64(stmt, 1);
stats->in_msatoshi_offered = sqlite3_column_int64(stmt, 2);
stats->in_msatoshi_fulfilled = sqlite3_column_int64(stmt, 3);
stats->out_payments_offered = sqlite3_column_int64(stmt, 4);
stats->out_payments_fulfilled = sqlite3_column_int64(stmt, 5);
stats->out_msatoshi_offered = sqlite3_column_int64(stmt, 6);
stats->out_msatoshi_fulfilled = sqlite3_column_int64(stmt, 7);
}
#ifdef COMPAT_V052
/* Upgrade of db (or initial create): do we have anything to scan for? */
static bool wallet_ever_used(struct wallet *w)

29
wallet/wallet.h

@ -119,6 +119,14 @@ struct outpoint {
u32 spendheight;
};
/* Statistics for a channel */
struct channel_stats {
u64 in_payments_offered, in_payments_fulfilled;
u64 in_msatoshi_offered, in_msatoshi_fulfilled;
u64 out_payments_offered, out_payments_fulfilled;
u64 out_msatoshi_offered, out_msatoshi_fulfilled;
};
/**
* wallet_new - Constructor for a new sqlite3 based wallet
*
@ -286,6 +294,27 @@ bool wallet_peer_by_nodeid(struct wallet *w, const struct pubkey *nodeid,
*/
bool wallet_channels_load_active(const tal_t *ctx, struct wallet *w);
/**
* wallet_channel_stats_incr_* - Increase channel statistics.
*
* @w: wallet containing the channel
* @cdbid: channel database id
* @msatoshi: amount in msatoshi being transferred
*/
void wallet_channel_stats_incr_in_offered(struct wallet *w, u64 cdbid, u64 msatoshi);
void wallet_channel_stats_incr_in_fulfilled(struct wallet *w, u64 cdbid, u64 msatoshi);
void wallet_channel_stats_incr_out_offered(struct wallet *w, u64 cdbid, u64 msatoshi);
void wallet_channel_stats_incr_out_fulfilled(struct wallet *w, u64 cdbid, u64 msatoshi);
/**
* wallet_channel_stats_load - Load channel statistics
*
* @w: wallet containing the channel
* @cdbid: channel database id
* @stats: location to load statistics to
*/
void wallet_channel_stats_load(struct wallet *w, u64 cdbid, struct channel_stats *stats);
/**
* wallet_first_blocknum - get first block we're interested in.
*

Loading…
Cancel
Save