From 4253dd8cbf2877fc2dd8dfcf6c35f963c2b50578 Mon Sep 17 00:00:00 2001 From: Alex Siegel Date: Tue, 17 Sep 2024 14:06:56 +0000 Subject: [PATCH] various fixes to make solana explorer work better --- agave | 2 +- src/app/rpcserver/fd_block_to_json.c | 151 +++++-- src/app/rpcserver/keywords.c | 32 +- src/app/rpcserver/keywords.h | 1 + src/app/rpcserver/keywords.txt | 1 + src/app/rpcserver/test_keywords.h | 36 ++ src/ballet/http/fd_http_server.c | 14 +- src/ballet/http/fd_http_server.h | 2 + src/flamenco/runtime/fd_executor.c | 68 ++-- src/flamenco/runtime/fd_runtime.c | 5 +- src/flamenco/types/fd_types.c | 564 +++++++++++++++++++++++++++ src/flamenco/types/gen_stubs.py | 8 +- src/funk/fd_funk_rec.c | 20 +- src/funk/fd_funk_val.c | 2 - src/funk/fd_funk_val.h | 1 + 15 files changed, 814 insertions(+), 93 deletions(-) diff --git a/agave b/agave index 3ab17a5da1..601d399e78 160000 --- a/agave +++ b/agave @@ -1 +1 @@ -Subproject commit 3ab17a5da17f7203778596fe91b0a519c3eee2aa +Subproject commit 601d399e7859c54b630e8ac75926803f4b846d45 diff --git a/src/app/rpcserver/fd_block_to_json.c b/src/app/rpcserver/fd_block_to_json.c index b9b643b01a..5408097d84 100644 --- a/src/app/rpcserver/fd_block_to_json.c +++ b/src/app/rpcserver/fd_block_to_json.c @@ -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, @@ -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; } @@ -291,10 +320,31 @@ 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; } @@ -302,10 +352,10 @@ 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; } @@ -313,10 +363,10 @@ 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; } @@ -324,10 +374,31 @@ 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; } @@ -335,10 +406,10 @@ 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; } @@ -346,10 +417,10 @@ 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; } @@ -357,10 +428,10 @@ 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; } @@ -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++) { @@ -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; @@ -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; } diff --git a/src/app/rpcserver/keywords.c b/src/app/rpcserver/keywords.c index 72bb910aaa..bcab8ab2b1 100644 --- a/src/app/rpcserver/keywords.c +++ b/src/app/rpcserver/keywords.c @@ -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; } @@ -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 "???"; } diff --git a/src/app/rpcserver/keywords.h b/src/app/rpcserver/keywords.h index ff8b231544..5d4d8cfd17 100644 --- a/src/app/rpcserver/keywords.h +++ b/src/app/rpcserver/keywords.h @@ -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 diff --git a/src/app/rpcserver/keywords.txt b/src/app/rpcserver/keywords.txt index d61d576e1f..afba5908ea 100644 --- a/src/app/rpcserver/keywords.txt +++ b/src/app/rpcserver/keywords.txt @@ -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 diff --git a/src/app/rpcserver/test_keywords.h b/src/app/rpcserver/test_keywords.h index 60c9e8f6f3..d95de21f09 100644 --- a/src/app/rpcserver/test_keywords.h +++ b/src/app/rpcserver/test_keywords.h @@ -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); } diff --git a/src/ballet/http/fd_http_server.c b/src/ballet/http/fd_http_server.c index a7de8b29a0..7a37469a7c 100644 --- a/src/ballet/http/fd_http_server.c +++ b/src/ballet/http/fd_http_server.c @@ -230,7 +230,9 @@ close_conn( fd_http_server_t * http, #ifdef FD_HTTP_SERVER_DEBUG FD_LOG_NOTICE(( "Closing connection %lu (fd=%d) (%d-%s)", conn_idx, http->pollfds[ conn_idx ].fd, reason, fd_http_server_connection_close_reason_str( reason ) )); #endif - if( FD_UNLIKELY( -1==close( http->pollfds[ conn_idx ].fd ) ) ) FD_LOG_ERR(( "close failed (%i-%s)", errno, strerror( errno ) )); + if( !http->conns[ conn_idx ].keep_alive ) { + if( FD_UNLIKELY( -1==close( http->pollfds[ conn_idx ].fd ) ) ) FD_LOG_ERR(( "close failed (%i-%s)", errno, strerror( errno ) )); + } http->pollfds[ conn_idx ].fd = -1; if( FD_LIKELY( conn_idxmax_conns ) ) { if( FD_LIKELY( http->callbacks.close ) ) http->callbacks.close( conn_idx, reason, http->callback_ctx ); @@ -257,7 +259,7 @@ fd_http_server_ws_close( fd_http_server_t * http, should be closed. Any errors from an accept(2), read(2), or send(2) that are not expected here will be considered fatal and terminate the server. */ - + static inline int is_expected_network_error( int err ) { return @@ -402,6 +404,14 @@ read_conn_http( fd_http_server_t * http, } } + conn->keep_alive = 0; + for( ulong i=0UL; ikeep_alive = ( headers[ i ].value_len==10UL && !strncasecmp( headers[ i ].value, "keep-alive", 10UL ) ); + break; + } + } + char content_type_nul_terminated[ 128 ] = {0}; for( ulong i=0UL; islot_ctx->status_cache ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -237,7 +237,7 @@ fd_executor_check_status_cache( fd_exec_txn_ctx_t * txn_ctx ) { fd_txncache_query_t curr_query; curr_query.blockhash = blockhash->uc; fd_blake3_t b3[1]; - + fd_blake3_init( b3 ); fd_blake3_append( b3, ((uchar *)txn_ctx->_txn_raw->raw + txn_ctx->txn_descriptor->message_off),(ulong)( txn_ctx->_txn_raw->txn_sz - txn_ctx->txn_descriptor->message_off ) ); fd_blake3_fini( b3, &txn_ctx->blake_txn_msg_hash ); @@ -300,8 +300,8 @@ fd_executor_check_txn_program_accounts_and_data_sz( fd_exec_txn_ctx_t * txn_ctx // Check for max loaded acct size fd_borrowed_account_t * acct = NULL; int err = fd_txn_borrowed_account_view_idx( txn_ctx, (uchar)i, &acct ); - ulong acc_size = err==FD_ACC_MGR_SUCCESS ? acct->const_meta->dlen : 0UL; - + ulong acc_size = err==FD_ACC_MGR_SUCCESS ? acct->const_meta->dlen : 0UL; + err = accumulate_and_check_loaded_account_data_size( acc_size, requested_loaded_accounts_data_size, &accumulated_account_size ); if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { return err; @@ -339,7 +339,7 @@ fd_executor_check_txn_program_accounts_and_data_sz( fd_exec_txn_ctx_t * txn_ctx /* https://github.com/anza-xyz/agave/blob/ae18213c19ea5335dfc75e6b6116def0f0910aff/svm/src/account_loader.rs#L406-L410 Side note: I don't think there's a single condition where this statement evaluates to false since builtins_start_index seems to be tied to accounts.len(), so I'll skip this check. Moving on... */ - + // https://github.com/anza-xyz/agave/blob/ae18213c19ea5335dfc75e6b6116def0f0910aff/svm/src/account_loader.rs#L412-L429 FD_BORROWED_ACCOUNT_DECL( owner_account ); err = fd_acc_mgr_view( txn_ctx->slot_ctx->acc_mgr, txn_ctx->slot_ctx->funk_txn, (fd_pubkey_t *) program_account->const_meta->info.owner, owner_account ); @@ -348,7 +348,7 @@ fd_executor_check_txn_program_accounts_and_data_sz( fd_exec_txn_ctx_t * txn_ctx } // https://github.com/anza-xyz/agave/blob/ae18213c19ea5335dfc75e6b6116def0f0910aff/svm/src/account_loader.rs#L413-L418 - if( FD_UNLIKELY( memcmp( owner_account->const_meta->info.owner, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) + if( FD_UNLIKELY( memcmp( owner_account->const_meta->info.owner, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) || !fd_account_is_executable( owner_account->const_meta ) ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; } @@ -371,6 +371,8 @@ fd_executor_check_replenish_program_cache( fd_exec_txn_ctx_t * txn_ctx ) { int err = FD_RUNTIME_EXECUTE_SUCCESS; for( ulong i=0UL; iaccounts_cnt; i++ ) { + FD_SCRATCH_SCOPE_BEGIN { + int hit_max_limit = 0; fd_borrowed_account_t * account = NULL; err = fd_txn_borrowed_account_view_idx( txn_ctx, (uchar)i, &account ); @@ -417,7 +419,7 @@ fd_executor_check_replenish_program_cache( fd_exec_txn_ctx_t * txn_ctx ) { fd_bpf_upgradeable_loader_state_t loader_state[1]; fd_borrowed_account_t * programdata_account = NULL; // https://github.com/anza-xyz/agave/blob/df892c42418047ade3365c1b3ddcf6c45f95d1f1/svm/src/program_loader.rs#L98 - if( FD_LIKELY( !fd_bpf_upgradeable_loader_state_decode( loader_state, &program_decode_ctx ) && + if( FD_LIKELY( !fd_bpf_upgradeable_loader_state_decode( loader_state, &program_decode_ctx ) && !fd_txn_borrowed_account_executable_view( txn_ctx, &loader_state->inner.program.programdata_address, &programdata_account) ) ) { fd_bincode_decode_ctx_t program_data_decode_ctx = { @@ -456,6 +458,8 @@ fd_executor_check_replenish_program_cache( fd_exec_txn_ctx_t * txn_ctx ) { // https://github.com/anza-xyz/agave/blob/df892c42418047ade3365c1b3ddcf6c45f95d1f1/svm/src/transaction_processor.rs#L271 return FD_RUNTIME_TXN_ERR_PROGRAM_CACHE_HIT_MAX_LIMIT; } + + } FD_SCRATCH_SCOPE_END; } return FD_RUNTIME_EXECUTE_SUCCESS; @@ -467,7 +471,7 @@ fd_should_set_exempt_rent_epoch_max( fd_exec_slot_ctx_t * slot_ctx, fd_borrowed_account_t * rec ) { /* https://github.com/anza-xyz/agave/blob/89050f3cb7e76d9e273f10bea5e8207f2452f79f/svm/src/account_loader.rs#L109-L125 */ if( FD_FEATURE_ACTIVE( slot_ctx, disable_rent_fees_collection ) ) { - if( FD_LIKELY( rec->const_meta->info.rent_epoch!=ULONG_MAX + if( FD_LIKELY( rec->const_meta->info.rent_epoch!=ULONG_MAX && rec->const_meta->info.lamports>=fd_rent_exempt_minimum_balance2( &slot_ctx->epoch_ctx->epoch_bank.rent, rec->const_meta->dlen ) ) ) { return 1; } @@ -523,13 +527,13 @@ fd_executor_collect_fees( fd_exec_txn_ctx_t * txn_ctx ) { /* At this point, the fee payer has been validated and the fee has been calculated. This means that the fee can be safely subtracted from the - fee payer's borrowed account. However, the starting lamports of the - account must be updated as well. Each instruction must have the net - same (balanced) amount of lamports. This is done by comparing the - borrowed accounts starting lamports and comparing it to the sum of + fee payer's borrowed account. However, the starting lamports of the + account must be updated as well. Each instruction must have the net + same (balanced) amount of lamports. This is done by comparing the + borrowed accounts starting lamports and comparing it to the sum of the ending lamports. Therefore, we need to update the starting lamports - specifically for the fee payer. - + specifically for the fee payer. + This is especially important in the case where the transaction fails. This is because we need to roll back the account to the balance AFTER the fee is paid. It is also possible for the accounts data and owner to change. @@ -546,7 +550,7 @@ fd_executor_collect_fees( fd_exec_txn_ctx_t * txn_ctx ) { txn_ctx->execution_fee = execution_fee; txn_ctx->priority_fee = priority_fee; - + return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -626,7 +630,7 @@ fd_executor_setup_accessed_accounts_for_txn( fd_exec_txn_ctx_t * txn_ctx ) { /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L175-L176 */ ulong active_addresses_len; - err = fd_get_active_addresses_len( &addr_lookup_table_state.inner.lookup_table, + err = fd_get_active_addresses_len( &addr_lookup_table_state.inner.lookup_table, txn_ctx->slot_ctx->slot_bank.slot, slot_hashes->hashes, lookup_addrs_cnt, @@ -1091,6 +1095,8 @@ void fd_executor_setup_borrowed_accounts_for_txn( fd_exec_txn_ctx_t * txn_ctx ) { ulong j = 0; for( ulong i = 0; i < txn_ctx->accounts_cnt; i++ ) { + FD_SCRATCH_SCOPE_BEGIN { + fd_pubkey_t * acc = &txn_ctx->accounts[i]; txn_ctx->nonce_accounts[i] = 0; @@ -1107,9 +1113,9 @@ fd_executor_setup_borrowed_accounts_for_txn( fd_exec_txn_ctx_t * txn_ctx ) { fd_borrowed_account_make_modifiable( borrowed_account, borrowed_account_data ); - /* All new accounts should have their rent epoch set to ULONG_MAX. + /* All new accounts should have their rent epoch set to ULONG_MAX. https://github.com/anza-xyz/agave/blob/89050f3cb7e76d9e273f10bea5e8207f2452f79f/svm/src/account_loader.rs#L485-L497 */ - if( is_unknown_account + if( is_unknown_account || ( i>0UL && fd_should_set_exempt_rent_epoch_max( txn_ctx->slot_ctx, borrowed_account ) ) ) { borrowed_account->meta->info.rent_epoch = ULONG_MAX; } @@ -1150,6 +1156,8 @@ fd_executor_setup_borrowed_accounts_for_txn( fd_exec_txn_ctx_t * txn_ctx ) { fd_acc_mgr_view( txn_ctx->acc_mgr, txn_ctx->funk_txn, programdata_acc, executable_account); j++; } + + } FD_SCRATCH_SCOPE_END; } txn_ctx->executable_cnt = j; } @@ -1282,7 +1290,7 @@ fd_execute_txn_finalize( fd_exec_txn_ctx_t * txn_ctx, /* Creates a TxnContext Protobuf message from a provided txn_ctx. - The transaction is assumed to have just finished phase 1 of preparation - - Caller of this function should have a scratch frame ready + - Caller of this function should have a scratch frame ready */ static void create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_msg, @@ -1362,7 +1370,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m message->account_keys[i] = account_key; } - /* Transaction Context -> tx -> message -> account_shared_data + /* Transaction Context -> tx -> message -> account_shared_data Contains: - Account data for regular accounts - Account data for LUT accounts @@ -1371,7 +1379,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m */ // Dump regular accounts first message->account_shared_data_count = 0; - message->account_shared_data = fd_scratch_alloc( alignof(fd_exec_test_acct_state_t), + message->account_shared_data = fd_scratch_alloc( alignof(fd_exec_test_acct_state_t), (txn_ctx->accounts_cnt * 2 + txn_descriptor->addr_table_lookup_cnt + num_sysvar_entries) * sizeof(fd_exec_test_acct_state_t) ); for( ulong i = 0; i < txn_ctx->accounts_cnt; ++i ) { FD_BORROWED_ACCOUNT_DECL(borrowed_account); @@ -1484,7 +1492,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m if( !message->is_legacy ) { /* Transaction Context -> tx -> message -> address_table_lookups */ message->address_table_lookups_count = txn_descriptor->addr_table_lookup_cnt; - message->address_table_lookups = fd_scratch_alloc( alignof(fd_exec_test_message_address_table_lookup_t), + message->address_table_lookups = fd_scratch_alloc( alignof(fd_exec_test_message_address_table_lookup_t), txn_descriptor->addr_table_lookup_cnt * sizeof(fd_exec_test_message_address_table_lookup_t) ); for( ulong i = 0; i < txn_descriptor->addr_table_lookup_cnt; ++i ) { // alut -> account_key @@ -1542,12 +1550,12 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m ulong max_age = slot_ctx->slot_bank.block_hash_queue.max_age; txn_context_msg->max_age = max_age; - /* Transaction Context -> blockhash_queue - NOTE: Agave's implementation of register_hash incorrectly allows the blockhash queue to hold max_age + 1 (max 301) - entries. We have this incorrect logic implemented in fd_sysvar_recent_hashes:register_blockhash and it's not a + /* Transaction Context -> blockhash_queue + NOTE: Agave's implementation of register_hash incorrectly allows the blockhash queue to hold max_age + 1 (max 301) + entries. We have this incorrect logic implemented in fd_sysvar_recent_hashes:register_blockhash and it's not a huge issue, but something to keep in mind. */ - pb_bytes_array_t ** output_blockhash_queue = fd_scratch_alloc( - alignof(pb_bytes_array_t *), + pb_bytes_array_t ** output_blockhash_queue = fd_scratch_alloc( + alignof(pb_bytes_array_t *), PB_BYTES_ARRAY_T_ALLOCSIZE((max_age + 1) * sizeof(pb_bytes_array_t *)) ); txn_context_msg->blockhash_queue_count = 0; txn_context_msg->blockhash_queue = output_blockhash_queue; @@ -1558,7 +1566,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m for ( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( queue->ages_pool, queue->ages_root ); n; n = nn ) { nn = fd_hash_hash_age_pair_t_map_successor( queue->ages_pool, n ); - /* Get the index in the blockhash queue + /* Get the index in the blockhash queue - Lower index = newer - 0 will be the most recent blockhash - Index range is [0, max_age] (not a typo) */ @@ -1782,8 +1790,8 @@ int fd_executor_txn_check( fd_exec_slot_ctx_t * slot_ctx, fd_exec_txn_ctx_t *tx ending_dlen += b->meta->dlen; /* Rent states are defined as followed: - - lamports == 0 -> Uninitialized - - 0 < lamports < rent_exempt_minimum -> RentPaying + - lamports == 0 -> Uninitialized + - 0 < lamports < rent_exempt_minimum -> RentPaying - lamports >= rent_exempt_minimum -> RentExempt In Agave, 'self' refers to our 'after' state. */ uchar after_uninitialized = b->meta->info.lamports == 0; diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 012a9b3377..08b76510f1 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1404,9 +1404,10 @@ fd_txn_copy_meta( fd_exec_txn_ctx_t * txn_ctx, uchar * dest, ulong dest_sz ) { for (ulong idx = 0; idx < acct_cnt; idx++) { fd_borrowed_account_t const * acct = &txn_ctx->borrowed_accounts[idx]; - pre_balances[idx] = acct->starting_lamports; + ulong pre = ( acct->starting_lamports == ULONG_MAX ? 0UL : acct->starting_lamports ); + pre_balances[idx] = pre; post_balances[idx] = ( acct->meta ? acct->meta->info.lamports : - ( acct->orig_meta ? acct->orig_meta->info.lamports : acct->starting_lamports ) ); + ( acct->orig_meta ? acct->orig_meta->info.lamports : pre ) ); } if( txn_ctx->return_data.len ) { diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index 6bc1e6fa9e..b4751f7c95 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -6581,6 +6581,22 @@ ulong fd_reward_type_align( void ){ return FD_REWARD_TYPE_ALIGN; } void fd_reward_type_walk( void * w, fd_reward_type_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_reward_type", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "fee", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "rent", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 2: { + fun( w, self, "staking", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 3: { + fun( w, self, "voting", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_reward_type", level-- ); } @@ -13449,6 +13465,22 @@ ulong fd_cluster_type_align( void ){ return FD_CLUSTER_TYPE_ALIGN; } void fd_cluster_type_walk( void * w, fd_cluster_type_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_cluster_type", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "Testnet", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "MainnetBeta", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 2: { + fun( w, self, "Devnet", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 3: { + fun( w, self, "Development", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_cluster_type", level-- ); } @@ -15290,6 +15322,14 @@ ulong fd_vote_authorize_align( void ){ return FD_VOTE_AUTHORIZE_ALIGN; } void fd_vote_authorize_walk( void * w, fd_vote_authorize_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_vote_authorize", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "voter", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "withdrawer", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_vote_authorize", level-- ); } @@ -16130,6 +16170,10 @@ void fd_vote_instruction_walk( void * w, fd_vote_instruction_t const * self, fd_ fun( w, &self->inner.withdraw, "withdraw", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); break; } + case 4: { + fun( w, self, "update_validator_identity", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 5: { fun( w, self, "update_commission", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, &self->inner.update_commission, "update_commission", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); @@ -17197,6 +17241,10 @@ void fd_system_program_instruction_walk( void * w, fd_system_program_instruction fd_system_program_instruction_create_account_with_seed_walk( w, &self->inner.create_account_with_seed, fun, "create_account_with_seed", level ); break; } + case 4: { + fun( w, self, "advance_nonce_account", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 5: { fun( w, self, "withdraw_nonce_account", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, &self->inner.withdraw_nonce_account, "withdraw_nonce_account", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); @@ -17232,6 +17280,10 @@ void fd_system_program_instruction_walk( void * w, fd_system_program_instruction fd_system_program_instruction_transfer_with_seed_walk( w, &self->inner.transfer_with_seed, fun, "transfer_with_seed", level ); break; } + case 12: { + fun( w, self, "upgrade_nonce_account", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_system_program_instruction", level-- ); } @@ -17522,6 +17574,42 @@ ulong fd_system_error_align( void ){ return FD_SYSTEM_ERROR_ALIGN; } void fd_system_error_walk( void * w, fd_system_error_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_system_error", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "account_already_in_use", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "result_with_negative_lamports", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 2: { + fun( w, self, "invalid_program_id", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 3: { + fun( w, self, "invalid_account_data_length", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 4: { + fun( w, self, "max_seed_length_exceeded", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 5: { + fun( w, self, "address_with_seed_mismatch", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 6: { + fun( w, self, "nonce_no_recent_blockhashes", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 7: { + fun( w, self, "nonce_blockhash_not_expired", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 8: { + fun( w, self, "nonce_unexpected_blockhash_value", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_system_error", level-- ); } @@ -17958,6 +18046,14 @@ ulong fd_stake_authorize_align( void ){ return FD_STAKE_AUTHORIZE_ALIGN; } void fd_stake_authorize_walk( void * w, fd_stake_authorize_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_stake_authorize", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "staker", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "withdrawer", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_stake_authorize", level-- ); } @@ -18980,6 +19076,10 @@ void fd_stake_instruction_walk( void * w, fd_stake_instruction_t const * self, f fd_stake_instruction_authorize_walk( w, &self->inner.authorize, fun, "authorize", level ); break; } + case 2: { + fun( w, self, "delegate_stake", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 3: { fun( w, self, "split", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, &self->inner.split, "split", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); @@ -18990,16 +19090,28 @@ void fd_stake_instruction_walk( void * w, fd_stake_instruction_t const * self, f fun( w, &self->inner.withdraw, "withdraw", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); break; } + case 5: { + fun( w, self, "deactivate", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 6: { fun( w, self, "set_lockup", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_lockup_args_walk( w, &self->inner.set_lockup, fun, "set_lockup", level ); break; } + case 7: { + fun( w, self, "merge", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 8: { fun( w, self, "authorize_with_seed", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_authorize_with_seed_args_walk( w, &self->inner.authorize_with_seed, fun, "authorize_with_seed", level ); break; } + case 9: { + fun( w, self, "initialize_checked", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 10: { fun( w, self, "authorize_checked", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_stake_authorize_walk( w, &self->inner.authorize_checked, fun, "authorize_checked", level ); @@ -19015,6 +19127,18 @@ void fd_stake_instruction_walk( void * w, fd_stake_instruction_t const * self, f fd_lockup_checked_args_walk( w, &self->inner.set_lockup_checked, fun, "set_lockup_checked", level ); break; } + case 13: { + fun( w, self, "get_minimum_delegation", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 14: { + fun( w, self, "deactivate_delinquent", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 15: { + fun( w, self, "redelegate", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 16: { fun( w, self, "move_stake", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, &self->inner.move_stake, "move_stake", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); @@ -19539,6 +19663,10 @@ ulong fd_stake_state_v2_align( void ){ return FD_STAKE_STATE_V2_ALIGN; } void fd_stake_state_v2_walk( void * w, fd_stake_state_v2_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_stake_state_v2", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "uninitialized", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 1: { fun( w, self, "initialized", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_stake_state_v2_initialized_walk( w, &self->inner.initialized, fun, "initialized", level ); @@ -19549,6 +19677,10 @@ void fd_stake_state_v2_walk( void * w, fd_stake_state_v2_t const * self, fd_type fd_stake_state_v2_stake_walk( w, &self->inner.stake, fun, "stake", level ); break; } + case 3: { + fun( w, self, "rewards_pool", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_stake_state_v2", level-- ); } @@ -19762,6 +19894,10 @@ ulong fd_nonce_state_align( void ){ return FD_NONCE_STATE_ALIGN; } void fd_nonce_state_walk( void * w, fd_nonce_state_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_nonce_state", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "uninitialized", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 1: { fun( w, self, "initialized", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_nonce_data_walk( w, &self->inner.initialized, fun, "initialized", level ); @@ -20546,6 +20682,10 @@ void fd_bpf_loader_program_instruction_walk( void * w, fd_bpf_loader_program_ins fd_bpf_loader_program_instruction_write_walk( w, &self->inner.write, fun, "write", level ); break; } + case 1: { + fun( w, self, "finalize", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_bpf_loader_program_instruction", level-- ); } @@ -20812,6 +20952,18 @@ void fd_bpf_loader_v4_program_instruction_walk( void * w, fd_bpf_loader_v4_progr fun( w, &self->inner.truncate, "truncate", FD_FLAMENCO_TYPE_UINT, "uint", level ); break; } + case 2: { + fun( w, self, "deploy", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 3: { + fun( w, self, "retract", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 4: { + fun( w, self, "transfer_authority", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_bpf_loader_v4_program_instruction", level-- ); } @@ -21231,6 +21383,10 @@ ulong fd_bpf_upgradeable_loader_program_instruction_align( void ){ return FD_BPF void fd_bpf_upgradeable_loader_program_instruction_walk( void * w, fd_bpf_upgradeable_loader_program_instruction_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_bpf_upgradeable_loader_program_instruction", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "initialize_buffer", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 1: { fun( w, self, "write", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_bpf_upgradeable_loader_program_instruction_write_walk( w, &self->inner.write, fun, "write", level ); @@ -21241,11 +21397,27 @@ void fd_bpf_upgradeable_loader_program_instruction_walk( void * w, fd_bpf_upgrad fd_bpf_upgradeable_loader_program_instruction_deploy_with_max_data_len_walk( w, &self->inner.deploy_with_max_data_len, fun, "deploy_with_max_data_len", level ); break; } + case 3: { + fun( w, self, "upgrade", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 4: { + fun( w, self, "set_authority", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 5: { + fun( w, self, "close", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 6: { fun( w, self, "extend_program", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_bpf_upgradeable_loader_program_instruction_extend_program_walk( w, &self->inner.extend_program, fun, "extend_program", level ); break; } + case 7: { + fun( w, self, "set_authority_checked", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_bpf_upgradeable_loader_program_instruction", level-- ); } @@ -21686,6 +21858,10 @@ ulong fd_bpf_upgradeable_loader_state_align( void ){ return FD_BPF_UPGRADEABLE_L void fd_bpf_upgradeable_loader_state_walk( void * w, fd_bpf_upgradeable_loader_state_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_bpf_upgradeable_loader_state", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "uninitialized", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 1: { fun( w, self, "buffer", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_bpf_upgradeable_loader_state_buffer_walk( w, &self->inner.buffer, fun, "buffer", level ); @@ -22213,6 +22389,10 @@ ulong fd_address_lookup_table_state_align( void ){ return FD_ADDRESS_LOOKUP_TABL void fd_address_lookup_table_state_walk( void * w, fd_address_lookup_table_state_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_address_lookup_table_state", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "uninitialized", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 1: { fun( w, self, "lookup_table", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_address_lookup_table_walk( w, &self->inner.lookup_table, fun, "lookup_table", level ); @@ -27004,11 +27184,23 @@ void fd_addrlut_instruction_walk( void * w, fd_addrlut_instruction_t const * sel fd_addrlut_create_walk( w, &self->inner.create_lut, fun, "create_lut", level ); break; } + case 1: { + fun( w, self, "freeze_lut", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 2: { fun( w, self, "extend_lut", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_addrlut_extend_walk( w, &self->inner.extend_lut, fun, "extend_lut", level ); break; } + case 3: { + fun( w, self, "deactivate_lut", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 4: { + fun( w, self, "close_lut", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_addrlut_instruction", level-- ); } @@ -27678,6 +27870,34 @@ ulong fd_repair_protocol_align( void ){ return FD_REPAIR_PROTOCOL_ALIGN; } void fd_repair_protocol_walk( void * w, fd_repair_protocol_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_repair_protocol", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "LegacyWindowIndex", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "LegacyHighestWindowIndex", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 2: { + fun( w, self, "LegacyOrphan", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 3: { + fun( w, self, "LegacyWindowIndexWithNonce", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 4: { + fun( w, self, "LegacyHighestWindowIndexWithNonce", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 5: { + fun( w, self, "LegacyOrphanWithNonce", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 6: { + fun( w, self, "LegacyAncestorHashes", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 7: { fun( w, self, "pong", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_gossip_ping_walk( w, &self->inner.pong, fun, "pong", level ); @@ -28619,16 +28839,224 @@ ulong fd_instr_error_enum_align( void ){ return FD_INSTR_ERROR_ENUM_ALIGN; } void fd_instr_error_enum_walk( void * w, fd_instr_error_enum_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_instr_error_enum", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "generic_error", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "invalid_argument", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 2: { + fun( w, self, "invalid_instruction_data", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 3: { + fun( w, self, "invalid_account_data", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 4: { + fun( w, self, "account_data_too_small", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 5: { + fun( w, self, "insufficient_funds", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 6: { + fun( w, self, "incorrect_program_id", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 7: { + fun( w, self, "missing_required_signature", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 8: { + fun( w, self, "account_already_initialized", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 9: { + fun( w, self, "uninitialized_account", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 10: { + fun( w, self, "unbalanced_instruction", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 11: { + fun( w, self, "modified_program_id", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 12: { + fun( w, self, "external_account_lamport_spend", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 13: { + fun( w, self, "external_account_data_modified", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 14: { + fun( w, self, "readonly_lamport_change", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 15: { + fun( w, self, "readonly_data_modified", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 16: { + fun( w, self, "duplicate_account_index", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 17: { + fun( w, self, "executable_modified", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 18: { + fun( w, self, "rent_epoch_modified", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 19: { + fun( w, self, "not_enough_account_keys", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 20: { + fun( w, self, "account_data_size_changed", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 21: { + fun( w, self, "account_not_executable", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 22: { + fun( w, self, "account_borrow_failed", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 23: { + fun( w, self, "account_borrow_outstanding", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 24: { + fun( w, self, "duplicate_account_out_of_sync", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 25: { fun( w, self, "custom", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, &self->inner.custom, "custom", FD_FLAMENCO_TYPE_UINT, "uint", level ); break; } + case 26: { + fun( w, self, "invalid_error", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 27: { + fun( w, self, "executable_data_modified", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 28: { + fun( w, self, "executable_lamport_change", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 29: { + fun( w, self, "executable_account_not_rent_exempt", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 30: { + fun( w, self, "unsupported_program_id", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 31: { + fun( w, self, "call_depth", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 32: { + fun( w, self, "missing_account", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 33: { + fun( w, self, "reentrancy_not_allowed", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 34: { + fun( w, self, "max_seed_length_exceeded", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 35: { + fun( w, self, "invalid_seeds", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 36: { + fun( w, self, "invalid_realloc", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 37: { + fun( w, self, "computational_budget_exceeded", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 38: { + fun( w, self, "privilege_escalation", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 39: { + fun( w, self, "program_environment_setup_failure", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 40: { + fun( w, self, "program_failed_to_complete", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 41: { + fun( w, self, "program_failed_to_compile", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 42: { + fun( w, self, "immutable", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 43: { + fun( w, self, "incorrect_authority", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 44: { fun( w, self, "borsh_io_error", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, self->inner.borsh_io_error, "borsh_io_error", FD_FLAMENCO_TYPE_CSTR, "char*", level ); break; } + case 45: { + fun( w, self, "account_not_rent_exempt", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 46: { + fun( w, self, "invalid_account_owner", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 47: { + fun( w, self, "arithmetic_overflow", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 48: { + fun( w, self, "unsupported_sysvar", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 49: { + fun( w, self, "illegal_owner", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 50: { + fun( w, self, "max_accounts_data_allocations_exceeded", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 51: { + fun( w, self, "max_accounts_exceeded", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 52: { + fun( w, self, "max_instruction_trace_length_exceeded", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 53: { + fun( w, self, "builtin_programs_must_consume_compute_units", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_instr_error_enum", level-- ); } @@ -29269,11 +29697,127 @@ ulong fd_txn_error_enum_align( void ){ return FD_TXN_ERROR_ENUM_ALIGN; } void fd_txn_error_enum_walk( void * w, fd_txn_error_enum_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_txn_error_enum", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "account_in_use", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 1: { + fun( w, self, "account_loaded_twice", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 2: { + fun( w, self, "account_not_found", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 3: { + fun( w, self, "program_account_not_found", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 4: { + fun( w, self, "insufficient_funds_for_fee", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 5: { + fun( w, self, "invalid_account_for_fee", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 6: { + fun( w, self, "already_processed", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 7: { + fun( w, self, "blockhash_not_found", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 8: { fun( w, self, "instruction_error", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_txn_instr_error_walk( w, &self->inner.instruction_error, fun, "instruction_error", level ); break; } + case 9: { + fun( w, self, "call_chain_too_deep", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 10: { + fun( w, self, "missing_signature_for_fee", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 11: { + fun( w, self, "invalid_account_index", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 12: { + fun( w, self, "signature_failure", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 13: { + fun( w, self, "invalid_program_for_execution", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 14: { + fun( w, self, "sanitize_failure", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 15: { + fun( w, self, "cluster_maintenance", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 16: { + fun( w, self, "account_borrow_outstanding", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 17: { + fun( w, self, "would_exceed_max_block_cost_limit", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 18: { + fun( w, self, "unsupported_version", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 19: { + fun( w, self, "invalid_writable_account", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 20: { + fun( w, self, "would_exceed_max_account_cost_limit", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 21: { + fun( w, self, "would_exceed_account_data_block_limit", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 22: { + fun( w, self, "too_many_account_locks", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 23: { + fun( w, self, "address_lookup_table_not_found", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 24: { + fun( w, self, "invalid_address_lookup_table_owner", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 25: { + fun( w, self, "invalid_address_lookup_table_data", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 26: { + fun( w, self, "invalid_address_lookup_table_index", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 27: { + fun( w, self, "invalid_rent_paying_account", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 28: { + fun( w, self, "would_exceed_max_vote_cost_limit", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 29: { + fun( w, self, "would_exceed_account_data_total_limit", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 30: { fun( w, self, "duplicate_instruction", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, &self->inner.duplicate_instruction, "duplicate_instruction", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); @@ -29284,11 +29828,27 @@ void fd_txn_error_enum_walk( void * w, fd_txn_error_enum_t const * self, fd_type fun( w, &self->inner.insufficient_funds_for_rent, "insufficient_funds_for_rent", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); break; } + case 32: { + fun( w, self, "max_loaded_accounts_data_size_exceeded", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 33: { + fun( w, self, "invalid_loaded_accounts_data_size_limit", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } + case 34: { + fun( w, self, "resanitization_needed", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 35: { fun( w, self, "program_execution_temporarily_restricted", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fun( w, &self->inner.program_execution_temporarily_restricted, "program_execution_temporarily_restricted", FD_FLAMENCO_TYPE_UCHAR, "uchar", level ); break; } + case 36: { + fun( w, self, "unbalanced_transaction", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } } fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "fd_txn_error_enum", level-- ); } @@ -29440,6 +30000,10 @@ ulong fd_txn_result_align( void ){ return FD_TXN_RESULT_ALIGN; } void fd_txn_result_walk( void * w, fd_txn_result_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "fd_txn_result", level++); switch( self->discriminant ) { + case 0: { + fun( w, self, "ok", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); + break; + } case 1: { fun( w, self, "error", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level ); fd_txn_error_enum_walk( w, &self->inner.error, fun, "error", level ); diff --git a/src/flamenco/types/gen_stubs.py b/src/flamenco/types/gen_stubs.py index b55c6fd236..d7a347df8c 100644 --- a/src/flamenco/types/gen_stubs.py +++ b/src/flamenco/types/gen_stubs.py @@ -2230,12 +2230,14 @@ def emitImpls(self): print(f' fun(w, self, name, FD_FLAMENCO_TYPE_ENUM, "{n}", level++);', file=body) print(' switch( self->discriminant ) {', file=body) for i, v in enumerate(self.variants): + print(f' case {i}: {{', file=body) if not isinstance(v, str): - print(f' case {i}: {{', file=body) print(f' fun( w, self, "{v.name}", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level );', file=body) v.emitWalk("inner.") - print(' break;', file=body) - print(' }', file=body) + else: + print(f' fun( w, self, "{v}", FD_FLAMENCO_TYPE_ENUM_DISC, "discriminant", level );', file=body) + print(' break;', file=body) + print(' }', file=body) print(' }', file=body) print(f' fun( w, self, name, FD_FLAMENCO_TYPE_ENUM_END, "{n}", level-- );', file=body) print("}", file=body) diff --git a/src/funk/fd_funk_rec.c b/src/funk/fd_funk_rec.c index 869f8701dd..d852c54f47 100644 --- a/src/funk/fd_funk_rec.c +++ b/src/funk/fd_funk_rec.c @@ -99,6 +99,9 @@ fd_funk_rec_query_xid_safe( fd_funk_t * funk, fd_funk_xid_key_pair_t pair[1]; fd_funk_xid_key_pair_init( pair, xid, key ); + void * result = NULL; + ulong alloc_len = 0; + *result_len = 0; for(;;) { ulong lock_start; for(;;) { @@ -114,10 +117,21 @@ fd_funk_rec_query_xid_safe( fd_funk_t * funk, FD_COMPILER_MFENCE(); if( lock_start == funk->write_lock ) return NULL; } else { - void * res = fd_funk_val_safe( rec, wksp, valloc, result_len ); + uint val_sz = rec->val_sz; + if( val_sz ) { + if( result == NULL ) { + result = fd_valloc_malloc( valloc, FD_FUNK_VAL_ALIGN, val_sz ); + alloc_len = val_sz; + } else if ( val_sz > alloc_len ) { + fd_valloc_free( valloc, result ); + result = fd_valloc_malloc( valloc, FD_FUNK_VAL_ALIGN, val_sz ); + alloc_len = val_sz; + } + fd_memcpy( result, fd_wksp_laddr_fast( wksp, rec->val_gaddr ), val_sz ); + } + *result_len = val_sz; FD_COMPILER_MFENCE(); - if( lock_start == funk->write_lock ) return res; - fd_valloc_free( valloc, res ); + if( lock_start == funk->write_lock ) return result; } /* else try again */ diff --git a/src/funk/fd_funk_val.c b/src/funk/fd_funk_val.c index 911b3e825c..bbef7c2c20 100644 --- a/src/funk/fd_funk_val.c +++ b/src/funk/fd_funk_val.c @@ -1,7 +1,5 @@ #include "fd_funk.h" -#define FD_FUNK_VAL_ALIGN 8UL - fd_funk_rec_t * fd_funk_val_copy( fd_funk_rec_t * rec, void const * data, diff --git a/src/funk/fd_funk_val.h b/src/funk/fd_funk_val.h index 0b83c78aaa..3de5810962 100644 --- a/src/funk/fd_funk_val.h +++ b/src/funk/fd_funk_val.h @@ -9,6 +9,7 @@ /* FD_FUNK_REC_VAL_MAX is the maximum size of a record value. */ #define FD_FUNK_REC_VAL_MAX UINT_MAX +#define FD_FUNK_VAL_ALIGN 8UL FD_PROTOTYPES_BEGIN