@@ -83,7 +83,7 @@ fn test_process_create_ok() {
8383 & [ ( config, config_account) ] ,
8484 & [
8585 Check :: success ( ) ,
86- Check :: compute_units ( 584 ) ,
86+ Check :: compute_units ( 580 ) ,
8787 Check :: account ( & config)
8888 . data (
8989 & bincode:: serialize ( & ( ConfigKeys { keys : vec ! [ ] } , MyConfig :: default ( ) ) )
@@ -111,7 +111,7 @@ fn test_process_store_ok() {
111111 & [ ( config, config_account) ] ,
112112 & [
113113 Check :: success ( ) ,
114- Check :: compute_units ( 584 ) ,
114+ Check :: compute_units ( 580 ) ,
115115 Check :: account ( & config)
116116 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , my_config) ) . unwrap ( ) )
117117 . build ( ) ,
@@ -186,7 +186,7 @@ fn test_process_store_with_additional_signers() {
186186 ] ,
187187 & [
188188 Check :: success ( ) ,
189- Check :: compute_units ( 3_253 ) ,
189+ Check :: compute_units ( 3_234 ) ,
190190 Check :: account ( & config)
191191 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , my_config) ) . unwrap ( ) )
192192 . build ( ) ,
@@ -262,6 +262,55 @@ fn test_process_store_with_bad_additional_signer() {
262262 ) ;
263263}
264264
265+ #[ test]
266+ fn test_store_requiring_config ( ) {
267+ let mollusk = setup ( ) ;
268+
269+ let config = Pubkey :: new_unique ( ) ;
270+
271+ // New keys contains the config account, as well as another signer.
272+ let signer = Pubkey :: new_unique ( ) ;
273+ let new_keys = vec ! [ ( config, true ) , ( signer, true ) ] ;
274+ let my_config = MyConfig :: new ( 42 ) ;
275+
276+ let config_account = {
277+ // Allocate enough space for they `new_keys`, but leave the account
278+ // uninitalized.
279+ let space = get_config_space ( new_keys. len ( ) ) ;
280+ let lamports = mollusk. sysvars . rent . minimum_balance ( space) ;
281+ AccountSharedData :: new ( lamports, space, & solana_config_program:: id ( ) )
282+ } ;
283+
284+ let mut instruction = config_instruction:: store ( & config, true , new_keys, & my_config) ;
285+ mollusk. process_and_validate_instruction (
286+ & instruction,
287+ & [
288+ ( config, config_account. clone ( ) ) ,
289+ ( signer, AccountSharedData :: default ( ) ) ,
290+ ] ,
291+ & [ Check :: err ( ProgramError :: MissingRequiredSignature ) ] ,
292+ ) ;
293+
294+ // This is kind of strange, since the `store` helper was taken directly
295+ // from the builtin crate, and it's designed to only add the config account
296+ // once, even if it's a signer.
297+ // However, if you include it in the instruction twice, the loop-counter
298+ // mechanism of the processor actually works...
299+ instruction. accounts = vec ! [
300+ AccountMeta :: new( config, true ) ,
301+ AccountMeta :: new( config, true ) ,
302+ AccountMeta :: new( signer, true ) ,
303+ ] ;
304+ mollusk. process_and_validate_instruction (
305+ & instruction,
306+ & [
307+ ( config, config_account) ,
308+ ( signer, AccountSharedData :: default ( ) ) ,
309+ ] ,
310+ & [ Check :: success ( ) ] ,
311+ ) ;
312+ }
313+
265314#[ test]
266315fn test_config_updates ( ) {
267316 let mollusk = setup ( ) ;
@@ -285,7 +334,7 @@ fn test_config_updates() {
285334 ( signer0, AccountSharedData :: default ( ) ) ,
286335 ( signer1, AccountSharedData :: default ( ) ) ,
287336 ] ,
288- & [ Check :: success ( ) , Check :: compute_units ( 3_253 ) ] ,
337+ & [ Check :: success ( ) , Check :: compute_units ( 3_234 ) ] ,
289338 ) ;
290339
291340 // Use this for next invoke.
@@ -303,7 +352,7 @@ fn test_config_updates() {
303352 ] ,
304353 & [
305354 Check :: success ( ) ,
306- Check :: compute_units ( 3_254 ) ,
355+ Check :: compute_units ( 3_235 ) ,
307356 Check :: account ( & config)
308357 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , new_config) ) . unwrap ( ) )
309358 . build ( ) ,
@@ -314,6 +363,22 @@ fn test_config_updates() {
314363 let updated_config_account = result. get_account ( & config) . unwrap ( ) ;
315364
316365 // Attempt update with incomplete signatures.
366+ let keys = vec ! [
367+ ( pubkey, false ) ,
368+ ( signer1, true ) , // Missing signer0.
369+ ] ;
370+ let instruction = config_instruction:: store ( & config, false , keys, & my_config) ;
371+ mollusk. process_and_validate_instruction (
372+ & instruction,
373+ & [
374+ ( config, updated_config_account. clone ( ) ) ,
375+ // Missing signer0.
376+ ( signer1, AccountSharedData :: default ( ) ) ,
377+ ] ,
378+ & [ Check :: err ( ProgramError :: MissingRequiredSignature ) ] ,
379+ ) ;
380+
381+ // Do it again, this time missing signer1.
317382 let keys = vec ! [
318383 ( pubkey, false ) ,
319384 ( signer0, true ) , // Missing signer1.
@@ -323,7 +388,8 @@ fn test_config_updates() {
323388 & instruction,
324389 & [
325390 ( config, updated_config_account. clone ( ) ) ,
326- ( signer0, AccountSharedData :: default ( ) ) , // Missing signer1.
391+ ( signer0, AccountSharedData :: default ( ) ) ,
392+ // Missing signer1.
327393 ] ,
328394 & [ Check :: err ( ProgramError :: MissingRequiredSignature ) ] ,
329395 ) ;
@@ -399,7 +465,7 @@ fn test_config_update_contains_duplicates_fails() {
399465 ( signer0, AccountSharedData :: default ( ) ) ,
400466 ( signer1, AccountSharedData :: default ( ) ) ,
401467 ] ,
402- & [ Check :: success ( ) , Check :: compute_units ( 3_253 ) ] ,
468+ & [ Check :: success ( ) , Check :: compute_units ( 3_234 ) ] ,
403469 ) ;
404470
405471 // Attempt update with duplicate signer inputs.
@@ -443,7 +509,7 @@ fn test_config_updates_requiring_config() {
443509 ] ,
444510 & [
445511 Check :: success ( ) ,
446- Check :: compute_units ( 3_352 ) ,
512+ Check :: compute_units ( 3_330 ) ,
447513 Check :: account ( & config)
448514 . data ( & bincode:: serialize ( & ( ConfigKeys { keys : keys. clone ( ) } , my_config) ) . unwrap ( ) )
449515 . build ( ) ,
@@ -464,7 +530,7 @@ fn test_config_updates_requiring_config() {
464530 ] ,
465531 & [
466532 Check :: success ( ) ,
467- Check :: compute_units ( 3_352 ) ,
533+ Check :: compute_units ( 3_330 ) ,
468534 Check :: account ( & config)
469535 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , new_config) ) . unwrap ( ) )
470536 . build ( ) ,
@@ -558,7 +624,7 @@ fn test_maximum_keys_input() {
558624 let result = mollusk. process_and_validate_instruction (
559625 & instruction,
560626 & [ ( config, config_account) ] ,
561- & [ Check :: success ( ) , Check :: compute_units ( 25_247 ) ] ,
627+ & [ Check :: success ( ) , Check :: compute_units ( 25_243 ) ] ,
562628 ) ;
563629
564630 // Use this for next invoke.
@@ -571,7 +637,7 @@ fn test_maximum_keys_input() {
571637 let result = mollusk. process_and_validate_instruction (
572638 & instruction,
573639 & [ ( config, updated_config_account) ] ,
574- & [ Check :: success ( ) , Check :: compute_units ( 25_247 ) ] ,
640+ & [ Check :: success ( ) , Check :: compute_units ( 25_243 ) ] ,
575641 ) ;
576642
577643 // Use this for next invoke.
0 commit comments