5
5
solana_program_runtime:: {
6
6
invoke_context:: InvokeContext ,
7
7
loaded_programs:: {
8
- LoadProgramMetrics , ProgramCacheEntry , ProgramCacheEntryType ,
8
+ LoadProgramMetrics , ProgramCacheEntry , ProgramCacheEntryOwner , ProgramCacheEntryType ,
9
9
DELAY_VISIBILITY_SLOT_OFFSET ,
10
10
} ,
11
11
stable_log,
@@ -199,10 +199,6 @@ fn check_program_account(
199
199
ic_logger_msg ! ( log_collector, "Program not owned by loader" ) ;
200
200
return Err ( InstructionError :: InvalidAccountOwner ) ;
201
201
}
202
- if program. get_data ( ) . is_empty ( ) {
203
- ic_logger_msg ! ( log_collector, "Program is uninitialized" ) ;
204
- return Err ( InstructionError :: InvalidAccountData ) ;
205
- }
206
202
let state = get_state ( program. get_data ( ) ) ?;
207
203
if !program. is_writable ( ) {
208
204
ic_logger_msg ! ( log_collector, "Program is not writeable" ) ;
@@ -488,12 +484,22 @@ pub fn process_instruction_retract(
488
484
) ;
489
485
return Err ( InstructionError :: InvalidArgument ) ;
490
486
}
491
- if matches ! ( state. status, LoaderV4Status :: Retracted ) {
487
+ if ! matches ! ( state. status, LoaderV4Status :: Deployed ) {
492
488
ic_logger_msg ! ( log_collector, "Program is not deployed" ) ;
493
489
return Err ( InstructionError :: InvalidArgument ) ;
494
490
}
495
491
let state = get_state_mut ( program. get_data_mut ( ) ?) ?;
496
492
state. status = LoaderV4Status :: Retracted ;
493
+ invoke_context
494
+ . program_cache_for_tx_batch
495
+ . store_modified_entry (
496
+ * program. get_key ( ) ,
497
+ Arc :: new ( ProgramCacheEntry :: new_tombstone (
498
+ current_slot,
499
+ ProgramCacheEntryOwner :: LoaderV4 ,
500
+ ProgramCacheEntryType :: Closed ,
501
+ ) ) ,
502
+ ) ;
497
503
Ok ( ( ) )
498
504
}
499
505
@@ -518,12 +524,16 @@ pub fn process_instruction_transfer_authority(
518
524
& program,
519
525
authority_address,
520
526
) ?;
521
- if new_authority_address. is_some ( ) && !instruction_context. is_instruction_account_signer ( 2 ) ? {
522
- ic_logger_msg ! ( log_collector, "New authority did not sign" ) ;
523
- return Err ( InstructionError :: MissingRequiredSignature ) ;
524
- }
525
527
let state = get_state_mut ( program. get_data_mut ( ) ?) ?;
526
528
if let Some ( new_authority_address) = new_authority_address {
529
+ if !instruction_context. is_instruction_account_signer ( 2 ) ? {
530
+ ic_logger_msg ! ( log_collector, "New authority did not sign" ) ;
531
+ return Err ( InstructionError :: MissingRequiredSignature ) ;
532
+ }
533
+ if state. authority_address == new_authority_address {
534
+ ic_logger_msg ! ( log_collector, "No change" ) ;
535
+ return Err ( InstructionError :: InvalidArgument ) ;
536
+ }
527
537
state. authority_address = new_authority_address;
528
538
} else if matches ! ( state. status, LoaderV4Status :: Deployed ) {
529
539
state. status = LoaderV4Status :: Finalized ;
@@ -575,26 +585,18 @@ pub fn process_instruction_inner(
575
585
. map_err ( |err| Box :: new ( err) as Box < dyn std:: error:: Error > )
576
586
} else {
577
587
let program = instruction_context. try_borrow_last_program_account ( transaction_context) ?;
578
- if !loader_v4:: check_id ( program. get_owner ( ) ) {
579
- ic_logger_msg ! ( log_collector, "Program not owned by loader" ) ;
580
- return Err ( Box :: new ( InstructionError :: InvalidAccountOwner ) ) ;
581
- }
582
- if program. get_data ( ) . is_empty ( ) {
583
- ic_logger_msg ! ( log_collector, "Program is uninitialized" ) ;
584
- return Err ( Box :: new ( InstructionError :: InvalidAccountData ) ) ;
585
- }
586
588
let state = get_state ( program. get_data ( ) ) ?;
587
589
if matches ! ( state. status, LoaderV4Status :: Retracted ) {
588
- ic_logger_msg ! ( log_collector, "Program is not deployed " ) ;
589
- return Err ( Box :: new ( InstructionError :: InvalidArgument ) ) ;
590
+ ic_logger_msg ! ( log_collector, "Program is retracted " ) ;
591
+ return Err ( Box :: new ( InstructionError :: UnsupportedProgramId ) ) ;
590
592
}
591
593
let mut get_or_create_executor_time = Measure :: start ( "get_or_create_executor_time" ) ;
592
594
let loaded_program = invoke_context
593
595
. program_cache_for_tx_batch
594
596
. find ( program. get_key ( ) )
595
597
. ok_or_else ( || {
596
598
ic_logger_msg ! ( log_collector, "Program is not cached" ) ;
597
- InstructionError :: InvalidAccountData
599
+ InstructionError :: UnsupportedProgramId
598
600
} ) ?;
599
601
get_or_create_executor_time. stop ( ) ;
600
602
saturating_add_assign ! (
@@ -610,10 +612,12 @@ pub fn process_instruction_inner(
610
612
| ProgramCacheEntryType :: Closed
611
613
| ProgramCacheEntryType :: DelayVisibility => {
612
614
ic_logger_msg ! ( log_collector, "Program is not deployed" ) ;
613
- Err ( Box :: new ( InstructionError :: InvalidAccountData ) as Box < dyn std:: error:: Error > )
615
+ Err ( Box :: new ( InstructionError :: UnsupportedProgramId ) as Box < dyn std:: error:: Error > )
614
616
}
615
617
ProgramCacheEntryType :: Loaded ( executable) => execute ( invoke_context, executable) ,
616
- _ => Err ( Box :: new ( InstructionError :: IncorrectProgramId ) as Box < dyn std:: error:: Error > ) ,
618
+ _ => {
619
+ Err ( Box :: new ( InstructionError :: UnsupportedProgramId ) as Box < dyn std:: error:: Error > )
620
+ }
617
621
}
618
622
}
619
623
. map ( |_| 0 )
@@ -1157,7 +1161,7 @@ mod tests {
1157
1161
& bincode:: serialize ( & LoaderV4Instruction :: Truncate { new_size : 0 } ) . unwrap ( ) ,
1158
1162
transaction_accounts. clone ( ) ,
1159
1163
& [ ( 3 , false , true ) , ( 1 , true , false ) , ( 2 , true , true ) ] ,
1160
- Err ( InstructionError :: InvalidAccountData ) ,
1164
+ Err ( InstructionError :: AccountDataTooSmall ) ,
1161
1165
) ;
1162
1166
1163
1167
// Error: Program is not retracted
@@ -1331,7 +1335,7 @@ mod tests {
1331
1335
& bincode:: serialize ( & LoaderV4Instruction :: Deploy ) . unwrap ( ) ,
1332
1336
transaction_accounts. clone ( ) ,
1333
1337
& [ ( 3 , false , true ) , ( 1 , true , false ) ] ,
1334
- Err ( InstructionError :: InvalidAccountData ) ,
1338
+ Err ( InstructionError :: AccountDataTooSmall ) ,
1335
1339
) ;
1336
1340
1337
1341
// Error: Program fails verification
@@ -1410,7 +1414,7 @@ mod tests {
1410
1414
& bincode:: serialize ( & LoaderV4Instruction :: Retract ) . unwrap ( ) ,
1411
1415
transaction_accounts. clone ( ) ,
1412
1416
& [ ( 2 , false , true ) , ( 1 , true , false ) ] ,
1413
- Err ( InstructionError :: InvalidAccountData ) ,
1417
+ Err ( InstructionError :: AccountDataTooSmall ) ,
1414
1418
) ;
1415
1419
1416
1420
// Error: Program is not deployed
@@ -1520,18 +1524,27 @@ mod tests {
1520
1524
& bincode:: serialize ( & LoaderV4Instruction :: TransferAuthority ) . unwrap ( ) ,
1521
1525
transaction_accounts. clone ( ) ,
1522
1526
& [ ( 2 , false , true ) , ( 3 , true , false ) , ( 4 , true , false ) ] ,
1523
- Err ( InstructionError :: InvalidAccountData ) ,
1527
+ Err ( InstructionError :: AccountDataTooSmall ) ,
1524
1528
) ;
1525
1529
1526
1530
// Error: New authority did not sign
1527
1531
process_instruction (
1528
1532
vec ! [ ] ,
1529
1533
& bincode:: serialize ( & LoaderV4Instruction :: TransferAuthority ) . unwrap ( ) ,
1530
- transaction_accounts,
1534
+ transaction_accounts. clone ( ) ,
1531
1535
& [ ( 0 , false , true ) , ( 3 , true , false ) , ( 4 , false , false ) ] ,
1532
1536
Err ( InstructionError :: MissingRequiredSignature ) ,
1533
1537
) ;
1534
1538
1539
+ // Error: Authority did not change
1540
+ process_instruction (
1541
+ vec ! [ ] ,
1542
+ & bincode:: serialize ( & LoaderV4Instruction :: TransferAuthority ) . unwrap ( ) ,
1543
+ transaction_accounts,
1544
+ & [ ( 0 , false , true ) , ( 3 , true , false ) , ( 3 , true , false ) ] ,
1545
+ Err ( InstructionError :: InvalidArgument ) ,
1546
+ ) ;
1547
+
1535
1548
test_loader_instruction_general_errors ( LoaderV4Instruction :: TransferAuthority ) ;
1536
1549
}
1537
1550
@@ -1598,7 +1611,7 @@ mod tests {
1598
1611
& [ 0 , 1 , 2 , 3 ] ,
1599
1612
transaction_accounts. clone ( ) ,
1600
1613
& [ ( 1 , false , true ) ] ,
1601
- Err ( InstructionError :: InvalidAccountData ) ,
1614
+ Err ( InstructionError :: AccountDataTooSmall ) ,
1602
1615
) ;
1603
1616
1604
1617
// Error: Program is not deployed
@@ -1607,7 +1620,7 @@ mod tests {
1607
1620
& [ 0 , 1 , 2 , 3 ] ,
1608
1621
transaction_accounts. clone ( ) ,
1609
1622
& [ ( 1 , false , true ) ] ,
1610
- Err ( InstructionError :: InvalidArgument ) ,
1623
+ Err ( InstructionError :: UnsupportedProgramId ) ,
1611
1624
) ;
1612
1625
1613
1626
// Error: Program fails verification
@@ -1616,7 +1629,7 @@ mod tests {
1616
1629
& [ 0 , 1 , 2 , 3 ] ,
1617
1630
transaction_accounts,
1618
1631
& [ ( 1 , false , true ) ] ,
1619
- Err ( InstructionError :: InvalidAccountData ) ,
1632
+ Err ( InstructionError :: UnsupportedProgramId ) ,
1620
1633
) ;
1621
1634
}
1622
1635
}
0 commit comments