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