Skip to content

Commit 6e901cf

Browse files
authored
Fix get_current_instruction_index (#10387)
* Fix function * Add unit test
1 parent 144737d commit 6e901cf

1 file changed

Lines changed: 103 additions & 4 deletions

File tree

transaction-context/src/transaction.rs

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,18 @@ impl<'ix_data> TransactionContext<'ix_data> {
239239

240240
/// Returns the index in the instruction trace of the current executing instruction
241241
pub fn get_current_instruction_index(&self) -> Result<usize, InstructionError> {
242-
self.get_instruction_stack_height()
243-
.checked_sub(1)
242+
self.instruction_stack
243+
.last()
244+
.copied()
244245
.ok_or(InstructionError::CallDepth)
245246
}
246247

247248
/// Returns a view on the current instruction
248249
pub fn get_current_instruction_context(
249250
&self,
250251
) -> Result<InstructionContext<'_, '_>, InstructionError> {
251-
let level = self.get_current_instruction_index()?;
252-
self.get_instruction_context_at_nesting_level(level)
252+
let index_in_trace = self.get_current_instruction_index()?;
253+
self.get_instruction_context_at_index_in_trace(index_in_trace)
253254
}
254255

255256
/// Returns a view on the next instruction. This function assumes it has already been
@@ -909,4 +910,102 @@ mod tests {
909910
1
910911
);
911912
}
913+
914+
#[test]
915+
fn test_get_current_instruction_index() {
916+
let transaction_accounts = vec![(Pubkey::new_unique(), AccountSharedData::default()); 3];
917+
let mut transaction_context =
918+
TransactionContext::new(transaction_accounts, Rent::default(), 20, 20, 3);
919+
920+
// First top level instruction
921+
transaction_context
922+
.configure_next_instruction(
923+
1,
924+
vec![
925+
InstructionAccount::new(0, false, false),
926+
InstructionAccount::new(1, false, false),
927+
],
928+
vec![u16::MAX; 256],
929+
Cow::Owned(Vec::new()),
930+
None,
931+
)
932+
.unwrap();
933+
transaction_context.push().unwrap();
934+
assert_eq!(
935+
transaction_context.get_current_instruction_index().unwrap(),
936+
0
937+
);
938+
transaction_context.pop().unwrap();
939+
940+
// Second top-level instruction
941+
transaction_context
942+
.configure_next_instruction(
943+
1,
944+
vec![
945+
InstructionAccount::new(0, false, false),
946+
InstructionAccount::new(1, false, true),
947+
],
948+
vec![u16::MAX; 256],
949+
Cow::Owned(Vec::new()),
950+
None,
951+
)
952+
.unwrap();
953+
transaction_context.push().unwrap();
954+
assert_eq!(
955+
transaction_context.get_current_instruction_index().unwrap(),
956+
1
957+
);
958+
959+
// Simulating a CPI
960+
transaction_context
961+
.configure_next_instruction(
962+
1,
963+
vec![
964+
InstructionAccount::new(0, false, true),
965+
InstructionAccount::new(1, false, false),
966+
],
967+
vec![u16::MAX; 256],
968+
Cow::Owned(Vec::new()),
969+
Some(1),
970+
)
971+
.unwrap();
972+
transaction_context.push().unwrap();
973+
assert_eq!(
974+
transaction_context.get_current_instruction_index().unwrap(),
975+
2
976+
);
977+
978+
// Yet another CPI
979+
transaction_context
980+
.configure_next_instruction(
981+
1,
982+
vec![
983+
InstructionAccount::new(0, false, true),
984+
InstructionAccount::new(1, false, false),
985+
],
986+
vec![u16::MAX; 256],
987+
Cow::Owned(Vec::new()),
988+
Some(2),
989+
)
990+
.unwrap();
991+
transaction_context.push().unwrap();
992+
assert_eq!(
993+
transaction_context.get_current_instruction_index().unwrap(),
994+
3
995+
);
996+
997+
// CPI return
998+
transaction_context.pop().unwrap();
999+
assert_eq!(
1000+
transaction_context.get_current_instruction_index().unwrap(),
1001+
2
1002+
);
1003+
1004+
// CPI return 2
1005+
transaction_context.pop().unwrap();
1006+
assert_eq!(
1007+
transaction_context.get_current_instruction_index().unwrap(),
1008+
1
1009+
);
1010+
}
9121011
}

0 commit comments

Comments
 (0)