Skip to content

Commit 2be6299

Browse files
authored
add support for return data (#63)
1 parent 11d1530 commit 2be6299

File tree

7 files changed

+46
-7
lines changed

7 files changed

+46
-7
lines changed

fuzz/fixture/proto/invoke.proto

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,17 @@ message InstrEffects {
6464
// Program return code. Zero is success, errors are non-zero.
6565
uint32 program_result = 3;
6666

67+
// The instruction return data.
68+
bytes return_data = 4;
69+
6770
// Copies of accounts that were provided to the instruction. May be in an
6871
// arbitrary order. The pubkey of each account is unique in this list. Each
6972
// account address must also be in the InstrContext.
70-
repeated AcctState resulting_accounts = 4;
73+
repeated AcctState resulting_accounts = 5;
7174
}
7275

7376
// An instruction processing test fixture.
7477
message InstrFixture {
7578
InstrContext input = 1;
7679
InstrEffects output = 2;
77-
}
80+
}

fuzz/fixture/src/effects.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct Effects {
1414
pub execution_time: u64,
1515
// Program return code. Zero is success, errors are non-zero.
1616
pub program_result: u32,
17+
pub return_data: Vec<u8>,
1718
/// Resulting accounts with state, to be checked post-simulation.
1819
pub resulting_accounts: Vec<(Pubkey, AccountSharedData)>,
1920
}
@@ -24,6 +25,7 @@ impl From<ProtoEffects> for Effects {
2425
compute_units_consumed,
2526
execution_time,
2627
program_result,
28+
return_data,
2729
resulting_accounts,
2830
} = value;
2931

@@ -34,6 +36,7 @@ impl From<ProtoEffects> for Effects {
3436
compute_units_consumed,
3537
execution_time,
3638
program_result,
39+
return_data,
3740
resulting_accounts,
3841
}
3942
}
@@ -45,6 +48,7 @@ impl From<Effects> for ProtoEffects {
4548
compute_units_consumed,
4649
execution_time,
4750
program_result,
51+
return_data,
4852
resulting_accounts,
4953
} = value;
5054

@@ -55,6 +59,7 @@ impl From<Effects> for ProtoEffects {
5559
compute_units_consumed,
5660
execution_time,
5761
program_result,
62+
return_data,
5863
resulting_accounts,
5964
}
6065
}

harness/src/fuzz/firedancer.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ fn build_fixture_effects(context: &FuzzContext, result: &InstructionResult) -> F
169169
}
170170
};
171171

172+
let return_data = result.return_data.clone();
173+
172174
let modified_accounts = context
173175
.accounts
174176
.iter()
@@ -191,7 +193,7 @@ fn build_fixture_effects(context: &FuzzContext, result: &InstructionResult) -> F
191193
compute_units_available: context
192194
.compute_units_available
193195
.saturating_sub(result.compute_units_consumed),
194-
return_data: Vec::new(), // TODO: Mollusk doesn't capture return data.
196+
return_data,
195197
}
196198
}
197199

@@ -210,6 +212,7 @@ fn parse_fixture_effects(
210212
};
211213

212214
let program_result = raw_result.clone().into();
215+
let return_data = effects.return_data.clone();
213216

214217
let resulting_accounts = accounts
215218
.iter()
@@ -232,6 +235,7 @@ fn parse_fixture_effects(
232235
.compute_budget
233236
.compute_unit_limit
234237
.saturating_sub(effects.compute_units_available),
238+
return_data,
235239
resulting_accounts,
236240
}
237241
}

harness/src/fuzz/mollusk.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ impl From<&InstructionResult> for FuzzEffects {
5656
fn from(input: &InstructionResult) -> Self {
5757
let compute_units_consumed = input.compute_units_consumed;
5858
let execution_time = input.execution_time;
59+
let return_data = input.return_data.clone();
5960

6061
let program_result = match &input.program_result {
6162
ProgramResult::Success => 0,
@@ -69,6 +70,7 @@ impl From<&InstructionResult> for FuzzEffects {
6970
compute_units_consumed,
7071
execution_time,
7172
program_result,
73+
return_data,
7274
resulting_accounts,
7375
}
7476
}
@@ -78,6 +80,7 @@ impl From<&FuzzEffects> for InstructionResult {
7880
fn from(input: &FuzzEffects) -> Self {
7981
let compute_units_consumed = input.compute_units_consumed;
8082
let execution_time = input.execution_time;
83+
let return_data = input.return_data.clone();
8184

8285
let raw_result = if input.program_result == 0 {
8386
Ok(())
@@ -94,6 +97,7 @@ impl From<&FuzzEffects> for InstructionResult {
9497
execution_time,
9598
program_result,
9699
raw_result,
100+
return_data,
97101
resulting_accounts,
98102
}
99103
}

harness/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ impl Mollusk {
217217
}
218218
};
219219

220+
let return_data = transaction_context.get_return_data().1.to_vec();
221+
220222
let resulting_accounts: Vec<(Pubkey, AccountSharedData)> = accounts
221223
.iter()
222224
.map(|(pubkey, account)| {
@@ -236,6 +238,7 @@ impl Mollusk {
236238
execution_time: timings.details.execute_us,
237239
program_result: invoke_result.clone().into(),
238240
raw_result: invoke_result,
241+
return_data,
239242
resulting_accounts,
240243
}
241244
}

harness/src/result.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ pub struct InstructionResult {
5151
pub program_result: ProgramResult,
5252
/// The raw result of the program's execution.
5353
pub raw_result: Result<(), InstructionError>,
54+
/// The return data produced by the instruction, if any.
55+
pub return_data: Vec<u8>,
5456
/// The resulting accounts after executing the instruction.
5557
///
5658
/// This includes all accounts provided to the processor, in the order
@@ -66,6 +68,7 @@ impl Default for InstructionResult {
6668
execution_time: 0,
6769
program_result: ProgramResult::Success,
6870
raw_result: Ok(()),
71+
return_data: vec![],
6972
resulting_accounts: vec![],
7073
}
7174
}
@@ -111,6 +114,15 @@ impl InstructionResult {
111114
actual_result, check_result,
112115
);
113116
}
117+
CheckType::ReturnData(return_data) => {
118+
let check_return_data = return_data;
119+
let actual_return_data = &self.return_data;
120+
assert_eq!(
121+
actual_return_data, check_return_data,
122+
"CHECK: return_data: got {:?}, expected {:?}",
123+
actual_return_data, check_return_data,
124+
);
125+
}
114126
CheckType::ResultingAccount(account) => {
115127
let pubkey = account.pubkey;
116128
let resulting_account = self
@@ -199,6 +211,7 @@ impl InstructionResult {
199211
b.resulting_accounts.len(),
200212
"resulting accounts length mismatch"
201213
);
214+
assert_eq!(self.return_data, b.return_data, "return data mismatch");
202215
for (a, b) in self
203216
.resulting_accounts
204217
.iter()
@@ -217,6 +230,8 @@ enum CheckType<'a> {
217230
ExecutionTime(u64),
218231
/// Check the result code of the program's execution.
219232
ProgramResult(ProgramResult),
233+
/// Check the return data produced by executing the instruction.
234+
ReturnData(Vec<u8>),
220235
/// Check a resulting account after executing the instruction.
221236
ResultingAccount(AccountCheck<'a>),
222237
}
@@ -255,6 +270,11 @@ impl<'a> Check<'a> {
255270
Check::new(CheckType::ProgramResult(ProgramResult::UnknownError(error)))
256271
}
257272

273+
/// Check the return data produced by executing the instruction.
274+
pub fn return_data(return_data: Vec<u8>) -> Self {
275+
Check::new(CheckType::ReturnData(return_data))
276+
}
277+
258278
/// Check a resulting account after executing the instruction.
259279
pub fn account(pubkey: &Pubkey) -> AccountCheckBuilder {
260280
AccountCheckBuilder::new(pubkey)

harness/tests/fd_test_vectors.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@ fn test_load_firedancer_fixtures() {
106106
loaded_fixture.output.compute_units_available,
107107
generated_fixture.output.compute_units_available,
108108
);
109-
// assert_eq!(
110-
// loaded_fixture.output.return_data,
111-
// generated_fixture.output.return_data,
112-
// );
109+
assert_eq!(
110+
loaded_fixture.output.return_data,
111+
generated_fixture.output.return_data,
112+
);
113113
}
114114
});
115115
});

0 commit comments

Comments
 (0)