@@ -169,7 +169,7 @@ pub enum ProgramCliCommand {
169
169
use_lamports_unit : bool ,
170
170
bypass_warning : bool ,
171
171
} ,
172
- ExtendProgram {
172
+ ExtendProgramChecked {
173
173
program_pubkey : Pubkey ,
174
174
additional_bytes : u32 ,
175
175
} ,
@@ -1018,7 +1018,7 @@ pub fn parse_program_subcommand(
1018
1018
) ?;
1019
1019
1020
1020
CliCommandInfo {
1021
- command : CliCommand :: Program ( ProgramCliCommand :: ExtendProgram {
1021
+ command : CliCommand :: Program ( ProgramCliCommand :: ExtendProgramChecked {
1022
1022
program_pubkey,
1023
1023
additional_bytes,
1024
1024
} ) ,
@@ -1231,7 +1231,7 @@ pub fn process_program_subcommand(
1231
1231
* use_lamports_unit,
1232
1232
* bypass_warning,
1233
1233
) ,
1234
- ProgramCliCommand :: ExtendProgram {
1234
+ ProgramCliCommand :: ExtendProgramChecked {
1235
1235
program_pubkey,
1236
1236
additional_bytes,
1237
1237
} => process_extend_program ( & rpc_client, config, * program_pubkey, * additional_bytes) ,
@@ -2411,21 +2411,28 @@ fn process_extend_program(
2411
2411
_ => Err ( format ! ( "Program {program_pubkey} is closed" ) ) ,
2412
2412
} ?;
2413
2413
2414
- match upgrade_authority_address {
2415
- None => Err ( format ! ( "Program {program_pubkey} is not upgradeable" ) ) ,
2416
- _ => Ok ( ( ) ) ,
2417
- } ?;
2414
+ let upgrade_authority_address = upgrade_authority_address
2415
+ . ok_or_else ( || format ! ( "Program {program_pubkey} is not upgradeable" ) ) ?;
2418
2416
2419
2417
let blockhash = rpc_client. get_latest_blockhash ( ) ?;
2420
-
2421
- let mut tx = Transaction :: new_unsigned ( Message :: new (
2422
- & [ loader_v3_instruction:: extend_program (
2423
- & program_pubkey,
2424
- Some ( & payer_pubkey) ,
2425
- additional_bytes,
2426
- ) ] ,
2427
- Some ( & payer_pubkey) ,
2428
- ) ) ;
2418
+ let feature_set = fetch_feature_set ( rpc_client) ?;
2419
+
2420
+ let instruction =
2421
+ if feature_set. is_active ( & agave_feature_set:: enable_extend_program_checked:: id ( ) ) {
2422
+ loader_v3_instruction:: extend_program_checked (
2423
+ & program_pubkey,
2424
+ & upgrade_authority_address,
2425
+ Some ( & payer_pubkey) ,
2426
+ additional_bytes,
2427
+ )
2428
+ } else {
2429
+ loader_v3_instruction:: extend_program (
2430
+ & program_pubkey,
2431
+ Some ( & payer_pubkey) ,
2432
+ additional_bytes,
2433
+ )
2434
+ } ;
2435
+ let mut tx = Transaction :: new_unsigned ( Message :: new ( & [ instruction] , Some ( & payer_pubkey) ) ) ;
2429
2436
2430
2437
tx. try_sign ( & [ config. signers [ 0 ] ] , blockhash) ?;
2431
2438
let result = rpc_client. send_and_confirm_transaction_with_spinner_and_config (
@@ -2972,6 +2979,17 @@ fn extend_program_data_if_needed(
2972
2979
return Ok ( ( ) ) ;
2973
2980
} ;
2974
2981
2982
+ let upgrade_authority_address = match program_data_account. state ( ) {
2983
+ Ok ( UpgradeableLoaderState :: ProgramData {
2984
+ slot : _,
2985
+ upgrade_authority_address,
2986
+ } ) => Ok ( upgrade_authority_address) ,
2987
+ _ => Err ( format ! ( "Program {program_id} is closed" ) ) ,
2988
+ } ?;
2989
+
2990
+ let upgrade_authority_address = upgrade_authority_address
2991
+ . ok_or_else ( || format ! ( "Program {program_id} is not upgradeable" ) ) ?;
2992
+
2975
2993
let required_len = UpgradeableLoaderState :: size_of_programdata ( program_len) ;
2976
2994
let max_permitted_data_length = usize:: try_from ( MAX_PERMITTED_DATA_LENGTH ) . unwrap ( ) ;
2977
2995
if required_len > max_permitted_data_length {
@@ -2993,11 +3011,20 @@ fn extend_program_data_if_needed(
2993
3011
2994
3012
let additional_bytes =
2995
3013
u32:: try_from ( additional_bytes) . expect ( "`u32` is big enough to hold an account size" ) ;
2996
- initial_instructions. push ( loader_v3_instruction:: extend_program (
2997
- program_id,
2998
- Some ( fee_payer) ,
2999
- additional_bytes,
3000
- ) ) ;
3014
+
3015
+ let feature_set = fetch_feature_set ( rpc_client) ?;
3016
+ let instruction =
3017
+ if feature_set. is_active ( & agave_feature_set:: enable_extend_program_checked:: id ( ) ) {
3018
+ loader_v3_instruction:: extend_program_checked (
3019
+ program_id,
3020
+ & upgrade_authority_address,
3021
+ Some ( fee_payer) ,
3022
+ additional_bytes,
3023
+ )
3024
+ } else {
3025
+ loader_v3_instruction:: extend_program ( program_id, Some ( fee_payer) , additional_bytes)
3026
+ } ;
3027
+ initial_instructions. push ( instruction) ;
3001
3028
3002
3029
Ok ( ( ) )
3003
3030
}
@@ -3096,7 +3123,12 @@ fn send_deploy_messages(
3096
3123
// account to sign the transaction. One (transfer) only requires the fee-payer signature.
3097
3124
// This check is to ensure signing does not fail on a KeypairPubkeyMismatch error from an
3098
3125
// extraneous signature.
3099
- if message. header . num_required_signatures == 2 {
3126
+ if message. header . num_required_signatures == 3 {
3127
+ initial_transaction. try_sign (
3128
+ & [ fee_payer_signer, initial_signer, write_signer. unwrap ( ) ] ,
3129
+ blockhash,
3130
+ ) ?;
3131
+ } else if message. header . num_required_signatures == 2 {
3100
3132
initial_transaction. try_sign ( & [ fee_payer_signer, initial_signer] , blockhash) ?;
3101
3133
} else {
3102
3134
initial_transaction. try_sign ( & [ fee_payer_signer] , blockhash) ?;
@@ -4406,7 +4438,7 @@ mod tests {
4406
4438
assert_eq ! (
4407
4439
parse_command( & test_command, & default_signer, & mut None ) . unwrap( ) ,
4408
4440
CliCommandInfo {
4409
- command: CliCommand :: Program ( ProgramCliCommand :: ExtendProgram {
4441
+ command: CliCommand :: Program ( ProgramCliCommand :: ExtendProgramChecked {
4410
4442
program_pubkey,
4411
4443
additional_bytes
4412
4444
} ) ,
0 commit comments