Skip to content

Commit 9f5a966

Browse files
ssmikebuffalojoec
andauthored
feat: add invoke context inspection callback (#143)
Co-authored-by: Joe C <[email protected]>
1 parent 4a5a1ca commit 9f5a966

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

harness/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ serde = [
2727
"dep:serde",
2828
"mollusk-svm-result/serde",
2929
]
30+
invocation-inspect-callback = []
3031

3132
[dependencies]
3233
agave-feature-set = { workspace = true }

harness/src/lib.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ pub mod sysvar;
452452
pub use mollusk_svm_result as result;
453453
#[cfg(any(feature = "fuzz", feature = "fuzz-fd"))]
454454
use mollusk_svm_result::Compare;
455+
#[cfg(feature = "invocation-inspect-callback")]
456+
use solana_transaction_context::InstructionAccount;
455457
use {
456458
crate::{
457459
account_store::AccountStore, compile_accounts::CompiledAccounts, epoch_stake::EpochStake,
@@ -489,6 +491,12 @@ pub struct Mollusk {
489491
pub program_cache: ProgramCache,
490492
pub sysvars: Sysvars,
491493

494+
/// The callback which can be used to inspect invoke_context
495+
/// and extract low-level information such as bpf traces, transaction context,
496+
/// detailed timings, etc.
497+
#[cfg(feature = "invocation-inspect-callback")]
498+
pub invocation_inspect_callback: Box<dyn InvocationInspectCallback>,
499+
492500
/// This field stores the slot only to be able to convert to and from FD
493501
/// fixtures and a Mollusk instance, since FD fixtures have a
494502
/// "slot context". However, this field is functionally irrelevant for
@@ -498,6 +506,36 @@ pub struct Mollusk {
498506
pub slot: u64,
499507
}
500508

509+
#[cfg(feature = "invocation-inspect-callback")]
510+
pub trait InvocationInspectCallback {
511+
fn before_invocation(
512+
&self,
513+
program_id: &Pubkey,
514+
instruction_data: &[u8],
515+
instruction_accounts: &[InstructionAccount],
516+
invoke_context: &InvokeContext,
517+
);
518+
519+
fn after_invocation(&self, invoke_context: &InvokeContext);
520+
}
521+
522+
#[cfg(feature = "invocation-inspect-callback")]
523+
pub struct EmptyInvocationInspectCallback;
524+
525+
#[cfg(feature = "invocation-inspect-callback")]
526+
impl InvocationInspectCallback for EmptyInvocationInspectCallback {
527+
fn before_invocation(
528+
&self,
529+
_: &Pubkey,
530+
_: &[u8],
531+
_: &[InstructionAccount],
532+
_: &InvokeContext,
533+
) {
534+
}
535+
536+
fn after_invocation(&self, _: &InvokeContext) {}
537+
}
538+
501539
impl Default for Mollusk {
502540
fn default() -> Self {
503541
#[rustfmt::skip]
@@ -528,6 +566,10 @@ impl Default for Mollusk {
528566
logger: None,
529567
program_cache,
530568
sysvars: Sysvars::default(),
569+
570+
#[cfg(feature = "invocation-inspect-callback")]
571+
invocation_inspect_callback: Box::new(EmptyInvocationInspectCallback {}),
572+
531573
#[cfg(feature = "fuzz-fd")]
532574
slot: 0,
533575
}
@@ -678,7 +720,16 @@ impl Mollusk {
678720
self.compute_budget.to_budget(),
679721
self.compute_budget.to_cost(),
680722
);
681-
if invoke_context.is_precompile(&instruction.program_id) {
723+
724+
#[cfg(feature = "invocation-inspect-callback")]
725+
self.invocation_inspect_callback.before_invocation(
726+
&instruction.program_id,
727+
&instruction.data,
728+
&instruction_accounts,
729+
&invoke_context,
730+
);
731+
732+
let result = if invoke_context.is_precompile(&instruction.program_id) {
682733
invoke_context.process_precompile(
683734
&instruction.program_id,
684735
&instruction.data,
@@ -694,7 +745,13 @@ impl Mollusk {
694745
&mut compute_units_consumed,
695746
&mut timings,
696747
)
697-
}
748+
};
749+
750+
#[cfg(feature = "invocation-inspect-callback")]
751+
self.invocation_inspect_callback
752+
.after_invocation(&invoke_context);
753+
754+
result
698755
};
699756

700757
let return_data = transaction_context.get_return_data().1.to_vec();

0 commit comments

Comments
 (0)