Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more fixes in rpc to support explorer #2924

Merged
merged 3 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 112 additions & 39 deletions src/app/rpcserver/fd_block_to_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,41 @@ fd_txn_meta_to_json( fd_webserver_t * ws,
return NULL;
}

const char*
generic_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw,
int * need_comma ) {
FD_SCRATCH_SCOPE_BEGIN { /* read_epoch consumes a ton of scratch space! */
if( *need_comma ) EMIT_SIMPLE(",");
EMIT_SIMPLE("{\"accounts\":[");
const uchar * instr_acc_idxs = raw + instr->acct_off;
const fd_pubkey_t * accts = (const fd_pubkey_t *)(raw + txn->acct_addr_off);
for (ushort j = 0; j < instr->acct_cnt; j++) {
char buf32[FD_BASE58_ENCODED_32_SZ];
fd_base58_encode_32((const uchar*)(accts + instr_acc_idxs[j]), NULL, buf32);
fd_web_reply_sprintf(ws, "%s\"%s\"", (j == 0 ? "" : ","), buf32);
}
EMIT_SIMPLE("],\"data\":\"");
fd_web_reply_encode_base58(ws, raw + instr->data_off, instr->data_sz);
char buf32[FD_BASE58_ENCODED_32_SZ];
fd_base58_encode_32((const uchar*)(accts + instr->program_id), NULL, buf32);
fd_web_reply_sprintf(ws, "\",\"program\":\"unknown\",\"programId\":\"%s\",\"stackHeight\":null}", buf32);
*need_comma = 1;
} FD_SCRATCH_SCOPE_END;
return NULL;
}

const char*
vote_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
const uchar * raw,
int * need_comma ) {
(void)txn;
FD_SCRATCH_SCOPE_BEGIN { /* read_epoch consumes a ton of scratch space! */
if( *need_comma ) EMIT_SIMPLE(",");
fd_vote_instruction_t instruction;
fd_bincode_decode_ctx_t decode = {
.data = raw + instr->data_off,
Expand All @@ -283,6 +311,7 @@ vote_program_to_json( fd_webserver_t * ws,
fd_vote_instruction_walk( json, &instruction, fd_rpc_json_walk, NULL, 0 );

EMIT_SIMPLE(",\"program\":\"vote\",\"programId\":\"Vote111111111111111111111111111111111111111\",\"stackHeight\":null}");
*need_comma = 1;
} FD_SCRATCH_SCOPE_END;
return NULL;
}
Expand All @@ -291,76 +320,118 @@ const char *
system_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
(void)ws;(void)txn;(void)instr;(void)raw;
FD_LOG_WARNING(( "system_program_to_json not implemented" ));
EMIT_SIMPLE("null");
const uchar * raw,
int * need_comma ) {
(void)txn;
FD_SCRATCH_SCOPE_BEGIN { /* read_epoch consumes a ton of scratch space! */
if( *need_comma ) EMIT_SIMPLE(",");
fd_system_program_instruction_t instruction;
fd_bincode_decode_ctx_t decode = {
.data = raw + instr->data_off,
.dataend = raw + instr->data_off + instr->data_sz,
.valloc = fd_scratch_virtual()
};
int decode_result = fd_system_program_instruction_decode( &instruction, &decode );
if( decode_result != FD_BINCODE_SUCCESS ) {
EMIT_SIMPLE("null");
return NULL;
}

EMIT_SIMPLE("{\"parsed\":");

fd_rpc_json_t * json = fd_rpc_json_init( fd_rpc_json_new( fd_scratch_alloc( fd_rpc_json_align(), fd_rpc_json_footprint() ) ), ws );
fd_system_program_instruction_walk( json, &instruction, fd_rpc_json_walk, NULL, 0 );

EMIT_SIMPLE(",\"program\":\"system\",\"programId\":\"11111111111111111111111111111111\",\"stackHeight\":null}");
*need_comma = 1;
} FD_SCRATCH_SCOPE_END;
return NULL;
}

const char*
config_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
(void)ws;(void)txn;(void)instr;(void)raw;
const uchar * raw,
int * need_comma ) {
FD_LOG_WARNING(( "config_program_to_json not implemented" ));
EMIT_SIMPLE("null");
generic_program_to_json( ws, txn, instr, raw, need_comma );
return NULL;
}

const char*
stake_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
(void)ws;(void)txn;(void)instr;(void)raw;
const uchar * raw,
int * need_comma ) {
FD_LOG_WARNING(( "stake_program_to_json not implemented" ));
EMIT_SIMPLE("null");
generic_program_to_json( ws, txn, instr, raw, need_comma );
return NULL;
}

const char*
compute_budget_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
(void)ws;(void)txn;(void)instr;(void)raw;
FD_LOG_WARNING(( "compute_budget_program_to_json not implemented" ));
EMIT_SIMPLE("null");
const uchar * raw,
int * need_comma ) {
(void)txn;
FD_SCRATCH_SCOPE_BEGIN { /* read_epoch consumes a ton of scratch space! */
if( *need_comma ) EMIT_SIMPLE(",");
fd_compute_budget_program_instruction_t instruction;
fd_bincode_decode_ctx_t decode = {
.data = raw + instr->data_off,
.dataend = raw + instr->data_off + instr->data_sz,
.valloc = fd_scratch_virtual()
};
int decode_result = fd_compute_budget_program_instruction_decode( &instruction, &decode );
if( decode_result != FD_BINCODE_SUCCESS ) {
EMIT_SIMPLE("null");
return NULL;
}

EMIT_SIMPLE("{\"parsed\":");

fd_rpc_json_t * json = fd_rpc_json_init( fd_rpc_json_new( fd_scratch_alloc( fd_rpc_json_align(), fd_rpc_json_footprint() ) ), ws );
fd_compute_budget_program_instruction_walk( json, &instruction, fd_rpc_json_walk, NULL, 0 );

EMIT_SIMPLE(",\"program\":\"compute_budget\",\"programId\":\"ComputeBudget111111111111111111111111111111\",\"stackHeight\":null}");
*need_comma = 1;
} FD_SCRATCH_SCOPE_END;
return NULL;
}

const char*
address_lookup_table_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
(void)ws;(void)txn;(void)instr;(void)raw;
const uchar * raw,
int * need_comma ) {
FD_LOG_WARNING(( "address_lookup_table_program_to_json not implemented" ));
EMIT_SIMPLE("null");
generic_program_to_json( ws, txn, instr, raw, need_comma );
return NULL;
}

const char*
executor_zk_elgamal_proof_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
(void)ws;(void)txn;(void)instr;(void)raw;
const uchar * raw,
int * need_comma ) {
FD_LOG_WARNING(( "executor_zk_elgamal_proof_program_to_json not implemented" ));
EMIT_SIMPLE("null");
generic_program_to_json( ws, txn, instr, raw, need_comma );
return NULL;
}

const char*
bpf_loader_program_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw ) {
(void)ws;(void)txn;(void)instr;(void)raw;
const uchar * raw,
int * need_comma ) {
FD_LOG_WARNING(( "bpf_loader_program_to_json not implemented" ));
EMIT_SIMPLE("null");
generic_program_to_json( ws, txn, instr, raw, need_comma );
return NULL;
}

Expand All @@ -369,8 +440,10 @@ fd_instr_to_json( fd_webserver_t * ws,
fd_txn_t * txn,
fd_txn_instr_t * instr,
const uchar * raw,
fd_rpc_encoding_t encoding ) {
fd_rpc_encoding_t encoding,
int * need_comma ) {
if( encoding == FD_ENC_JSON ) {
if( *need_comma ) EMIT_SIMPLE(",");
EMIT_SIMPLE("{\"accounts\":[");
const uchar * instr_acc_idxs = raw + instr->acct_off;
for (ushort j = 0; j < instr->acct_cnt; j++) {
Expand All @@ -379,37 +452,37 @@ fd_instr_to_json( fd_webserver_t * ws,
EMIT_SIMPLE("],\"data\":\"");
fd_web_reply_encode_base58(ws, raw + instr->data_off, instr->data_sz);
fd_web_reply_sprintf(ws, "\",\"programIdIndex\":%u,\"stackHeight\":null}", (uint)instr->program_id);
*need_comma = 1;

} else if( encoding == FD_ENC_JSON_PARSED ) {
ushort acct_cnt = txn->acct_addr_cnt;
const fd_pubkey_t * accts = (const fd_pubkey_t *)(raw + txn->acct_addr_off);
if( instr->program_id >= acct_cnt ) {
EMIT_SIMPLE("null");
return NULL;
}
const fd_pubkey_t * prog = accts + instr->program_id;
if ( !memcmp( prog, fd_solana_vote_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return vote_program_to_json( ws, txn, instr, raw );
return vote_program_to_json( ws, txn, instr, raw, need_comma );
} else if ( !memcmp( prog, fd_solana_system_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return system_program_to_json( ws, txn, instr, raw );
return system_program_to_json( ws, txn, instr, raw, need_comma );
} else if ( !memcmp( prog, fd_solana_config_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return config_program_to_json( ws, txn, instr, raw );
return config_program_to_json( ws, txn, instr, raw, need_comma );
} else if ( !memcmp( prog, fd_solana_stake_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return stake_program_to_json( ws, txn, instr, raw );
return stake_program_to_json( ws, txn, instr, raw, need_comma );
} else if ( !memcmp( prog, fd_solana_compute_budget_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return compute_budget_program_to_json( ws, txn, instr, raw );
return compute_budget_program_to_json( ws, txn, instr, raw, need_comma );
} else if( !memcmp( prog, fd_solana_address_lookup_table_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return address_lookup_table_program_to_json( ws, txn, instr, raw );
return address_lookup_table_program_to_json( ws, txn, instr, raw, need_comma );
} else if( !memcmp( prog, fd_solana_zk_elgamal_proof_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return executor_zk_elgamal_proof_program_to_json( ws, txn, instr, raw );
return executor_zk_elgamal_proof_program_to_json( ws, txn, instr, raw, need_comma );
} else if( !memcmp( prog, fd_solana_bpf_loader_deprecated_program_id.key, sizeof( fd_pubkey_t ))) {
return bpf_loader_program_to_json( ws, txn, instr, raw );
return bpf_loader_program_to_json( ws, txn, instr, raw, need_comma );
} else if( !memcmp( prog, fd_solana_bpf_loader_program_id.key, sizeof(fd_pubkey_t) ) ) {
return bpf_loader_program_to_json( ws, txn, instr, raw );
return bpf_loader_program_to_json( ws, txn, instr, raw, need_comma );
} else if( !memcmp( prog, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) {
return bpf_loader_program_to_json( ws, txn, instr, raw );
return bpf_loader_program_to_json( ws, txn, instr, raw, need_comma );
} else {
EMIT_SIMPLE("null");
generic_program_to_json( ws, txn, instr, raw, need_comma );
}
}
return NULL;
Expand Down Expand Up @@ -470,9 +543,9 @@ fd_txn_to_json_full( fd_webserver_t * ws,
(uint)txn->readonly_signed_cnt, (uint)txn->readonly_unsigned_cnt, (uint)txn->signature_cnt);

ushort instr_cnt = txn->instr_cnt;
int need_comma = 0;
for (ushort idx = 0; idx < instr_cnt; idx++) {
if( idx ) EMIT_SIMPLE(",");
const char * res = fd_instr_to_json( ws, txn, &txn->instr[idx], raw, encoding );
const char * res = fd_instr_to_json( ws, txn, &txn->instr[idx], raw, encoding, &need_comma );
if( res ) return res;
}

Expand Down
32 changes: 21 additions & 11 deletions src/app/rpcserver/keywords.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,19 +732,28 @@ long fd_webserver_json_keyword(const char* keyw, unsigned long keyw_sz) {
}
break;
case 33:
if ((*(unsigned long*)&keyw[0] & 0xFFFFFFUL) == 0x746567UL) {
switch (keyw[3]) {
case 'C':
if (*(unsigned long*)&keyw[4] == 0x64656D7269666E6FUL && *(unsigned long*)&keyw[12] == 0x727574616E676953UL && *(unsigned long*)&keyw[20] == 0x646441726F467365UL && (*(unsigned long*)&keyw[28] & 0xFFFFFFFFFFUL) == 0x3273736572UL) {
return KEYW_RPCMETHOD_GETCONFIRMEDSIGNATURESFORADDRESS2; // "getConfirmedSignaturesForAddress2"
}
break;
case 'M':
if (*(unsigned long*)&keyw[4] == 0x61426D756D696E69UL && *(unsigned long*)&keyw[12] == 0x726F4665636E616CUL && *(unsigned long*)&keyw[20] == 0x6D657845746E6552UL && (*(unsigned long*)&keyw[28] & 0xFFFFFFFFFFUL) == 0x6E6F697470UL) {
return KEYW_RPCMETHOD_GETMINIMUMBALANCEFORRENTEXEMPTION; // "getMinimumBalanceForRentExemption"
switch (keyw[0]) {
case 'e':
if (*(unsigned long*)&keyw[1] == 0x6F4E6564756C6378UL && *(unsigned long*)&keyw[9] == 0x616C75637269436EUL && *(unsigned long*)&keyw[17] == 0x6F636341676E6974UL && *(unsigned long*)&keyw[25] == 0x7473694C73746E75UL) {
return KEYW_JSON_EXCLUDENONCIRCULATINGACCOUNTSLIST; // "excludeNonCirculatingAccountsList"
}
break;
case 'g':
if ((*(unsigned long*)&keyw[1] & 0xFFFFUL) == 0x7465UL) {
switch (keyw[3]) {
case 'C':
if (*(unsigned long*)&keyw[4] == 0x64656D7269666E6FUL && *(unsigned long*)&keyw[12] == 0x727574616E676953UL && *(unsigned long*)&keyw[20] == 0x646441726F467365UL && (*(unsigned long*)&keyw[28] & 0xFFFFFFFFFFUL) == 0x3273736572UL) {
return KEYW_RPCMETHOD_GETCONFIRMEDSIGNATURESFORADDRESS2; // "getConfirmedSignaturesForAddress2"
}
break;
case 'M':
if (*(unsigned long*)&keyw[4] == 0x61426D756D696E69UL && *(unsigned long*)&keyw[12] == 0x726F4665636E616CUL && *(unsigned long*)&keyw[20] == 0x6D657845746E6552UL && (*(unsigned long*)&keyw[28] & 0xFFFFFFFFFFUL) == 0x6E6F697470UL) {
return KEYW_RPCMETHOD_GETMINIMUMBALANCEFORRENTEXEMPTION; // "getMinimumBalanceForRentExemption"
}
break;
}
break;
}
break;
}
break;
}
Expand Down Expand Up @@ -861,6 +870,7 @@ const char* un_fd_webserver_json_keyword(long id) {
case KEYW_WS_METHOD_SLOTSUPDATESUNSUBSCRIBE: return "slotsUpdatesUnsubscribe";
case KEYW_WS_METHOD_VOTESUBSCRIBE: return "voteSubscribe";
case KEYW_WS_METHOD_VOTEUNSUBSCRIBE: return "voteUnsubscribe";
case KEYW_JSON_EXCLUDENONCIRCULATINGACCOUNTSLIST: return "excludeNonCirculatingAccountsList";
}
return "???";
}
1 change: 1 addition & 0 deletions src/app/rpcserver/keywords.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
#define KEYW_WS_METHOD_SLOTSUPDATESUNSUBSCRIBE 106L
#define KEYW_WS_METHOD_VOTESUBSCRIBE 107L
#define KEYW_WS_METHOD_VOTEUNSUBSCRIBE 108L
#define KEYW_JSON_EXCLUDENONCIRCULATINGACCOUNTSLIST 109L
#ifndef KEYW_UNKNOWN
#define KEYW_UNKNOWN -1L
#endif
Expand Down
1 change: 1 addition & 0 deletions src/app/rpcserver/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,4 @@ slotsUpdatesSubscribe KEYW_WS_METHOD_SLOTSUPDATESSUBSCRIBE
slotsUpdatesUnsubscribe KEYW_WS_METHOD_SLOTSUPDATESUNSUBSCRIBE
voteSubscribe KEYW_WS_METHOD_VOTESUBSCRIBE
voteUnsubscribe KEYW_WS_METHOD_VOTEUNSUBSCRIBE
excludeNonCirculatingAccountsList KEYW_JSON_EXCLUDENONCIRCULATINGACCOUNTSLIST
36 changes: 36 additions & 0 deletions src/app/rpcserver/test_keywords.h
Original file line number Diff line number Diff line change
Expand Up @@ -2002,4 +2002,40 @@ void test_fd_webserver_json_keyword(void) {
assert(fd_webserver_json_keyword("voteUnsubscr|be\0\0\0\0\0\0\0", 15) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("voteUnsubscri|e\0\0\0\0\0\0\0", 15) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("voteUnsubscrib|\0\0\0\0\0\0\0", 15) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_JSON_EXCLUDENONCIRCULATINGACCOUNTSLIST);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccountsListx\0\0\0\0\0\0\0", 34) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccountsLis\0\0\0\0\0\0\0", 32) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("|xcludeNonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("e|cludeNonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("ex|ludeNonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("exc|udeNonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excl|deNonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("exclu|eNonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("exclud|NonCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("exclude|onCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeN|nCirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNo|CirculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNon|irculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonC|rculatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCi|culatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCir|ulatingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirc|latingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCircu|atingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCircul|tingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCircula|ingAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculat|ngAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculati|gAccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatin|AccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculating|ccountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingA|countsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAc|ountsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAcc|untsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAcco|ntsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccou|tsList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccoun|sList\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccount|List\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccounts|ist\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccountsL|st\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccountsLi|t\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
assert(fd_webserver_json_keyword("excludeNonCirculatingAccountsLis|\0\0\0\0\0\0\0", 33) == KEYW_UNKNOWN);
}
Loading
Loading