8
8
#include "../fd_txn_m_t.h"
9
9
#include "../plugin/fd_plugin.h"
10
10
#include "../../waltz/h2/fd_h2_conn.h"
11
+ #include "../../waltz/http/fd_url.h" /* fd_url_unescape */
11
12
#include "../../ballet/base58/fd_base58.h"
12
13
#include "../../ballet/nanopb/pb_decode.h"
13
14
#include "../../util/net/fd_ip4.h"
21
22
22
23
#define FD_BUNDLE_CLIENT_REQUEST_TIMEOUT ((long)8e9) /* 8 seconds */
23
24
24
- static void
25
+ void
25
26
fd_bundle_client_reset ( fd_bundle_tile_t * ctx ) {
26
27
if ( FD_UNLIKELY ( ctx -> tcp_sock >= 0 ) ) {
27
28
if ( FD_UNLIKELY ( 0 != close ( ctx -> tcp_sock ) ) ) {
@@ -50,7 +51,8 @@ fd_bundle_client_reset( fd_bundle_tile_t * ctx ) {
50
51
51
52
fd_bundle_tile_backoff ( ctx , fd_tickcount () );
52
53
53
- fd_bundle_auther_handle_request_fail ( & ctx -> auther );
54
+ fd_bundle_auther_reset ( & ctx -> auther );
55
+ fd_grpc_client_reset ( ctx -> grpc_client );
54
56
}
55
57
56
58
static int
@@ -152,6 +154,8 @@ fd_bundle_client_create_conn( fd_bundle_tile_t * ctx ) {
152
154
# endif /* FD_HAS_OPENSSL */
153
155
154
156
fd_grpc_client_reset ( ctx -> grpc_client );
157
+ ctx -> last_ping_tx_ticks = fd_tickcount ();
158
+ ctx -> last_ping_tx_nanos = fd_log_wallclock ();
155
159
}
156
160
157
161
static int
@@ -232,7 +236,7 @@ fd_bundle_client_subscribe_bundles( fd_bundle_tile_t * ctx ) {
232
236
ctx -> bundle_subscription_wait = 1 ;
233
237
}
234
238
235
- static void
239
+ void
236
240
fd_bundle_client_send_ping ( fd_bundle_tile_t * ctx ) {
237
241
if ( FD_UNLIKELY ( !ctx -> grpc_client ) ) return ; /* no client */
238
242
fd_h2_conn_t * conn = fd_grpc_client_h2_conn ( ctx -> grpc_client );
@@ -247,9 +251,9 @@ fd_bundle_client_send_ping( fd_bundle_tile_t * ctx ) {
247
251
}
248
252
}
249
253
250
- FD_FN_PURE static int
251
- fd_bundle_client_keepalive_due ( fd_bundle_tile_t const * ctx ,
252
- long now_ticks ) {
254
+ FD_FN_PURE int
255
+ fd_bundle_client_ping_is_due ( fd_bundle_tile_t const * ctx ,
256
+ long now_ticks ) {
253
257
ulong delay_min = ctx -> ping_threshold_ticks >>1 ;
254
258
ulong delay_rng = ctx -> ping_threshold_ticks & ctx -> ping_randomize ;
255
259
ulong delay = delay_min + delay_rng ;
@@ -289,7 +293,7 @@ fd_bundle_client_step_reconnect( fd_bundle_tile_t * ctx,
289
293
}
290
294
291
295
/* Send a PING */
292
- if ( FD_UNLIKELY ( fd_bundle_client_keepalive_due ( ctx , io_ticks ) ) ) {
296
+ if ( FD_UNLIKELY ( fd_bundle_client_ping_is_due ( ctx , io_ticks ) ) ) {
293
297
fd_bundle_client_send_ping ( ctx );
294
298
return 1 ;
295
299
}
@@ -342,6 +346,16 @@ fd_bundle_client_step1( fd_bundle_tile_t * ctx,
342
346
return ;
343
347
}
344
348
349
+ /* Did a HTTP/2 PING time out */
350
+ long check_ts = fd_tickcount ();
351
+ if ( FD_UNLIKELY ( fd_bundle_client_ping_is_timeout ( ctx , check_ts ) ) ) {
352
+ FD_LOG_WARNING (( "Bundle gRPC timed out (HTTP/2 PING went unanswered for %.2f seconds)" ,
353
+ ( (double )ctx -> ping_deadline_ticks / fd_tempo_tick_per_ns ( NULL ) )* 1e-9 ));
354
+ ctx -> defer_reset = 1 ;
355
+ * charge_busy = 1 ;
356
+ return ;
357
+ }
358
+
345
359
/* Drive I/O, SSL handshake, and any inflight requests */
346
360
if ( FD_UNLIKELY ( !fd_bundle_client_drive_io ( ctx , charge_busy ) ||
347
361
ctx -> defer_reset /* new error? */ ) ) {
@@ -713,7 +727,7 @@ fd_bundle_client_grpc_tx_complete(
713
727
(void )app_ctx ; (void )request_ctx ;
714
728
}
715
729
716
- static void
730
+ void
717
731
fd_bundle_client_grpc_rx_start (
718
732
void * app_ctx ,
719
733
ulong request_ctx
@@ -779,51 +793,6 @@ fd_bundle_client_request_failed( fd_bundle_tile_t * ctx,
779
793
}
780
794
}
781
795
782
- static inline int
783
- fd_hex_unhex ( int c ) {
784
- if ( c >='0' && c <='9' ) return c - '0' ;
785
- if ( c >='a' && c <='f' ) return c - 'a' + 0xa ;
786
- if ( c >='A' && c <='F' ) return c - 'A' + 0xa ;
787
- return -1 ;
788
- }
789
-
790
- static ulong
791
- fd_url_unescape ( char * const msg ,
792
- ulong const len ) {
793
- char * end = msg + len ;
794
- int state = 0 ;
795
- char * dst = msg ;
796
- for ( char * src = msg ; src < end ; src ++ ) {
797
- /* invariant: p<=msg */
798
- switch ( state ) {
799
- case 0 :
800
- if ( FD_LIKELY ( (* src )!= '%' ) ) {
801
- * dst = * src ;
802
- dst ++ ;
803
- } else {
804
- state = 1 ;
805
- }
806
- break ;
807
- case 1 :
808
- if ( FD_LIKELY ( (* src )!= '%' ) ) {
809
- * dst = (char )( ( fd_hex_unhex ( * src )& 0xf )<<4 );
810
- state = 2 ;
811
- } else {
812
- /* FIXME is 'aa%%aa' a valid escape? */
813
- * (dst ++ ) = '%' ;
814
- state = 0 ;
815
- }
816
- break ;
817
- case 2 :
818
- * dst = (char )( (* dst ) | ( fd_hex_unhex ( * src )& 0xf ) );
819
- dst ++ ;
820
- state = 0 ;
821
- break ;
822
- }
823
- }
824
- return (ulong )( dst - msg );
825
- }
826
-
827
796
void
828
797
fd_bundle_client_grpc_rx_end (
829
798
void * app_ctx ,
@@ -860,6 +829,9 @@ fd_bundle_client_grpc_rx_end(
860
829
FD_LOG_INFO (( "SubscribeBundles stream failed (gRPC status %u-%s). Reconnecting ..." ,
861
830
resp -> grpc_status , fd_grpc_status_cstr ( resp -> grpc_status ) ));
862
831
return ;
832
+ case FD_BUNDLE_CLIENT_REQ_Bundle_GetBlockBuilderFeeInfo :
833
+ ctx -> builder_info_wait = 0 ;
834
+ break ;
863
835
default :
864
836
break ;
865
837
}
@@ -892,7 +864,7 @@ fd_bundle_client_grpc_rx_timeout(
892
864
static void
893
865
fd_bundle_client_grpc_ping_ack ( void * app_ctx ) {
894
866
fd_bundle_tile_t * ctx = app_ctx ;
895
- ctx -> last_ping_rx_ts = fd_tickcount ();
867
+ ctx -> last_ping_rx_ticks = fd_tickcount ();
896
868
ctx -> metrics .ping_ack_cnt ++ ;
897
869
long rtt_sample = fd_log_wallclock () - ctx -> last_ping_tx_nanos ;
898
870
fd_rtt_sample ( ctx -> rtt , (float )rtt_sample , 0 );
@@ -949,13 +921,12 @@ fd_bundle_client_status( fd_bundle_tile_t const * ctx ) {
949
921
return CONNECTING ; /* not fully connected */
950
922
}
951
923
952
- long ping_timeout = (long )( 3UL * ctx -> ping_threshold_ticks );
953
- if ( FD_UNLIKELY ( fd_tickcount () > ctx -> last_ping_rx_ts + ping_timeout ) ) {
924
+ if ( FD_UNLIKELY ( fd_bundle_client_ping_is_timeout ( ctx , fd_tickcount () ) ) ) {
954
925
return DISCONNECTED ; /* possible timeout */
955
926
}
956
927
957
928
if ( FD_UNLIKELY ( !fd_grpc_client_is_connected ( ctx -> grpc_client ) ) ) {
958
- return DISCONNECTED ;
929
+ return CONNECTING ;
959
930
}
960
931
961
932
/* As far as we know, the bundle connection is alive and well. */
@@ -983,3 +954,12 @@ fd_bundle_request_ctx_cstr( ulong request_ctx ) {
983
954
return "unknown" ;
984
955
}
985
956
}
957
+
958
+ void
959
+ fd_bundle_client_set_ping_interval ( fd_bundle_tile_t * ctx ,
960
+ long ping_interval_ns ) {
961
+ ctx -> ping_threshold_ticks = fd_ulong_pow2_up ( (ulong )
962
+ ( (double )ping_interval_ns * fd_tempo_tick_per_ns ( NULL ) ) );
963
+ ctx -> ping_randomize = fd_rng_ulong ( ctx -> rng );
964
+ ctx -> ping_deadline_ticks = 4UL * ctx -> ping_threshold_ticks ;
965
+ }
0 commit comments