Line data Source code
1 : #define _DEFAULT_SOURCE
2 :
3 : #include <fcntl.h>
4 : #include <stdio.h>
5 : #include <stdlib.h>
6 : #include <signal.h>
7 : #include <errno.h>
8 : #include <unistd.h>
9 : #include <netdb.h>
10 : #include <sys/socket.h>
11 : #include <netinet/in.h>
12 : #include <arpa/inet.h>
13 : #include "../../discof/rpcserver/fd_rpc_service.h"
14 :
15 : #define SHAM_LINK_CONTEXT fd_rpc_ctx_t
16 : #define SHAM_LINK_STATE fd_replay_notif_msg_t
17 : #define SHAM_LINK_NAME replay_sham_link
18 : #include "sham_link.h"
19 :
20 : #define SHAM_LINK_CONTEXT fd_rpc_ctx_t
21 : #define SHAM_LINK_STATE fd_multi_epoch_leaders_t
22 : #define SHAM_LINK_NAME stake_sham_link
23 : #include "sham_link.h"
24 :
25 : static void
26 0 : init_args( int * argc, char *** argv, fd_rpcserver_args_t * args ) {
27 0 : memset( args, 0, sizeof(fd_rpcserver_args_t) );
28 :
29 0 : const char * funk_wksp_name = fd_env_strip_cmdline_cstr( argc, argv, "--funk-wksp-name", NULL, "fd1_funk.wksp" );
30 0 : if( FD_UNLIKELY( !funk_wksp_name ))
31 0 : FD_LOG_ERR(( "--funk-wksp-name argument is required" ));
32 0 : fd_wksp_t * funk_wksp = fd_wksp_attach( funk_wksp_name );
33 0 : if( FD_UNLIKELY( !funk_wksp ))
34 0 : FD_LOG_ERR(( "unable to attach to \"%s\"\n\tprobably does not exist or bad permissions", funk_wksp_name ));
35 0 : fd_wksp_tag_query_info_t info;
36 0 : ulong tag = 1;
37 0 : if( fd_wksp_tag_query( funk_wksp, &tag, 1, &info, 1 ) <= 0 ) {
38 0 : FD_LOG_ERR(( "workspace does not contain a funk" ));
39 0 : }
40 0 : void * funk_shmem = fd_wksp_laddr_fast( funk_wksp, info.gaddr_lo );
41 0 : fd_funk_t * funk = fd_funk_join( args->funk, funk_shmem );
42 0 : if( FD_UNLIKELY( !funk ))
43 0 : FD_LOG_ERR(( "failed to join funk" ));
44 :
45 0 : args->blockstore_fd = -1;
46 :
47 0 : const char * wksp_name = fd_env_strip_cmdline_cstr ( argc, argv, "--wksp-name-blockstore", NULL, "fd1_blockstore.wksp" );
48 0 : FD_LOG_NOTICE(( "attaching to workspace \"%s\"", wksp_name ));
49 0 : fd_wksp_t * wksp = fd_wksp_attach( wksp_name );
50 0 : if( FD_UNLIKELY( !wksp ) )
51 0 : FD_LOG_ERR(( "unable to attach to \"%s\"\n\tprobably does not exist or bad permissions", wksp_name ));
52 0 : tag = 1;
53 0 : if( fd_wksp_tag_query( wksp, &tag, 1, &info, 1 ) <= 0 ) {
54 0 : FD_LOG_ERR(( "workspace \"%s\" does not contain a blockstore", wksp_name ));
55 0 : }
56 0 : void * shmem = fd_wksp_laddr_fast( wksp, info.gaddr_lo );
57 0 : args->blockstore = fd_blockstore_join( &args->blockstore_ljoin, shmem );
58 0 : if( args->blockstore == NULL ) {
59 0 : FD_LOG_ERR(( "failed to join a blockstore" ));
60 0 : }
61 0 : FD_LOG_NOTICE(( "blockstore has slot root=%lu", args->blockstore->shmem->wmk ));
62 0 : fd_wksp_mprotect( wksp, 1 );
63 :
64 0 : args->leaders = fd_multi_epoch_leaders_join( fd_multi_epoch_leaders_new( aligned_alloc( fd_multi_epoch_leaders_align(), fd_multi_epoch_leaders_footprint() ) ) );
65 0 : args->port = (ushort)fd_env_strip_cmdline_ulong( argc, argv, "--port", NULL, 8899 );
66 :
67 0 : args->params.max_connection_cnt = fd_env_strip_cmdline_ulong( argc, argv, "--max-connection-cnt", NULL, 30 );
68 0 : args->params.max_ws_connection_cnt = fd_env_strip_cmdline_ulong( argc, argv, "--max-ws-connection-cnt", NULL, 10 );
69 0 : args->params.max_request_len = fd_env_strip_cmdline_ulong( argc, argv, "--max-request-len", NULL, 1<<16 );
70 0 : args->params.max_ws_recv_frame_len = fd_env_strip_cmdline_ulong( argc, argv, "--max-ws-recv-frame-len", NULL, 1<<16 );
71 0 : args->params.max_ws_send_frame_cnt = fd_env_strip_cmdline_ulong( argc, argv, "--max-ws-send-frame-cnt", NULL, 100 );
72 0 : args->params.outgoing_buffer_sz = fd_env_strip_cmdline_ulong( argc, argv, "--max-send-buf", NULL, 100U<<20U );
73 0 : args->block_index_max = fd_env_strip_cmdline_uint ( argc, argv, "--max-block_idx", NULL, 65536 );
74 0 : args->txn_index_max = fd_env_strip_cmdline_uint ( argc, argv, "--max-txn-idx", NULL, 1048576 );
75 0 : args->acct_index_max = fd_env_strip_cmdline_uint ( argc, argv, "--max-acct-idx", NULL, 1048576 );
76 0 : strncpy(args->history_file, fd_env_strip_cmdline_cstr ( argc, argv, "--rpc-history-file", NULL, "rpc_history" ), sizeof(args->history_file)-1 );
77 :
78 0 : const char * tpu_host = fd_env_strip_cmdline_cstr ( argc, argv, "--local-tpu-host", NULL, "127.0.0.1" );
79 0 : ulong tpu_port = fd_env_strip_cmdline_ulong( argc, argv, "--local-tpu-port", NULL, 9001U );
80 0 : memset( &args->tpu_addr, 0, sizeof(args->tpu_addr) );
81 0 : args->tpu_addr.sin_family = AF_INET;
82 0 : if( !inet_aton( tpu_host, &args->tpu_addr.sin_addr ) ) {
83 0 : struct hostent * hent = gethostbyname( tpu_host );
84 0 : if( hent == NULL ) {
85 0 : FD_LOG_WARNING(( "unable to resolve tpu host %s", tpu_host ));
86 0 : exit(-1);
87 0 : }
88 0 : args->tpu_addr.sin_addr.s_addr = ( (struct in_addr *)hent->h_addr_list[0] )->s_addr;
89 0 : }
90 0 : if( tpu_port < 1024 || tpu_port > (int)USHORT_MAX ) {
91 0 : FD_LOG_ERR(( "invalid tpu port number" ));
92 0 : exit(-1);
93 0 : }
94 0 : args->tpu_addr.sin_port = htons( (ushort)tpu_port );
95 0 : FD_LOG_NOTICE(( "using tpu %s:%u", inet_ntoa( args->tpu_addr.sin_addr ), (uint)ntohs( args->tpu_addr.sin_port ) ));
96 0 : }
97 :
98 : static void
99 0 : init_args_offline( int * argc, char *** argv, fd_rpcserver_args_t * args ) {
100 0 : memset( args, 0, sizeof(fd_rpcserver_args_t) );
101 0 : args->offline = 1;
102 :
103 0 : const char * funk_wksp_name = fd_env_strip_cmdline_cstr( argc, argv, "--funk-wksp-name", NULL, "fd1_funk.wksp" );
104 0 : if( FD_UNLIKELY( !funk_wksp_name ))
105 0 : FD_LOG_ERR(( "--funk-wksp-name argument is required" ));
106 0 : fd_wksp_t * funk_wksp = fd_wksp_attach( funk_wksp_name );
107 0 : if( FD_UNLIKELY( !funk_wksp ))
108 0 : FD_LOG_ERR(( "unable to attach to \"%s\"\n\tprobably does not exist or bad permissions", funk_wksp_name ));
109 0 : fd_wksp_tag_query_info_t info;
110 0 : ulong tag = 1;
111 0 : if( fd_wksp_tag_query( funk_wksp, &tag, 1, &info, 1 ) <= 0 ) {
112 0 : FD_LOG_ERR(( "workspace does not contain a funk" ));
113 0 : }
114 0 : void * funk_shmem = fd_wksp_laddr_fast( funk_wksp, info.gaddr_lo );
115 0 : fd_funk_t * funk = fd_funk_join( args->funk, funk_shmem );
116 0 : if( FD_UNLIKELY( !funk ))
117 0 : FD_LOG_ERR(( "failed to join funk" ));
118 :
119 0 : fd_wksp_t * wksp;
120 0 : const char * wksp_name = fd_env_strip_cmdline_cstr ( argc, argv, "--wksp-name-blockstore", NULL, NULL );
121 0 : if( wksp_name != NULL ) {
122 0 : FD_LOG_NOTICE(( "attaching to workspace \"%s\"", wksp_name ));
123 0 : wksp = fd_wksp_attach( wksp_name );
124 0 : if( !wksp ) FD_LOG_ERR(( "unable to attach to \"%s\"\n\tprobably does not exist or bad permissions", wksp_name ));
125 0 : } else {
126 0 : char const * restore = fd_env_strip_cmdline_cstr ( argc, argv, "--restore-blockstore", NULL, NULL );
127 0 : if( restore == NULL ) FD_LOG_ERR(( "must use --wksp-name-blockstore or --restore-blockstore in offline mode" ));
128 0 : fd_wksp_preview_t preview[1];
129 0 : int err = fd_wksp_preview( restore, preview );
130 0 : if( err ) FD_LOG_ERR(( "unable to restore %s: error %d", restore, err ));
131 0 : ulong page_cnt = (preview->data_max + FD_SHMEM_GIGANTIC_PAGE_SZ-1U)/FD_SHMEM_GIGANTIC_PAGE_SZ;
132 0 : wksp = fd_wksp_new_anonymous( FD_SHMEM_GIGANTIC_PAGE_SZ, page_cnt, 0, "wksp-blockstore", 0UL );
133 0 : if( !wksp ) FD_LOG_ERR(( "unable to restore %s: failed to create wksp", restore ));
134 0 : FD_LOG_NOTICE(( "restoring blockstore wksp %s", restore ));
135 0 : fd_wksp_restore( wksp, restore, preview->seed );
136 0 : }
137 0 : tag = 1;
138 0 : if( fd_wksp_tag_query( wksp, &tag, 1, &info, 1 ) <= 0 ) {
139 0 : FD_LOG_ERR(( "workspace does not contain a blockstore" ));
140 0 : }
141 0 : void * shmem = fd_wksp_laddr_fast( wksp, info.gaddr_lo );
142 0 : args->blockstore = fd_blockstore_join( &args->blockstore_ljoin, shmem );
143 0 : if( args->blockstore == NULL ) {
144 0 : FD_LOG_ERR(( "failed to join a blockstore" ));
145 0 : }
146 0 : FD_LOG_NOTICE(( "blockstore has slot root=%lu", args->blockstore->shmem->wmk ));
147 0 : fd_wksp_mprotect( wksp, 1 );
148 :
149 0 : args->port = (ushort)fd_env_strip_cmdline_ulong( argc, argv, "--port", NULL, 8899 );
150 :
151 0 : args->params.max_connection_cnt = fd_env_strip_cmdline_ulong( argc, argv, "--max-connection-cnt", NULL, 50 );
152 0 : args->params.max_ws_connection_cnt = fd_env_strip_cmdline_ulong( argc, argv, "--max-ws-connection-cnt", NULL, 10 );
153 0 : args->params.max_request_len = fd_env_strip_cmdline_ulong( argc, argv, "--max-request-len", NULL, 1<<16 );
154 0 : args->params.max_ws_recv_frame_len = fd_env_strip_cmdline_ulong( argc, argv, "--max-ws-recv-frame-len", NULL, 2048 );
155 0 : args->params.max_ws_send_frame_cnt = fd_env_strip_cmdline_ulong( argc, argv, "--max-ws-send-frame-cnt", NULL, 100 );
156 0 : args->params.outgoing_buffer_sz = fd_env_strip_cmdline_ulong( argc, argv, "--max-send-buf", NULL, 100U<<20U );
157 0 : args->block_index_max = fd_env_strip_cmdline_uint ( argc, argv, "--max-block_idx", NULL, 65536 );
158 0 : args->txn_index_max = fd_env_strip_cmdline_uint ( argc, argv, "--max-txn-idx", NULL, 1048576 );
159 0 : args->acct_index_max = fd_env_strip_cmdline_uint ( argc, argv, "--max-acct-idx", NULL, 1048576 );
160 0 : strncpy(args->history_file, fd_env_strip_cmdline_cstr ( argc, argv, "--rpc-history-file", NULL, "rpc_history" ), sizeof(args->history_file)-1 );
161 0 : }
162 :
163 : static int stopflag = 0;
164 : static void
165 0 : signal1( int sig ) {
166 0 : (void)sig;
167 0 : stopflag = 1;
168 0 : }
169 :
170 : int main( int argc, char ** argv ) {
171 : fd_boot( &argc, &argv );
172 : fd_rpcserver_args_t args;
173 :
174 : replay_sham_link_t * rep_notify = NULL;
175 : stake_sham_link_t * stake_notify = NULL;
176 :
177 : ulong offline = fd_env_strip_cmdline_ulong( &argc, &argv, "--offline", NULL, 0 );
178 : if( !offline ) {
179 : init_args( &argc, &argv, &args );
180 :
181 : const char * wksp_name = fd_env_strip_cmdline_cstr ( &argc, &argv, "--wksp-name-replay-notify", NULL, "fd1_replay_notif.wksp" );
182 : rep_notify = replay_sham_link_new( aligned_alloc( replay_sham_link_align(), replay_sham_link_footprint() ), wksp_name );
183 :
184 : wksp_name = fd_env_strip_cmdline_cstr ( &argc, &argv, "--wksp-name-stake-out", NULL, "fd1_stake_out.wksp" );
185 : stake_notify = stake_sham_link_new( aligned_alloc( stake_sham_link_align(), stake_sham_link_footprint() ), wksp_name );
186 :
187 : } else {
188 : init_args_offline( &argc, &argv, &args );
189 : }
190 :
191 : #define SMAX 1LU<<30
192 : uchar * smem = aligned_alloc( FD_SPAD_ALIGN, SMAX );
193 : args.spad = fd_spad_join( fd_spad_new( smem, SMAX ) );
194 : fd_spad_push( args.spad );
195 :
196 : struct sigaction sa = {
197 : .sa_handler = signal1,
198 : .sa_flags = 0,
199 : };
200 : if( FD_UNLIKELY( sigaction( SIGTERM, &sa, NULL ) ) )
201 : FD_LOG_ERR(( "sigaction(SIGTERM) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
202 : if( FD_UNLIKELY( sigaction( SIGINT, &sa, NULL ) ) )
203 : FD_LOG_ERR(( "sigaction(SIGINT) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
204 : signal( SIGPIPE, SIG_IGN );
205 :
206 : fd_rpc_ctx_t * ctx = NULL;
207 : fd_rpc_create_ctx( &args, &ctx );
208 : fd_rpc_start_service( &args, ctx );
209 :
210 : if( args.offline ) {
211 : while( !stopflag ) {
212 : fd_rpc_ws_poll( ctx );
213 : }
214 : fd_halt();
215 : return 0;
216 : }
217 :
218 : replay_sham_link_start( rep_notify );
219 : stake_sham_link_start( stake_notify );
220 : while( !stopflag ) {
221 : fd_replay_notif_msg_t msg;
222 : replay_sham_link_poll( rep_notify, ctx, &msg );
223 :
224 : stake_sham_link_poll( stake_notify, ctx, args.leaders );
225 :
226 : fd_rpc_ws_poll( ctx );
227 : }
228 :
229 : fd_halt();
230 : return 0;
231 : }
232 :
233 : static void
234 0 : replay_sham_link_during_frag(fd_rpc_ctx_t * ctx, fd_replay_notif_msg_t * state, void const * msg, int sz) {
235 0 : fd_rpc_replay_during_frag( ctx, state, msg, sz );
236 0 : }
237 :
238 : static void
239 0 : replay_sham_link_after_frag(fd_rpc_ctx_t * ctx, fd_replay_notif_msg_t * msg) {
240 0 : fd_rpc_replay_after_frag( ctx, msg );
241 0 : }
242 :
243 : static void
244 0 : stake_sham_link_during_frag(fd_rpc_ctx_t * ctx, fd_multi_epoch_leaders_t * state, void const * msg, int sz) {
245 0 : fd_rpc_stake_during_frag( ctx, state, msg, sz );
246 0 : }
247 :
248 : static void
249 0 : stake_sham_link_after_frag(fd_rpc_ctx_t * ctx, fd_multi_epoch_leaders_t * state) {
250 0 : fd_rpc_stake_after_frag( ctx, state );
251 0 : }
|