@@ -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