@@ -44,11 +44,16 @@ use {
44
44
client:: {
45
45
ProgramClient , ProgramOfflineClient , ProgramRpcClient , ProgramRpcClientSendTransaction ,
46
46
} ,
47
- token:: Token ,
47
+ token:: { ComputeUnitLimit , Token } ,
48
48
} ,
49
49
spl_token_group_interface:: state:: { TokenGroup , TokenGroupMember } ,
50
50
spl_token_metadata_interface:: state:: TokenMetadata ,
51
- std:: { ffi:: OsString , path:: PathBuf , str:: FromStr , sync:: Arc } ,
51
+ std:: {
52
+ ffi:: { OsStr , OsString } ,
53
+ path:: PathBuf ,
54
+ str:: FromStr ,
55
+ sync:: Arc ,
56
+ } ,
52
57
tempfile:: NamedTempFile ,
53
58
} ;
54
59
@@ -201,7 +206,7 @@ fn test_config_with_default_signer<'a>(
201
206
program_id : * program_id,
202
207
restrict_to_program_id : true ,
203
208
compute_unit_price : None ,
204
- compute_unit_limit : None ,
209
+ compute_unit_limit : ComputeUnitLimit :: Simulated ,
205
210
}
206
211
}
207
212
@@ -230,7 +235,7 @@ fn test_config_without_default_signer<'a>(
230
235
program_id : * program_id,
231
236
restrict_to_program_id : true ,
232
237
compute_unit_price : None ,
233
- compute_unit_limit : None ,
238
+ compute_unit_limit : ComputeUnitLimit :: Simulated ,
234
239
}
235
240
}
236
241
@@ -441,7 +446,7 @@ where
441
446
process_command ( & sub_command, matches, config, wallet_manager, bulk_signers) . await
442
447
}
443
448
444
- async fn exec_test_cmd ( config : & Config < ' _ > , args : & [ & str ] ) -> CommandResult {
449
+ async fn exec_test_cmd < T : AsRef < OsStr > > ( config : & Config < ' _ > , args : & [ T ] ) -> CommandResult {
445
450
let default_decimals = format ! ( "{}" , spl_token_2022:: native_mint:: DECIMALS ) ;
446
451
let minimum_signers_help = minimum_signers_help_string ( ) ;
447
452
let multisig_member_help = multisig_member_help_string ( ) ;
@@ -2974,10 +2979,17 @@ async fn multisig_transfer(test_validator: &TestValidator, payer: &Keypair) {
2974
2979
}
2975
2980
}
2976
2981
2977
- async fn offline_multisig_transfer_with_nonce ( test_validator : & TestValidator , payer : & Keypair ) {
2982
+ async fn do_offline_multisig_transfer (
2983
+ test_validator : & TestValidator ,
2984
+ payer : & Keypair ,
2985
+ compute_unit_price : Option < u64 > ,
2986
+ ) {
2978
2987
let m = 2 ;
2979
2988
let n = 3u8 ;
2980
2989
2990
+ let fee_payer_keypair_file = NamedTempFile :: new ( ) . unwrap ( ) ;
2991
+ write_keypair_file ( payer, & fee_payer_keypair_file) . unwrap ( ) ;
2992
+
2981
2993
let ( multisig_members, multisig_paths) : ( Vec < _ > , Vec < _ > ) = std:: iter:: repeat_with ( Keypair :: new)
2982
2994
. take ( n as usize )
2983
2995
. map ( |s| {
@@ -2988,6 +3000,7 @@ async fn offline_multisig_transfer_with_nonce(test_validator: &TestValidator, pa
2988
3000
. unzip ( ) ;
2989
3001
for program_id in VALID_TOKEN_PROGRAM_IDS . iter ( ) {
2990
3002
let mut config = test_config_with_default_signer ( test_validator, payer, program_id) ;
3003
+ config. compute_unit_limit = ComputeUnitLimit :: Default ;
2991
3004
let token = create_token ( & config, payer) . await ;
2992
3005
let nonce = create_nonce ( & config, payer) . await ;
2993
3006
@@ -3032,58 +3045,121 @@ async fn offline_multisig_transfer_with_nonce(test_validator: &TestValidator, pa
3032
3045
let program_client: Arc < dyn ProgramClient < ProgramRpcClientSendTransaction > > = Arc :: new (
3033
3046
ProgramOfflineClient :: new ( blockhash, ProgramRpcClientSendTransaction ) ,
3034
3047
) ;
3048
+ let mut args = vec ! [
3049
+ "spl-token" . to_string( ) ,
3050
+ CommandName :: Transfer . as_ref( ) . to_string( ) ,
3051
+ token. to_string( ) ,
3052
+ "10" . to_string( ) ,
3053
+ destination. to_string( ) ,
3054
+ "--blockhash" . to_string( ) ,
3055
+ blockhash. to_string( ) ,
3056
+ "--nonce" . to_string( ) ,
3057
+ nonce. to_string( ) ,
3058
+ "--nonce-authority" . to_string( ) ,
3059
+ payer. pubkey( ) . to_string( ) ,
3060
+ "--sign-only" . to_string( ) ,
3061
+ "--mint-decimals" . to_string( ) ,
3062
+ format!( "{}" , TEST_DECIMALS ) ,
3063
+ "--multisig-signer" . to_string( ) ,
3064
+ multisig_paths[ 1 ] . path( ) . to_str( ) . unwrap( ) . to_string( ) ,
3065
+ "--multisig-signer" . to_string( ) ,
3066
+ multisig_members[ 2 ] . to_string( ) ,
3067
+ "--from" . to_string( ) ,
3068
+ source. to_string( ) ,
3069
+ "--owner" . to_string( ) ,
3070
+ multisig_pubkey. to_string( ) ,
3071
+ "--fee-payer" . to_string( ) ,
3072
+ payer. pubkey( ) . to_string( ) ,
3073
+ "--program-id" . to_string( ) ,
3074
+ program_id. to_string( ) ,
3075
+ ] ;
3076
+ if let Some ( compute_unit_price) = compute_unit_price {
3077
+ args. push ( "--with-compute-unit-price" . to_string ( ) ) ;
3078
+ args. push ( compute_unit_price. to_string ( ) ) ;
3079
+ args. push ( "--with-compute-unit-limit" . to_string ( ) ) ;
3080
+ args. push ( 10_000 . to_string ( ) ) ;
3081
+ }
3035
3082
config. program_client = program_client;
3036
- let result = exec_test_cmd (
3037
- & config,
3038
- & [
3039
- "spl-token" ,
3040
- CommandName :: Transfer . into ( ) ,
3041
- & token. to_string ( ) ,
3042
- "10" ,
3043
- & destination. to_string ( ) ,
3044
- "--blockhash" ,
3045
- & blockhash. to_string ( ) ,
3046
- "--nonce" ,
3047
- & nonce. to_string ( ) ,
3048
- "--nonce-authority" ,
3049
- & payer. pubkey ( ) . to_string ( ) ,
3050
- "--sign-only" ,
3051
- "--mint-decimals" ,
3052
- & format ! ( "{}" , TEST_DECIMALS ) ,
3053
- "--multisig-signer" ,
3054
- multisig_paths[ 1 ] . path ( ) . to_str ( ) . unwrap ( ) ,
3055
- "--multisig-signer" ,
3056
- & multisig_members[ 2 ] . to_string ( ) ,
3057
- "--from" ,
3058
- & source. to_string ( ) ,
3059
- "--owner" ,
3060
- & multisig_pubkey. to_string ( ) ,
3061
- "--fee-payer" ,
3062
- & multisig_members[ 0 ] . to_string ( ) ,
3063
- ] ,
3064
- )
3065
- . await
3066
- . unwrap ( ) ;
3083
+ let result = exec_test_cmd ( & config, & args) . await . unwrap ( ) ;
3067
3084
// the provided signer has a signature, denoted by the pubkey followed
3068
3085
// by "=" and the signature
3069
- assert ! ( result. contains( & format!( "{}=" , multisig_members[ 1 ] ) ) ) ;
3086
+ let member_prefix = format ! ( "{}=" , multisig_members[ 1 ] ) ;
3087
+ let signature_position = result. find ( & member_prefix) . unwrap ( ) ;
3088
+ let end_position = result[ signature_position..] . find ( '\n' ) . unwrap ( ) ;
3089
+ let signer = result[ signature_position..] . get ( ..end_position) . unwrap ( ) ;
3070
3090
3071
3091
// other three expected signers are absent
3072
3092
let absent_signers_position = result. find ( "Absent Signers" ) . unwrap ( ) ;
3073
3093
let absent_signers = result. get ( absent_signers_position..) . unwrap ( ) ;
3074
- assert ! ( absent_signers. contains( & multisig_members[ 0 ] . to_string( ) ) ) ;
3075
3094
assert ! ( absent_signers. contains( & multisig_members[ 2 ] . to_string( ) ) ) ;
3076
3095
assert ! ( absent_signers. contains( & payer. pubkey( ) . to_string( ) ) ) ;
3077
3096
3078
3097
// and nothing else is marked a signer
3098
+ assert ! ( !absent_signers. contains( & multisig_members[ 0 ] . to_string( ) ) ) ;
3079
3099
assert ! ( !absent_signers. contains( & multisig_pubkey. to_string( ) ) ) ;
3080
3100
assert ! ( !absent_signers. contains( & nonce. to_string( ) ) ) ;
3081
3101
assert ! ( !absent_signers. contains( & source. to_string( ) ) ) ;
3082
3102
assert ! ( !absent_signers. contains( & destination. to_string( ) ) ) ;
3083
3103
assert ! ( !absent_signers. contains( & token. to_string( ) ) ) ;
3104
+
3105
+ // now send the transaction
3106
+ let program_client: Arc < dyn ProgramClient < ProgramRpcClientSendTransaction > > = Arc :: new (
3107
+ ProgramRpcClient :: new ( config. rpc_client . clone ( ) , ProgramRpcClientSendTransaction ) ,
3108
+ ) ;
3109
+ config. program_client = program_client;
3110
+ let mut args = vec ! [
3111
+ "spl-token" . to_string( ) ,
3112
+ CommandName :: Transfer . as_ref( ) . to_string( ) ,
3113
+ token. to_string( ) ,
3114
+ "10" . to_string( ) ,
3115
+ destination. to_string( ) ,
3116
+ "--blockhash" . to_string( ) ,
3117
+ blockhash. to_string( ) ,
3118
+ "--nonce" . to_string( ) ,
3119
+ nonce. to_string( ) ,
3120
+ "--nonce-authority" . to_string( ) ,
3121
+ fee_payer_keypair_file. path( ) . to_str( ) . unwrap( ) . to_string( ) ,
3122
+ "--mint-decimals" . to_string( ) ,
3123
+ format!( "{}" , TEST_DECIMALS ) ,
3124
+ "--multisig-signer" . to_string( ) ,
3125
+ multisig_members[ 1 ] . to_string( ) ,
3126
+ "--multisig-signer" . to_string( ) ,
3127
+ multisig_paths[ 2 ] . path( ) . to_str( ) . unwrap( ) . to_string( ) ,
3128
+ "--from" . to_string( ) ,
3129
+ source. to_string( ) ,
3130
+ "--owner" . to_string( ) ,
3131
+ multisig_pubkey. to_string( ) ,
3132
+ "--fee-payer" . to_string( ) ,
3133
+ fee_payer_keypair_file. path( ) . to_str( ) . unwrap( ) . to_string( ) ,
3134
+ "--program-id" . to_string( ) ,
3135
+ program_id. to_string( ) ,
3136
+ "--signer" . to_string( ) ,
3137
+ signer. to_string( ) ,
3138
+ ] ;
3139
+ if let Some ( compute_unit_price) = compute_unit_price {
3140
+ args. push ( "--with-compute-unit-price" . to_string ( ) ) ;
3141
+ args. push ( compute_unit_price. to_string ( ) ) ;
3142
+ args. push ( "--with-compute-unit-limit" . to_string ( ) ) ;
3143
+ args. push ( 10_000 . to_string ( ) ) ;
3144
+ }
3145
+ exec_test_cmd ( & config, & args) . await . unwrap ( ) ;
3146
+
3147
+ let account = config. rpc_client . get_account ( & source) . await . unwrap ( ) ;
3148
+ let token_account = StateWithExtensionsOwned :: < Account > :: unpack ( account. data ) . unwrap ( ) ;
3149
+ let amount = spl_token:: ui_amount_to_amount ( 90.0 , TEST_DECIMALS ) ;
3150
+ assert_eq ! ( token_account. base. amount, amount) ;
3151
+ let account = config. rpc_client . get_account ( & destination) . await . unwrap ( ) ;
3152
+ let token_account = StateWithExtensionsOwned :: < Account > :: unpack ( account. data ) . unwrap ( ) ;
3153
+ let amount = spl_token:: ui_amount_to_amount ( 10.0 , TEST_DECIMALS ) ;
3154
+ assert_eq ! ( token_account. base. amount, amount) ;
3084
3155
}
3085
3156
}
3086
3157
3158
+ async fn offline_multisig_transfer_with_nonce ( test_validator : & TestValidator , payer : & Keypair ) {
3159
+ do_offline_multisig_transfer ( test_validator, payer, None ) . await ;
3160
+ do_offline_multisig_transfer ( test_validator, payer, Some ( 10 ) ) . await ;
3161
+ }
3162
+
3087
3163
async fn withdraw_excess_lamports_from_multisig ( test_validator : & TestValidator , payer : & Keypair ) {
3088
3164
let m = 3 ;
3089
3165
let n = 5u8 ;
@@ -4024,7 +4100,7 @@ async fn compute_budget(test_validator: &TestValidator, payer: &Keypair) {
4024
4100
for program_id in VALID_TOKEN_PROGRAM_IDS . iter ( ) {
4025
4101
let mut config = test_config_with_default_signer ( test_validator, payer, program_id) ;
4026
4102
config. compute_unit_price = Some ( 42 ) ;
4027
- config. compute_unit_limit = Some ( 30_000 ) ;
4103
+ config. compute_unit_limit = ComputeUnitLimit :: Static ( 30_000 ) ;
4028
4104
run_transfer_test ( & config, payer) . await ;
4029
4105
}
4030
4106
}
0 commit comments