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

add support for return data #63

Merged
merged 4 commits into from
Dec 10, 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
7 changes: 5 additions & 2 deletions fuzz/fixture/proto/invoke.proto
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,17 @@ message InstrEffects {
// Program return code. Zero is success, errors are non-zero.
uint32 program_result = 3;

// The instruction return data.
bytes return_data = 4;

// Copies of accounts that were provided to the instruction. May be in an
// arbitrary order. The pubkey of each account is unique in this list. Each
// account address must also be in the InstrContext.
repeated AcctState resulting_accounts = 4;
repeated AcctState resulting_accounts = 5;
}

// An instruction processing test fixture.
message InstrFixture {
InstrContext input = 1;
InstrEffects output = 2;
}
}
5 changes: 5 additions & 0 deletions fuzz/fixture/src/effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub struct Effects {
pub execution_time: u64,
// Program return code. Zero is success, errors are non-zero.
pub program_result: u32,
pub return_data: Vec<u8>,
/// Resulting accounts with state, to be checked post-simulation.
pub resulting_accounts: Vec<(Pubkey, AccountSharedData)>,
}
Expand All @@ -24,6 +25,7 @@ impl From<ProtoEffects> for Effects {
compute_units_consumed,
execution_time,
program_result,
return_data,
resulting_accounts,
} = value;

Expand All @@ -34,6 +36,7 @@ impl From<ProtoEffects> for Effects {
compute_units_consumed,
execution_time,
program_result,
return_data,
resulting_accounts,
}
}
Expand All @@ -45,6 +48,7 @@ impl From<Effects> for ProtoEffects {
compute_units_consumed,
execution_time,
program_result,
return_data,
resulting_accounts,
} = value;

Expand All @@ -55,6 +59,7 @@ impl From<Effects> for ProtoEffects {
compute_units_consumed,
execution_time,
program_result,
return_data,
resulting_accounts,
}
}
Expand Down
6 changes: 5 additions & 1 deletion harness/src/fuzz/firedancer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ fn build_fixture_effects(context: &FuzzContext, result: &InstructionResult) -> F
}
};

let return_data = result.return_data.clone();

let modified_accounts = context
.accounts
.iter()
Expand All @@ -191,7 +193,7 @@ fn build_fixture_effects(context: &FuzzContext, result: &InstructionResult) -> F
compute_units_available: context
.compute_units_available
.saturating_sub(result.compute_units_consumed),
return_data: Vec::new(), // TODO: Mollusk doesn't capture return data.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Niceeee

return_data,
}
}

Expand All @@ -210,6 +212,7 @@ fn parse_fixture_effects(
};

let program_result = raw_result.clone().into();
let return_data = effects.return_data.clone();

let resulting_accounts = accounts
.iter()
Expand All @@ -232,6 +235,7 @@ fn parse_fixture_effects(
.compute_budget
.compute_unit_limit
.saturating_sub(effects.compute_units_available),
return_data,
resulting_accounts,
}
}
Expand Down
4 changes: 4 additions & 0 deletions harness/src/fuzz/mollusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl From<&InstructionResult> for FuzzEffects {
fn from(input: &InstructionResult) -> Self {
let compute_units_consumed = input.compute_units_consumed;
let execution_time = input.execution_time;
let return_data = input.return_data.clone();

let program_result = match &input.program_result {
ProgramResult::Success => 0,
Expand All @@ -69,6 +70,7 @@ impl From<&InstructionResult> for FuzzEffects {
compute_units_consumed,
execution_time,
program_result,
return_data,
resulting_accounts,
}
}
Expand All @@ -78,6 +80,7 @@ impl From<&FuzzEffects> for InstructionResult {
fn from(input: &FuzzEffects) -> Self {
let compute_units_consumed = input.compute_units_consumed;
let execution_time = input.execution_time;
let return_data = input.return_data.clone();

let raw_result = if input.program_result == 0 {
Ok(())
Expand All @@ -94,6 +97,7 @@ impl From<&FuzzEffects> for InstructionResult {
execution_time,
program_result,
raw_result,
return_data,
resulting_accounts,
}
}
Expand Down
3 changes: 3 additions & 0 deletions harness/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ impl Mollusk {
}
};

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

let resulting_accounts: Vec<(Pubkey, AccountSharedData)> = accounts
.iter()
.map(|(pubkey, account)| {
Expand All @@ -236,6 +238,7 @@ impl Mollusk {
execution_time: timings.details.execute_us,
program_result: invoke_result.clone().into(),
raw_result: invoke_result,
return_data,
resulting_accounts,
}
}
Expand Down
20 changes: 20 additions & 0 deletions harness/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pub struct InstructionResult {
pub program_result: ProgramResult,
/// The raw result of the program's execution.
pub raw_result: Result<(), InstructionError>,
/// The return data produced by the instruction, if any.
pub return_data: Vec<u8>,
/// The resulting accounts after executing the instruction.
///
/// This includes all accounts provided to the processor, in the order
Expand All @@ -66,6 +68,7 @@ impl Default for InstructionResult {
execution_time: 0,
program_result: ProgramResult::Success,
raw_result: Ok(()),
return_data: vec![],
resulting_accounts: vec![],
}
}
Expand Down Expand Up @@ -111,6 +114,15 @@ impl InstructionResult {
actual_result, check_result,
);
}
CheckType::ReturnData(return_data) => {
let check_return_data = return_data;
let actual_return_data = &self.return_data;
assert_eq!(
actual_return_data, check_return_data,
"CHECK: return_data: got {:?}, expected {:?}",
actual_return_data, check_return_data,
);
}
CheckType::ResultingAccount(account) => {
let pubkey = account.pubkey;
let resulting_account = self
Expand Down Expand Up @@ -199,6 +211,7 @@ impl InstructionResult {
b.resulting_accounts.len(),
"resulting accounts length mismatch"
);
assert_eq!(self.return_data, b.return_data, "return data mismatch");
for (a, b) in self
.resulting_accounts
.iter()
Expand All @@ -217,6 +230,8 @@ enum CheckType<'a> {
ExecutionTime(u64),
/// Check the result code of the program's execution.
ProgramResult(ProgramResult),
/// Check the return data produced by executing the instruction.
ReturnData(Vec<u8>),
/// Check a resulting account after executing the instruction.
ResultingAccount(AccountCheck<'a>),
}
Expand Down Expand Up @@ -255,6 +270,11 @@ impl<'a> Check<'a> {
Check::new(CheckType::ProgramResult(ProgramResult::UnknownError(error)))
}

/// Check the return data produced by executing the instruction.
pub fn return_data(return_data: Vec<u8>) -> Self {
Check::new(CheckType::ReturnData(return_data))
}

/// Check a resulting account after executing the instruction.
pub fn account(pubkey: &Pubkey) -> AccountCheckBuilder {
AccountCheckBuilder::new(pubkey)
Expand Down
8 changes: 4 additions & 4 deletions harness/tests/fd_test_vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ fn test_load_firedancer_fixtures() {
loaded_fixture.output.compute_units_available,
generated_fixture.output.compute_units_available,
);
// assert_eq!(
// loaded_fixture.output.return_data,
// generated_fixture.output.return_data,
// );
assert_eq!(
loaded_fixture.output.return_data,
generated_fixture.output.return_data,
);
}
});
});
Expand Down
Loading