Skip to content

Commit 13571b5

Browse files
rustyrussellendothermicdev
authored andcommitted
lightningd: db infrastructure for network events.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent c568bd2 commit 13571b5

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
@@ -273,10 +273,10 @@ bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNE
273273
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)
274274
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
275275
/* Generated stub for fromwire_connectd_peer_disconnected */
276-
bool fromwire_connectd_peer_disconnected(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u64 *connect_time_nsec UNNEEDED)
276+
bool fromwire_connectd_peer_disconnected(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u64 *connected_time_nsec UNNEEDED)
277277
{ fprintf(stderr, "fromwire_connectd_peer_disconnected called!\n"); abort(); }
278278
/* Generated stub for fromwire_connectd_peer_reconnected */
279-
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)
279+
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)
280280
{ fprintf(stderr, "fromwire_connectd_peer_reconnected called!\n"); abort(); }
281281
/* Generated stub for fromwire_connectd_peer_spoke */
282282
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
@@ -354,6 +354,13 @@ u8 *towire_hsmd_get_output_scriptpubkey(const tal_t *ctx UNNEEDED, u64 channel_i
354354
/* Generated stub for txfilter_add_scriptpubkey */
355355
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES UNNEEDED)
356356
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }
357+
/* Generated stub for wait_index_increment */
358+
u64 wait_index_increment(struct lightningd *ld UNNEEDED,
359+
struct db *db UNNEEDED,
360+
enum wait_subsystem subsystem UNNEEDED,
361+
enum wait_index index UNNEEDED,
362+
...)
363+
{ fprintf(stderr, "wait_index_increment called!\n"); abort(); }
357364
/* Generated stub for wait_index_name */
358365
const char *wait_index_name(enum wait_index index UNNEEDED)
359366
{ 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
@@ -367,6 +367,13 @@ u8 *towire_hsmd_get_output_scriptpubkey(const tal_t *ctx UNNEEDED, u64 channel_i
367367
/* Generated stub for txfilter_add_scriptpubkey */
368368
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES UNNEEDED)
369369
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }
370+
/* Generated stub for wait_index_increment */
371+
u64 wait_index_increment(struct lightningd *ld UNNEEDED,
372+
struct db *db UNNEEDED,
373+
enum wait_subsystem subsystem UNNEEDED,
374+
enum wait_index index UNNEEDED,
375+
...)
376+
{ fprintf(stderr, "wait_index_increment called!\n"); abort(); }
370377
/* Generated stub for wait_index_name */
371378
const char *wait_index_name(enum wait_index index UNNEEDED)
372379
{ 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
@@ -377,6 +377,13 @@ u8 *towire_hsmd_get_output_scriptpubkey(const tal_t *ctx UNNEEDED, u64 channel_i
377377
/* Generated stub for txfilter_add_scriptpubkey */
378378
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES UNNEEDED)
379379
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }
380+
/* Generated stub for wait_index_increment */
381+
u64 wait_index_increment(struct lightningd *ld UNNEEDED,
382+
struct db *db UNNEEDED,
383+
enum wait_subsystem subsystem UNNEEDED,
384+
enum wait_index index UNNEEDED,
385+
...)
386+
{ fprintf(stderr, "wait_index_increment called!\n"); abort(); }
380387
/* Generated stub for wait_index_name */
381388
const char *wait_index_name(enum wait_index index UNNEEDED)
382389
{ 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
@@ -7438,6 +7438,155 @@ struct db_stmt *wallet_channel_moves_next(struct wallet *wallet, struct db_stmt
74387438
return stmt;
74397439
}
74407440

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

wallet/wallet.h

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

18781878

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

0 commit comments

Comments
 (0)