@@ -3143,3 +3143,264 @@ fn test_forged_block_subdags() {
31433143 assert ! ( ledger. check_next_block( & forged_block_2_from_both_subdags, & mut rand:: thread_rng( ) ) . is_err( ) ) ;
31443144 }
31453145}
3146+
3147+ #[ test]
3148+ fn test_record_creation_and_consumption_in_call ( ) {
3149+ let rng = & mut TestRng :: default ( ) ;
3150+
3151+ // Sample the test environment.
3152+ let crate :: test_helpers:: TestEnv { ledger, private_key, view_key, .. } = crate :: test_helpers:: sample_test_env ( rng) ;
3153+
3154+ // A helper function to get the record counts.
3155+ let get_record_counts = || {
3156+ let slow_spent_filter = RecordsFilter :: SlowSpent ( private_key) ;
3157+ let slow_unspent_filter = RecordsFilter :: SlowUnspent ( private_key) ;
3158+ let spent_records = ledger. find_records ( & view_key, RecordsFilter :: Spent ) . unwrap ( ) . collect_vec ( ) . len ( ) ;
3159+ let slow_spent_records = ledger. find_records ( & view_key, slow_spent_filter) . unwrap ( ) . collect_vec ( ) . len ( ) ;
3160+ let unspent_records = ledger. find_records ( & view_key, RecordsFilter :: Unspent ) . unwrap ( ) . collect_vec ( ) . len ( ) ;
3161+ let slow_unspent_records = ledger. find_records ( & view_key, slow_unspent_filter) . unwrap ( ) . collect_vec ( ) . len ( ) ;
3162+ let records = ledger. records ( ) . collect_vec ( ) . len ( ) ;
3163+ ( spent_records, slow_spent_records, unspent_records, slow_unspent_records, records)
3164+ } ;
3165+
3166+ // Check the initial record counts.
3167+ let (
3168+ initial_spent_records,
3169+ initial_slow_spent_records,
3170+ initial_unspent_records,
3171+ initial_slow_unspent_records,
3172+ initial_records,
3173+ ) = get_record_counts ( ) ;
3174+ assert_eq ! ( 0 , initial_spent_records) ;
3175+ assert_eq ! ( 0 , initial_slow_spent_records) ;
3176+ assert_eq ! ( 4 , initial_unspent_records) ;
3177+ assert_eq ! ( 4 , initial_slow_unspent_records) ;
3178+ assert_eq ! ( 4 , initial_records) ;
3179+
3180+ // Initialize the two programs.
3181+ let program_0 = Program :: from_str (
3182+ r"
3183+ program child.aleo;
3184+
3185+ record data:
3186+ owner as address.private;
3187+ val as u64.private;
3188+
3189+ function mint:
3190+ cast self.signer 0u64 into r0 as data.record;
3191+ output r0 as data.record;
3192+
3193+ function burn:
3194+ input r0 as data.record;
3195+ " ,
3196+ )
3197+ . unwrap ( ) ;
3198+
3199+ let program_1 = Program :: from_str (
3200+ r"
3201+ import child.aleo;
3202+
3203+ program parent.aleo;
3204+
3205+ function create_without_output:
3206+ call child.aleo/mint into r0;
3207+
3208+ function create:
3209+ call child.aleo/mint into r0;
3210+ output r0 as child.aleo/data.record;
3211+
3212+ function consume_without_call:
3213+ input r0 as child.aleo/data.record;
3214+
3215+ function consume:
3216+ input r0 as child.aleo/data.record;
3217+ call child.aleo/burn r0;
3218+
3219+ function create_and_consume:
3220+ call child.aleo/mint into r0;
3221+ call child.aleo/burn r0;
3222+ " ,
3223+ )
3224+ . unwrap ( ) ;
3225+
3226+ // Deploy the programs.
3227+ let deployment_0 = ledger. vm ( ) . deploy ( & private_key, & program_0, None , 0 , None , rng) . unwrap ( ) ;
3228+ let block =
3229+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ deployment_0] , rng) . unwrap ( ) ;
3230+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3231+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3232+
3233+ let deployment_1 = ledger. vm ( ) . deploy ( & private_key, & program_1, None , 0 , None , rng) . unwrap ( ) ;
3234+ let block =
3235+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ deployment_1] , rng) . unwrap ( ) ;
3236+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3237+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3238+
3239+ // Call the `mint` function.
3240+ let transaction = ledger
3241+ . vm ( )
3242+ . execute ( & private_key, ( "child.aleo" , "mint" ) , Vec :: < Value < CurrentNetwork > > :: new ( ) . iter ( ) , None , 0 , None , rng)
3243+ . unwrap ( ) ;
3244+ let mint_record = transaction. records ( ) . last ( ) . unwrap ( ) . 1 . decrypt ( & view_key) . unwrap ( ) ;
3245+ let block =
3246+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ transaction] , rng) . unwrap ( ) ;
3247+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3248+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3249+
3250+ // Check the record counts.
3251+ let ( num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3252+ get_record_counts ( ) ;
3253+ assert_eq ! ( num_spent_records, initial_spent_records) ;
3254+ assert_eq ! ( num_slow_spent_records, initial_slow_spent_records) ;
3255+ assert_eq ! ( num_unspent_records, initial_unspent_records + 1 ) ;
3256+ assert_eq ! ( num_slow_unspent_records, initial_slow_unspent_records + 1 ) ;
3257+ assert_eq ! ( num_records, initial_records + 1 ) ;
3258+
3259+ // Call the `create_without_output` function.
3260+ let transaction = ledger
3261+ . vm ( )
3262+ . execute (
3263+ & private_key,
3264+ ( "parent.aleo" , "create_without_output" ) ,
3265+ Vec :: < Value < CurrentNetwork > > :: new ( ) . iter ( ) ,
3266+ None ,
3267+ 0 ,
3268+ None ,
3269+ rng,
3270+ )
3271+ . unwrap ( ) ;
3272+
3273+ let block =
3274+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ transaction] , rng) . unwrap ( ) ;
3275+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3276+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3277+
3278+ // Check the record counts.
3279+ let ( num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3280+ get_record_counts ( ) ;
3281+ assert_eq ! ( num_spent_records, initial_spent_records) ;
3282+ assert_eq ! ( num_slow_spent_records, initial_slow_spent_records) ;
3283+ assert_eq ! ( num_unspent_records, initial_unspent_records + 2 ) ;
3284+ assert_eq ! ( num_slow_unspent_records, initial_slow_unspent_records + 2 ) ;
3285+ assert_eq ! ( num_records, initial_records + 2 ) ;
3286+
3287+ // Call the `burn` function on record created by `create_without_output`.
3288+ let record = block. records ( ) . collect_vec ( ) . last ( ) . unwrap ( ) . 1 . decrypt ( & view_key) . unwrap ( ) ;
3289+ let transaction = ledger
3290+ . vm ( )
3291+ . execute ( & private_key, ( "child.aleo" , "burn" ) , vec ! [ Value :: Record ( record) ] . iter ( ) , None , 0 , None , rng)
3292+ . unwrap ( ) ;
3293+ let block =
3294+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ transaction] , rng) . unwrap ( ) ;
3295+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3296+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3297+
3298+ // Check the record counts.
3299+ let ( num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3300+ get_record_counts ( ) ;
3301+ assert_eq ! ( num_spent_records, initial_spent_records + 1 ) ;
3302+ assert_eq ! ( num_slow_spent_records, initial_slow_spent_records + 1 ) ;
3303+ assert_eq ! ( num_unspent_records, initial_unspent_records + 1 ) ;
3304+ assert_eq ! ( num_slow_unspent_records, initial_slow_unspent_records + 1 ) ;
3305+ assert_eq ! ( num_records, initial_records + 2 ) ;
3306+
3307+ // Call the `create` function.
3308+ let transaction = ledger
3309+ . vm ( )
3310+ . execute (
3311+ & private_key,
3312+ ( "parent.aleo" , "create" ) ,
3313+ Vec :: < Value < CurrentNetwork > > :: new ( ) . iter ( ) ,
3314+ None ,
3315+ 0 ,
3316+ None ,
3317+ rng,
3318+ )
3319+ . unwrap ( ) ;
3320+ let block =
3321+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ transaction] , rng) . unwrap ( ) ;
3322+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3323+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3324+
3325+ // Ensure that a record was created and spent.
3326+ let ( num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3327+ get_record_counts ( ) ;
3328+ assert_eq ! ( num_spent_records, initial_spent_records + 1 ) ;
3329+ assert_eq ! ( num_slow_spent_records, initial_slow_spent_records + 1 ) ;
3330+ assert_eq ! ( num_unspent_records, initial_unspent_records + 2 ) ;
3331+ assert_eq ! ( num_slow_unspent_records, initial_slow_unspent_records + 2 ) ;
3332+ assert_eq ! ( num_records, initial_records + 3 ) ;
3333+
3334+ // Call the `consume_without_call` function.
3335+ let transaction = ledger
3336+ . vm ( )
3337+ . execute (
3338+ & private_key,
3339+ ( "parent.aleo" , "consume_without_call" ) ,
3340+ vec ! [ Value :: Record ( mint_record. clone( ) ) ] . iter ( ) ,
3341+ None ,
3342+ 0 ,
3343+ None ,
3344+ rng,
3345+ )
3346+ . unwrap ( ) ;
3347+ let block =
3348+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ transaction] , rng) . unwrap ( ) ;
3349+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3350+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3351+
3352+ // Ensure that no records were created or spent.
3353+ let ( num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3354+ get_record_counts ( ) ;
3355+ assert_eq ! ( num_spent_records, initial_spent_records + 1 ) ;
3356+ assert_eq ! ( num_slow_spent_records, initial_slow_spent_records + 1 ) ;
3357+ assert_eq ! ( num_unspent_records, initial_unspent_records + 2 ) ;
3358+ assert_eq ! ( num_slow_unspent_records, initial_slow_unspent_records + 2 ) ;
3359+ assert_eq ! ( num_records, initial_records + 3 ) ;
3360+
3361+ // Call the `consume` function.
3362+ let transaction = ledger
3363+ . vm ( )
3364+ . execute ( & private_key, ( "parent.aleo" , "consume" ) , vec ! [ Value :: Record ( mint_record) ] . iter ( ) , None , 0 , None , rng)
3365+ . unwrap ( ) ;
3366+ let block =
3367+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ transaction] , rng) . unwrap ( ) ;
3368+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3369+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3370+
3371+ // Ensure that the record was spent.
3372+ let ( num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3373+ get_record_counts ( ) ;
3374+ assert_eq ! ( num_spent_records, initial_spent_records + 2 ) ;
3375+ assert_eq ! ( num_slow_spent_records, initial_slow_spent_records + 2 ) ;
3376+ assert_eq ! ( num_unspent_records, initial_unspent_records + 1 ) ;
3377+ assert_eq ! ( num_slow_unspent_records, initial_slow_unspent_records + 1 ) ;
3378+ assert_eq ! ( num_records, initial_records + 3 ) ;
3379+
3380+ // Call the `create_and_consume` function.
3381+ let transaction = ledger
3382+ . vm ( )
3383+ . execute (
3384+ & private_key,
3385+ ( "parent.aleo" , "create_and_consume" ) ,
3386+ Vec :: < Value < CurrentNetwork > > :: new ( ) . iter ( ) ,
3387+ None ,
3388+ 0 ,
3389+ None ,
3390+ rng,
3391+ )
3392+ . unwrap ( ) ;
3393+ let block =
3394+ ledger. prepare_advance_to_next_beacon_block ( & private_key, vec ! [ ] , vec ! [ ] , vec ! [ transaction] , rng) . unwrap ( ) ;
3395+ assert_eq ! ( block. transactions( ) . num_accepted( ) , 1 ) ;
3396+ ledger. advance_to_next_block ( & block) . unwrap ( ) ;
3397+
3398+ // Ensure that a record was created and spent.
3399+ let ( num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3400+ get_record_counts ( ) ;
3401+ assert_eq ! ( num_spent_records, initial_spent_records + 3 ) ;
3402+ assert_eq ! ( num_slow_spent_records, initial_slow_spent_records + 3 ) ;
3403+ assert_eq ! ( num_unspent_records, initial_unspent_records + 1 ) ;
3404+ assert_eq ! ( num_slow_unspent_records, initial_slow_unspent_records + 1 ) ;
3405+ assert_eq ! ( num_records, initial_records + 4 ) ;
3406+ }
0 commit comments