Skip to content

Commit 0eb9962

Browse files
committed
gui: add name, country code to peer metrics table
1 parent d2d03d7 commit 0eb9962

File tree

8 files changed

+166
-134
lines changed

8 files changed

+166
-134
lines changed

book/api/websocket.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,8 @@ default, until an update is made.
15091509

15101510
- ("Stake", desc)
15111511
- ("Pubkey", desc)
1512+
- ("Name", desc)
1513+
- ("Country", desc)
15121514
- ("IP Addr", desc)
15131515
- ("Ingress Push", desc)
15141516
- ("Ingress Pull", desc)
@@ -1536,8 +1538,8 @@ direction of `0`. Not that the relative ordering of columns with
15361538
"key": "query_sort",
15371539
"id": 32,
15381540
"params": {
1539-
"col": ["IP Addr", "Pubkey", "Stake", "Egress Pull", "Egress Push", "Ingress Pull", "Ingress Push"],
1540-
"dir": [1, 0, 0, 0, 0, 0, 0],
1541+
"col": ["IP Addr", "Pubkey", "Name", "Country", "Stake", "Egress Pull", "Egress Push", "Ingress Pull", "Ingress Push"],
1542+
"dir": [1, 0, 0, 0, 0, 0, 0, 0, 0],
15411543
}
15421544
}
15431545
```

src/disco/gui/fd_gui.c

Lines changed: 1 addition & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
#include "../../disco/pack/fd_pack.h"
1313
#include "../../disco/pack/fd_pack_cost.h"
1414

15-
FD_IMPORT_BINARY( ipinfo, "src/disco/gui/ipinfo.bin" );
16-
#define IPINFO_MAX_NODES (1UL<<22UL) /* 4M nodes */
17-
1815
#include <stdio.h>
1916

2017
FD_FN_CONST ulong
@@ -25,77 +22,10 @@ fd_gui_align( void ) {
2522
FD_FN_CONST ulong
2623
fd_gui_footprint( void ) {
2724
ulong l = FD_LAYOUT_INIT;
28-
l = FD_LAYOUT_APPEND( l, fd_gui_align(), sizeof( fd_gui_t ) );
29-
l = FD_LAYOUT_APPEND( l, alignof(fd_gui_ipinfo_node_t), sizeof(fd_gui_ipinfo_node_t)*IPINFO_MAX_NODES );
25+
l = FD_LAYOUT_APPEND( l, fd_gui_align(), sizeof( fd_gui_t ) );
3026
return FD_LAYOUT_FINI( l, fd_gui_align() );
3127
}
3228

33-
static void
34-
build_ipinfo_trie( fd_gui_t * gui,
35-
fd_gui_ipinfo_node_t * nodes ) {
36-
gui->ipinfo.nodes = nodes;
37-
ulong country_code_cnt = FD_LOAD( ulong, ipinfo );
38-
FD_TEST( country_code_cnt && country_code_cnt<256UL ); /* 256 reserved for unknown */
39-
FD_TEST( ipinfo_sz>=8UL+country_code_cnt*2UL );
40-
41-
for( ulong i=0UL; i<country_code_cnt; i++ ) {
42-
fd_memcpy( gui->ipinfo.country_code[ i ], ipinfo+8UL+i*2UL, 2UL );
43-
gui->ipinfo.country_code[ i ][ 2 ] = '\0';
44-
}
45-
46-
ulong processed = 8UL+country_code_cnt*2UL;
47-
FD_TEST( !((ipinfo_sz-processed)%6UL) );
48-
FD_TEST( (ipinfo_sz-processed)/6UL<=IPINFO_MAX_NODES-1UL );
49-
50-
fd_gui_ipinfo_node_t * root = &nodes[ 0 ];
51-
root->left = NULL;
52-
root->right = NULL;
53-
root->has_prefix = 0;
54-
55-
ulong node_cnt = 1UL;
56-
while( processed<ipinfo_sz ) {
57-
uint ip_addr = fd_uint_bswap( FD_LOAD( uint, ipinfo+processed ) );
58-
uchar prefix_len = *( ipinfo+processed+4UL );
59-
FD_TEST( prefix_len<=32UL );
60-
uchar country_idx = *( ipinfo+processed+5UL );
61-
FD_TEST( country_idx<country_code_cnt );
62-
63-
fd_gui_ipinfo_node_t * node = root;
64-
for( uchar bit_pos=0; bit_pos<prefix_len; bit_pos++ ) {
65-
uchar bit = (ip_addr >> (31 - bit_pos)) & 1;
66-
67-
fd_gui_ipinfo_node_t * child;
68-
if( FD_LIKELY( !bit ) ) {
69-
child = node->left;
70-
if( FD_LIKELY( !child ) ) {
71-
FD_TEST( node_cnt<IPINFO_MAX_NODES );
72-
child = &nodes[ node_cnt++ ];
73-
child->left = NULL;
74-
child->right = NULL;
75-
child->has_prefix = 0;
76-
node->left = child;
77-
}
78-
} else {
79-
child = node->right;
80-
if( FD_LIKELY( !child ) ) {
81-
FD_TEST( node_cnt<IPINFO_MAX_NODES );
82-
child = &nodes[ node_cnt++ ];
83-
child->left = NULL;
84-
child->right = NULL;
85-
child->has_prefix = 0;
86-
node->right = child;
87-
}
88-
}
89-
node = child;
90-
}
91-
92-
node->has_prefix = 1;
93-
node->country_code_idx = country_idx;
94-
95-
processed += 6UL;
96-
}
97-
}
98-
9929
void *
10030
fd_gui_new( void * shmem,
10131
fd_http_server_t * http,
@@ -128,7 +58,6 @@ fd_gui_new( void * shmem,
12858

12959
FD_SCRATCH_ALLOC_INIT( l, shmem );
13060
fd_gui_t * gui = FD_SCRATCH_ALLOC_APPEND( l, fd_gui_align(), sizeof(fd_gui_t) );
131-
fd_gui_ipinfo_node_t * _nodes = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_gui_ipinfo_node_t), sizeof(fd_gui_ipinfo_node_t)*IPINFO_MAX_NODES );
13261

13362
gui->http = http;
13463
gui->topo = topo;
@@ -252,8 +181,6 @@ fd_gui_new( void * shmem,
252181
gui->summary.catch_up_repair_sz = 0UL;
253182
gui->summary.catch_up_turbine_sz = 0UL;
254183

255-
build_ipinfo_trie( gui, _nodes );
256-
257184
return gui;
258185
}
259186

src/disco/gui/fd_gui.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -666,11 +666,6 @@ struct fd_gui {
666666
fd_gui_scheduler_counts_t scheduler_counts_snap[ FD_GUI_SCHEDULER_COUNT_SNAP_CNT ][ 1 ];
667667
} summary;
668668

669-
struct {
670-
fd_gui_ipinfo_node_t * nodes;
671-
char country_code[ 512 ][ 3 ]; /* ISO 3166-1 alpha-2 country codes */
672-
} ipinfo;
673-
674669
fd_gui_slot_t slots[ FD_GUI_SLOTS_CNT ][ 1 ];
675670

676671
fd_gui_leader_slot_t leader_slots[ FD_GUI_LEADER_CNT ][ 1 ];

src/disco/gui/fd_gui_peers.c

Lines changed: 101 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#include "../../flamenco/gossip/fd_gossip_private.h"
77
#include "../../disco/metrics/fd_metrics_base.h"
88

9+
FD_IMPORT_BINARY( ipinfo, "src/disco/gui/ipinfo.bin" );
10+
#define IPINFO_MAX_NODES (1UL<<22UL) /* 4M nodes */
11+
912
#define LOGGING 0
1013

1114
FD_FN_CONST ulong
@@ -19,6 +22,7 @@ fd_gui_peers_align( void ) {
1922
a = fd_ulong_max( a, fd_gui_peers_node_pubkey_map_align() );
2023
a = fd_ulong_max( a, fd_gui_peers_node_sock_map_align() );
2124
a = fd_ulong_max( a, alignof(fd_gui_peers_ws_conn_t) );
25+
a = fd_ulong_max( a, alignof(fd_gui_ipinfo_node_t) );
2226
FD_TEST( fd_ulong_pow2_up( a )==a );
2327
return a;
2428
}
@@ -38,10 +42,86 @@ fd_gui_peers_footprint( ulong max_ws_conn_cnt ) {
3842
l = FD_LAYOUT_APPEND( l, fd_gui_peers_node_pubkey_map_align(), fd_gui_peers_node_pubkey_map_footprint ( pubkey_chain_cnt ) );
3943
l = FD_LAYOUT_APPEND( l, fd_gui_peers_node_sock_map_align(), fd_gui_peers_node_sock_map_footprint ( sock_chain_cnt ) );
4044
l = FD_LAYOUT_APPEND( l, alignof(fd_gui_peers_ws_conn_t), max_ws_conn_cnt*sizeof(fd_gui_peers_ws_conn_t) );
45+
l = FD_LAYOUT_APPEND( l, alignof(fd_gui_ipinfo_node_t), sizeof(fd_gui_ipinfo_node_t)*IPINFO_MAX_NODES );
4146

4247
return FD_LAYOUT_FINI( l, fd_gui_peers_align() );
4348
}
4449

50+
/* We sort the country codes so that fd_gui_peers_live_table can sort by
51+
table index instead of the codes themselves. */
52+
#define SORT_NAME fd_gui_country_code_sort
53+
#define SORT_KEY_T fd_gui_country_code_t
54+
#define SORT_BEFORE(a,b) (strcmp( (char *)&(a), (char *)&(b) ) < 0)
55+
#include "../../util/tmpl/fd_sort.c"
56+
57+
static void
58+
build_ipinfo_trie( fd_gui_peers_ctx_t * peers,
59+
fd_gui_ipinfo_node_t * nodes ) {
60+
peers->ipinfo.nodes = nodes;
61+
ulong country_code_cnt = FD_LOAD( ulong, ipinfo );
62+
FD_TEST( country_code_cnt && country_code_cnt<256UL ); /* 256 reserved for unknown */
63+
FD_TEST( ipinfo_sz>=8UL+country_code_cnt*2UL );
64+
65+
for( ulong i=0UL; i<country_code_cnt; i++ ) {
66+
fd_memcpy( peers->ipinfo.country_code[ i ].cc, ipinfo+8UL+i*2UL, 2UL );
67+
peers->ipinfo.country_code[ i ].cc[ 2 ] = '\0';
68+
}
69+
70+
fd_gui_country_code_sort_insert( peers->ipinfo.country_code, country_code_cnt );
71+
72+
ulong processed = 8UL+country_code_cnt*2UL;
73+
FD_TEST( !((ipinfo_sz-processed)%6UL) );
74+
FD_TEST( (ipinfo_sz-processed)/6UL<=IPINFO_MAX_NODES-1UL );
75+
76+
fd_gui_ipinfo_node_t * root = &nodes[ 0 ];
77+
root->left = NULL;
78+
root->right = NULL;
79+
root->has_prefix = 0;
80+
81+
ulong node_cnt = 1UL;
82+
while( processed<ipinfo_sz ) {
83+
uint ip_addr = fd_uint_bswap( FD_LOAD( uint, ipinfo+processed ) );
84+
uchar prefix_len = *( ipinfo+processed+4UL );
85+
FD_TEST( prefix_len<=32UL );
86+
uchar country_idx = *( ipinfo+processed+5UL );
87+
FD_TEST( country_idx<country_code_cnt );
88+
89+
fd_gui_ipinfo_node_t * node = root;
90+
for( uchar bit_pos=0; bit_pos<prefix_len; bit_pos++ ) {
91+
uchar bit = (ip_addr >> (31 - bit_pos)) & 1;
92+
93+
fd_gui_ipinfo_node_t * child;
94+
if( FD_LIKELY( !bit ) ) {
95+
child = node->left;
96+
if( FD_LIKELY( !child ) ) {
97+
FD_TEST( node_cnt<IPINFO_MAX_NODES );
98+
child = &nodes[ node_cnt++ ];
99+
child->left = NULL;
100+
child->right = NULL;
101+
child->has_prefix = 0;
102+
node->left = child;
103+
}
104+
} else {
105+
child = node->right;
106+
if( FD_LIKELY( !child ) ) {
107+
FD_TEST( node_cnt<IPINFO_MAX_NODES );
108+
child = &nodes[ node_cnt++ ];
109+
child->left = NULL;
110+
child->right = NULL;
111+
child->has_prefix = 0;
112+
node->right = child;
113+
}
114+
}
115+
node = child;
116+
}
117+
118+
node->has_prefix = 1;
119+
node->country_code_idx = country_idx;
120+
121+
processed += 6UL;
122+
}
123+
}
124+
45125
void *
46126
fd_gui_peers_new( void * shmem,
47127
fd_http_server_t * http,
@@ -71,6 +151,7 @@ fd_gui_peers_new( void * shmem,
71151
void * _pubkey_map = FD_SCRATCH_ALLOC_APPEND( l, fd_gui_peers_node_pubkey_map_align(), fd_gui_peers_node_pubkey_map_footprint ( pubkey_chain_cnt ) );
72152
void * _sock_map = FD_SCRATCH_ALLOC_APPEND( l, fd_gui_peers_node_sock_map_align(), fd_gui_peers_node_sock_map_footprint ( sock_chain_cnt ) );
73153
ctx->client_viewports = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_gui_peers_ws_conn_t), max_ws_conn_cnt*sizeof(fd_gui_peers_ws_conn_t) );
154+
void * _nodes = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_gui_ipinfo_node_t), sizeof(fd_gui_ipinfo_node_t)*IPINFO_MAX_NODES );
74155

75156
for( ulong i = 0UL; i<max_ws_conn_cnt; i++ ) ctx->client_viewports[ i ].connected = 0;
76157

@@ -101,6 +182,8 @@ fd_gui_peers_new( void * shmem,
101182
ctx->node_pubkey_map = fd_gui_peers_node_pubkey_map_join( fd_gui_peers_node_pubkey_map_new( _pubkey_map, pubkey_chain_cnt, 42UL ) );
102183
ctx->node_sock_map = fd_gui_peers_node_sock_map_join ( fd_gui_peers_node_sock_map_new ( _sock_map, sock_chain_cnt, 42UL ) );
103184

185+
build_ipinfo_trie( ctx, _nodes );
186+
104187
return shmem;
105188
}
106189

@@ -462,10 +545,8 @@ ipinfo_lookup( fd_gui_ipinfo_node_t const * nodes,
462545

463546
void
464547
fd_gui_peers_handle_gossip_update( fd_gui_peers_ctx_t * peers,
465-
fd_gui_ipinfo_node_t const * ipinfo_nodes,
466548
fd_gossip_update_message_t const * update,
467-
long now,
468-
char country_code_map[ static 512 ][ 3 ] ) {
549+
long now ) {
469550
switch( update->tag ) {
470551
case FD_GOSSIP_UPDATE_TAG_CONTACT_INFO: {
471552
#ifdef FD_GUI_USE_HANDHOLDING
@@ -523,7 +604,7 @@ fd_gui_peers_handle_gossip_update( fd_gui_peers_ctx_t * peers,
523604
peer->update_time_nanos = now;
524605
/* fetch and set country code */
525606
#if FD_HAS_ZSTD
526-
peer->country_code_idx = ipinfo_lookup( ipinfo_nodes, peer->contact_info.sockets[ FD_CONTACT_INFO_SOCKET_GOSSIP ].addr );
607+
peer->country_code_idx = ipinfo_lookup( peers->ipinfo.nodes, peer->contact_info.sockets[ FD_CONTACT_INFO_SOCKET_GOSSIP ].addr );
527608
#else
528609
peer->country_code_idx = UCHAR_MAX;
529610
#endif
@@ -532,7 +613,7 @@ fd_gui_peers_handle_gossip_update( fd_gui_peers_ctx_t * peers,
532613
fd_gui_peers_node_sock_map_idx_insert ( peers->node_sock_map, update->contact_info.idx, peers->contact_info_table );
533614

534615
/* broadcast update to WebSocket clients */
535-
fd_gui_peers_printf_nodes( peers, (int[]){ FD_GUI_PEERS_NODE_UPDATE }, (ulong[]){ update->contact_info.idx }, 1UL, country_code_map );
616+
fd_gui_peers_printf_nodes( peers, (int[]){ FD_GUI_PEERS_NODE_UPDATE }, (ulong[]){ update->contact_info.idx }, 1UL );
536617
fd_http_server_ws_broadcast( peers->http );
537618
} else {
538619
FD_TEST( !fd_gui_peers_node_pubkey_map_ele_query_const( peers->node_pubkey_map, &update->contact_info.contact_info->pubkey, NULL, peers->contact_info_table ) );
@@ -547,17 +628,21 @@ fd_gui_peers_handle_gossip_update( fd_gui_peers_ctx_t * peers,
547628
memset( &peer->gossip_tx_sum, 0, sizeof(peer->gossip_tx_sum) );
548629
peer->has_vote_info = 0;
549630
peer->stake = ULONG_MAX;
550-
peer->valid = 1;
631+
632+
fd_gui_config_parse_info_t * info = fd_gui_peers_node_info_map_ele_query( peers->node_info_map, &update->contact_info.contact_info->pubkey, NULL, peers->node_info_pool );
633+
if( FD_LIKELY( info ) ) fd_memcpy( peer->name, info->name, sizeof(info->name) );
634+
else peer->name[ 0 ] = '\0';
635+
551636
peer->update_time_nanos = now;
552637
fd_memcpy( &peer->contact_info, update->contact_info.contact_info, sizeof(peer->contact_info) );
553638

554639
/* fetch and set country code */
555640
#if FD_HAS_ZSTD
556-
peer->country_code_idx = ipinfo_lookup( ipinfo_nodes, peer->contact_info.sockets[ FD_CONTACT_INFO_SOCKET_GOSSIP ].addr );
641+
peer->country_code_idx = ipinfo_lookup( peers->ipinfo.nodes, peer->contact_info.sockets[ FD_CONTACT_INFO_SOCKET_GOSSIP ].addr );
557642
#else
558643
peer->country_code_idx = UCHAR_MAX;
559-
(void)ipinfo_nodes;
560644
#endif
645+
peer->valid = 1;
561646

562647
/* update pubkey_map, sock_map */
563648
fd_gui_peers_node_sock_map_idx_insert ( peers->node_sock_map, update->contact_info.idx, peers->contact_info_table );
@@ -571,7 +656,7 @@ fd_gui_peers_handle_gossip_update( fd_gui_peers_ctx_t * peers,
571656
fd_http_server_ws_broadcast( peers->http );
572657

573658
/* broadcast update to WebSocket clients */
574-
fd_gui_peers_printf_nodes( peers, (int[]){ FD_GUI_PEERS_NODE_ADD }, (ulong[]){ update->contact_info.idx }, 1UL, country_code_map );
659+
fd_gui_peers_printf_nodes( peers, (int[]){ FD_GUI_PEERS_NODE_ADD }, (ulong[]){ update->contact_info.idx }, 1UL );
575660
fd_http_server_ws_broadcast( peers->http );
576661
}
577662
break;
@@ -610,7 +695,7 @@ fd_gui_peers_handle_gossip_update( fd_gui_peers_ctx_t * peers,
610695
fd_http_server_ws_broadcast( peers->http );
611696

612697
/* broadcast update to WebSocket clients */
613-
fd_gui_peers_printf_nodes( peers, (int[]){ FD_GUI_PEERS_NODE_DELETE }, (ulong[]){ update->contact_info_remove.idx }, 1UL, country_code_map );
698+
fd_gui_peers_printf_nodes( peers, (int[]){ FD_GUI_PEERS_NODE_DELETE }, (ulong[]){ update->contact_info_remove.idx }, 1UL );
614699
fd_http_server_ws_broadcast( peers->http );
615700
break;
616701
}
@@ -638,8 +723,7 @@ fd_gui_peers_handle_vote_update( fd_gui_peers_ctx_t * peers,
638723
fd_gui_peers_vote_t * votes,
639724
ulong vote_cnt,
640725
long now,
641-
fd_pubkey_t * identity,
642-
char country_code_map[ static 512 ][ 3 ] ) {
726+
fd_pubkey_t * identity ) {
643727
(void)now;
644728
fd_gui_peers_vote_t * votes_sorted = votes;
645729
fd_gui_peers_vote_t * votes_scratch = peers->votes_scratch;
@@ -745,7 +829,7 @@ fd_gui_peers_handle_vote_update( fd_gui_peers_ctx_t * peers,
745829
}
746830

747831
if( FD_UNLIKELY( count ) ) {
748-
fd_gui_peers_printf_nodes( peers, actions, idxs, count, country_code_map );
832+
fd_gui_peers_printf_nodes( peers, actions, idxs, count );
749833
fd_http_server_ws_broadcast( peers->http );
750834
}
751835
}
@@ -1144,18 +1228,17 @@ fd_gui_peers_poll( fd_gui_peers_ctx_t * peers, long now ) {
11441228
}
11451229

11461230
void
1147-
fd_gui_peers_ws_open( fd_gui_peers_ctx_t * peers,
1148-
ulong ws_conn_id,
1149-
long now,
1150-
char country_code_map[ static 512 ][ 3 ] ) {
1231+
fd_gui_peers_ws_open( fd_gui_peers_ctx_t * peers,
1232+
ulong ws_conn_id,
1233+
long now ) {
11511234
peers->client_viewports[ ws_conn_id ].connected = 1;
11521235
peers->client_viewports[ ws_conn_id ].connected_time = now;
11531236
peers->client_viewports[ ws_conn_id ].start_row = 0;
11541237
peers->client_viewports[ ws_conn_id ].row_cnt = 0;
11551238
peers->client_viewports[ ws_conn_id ].sort_key = FD_GUI_PEERS_LIVE_TABLE_DEFAULT_SORT_KEY;
11561239
fd_gui_peers_ws_conn_rr_grow( peers, ws_conn_id );
11571240

1158-
fd_gui_peers_printf_node_all( peers, country_code_map );
1241+
fd_gui_peers_printf_node_all( peers );
11591242
FD_TEST( !fd_http_server_ws_send( peers->http, ws_conn_id ) );
11601243
}
11611244

0 commit comments

Comments
 (0)