1+ // Copyright (c) 2019-2025 Provable Inc.
2+ // This file is part of the snarkVM library.
3+
4+ // Licensed under the Apache License, Version 2.0 (the "License");
5+ // you may not use this file except in compliance with the License.
6+ // You may obtain a copy of the License at:
7+
8+ // http://www.apache.org/licenses/LICENSE-2.0
9+
10+ // Unless required by applicable law or agreed to in writing, software
11+ // distributed under the License is distributed on an "AS IS" BASIS,
12+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ // See the License for the specific language governing permissions and
14+ // limitations under the License.
15+
16+ use super :: * ;
17+
18+ #[ test]
19+ fn test_get_dynamic_record ( ) {
20+ // Parameters for dynamic-function calls
21+ let program_name_str = "warehouse" ;
22+ let network_str = "aleo" ;
23+ let mint_nineties_bleach_function_str = "mint_nineties_bleach" ;
24+ let mint_fake_compliance_cert_function_str = "mint_fake_compliance_cert" ;
25+
26+ let program_name_field = Identifier :: < CurrentNetwork > :: from_str ( program_name_str) . unwrap ( ) . to_field ( ) . unwrap ( ) ;
27+ let network_field = Identifier :: < CurrentNetwork > :: from_str ( network_str) . unwrap ( ) . to_field ( ) . unwrap ( ) ;
28+ let mint_nineties_bleach_function_field =
29+ Identifier :: < CurrentNetwork > :: from_str ( mint_nineties_bleach_function_str) . unwrap ( ) . to_field ( ) . unwrap ( ) ;
30+ let mint_fake_compliance_cert_function_field =
31+ Identifier :: < CurrentNetwork > :: from_str ( mint_fake_compliance_cert_function_str) . unwrap ( ) . to_field ( ) . unwrap ( ) ;
32+
33+ let rng = & mut TestRng :: default ( ) ;
34+
35+ let caller_private_key = sample_genesis_private_key ( rng) ;
36+ let caller_address = Address :: try_from ( & caller_private_key) . unwrap ( ) ;
37+ let caller_view_key = ViewKey :: < CurrentNetwork > :: try_from ( caller_private_key) . unwrap ( ) ;
38+
39+ // Initialize a new program.
40+ let program_string = format ! (
41+ r"
42+ program {program_name_str}.aleo;
43+
44+ struct safety_struct:
45+ first as field;
46+ second as field;
47+
48+ record consumable:
49+ owner as address.private;
50+ // D, M, Y
51+ expiry_date as [u8; 3u32].private;
52+ critical as boolean.public;
53+ // D, M, Y
54+ production_date as [u8; 3u32].public;
55+
56+ record non_consumable:
57+ owner as address.private;
58+ amount as u64.private;
59+ producer_country_code as u16.public;
60+ producer_pk as group.private;
61+ id as field.public;
62+ production_date as [u8; 3u32].public;
63+ safety as safety_struct.public;
64+
65+ function production_month:
66+ input r0 as dynamic.record;
67+ get.dynamic.record r0.production_date into r1 as [u8; 3u32];
68+ output r1[1u32] as u8.public;
69+
70+ function production_year_difference:
71+ call.dynamic {program_name_field} {network_field} {mint_nineties_bleach_function_field} into r0 (as dynamic.record);
72+ call.dynamic {program_name_field} {network_field} {mint_fake_compliance_cert_function_field} into r1 (as dynamic.record);
73+
74+ get.dynamic.record r0.production_date into r2 as [u8; 3u32];
75+ get.dynamic.record r1.production_date into r3 as [u8; 3u32];
76+
77+ sub r2[2u32] r3[2u32] into r4;
78+
79+ output r4 as u8.public;
80+
81+ function {mint_nineties_bleach_function_str}:
82+ cast 10u8 9u8 92u8 into r0 as [u8; 3u32];
83+ cast 10u8 9u8 42u8 into r1 as [u8; 3u32];
84+
85+ cast {caller_address} r0 true r1 into r2 as consumable.record;
86+
87+ output r2 as consumable.record;
88+
89+ function {mint_fake_compliance_cert_function_str}:
90+ cast 11u8 7u8 17u8 into r0 as [u8; 3u32];
91+ cast 10field 13field into r1 as safety_struct;
92+
93+ cast {caller_address} 2u64 91u16 2group 1field r0 r1 into r2 as non_consumable.record;
94+
95+ output r2 as non_consumable.record;
96+
97+ constructor:
98+ assert.eq true true;
99+ "
100+ ) ;
101+
102+ let program = Program :: < CurrentNetwork > :: from_str ( & program_string) . unwrap ( ) ;
103+
104+ // Initialize the VM.
105+ let vm = sample_vm_at_height ( CurrentNetwork :: CONSENSUS_HEIGHT ( ConsensusVersion :: V12 ) . unwrap ( ) , rng) ;
106+
107+ // Deploy the program.
108+ println ! ( "Deploying program warehouse.aleo..." ) ;
109+ let transaction_deploy = vm. deploy ( & caller_private_key, & program, None , 0 , None , rng) . unwrap ( ) ;
110+ add_and_test ( & vm, & caller_private_key, & [ transaction_deploy] , rng) ;
111+
112+ /************** Case 1: Simple read **************/
113+
114+ let record_static_str = format ! (
115+ r#"{{
116+ owner: {caller_address}.private,
117+ expiry_date: [29u8.private, 2u8.private, 25u8.private],
118+ critical: false.public,
119+ production_date: [10u8.private, 7u8.private, 87u8.private],
120+ _nonce: 0group.public,
121+ _version: 1u8.public
122+ }}"#
123+ ) ;
124+
125+ let record_static = Record :: < CurrentNetwork , Plaintext < CurrentNetwork > > :: from_str ( & record_static_str) . unwrap ( ) ;
126+ let record_dynamic = DynamicRecord :: < CurrentNetwork > :: from_record ( & record_static) . unwrap ( ) ;
127+
128+ println ! ( "Executing root function warehouse.aleo/production_month..." ) ;
129+ let transaction_1 = vm
130+ . execute (
131+ & caller_private_key,
132+ ( "warehouse.aleo" , "production_month" ) ,
133+ vec ! [ Value :: <CurrentNetwork >:: DynamicRecord ( record_dynamic) ] . into_iter ( ) ,
134+ None ,
135+ 0 ,
136+ None ,
137+ rng,
138+ )
139+ . unwrap ( ) ;
140+
141+ let expected_output = Plaintext :: < CurrentNetwork > :: from_str ( "7u8" ) . unwrap ( ) ;
142+
143+ assert ! (
144+ matches!( transaction_1. transitions( ) . next( ) . unwrap( ) . outputs( ) , [ Output :: Public ( _, Some ( plaintext) ) ] if * plaintext == expected_output) ,
145+ "Expected output: {:?}, got: {:?}" ,
146+ expected_output,
147+ transaction_1. transitions( ) . next( ) . unwrap( ) . outputs( )
148+ ) ;
149+
150+ add_and_test ( & vm, & caller_private_key, & [ transaction_1] , rng) ;
151+
152+ /************** Case 2: Read from minted records (using polymorphy) **************/
153+
154+ // Here this case a function outputs two static records of different types that are received as
155+ // dynamic by the caller; and the caller then proceeds to field two fields with the same name
156+ // that the two static-record types happen to have.
157+
158+ let transaction_2 = vm
159+ . execute (
160+ & caller_private_key,
161+ ( "warehouse.aleo" , "production_year_difference" ) ,
162+ Vec :: < Value < CurrentNetwork > > :: new ( ) . into_iter ( ) ,
163+ None ,
164+ 0 ,
165+ None ,
166+ rng,
167+ )
168+ . unwrap ( ) ;
169+
170+ let expected_output = Plaintext :: < CurrentNetwork > :: from_str ( "25u8" ) . unwrap ( ) ;
171+
172+ assert ! (
173+ // The first two transactions correspond to the two minting operations
174+ matches!( transaction_2. transitions( ) . skip( 2 ) . next( ) . unwrap( ) . outputs( ) , [ Output :: Public ( _, Some ( plaintext) ) ] if * plaintext == expected_output) ,
175+ "Expected output: {:?}, got: {:?}" ,
176+ expected_output,
177+ transaction_2. transitions( ) . next( ) . unwrap( ) . outputs( )
178+ ) ;
179+
180+ add_and_test ( & vm, & caller_private_key, & [ transaction_2] , rng) ;
181+ }
0 commit comments