@@ -101,6 +101,8 @@ fd_get_executable_program_content_for_v4_loader( fd_txn_account_t const * progra
101
101
return NULL ;
102
102
}
103
103
104
+ /* This subtraction is safe because get_state() implicitly checks the
105
+ dlen. */
104
106
* program_data_len = program_acc -> vt -> get_data_len ( program_acc ) - LOADER_V4_PROGRAM_DATA_OFFSET ;
105
107
return program_acc -> vt -> get_data ( program_acc ) + LOADER_V4_PROGRAM_DATA_OFFSET ;
106
108
}
@@ -361,9 +363,6 @@ fd_program_cache_create_cache_entry( fd_exec_slot_ctx_t * slot_ctx,
361
363
program_acc ,
362
364
& program_data_len ,
363
365
runtime_spad );
364
- if ( FD_UNLIKELY ( program_data == NULL ) ) {
365
- return ;
366
- }
367
366
368
367
/* This prepare should never fail. */
369
368
int funk_err = FD_FUNK_SUCCESS ;
@@ -373,6 +372,20 @@ fd_program_cache_create_cache_entry( fd_exec_slot_ctx_t * slot_ctx,
373
372
FD_LOG_CRIT (( "fd_funk_rec_prepare() failed: %i-%s" , funk_err , fd_funk_strerror ( funk_err ) ));
374
373
}
375
374
375
+ /* In Agave's load_program_with_pubkey(), if program data cannot be
376
+ obtained, a tombstone cache entry of type Closed or
377
+ FailedVerification is created. For correctness, we could just
378
+ not insert a cache entry when there is no valid program data.
379
+ Nonetheless, for purely conformance on instruction error log
380
+ messages reasons, specifically "Program is not deployed" vs
381
+ "Program is not cached", we would like to have a cache entry
382
+ precisely when Agave does, such that we match Agave exactly on
383
+ this error log. So, we insert a cache entry here. */
384
+ if ( FD_UNLIKELY ( program_data == NULL ) ) {
385
+ fd_program_cache_publish_failed_verification_rec ( funk , prepare , rec , current_slot );
386
+ return ;
387
+ }
388
+
376
389
fd_sbpf_elf_info_t elf_info = {0 };
377
390
if ( FD_UNLIKELY ( fd_program_cache_parse_elf_info ( & elf_info , program_data , program_data_len , slot_ctx ) ) ) {
378
391
fd_program_cache_publish_failed_verification_rec ( funk , prepare , rec , current_slot );
@@ -516,6 +529,12 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) {
516
529
& program_data_len ,
517
530
runtime_spad );
518
531
if ( FD_UNLIKELY ( program_data == NULL ) ) {
532
+ /* Unlike in fd_program_cache_create_cache_entry(), where we need to
533
+ insert an entry into the cache when we cannot obtain valid
534
+ program data, here we could simply return because we know, at
535
+ this point, that the program is already in the cache. So we
536
+ don't need to do anything extra for matching Agave on cache entry
537
+ presence. */
519
538
return ;
520
539
}
521
540
0 commit comments