Skip to content

Commit da33eb7

Browse files
committed
lightningd: db infrastructure for network events.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 8c2aaa7 commit da33eb7

File tree

9 files changed

+261
-5
lines changed

9 files changed

+261
-5
lines changed

lightningd/test/run-invoice-select-inchan.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,10 @@ bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNE
270270
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED, wirestring **connect_reason UNNEEDED, u64 *connect_nsec UNNEEDED)
271271
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
272272
/* Generated stub for fromwire_connectd_peer_disconnected */
273-
bool fromwire_connectd_peer_disconnected(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u64 *connect_time_nsec UNNEEDED)
273+
bool fromwire_connectd_peer_disconnected(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u64 *connected_time_nsec UNNEEDED)
274274
{ fprintf(stderr, "fromwire_connectd_peer_disconnected called!\n"); abort(); }
275275
/* Generated stub for fromwire_connectd_peer_reconnected */
276-
bool fromwire_connectd_peer_reconnected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *prev_counter UNNEEDED, u64 *counter UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED, u64 *connect_time_nsec UNNEEDED)
276+
bool fromwire_connectd_peer_reconnected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *prev_counter UNNEEDED, u64 *counter UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED, u64 *connected_time_nsec UNNEEDED)
277277
{ fprintf(stderr, "fromwire_connectd_peer_reconnected called!\n"); abort(); }
278278
/* Generated stub for fromwire_connectd_peer_spoke */
279279
bool fromwire_connectd_peer_spoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u16 *msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED, wirestring **error UNNEEDED)

lightningd/wait.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const char *wait_subsystem_name(enum wait_subsystem subsystem);
4646
* Increase index, write to db, wake any waiters, give them any name/value pairs.
4747
* If the value is NULL, omit that name.
4848
* If the name starts with '=', the value is a JSON literal (and skip over the =)
49+
* If the value is "", use the resulting index value.
4950
*
5051
* Returns the updated index value (always > 0).
5152
*/

wallet/db.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,17 @@ static struct migration dbmigrations[] = {
10871087
{SQL("CREATE INDEX chain_moves_utxo_idx ON chain_moves (utxo)"), NULL},
10881088
{NULL, migrate_from_account_db},
10891089
/* We accidentally allowed duplicate entries */
1090-
{NULL, migrate_remove_chain_moves_duplicates}
1090+
{NULL, migrate_remove_chain_moves_duplicates},
1091+
{SQL("CREATE TABLE network_events ("
1092+
" id BIGSERIAL,"
1093+
" peer_id BLOB NOT NULL,"
1094+
" type INTEGER NOT NULL,"
1095+
" timestamp BIGINT,"
1096+
" reason TEXT,"
1097+
" duration_nsec BIGINT,"
1098+
" connect_attempted INTEGER NOT NULL,"
1099+
" PRIMARY KEY (id)"
1100+
")"), NULL},
10911101
};
10921102

10931103
/**

wallet/test/run-chain_moves_duplicate-detect.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,13 @@ u8 *towire_hsmd_get_output_scriptpubkey(const tal_t *ctx UNNEEDED, u64 channel_i
351351
/* Generated stub for txfilter_add_scriptpubkey */
352352
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES UNNEEDED)
353353
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }
354+
/* Generated stub for wait_index_increment */
355+
u64 wait_index_increment(struct lightningd *ld UNNEEDED,
356+
struct db *db UNNEEDED,
357+
enum wait_subsystem subsystem UNNEEDED,
358+
enum wait_index index UNNEEDED,
359+
...)
360+
{ fprintf(stderr, "wait_index_increment called!\n"); abort(); }
354361
/* Generated stub for wait_index_name */
355362
const char *wait_index_name(enum wait_index index UNNEEDED)
356363
{ fprintf(stderr, "wait_index_name called!\n"); abort(); }

wallet/test/run-db.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,13 @@ u8 *towire_hsmd_get_output_scriptpubkey(const tal_t *ctx UNNEEDED, u64 channel_i
364364
/* Generated stub for txfilter_add_scriptpubkey */
365365
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES UNNEEDED)
366366
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }
367+
/* Generated stub for wait_index_increment */
368+
u64 wait_index_increment(struct lightningd *ld UNNEEDED,
369+
struct db *db UNNEEDED,
370+
enum wait_subsystem subsystem UNNEEDED,
371+
enum wait_index index UNNEEDED,
372+
...)
373+
{ fprintf(stderr, "wait_index_increment called!\n"); abort(); }
367374
/* Generated stub for wait_index_name */
368375
const char *wait_index_name(enum wait_index index UNNEEDED)
369376
{ fprintf(stderr, "wait_index_name called!\n"); abort(); }

wallet/test/run-migrate_remove_chain_moves_duplicates.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,13 @@ u8 *towire_hsmd_get_output_scriptpubkey(const tal_t *ctx UNNEEDED, u64 channel_i
374374
/* Generated stub for txfilter_add_scriptpubkey */
375375
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES UNNEEDED)
376376
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }
377+
/* Generated stub for wait_index_increment */
378+
u64 wait_index_increment(struct lightningd *ld UNNEEDED,
379+
struct db *db UNNEEDED,
380+
enum wait_subsystem subsystem UNNEEDED,
381+
enum wait_index index UNNEEDED,
382+
...)
383+
{ fprintf(stderr, "wait_index_increment called!\n"); abort(); }
377384
/* Generated stub for wait_index_name */
378385
const char *wait_index_name(enum wait_index index UNNEEDED)
379386
{ fprintf(stderr, "wait_index_name called!\n"); abort(); }

wallet/test/run-wallet.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,10 @@ bool fromwire_channeld_sending_commitsig(const tal_t *ctx UNNEEDED, const void *
302302
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED, wirestring **connect_reason UNNEEDED, u64 *connect_nsec UNNEEDED)
303303
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
304304
/* Generated stub for fromwire_connectd_peer_disconnected */
305-
bool fromwire_connectd_peer_disconnected(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u64 *connect_time_nsec UNNEEDED)
305+
bool fromwire_connectd_peer_disconnected(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u64 *connected_time_nsec UNNEEDED)
306306
{ fprintf(stderr, "fromwire_connectd_peer_disconnected called!\n"); abort(); }
307307
/* Generated stub for fromwire_connectd_peer_reconnected */
308-
bool fromwire_connectd_peer_reconnected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *prev_counter UNNEEDED, u64 *counter UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED, u64 *connect_time_nsec UNNEEDED)
308+
bool fromwire_connectd_peer_reconnected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *prev_counter UNNEEDED, u64 *counter UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED, u64 *connected_time_nsec UNNEEDED)
309309
{ fprintf(stderr, "fromwire_connectd_peer_reconnected called!\n"); abort(); }
310310
/* Generated stub for fromwire_connectd_peer_spoke */
311311
bool fromwire_connectd_peer_spoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u16 *msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED, wirestring **error UNNEEDED)

wallet/wallet.c

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7423,6 +7423,155 @@ struct db_stmt *wallet_channel_moves_next(struct wallet *wallet, struct db_stmt
74237423
return stmt;
74247424
}
74257425

7426+
struct db_stmt *wallet_network_events_first(struct wallet *w,
7427+
const struct node_id *specific_id,
7428+
u64 liststart,
7429+
u32 *listlimit)
7430+
{
7431+
struct db_stmt *stmt;
7432+
7433+
if (specific_id) {
7434+
stmt = db_prepare_v2(w->db,
7435+
SQL("SELECT"
7436+
" id"
7437+
", peer_id"
7438+
", type"
7439+
", reason"
7440+
", timestamp"
7441+
", duration_nsec"
7442+
", connect_attempted"
7443+
" FROM network_events"
7444+
" WHERE peer_id = ? AND id >= ?"
7445+
" ORDER BY id"
7446+
" LIMIT ?;"));
7447+
db_bind_node_id(stmt, specific_id);
7448+
} else {
7449+
stmt = db_prepare_v2(w->db,
7450+
SQL("SELECT"
7451+
" id"
7452+
", peer_id"
7453+
", type"
7454+
", reason"
7455+
", timestamp"
7456+
", duration_nsec"
7457+
", connect_attempted"
7458+
" FROM network_events"
7459+
" WHERE id >= ?"
7460+
" ORDER BY id"
7461+
" LIMIT ?;"));
7462+
}
7463+
db_bind_u64(stmt, liststart);
7464+
if (listlimit)
7465+
db_bind_int(stmt, *listlimit);
7466+
else
7467+
db_bind_int(stmt, INT_MAX);
7468+
db_query_prepared(stmt);
7469+
return wallet_channel_moves_next(w, stmt);
7470+
}
7471+
7472+
const char *network_event_name(enum network_event n)
7473+
{
7474+
switch (n) {
7475+
case NETWORK_EVENT_CONNECT:
7476+
return "connect";
7477+
case NETWORK_EVENT_CONNECTFAIL:
7478+
return "connect_fail";
7479+
case NETWORK_EVENT_PING:
7480+
return "ping";
7481+
case NETWORK_EVENT_DISCONNECT:
7482+
return "disconnect";
7483+
}
7484+
fatal("%s: %u is invalid", __func__, n);
7485+
}
7486+
7487+
struct db_stmt *wallet_network_events_next(struct wallet *w,
7488+
struct db_stmt *stmt)
7489+
{
7490+
if (!db_step(stmt))
7491+
return tal_free(stmt);
7492+
7493+
return stmt;
7494+
}
7495+
7496+
void wallet_network_events_extract(const tal_t *ctx,
7497+
struct db_stmt *stmt,
7498+
u64 *id,
7499+
struct node_id *peer_id,
7500+
u64 *timestamp,
7501+
enum network_event *etype,
7502+
const char **reason,
7503+
u64 *duration_nsec,
7504+
bool *connect_attempted)
7505+
{
7506+
*id = db_col_u64(stmt, "id");
7507+
db_col_node_id(stmt, "peer_id", peer_id);
7508+
*etype = network_event_in_db(db_col_int(stmt, "type"));
7509+
*timestamp = db_col_u64(stmt, "timestamp");
7510+
*reason = db_col_strdup_optional(ctx, stmt, "reason");
7511+
*duration_nsec = db_col_u64(stmt, "duration_nsec");
7512+
*connect_attempted = db_col_u64(stmt, "connect_attempted");
7513+
}
7514+
7515+
static u64 network_event_index_inc(struct lightningd *ld,
7516+
/* NULL means it's being created */
7517+
const u64 *created_index,
7518+
const enum network_event *etype,
7519+
const struct node_id *peer_id,
7520+
enum wait_index idx)
7521+
{
7522+
return wait_index_increment(ld, ld->wallet->db,
7523+
WAIT_SUBSYSTEM_NETWORKEVENTS, idx,
7524+
/* "" is a magic value meaning 'current val' */
7525+
"=created_index", created_index ? tal_fmt(tmpctx, "%"PRIu64, *created_index) : "",
7526+
"type", etype ? network_event_name(*etype) : NULL,
7527+
"peer_id", peer_id ? fmt_node_id(tmpctx, peer_id) : NULL,
7528+
NULL);
7529+
}
7530+
7531+
static u64 network_event_index_created(struct lightningd *ld,
7532+
enum network_event etype,
7533+
const struct node_id *peer_id)
7534+
{
7535+
return network_event_index_inc(ld, NULL,
7536+
&etype, peer_id,
7537+
WAIT_INDEX_CREATED);
7538+
}
7539+
7540+
/* Put the next network event into the db */
7541+
void wallet_save_network_event(struct lightningd *ld,
7542+
const struct node_id *peer_id,
7543+
enum network_event etype,
7544+
const char *reason,
7545+
u64 duration_nsec,
7546+
bool connect_attempted)
7547+
{
7548+
u64 id;
7549+
struct db_stmt *stmt;
7550+
7551+
stmt = db_prepare_v2(ld->wallet->db,
7552+
SQL("INSERT INTO network_events ("
7553+
" id,"
7554+
" peer_id,"
7555+
" type, "
7556+
" timestamp,"
7557+
" reason,"
7558+
" duration_nsec,"
7559+
" connect_attempted) VALUES "
7560+
"(?, ?, ?, ?, ?, ?, ?);"));
7561+
id = network_event_index_created(ld, etype, peer_id);
7562+
db_bind_u64(stmt, id);
7563+
db_bind_node_id(stmt, peer_id);
7564+
db_bind_int(stmt, network_event_in_db(etype));
7565+
db_bind_u64(stmt, time_now().ts.tv_sec);
7566+
if (reason)
7567+
db_bind_text(stmt, reason);
7568+
else
7569+
db_bind_null(stmt);
7570+
db_bind_u64(stmt, duration_nsec);
7571+
db_bind_int(stmt, connect_attempted);
7572+
db_exec_prepared_v2(take(stmt));
7573+
}
7574+
74267575
struct missing {
74277576
size_t num_found;
74287577
struct missing_addr *addrs;

wallet/wallet.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,6 +1875,81 @@ struct issued_address_type *wallet_list_addresses(const tal_t *ctx, struct walle
18751875
u64 liststart, const u32 *listlimit);
18761876

18771877

1878+
enum network_event {
1879+
NETWORK_EVENT_CONNECT = 1,
1880+
NETWORK_EVENT_CONNECTFAIL = 2,
1881+
NETWORK_EVENT_PING = 3,
1882+
NETWORK_EVENT_DISCONNECT = 4,
1883+
};
1884+
1885+
static inline enum network_event network_event_in_db(enum network_event n)
1886+
{
1887+
switch (n) {
1888+
case NETWORK_EVENT_CONNECT:
1889+
BUILD_ASSERT(NETWORK_EVENT_CONNECT == 1);
1890+
return n;
1891+
case NETWORK_EVENT_CONNECTFAIL:
1892+
BUILD_ASSERT(NETWORK_EVENT_CONNECTFAIL == 2);
1893+
return n;
1894+
case NETWORK_EVENT_PING:
1895+
BUILD_ASSERT(NETWORK_EVENT_PING == 3);
1896+
return n;
1897+
case NETWORK_EVENT_DISCONNECT:
1898+
BUILD_ASSERT(NETWORK_EVENT_DISCONNECT == 4);
1899+
return n;
1900+
}
1901+
fatal("%s: %u is invalid", __func__, n);
1902+
}
1903+
1904+
const char *network_event_name(enum network_event n);
1905+
1906+
/**
1907+
* Iterate through the network events.
1908+
* @w: the wallet
1909+
* @specific_id: filter by peer_id if non-NULL.
1910+
* @liststart: first index to return (0 == all).
1911+
* @listlimit: limit on number of entries to return (NULL == no limit).
1912+
*
1913+
* Returns pointer to hand as @stmt to wallet_network_events_next(), or NULL.
1914+
* If you choose not to call wallet_network_events_next() you must free it!
1915+
*/
1916+
struct db_stmt *wallet_network_events_first(struct wallet *w,
1917+
const struct node_id *specific_id,
1918+
u64 liststart,
1919+
u32 *listlimit);
1920+
struct db_stmt *wallet_network_events_next(struct wallet *w,
1921+
struct db_stmt *stmt);
1922+
1923+
/**
1924+
* Extract a network event from the db.
1925+
* @ctx: the tal ctx to allocate off
1926+
* @stmt: the db_stmt from wallet_network_events_first/next
1927+
* @id: the creation key
1928+
* @peer_id: the peer we're talking to
1929+
* @timestamp: the time the event was recorded
1930+
* @etype: the network_event type
1931+
* @reason: the optional reason (or set to NULL)
1932+
* @duration_nsec: the time it took (if applicable).
1933+
* @connect_attempted: whether we attempted at least one address (for NETWORK_EVENT_CONNECTFAIL)
1934+
*/
1935+
void wallet_network_events_extract(const tal_t *ctx,
1936+
struct db_stmt *stmt,
1937+
u64 *id,
1938+
struct node_id *peer_id,
1939+
u64 *timestamp,
1940+
enum network_event *etype,
1941+
const char **reason,
1942+
u64 *duration_nsec,
1943+
bool *connect_attempted);
1944+
1945+
/* Put the next network event into the db */
1946+
void wallet_save_network_event(struct lightningd *ld,
1947+
const struct node_id *peer_id,
1948+
enum network_event etype,
1949+
const char *reason,
1950+
u64 duration_nsec,
1951+
bool connect_attempted);
1952+
18781953
/**
18791954
* wallet_begin_old_close_rescan: rescan for missing mutual close p2wpkh outputs.
18801955
*

0 commit comments

Comments
 (0)