@@ -39,9 +39,8 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
3939 /// The mapping of `transaction ID` to `program ID`.
4040 type IDMap : for < ' a > Map < ' a , N :: TransactionID , ProgramID < N > > ;
4141 /// The mapping of `transaction ID` to `edition`.
42- /// Note: The `IDEditionMap` stores the non-zero editions for deployment transactions.
4342 type IDEditionMap : for < ' a > Map < ' a , N :: TransactionID , u16 > ;
44- /// The mapping of `program ID` to `edition`.
43+ /// The mapping of `program ID` to the **latest** `edition`.
4544 type EditionMap : for < ' a > Map < ' a , ProgramID < N > , u16 > ;
4645 /// The mapping of `(program ID, edition)` to `transaction ID`.
4746 type ReverseIDMap : for < ' a > Map < ' a , ( ProgramID < N > , u16 ) , N :: TransactionID > ;
@@ -200,7 +199,7 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
200199 self . id_map( ) . insert( * transaction_id, program_id) ?;
201200 // Store the edition for the transaction ID.
202201 self . id_edition_map( ) . insert( * transaction_id, edition) ?;
203- // Store the edition for the program ID.
202+ // Store the latest edition for the program ID.
204203 self . edition_map( ) . insert( program_id, edition) ?;
205204
206205 // Store the reverse program ID.
@@ -227,19 +226,18 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
227226
228227 /// Removes the deployment transaction for the given `transaction ID`.
229228 fn remove ( & self , transaction_id : & N :: TransactionID ) -> Result < ( ) > {
230- // Retrieve the program ID.
229+ // Retrieve the program ID for the transaction ID .
231230 let Some ( program_id) = self . get_program_id ( transaction_id) ? else {
232231 bail ! ( "Failed to get the program ID for transaction '{transaction_id}'" ) ;
233232 } ;
234- // Retrieve the edition for the transaction.
233+ // Retrieve the edition for the transaction ID .
235234 let Some ( edition) = self . get_edition_for_transaction ( transaction_id) ? else {
236235 bail ! ( "Failed to locate the edition for transaction '{transaction_id}'" ) ;
237236 } ;
238- // Retrieve the latest edition for the program.
237+ // Retrieve the latest edition for the program ID .
239238 let Some ( latest_edition) = self . get_edition_for_program ( & program_id) ? else {
240239 bail ! ( "Failed to locate the latest edition for program '{program_id}'" ) ;
241240 } ;
242-
243241 // Retrieve the program.
244242 let program = match self . program_map ( ) . get_confirmed ( & ( program_id, edition) ) ? {
245243 Some ( program) => cow_to_cloned ! ( program) ,
@@ -253,8 +251,8 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
253251 self . id_edition_map( ) . remove( transaction_id) ?;
254252 // Update the latest edition.
255253 match ( edition, latest_edition) {
256- // If the removed edition is 0, remove the program ID from the latest edition map.
257- ( 0 , _ ) => self . edition_map( ) . remove( & program_id) ?,
254+ // If the removed and latest edition are 0, remove the program ID from the latest edition map.
255+ ( 0 , 0 ) => self . edition_map( ) . remove( & program_id) ?,
258256 // If the removed edition is the latest one, update the latest edition map by decrementing the edition.
259257 ( edition, latest_edition) if edition == latest_edition => {
260258 self . edition_map( ) . insert( program_id, edition. saturating_sub( 1 ) ) ?
@@ -387,6 +385,22 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
387385 }
388386 }
389387
388+ /// Returns the program for the given `program ID` and `edition`.
389+ fn get_program_with_edition ( & self , program_id : & ProgramID < N > , edition : u16 ) -> Result < Option < Program < N > > > {
390+ // Check if the program ID is for 'credits.aleo'.
391+ // This case is handled separately, as it is a default program of the VM.
392+ // TODO (howardwu): After we update 'fee' rules and 'Ratify' in genesis, we can remove this.
393+ if program_id == & ProgramID :: from_str ( "credits.aleo" ) ? {
394+ return Ok ( Some ( Program :: credits ( ) ?) ) ;
395+ }
396+
397+ // Retrieve the program.
398+ match self . program_map ( ) . get_confirmed ( & ( * program_id, edition) ) ? {
399+ Some ( program) => Ok ( Some ( cow_to_cloned ! ( program) ) ) ,
400+ None => bail ! ( "Failed to get program '{program_id}' (edition {edition})" ) ,
401+ }
402+ }
403+
390404 /// Returns the latest verifying key for the given `program ID` and `function name`.
391405 fn get_verifying_key (
392406 & self ,
@@ -419,6 +433,34 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
419433 }
420434 }
421435
436+ /// Returns the verifying key for the given `program ID`, `function name` and `edition`.
437+ fn get_verifying_key_with_edition (
438+ & self ,
439+ program_id : & ProgramID < N > ,
440+ function_name : & Identifier < N > ,
441+ edition : u16 ,
442+ ) -> Result < Option < VerifyingKey < N > > > {
443+ // Check if the program ID is for 'credits.aleo'.
444+ // This case is handled separately, as it is a default program of the VM.
445+ // TODO (howardwu): After we update 'fee' rules and 'Ratify' in genesis, we can remove this.
446+ if program_id == & ProgramID :: from_str ( "credits.aleo" ) ? {
447+ // Load the verifying key.
448+ let verifying_key = N :: get_credits_verifying_key ( function_name. to_string ( ) ) ?;
449+ // Retrieve the number of public and private variables.
450+ // Note: This number does *NOT* include the number of constants. This is safe because
451+ // this program is never deployed, as it is a first-class citizen of the protocol.
452+ let num_variables = verifying_key. circuit_info . num_public_and_private_variables as u64 ;
453+ // Return the verifying key.
454+ return Ok ( Some ( VerifyingKey :: new ( verifying_key. clone ( ) , num_variables) ) ) ;
455+ }
456+
457+ // Retrieve the verifying key.
458+ match self . verifying_key_map ( ) . get_confirmed ( & ( * program_id, * function_name, edition) ) ? {
459+ Some ( verifying_key) => Ok ( Some ( cow_to_cloned ! ( verifying_key) ) ) ,
460+ None => bail ! ( "Failed to get the verifying key for '{program_id}/{function_name}' (edition {edition})" ) ,
461+ }
462+ }
463+
422464 /// Returns the latest certificate for the given `program ID` and `function name`.
423465 fn get_certificate (
424466 & self ,
@@ -444,6 +486,27 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
444486 }
445487 }
446488
489+ /// Returns the certificate for the given `program ID`, `function name`, and `edition`.
490+ fn get_certificate_with_edition (
491+ & self ,
492+ program_id : & ProgramID < N > ,
493+ function_name : & Identifier < N > ,
494+ edition : u16 ,
495+ ) -> Result < Option < Certificate < N > > > {
496+ // Check if the program ID is for 'credits.aleo'.
497+ // This case is handled separately, as it is a default program of the VM.
498+ // TODO (howardwu): After we update 'fee' rules and 'Ratify' in genesis, we can remove this.
499+ if program_id == & ProgramID :: from_str ( "credits.aleo" ) ? {
500+ return Ok ( None ) ;
501+ }
502+
503+ // Retrieve the certificate.
504+ match self . certificate_map ( ) . get_confirmed ( & ( * program_id, * function_name, edition) ) ? {
505+ Some ( certificate) => Ok ( Some ( cow_to_cloned ! ( certificate) ) ) ,
506+ None => bail ! ( "Failed to get the certificate for '{program_id}/{function_name}' (edition {edition})" ) ,
507+ }
508+ }
509+
447510 /// Returns the deployment for the given `transaction ID`.
448511 fn get_deployment ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < Deployment < N > > > {
449512 // Retrieve the program ID.
@@ -513,6 +576,22 @@ pub trait DeploymentStorage<N: Network>: Clone + Send + Sync {
513576 }
514577 }
515578
579+ /// Returns the owner for the given `program ID` and `edition`.
580+ fn get_owner_with_edition ( & self , program_id : & ProgramID < N > , edition : u16 ) -> Result < Option < ProgramOwner < N > > > {
581+ // Check if the program ID is for 'credits.aleo'.
582+ // This case is handled separately, as it is a default program of the VM.
583+ // TODO (howardwu): After we update 'fee' rules and 'Ratify' in genesis, we can remove this.
584+ if program_id == & ProgramID :: from_str ( "credits.aleo" ) ? {
585+ return Ok ( None ) ;
586+ }
587+
588+ // Retrieve the owner.
589+ match self . owner_map ( ) . get_confirmed ( & ( * program_id, edition) ) ? {
590+ Some ( owner) => Ok ( Some ( cow_to_copied ! ( owner) ) ) ,
591+ None => bail ! ( "Failed to find the Owner for program '{program_id}' (edition {edition})" ) ,
592+ }
593+ }
594+
516595 /// Returns the transaction for the given `transaction ID`.
517596 fn get_transaction ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < Transaction < N > > > {
518597 // Retrieve the deployment.
@@ -647,6 +726,11 @@ impl<N: Network, D: DeploymentStorage<N>> DeploymentStore<N, D> {
647726 self . storage . get_program ( program_id)
648727 }
649728
729+ /// Returns the program for the given `program ID` and `edition`.
730+ pub fn get_program_with_edition ( & self , program_id : & ProgramID < N > , edition : u16 ) -> Result < Option < Program < N > > > {
731+ self . storage . get_program_with_edition ( program_id, edition)
732+ }
733+
650734 /// Returns the latest verifying key for the given `(program ID, function name)`.
651735 pub fn get_verifying_key (
652736 & self ,
@@ -656,6 +740,16 @@ impl<N: Network, D: DeploymentStorage<N>> DeploymentStore<N, D> {
656740 self . storage . get_verifying_key ( program_id, function_name)
657741 }
658742
743+ /// Returns the verifying key for the given `(program ID, function name, edition)`.
744+ pub fn get_verifying_key_with_edition (
745+ & self ,
746+ program_id : & ProgramID < N > ,
747+ function_name : & Identifier < N > ,
748+ edition : u16 ,
749+ ) -> Result < Option < VerifyingKey < N > > > {
750+ self . storage . get_verifying_key_with_edition ( program_id, function_name, edition)
751+ }
752+
659753 /// Returns the latest certificate for the given `(program ID, function name)`.
660754 pub fn get_certificate (
661755 & self ,
@@ -665,6 +759,16 @@ impl<N: Network, D: DeploymentStorage<N>> DeploymentStore<N, D> {
665759 self . storage . get_certificate ( program_id, function_name)
666760 }
667761
762+ /// Returns the certificate for the given `(program ID, function name, edition)`.
763+ pub fn get_certificate_with_edition (
764+ & self ,
765+ program_id : & ProgramID < N > ,
766+ function_name : & Identifier < N > ,
767+ edition : u16 ,
768+ ) -> Result < Option < Certificate < N > > > {
769+ self . storage . get_certificate_with_edition ( program_id, function_name, edition)
770+ }
771+
668772 /// Returns the fee for the given `transaction ID`.
669773 pub fn get_fee ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < Fee < N > > > {
670774 self . storage . get_fee ( transaction_id)
@@ -707,6 +811,7 @@ impl<N: Network, D: DeploymentStorage<N>> DeploymentStore<N, D> {
707811 }
708812}
709813
814+ type ProgramIDEdition < N > = ( ProgramID < N > , u16 ) ;
710815type ProgramTriplet < N > = ( ProgramID < N > , Identifier < N > , u16 ) ;
711816
712817impl < N : Network , D : DeploymentStorage < N > > DeploymentStore < N , D > {
@@ -724,6 +829,11 @@ impl<N: Network, D: DeploymentStorage<N>> DeploymentStore<N, D> {
724829 } )
725830 }
726831
832+ /// Returns an iterator over the program IDs and latest editions.
833+ pub fn program_ids_and_editions ( & self ) -> impl ' _ + Iterator < Item = ( Cow < ' _ , ProgramID < N > > , Cow < ' _ , u16 > ) > {
834+ self . storage . edition_map ( ) . iter_confirmed ( )
835+ }
836+
727837 /// Returns an iterator over the programs, for all deployments.
728838 /// If a program has been updated, multiple versions of the program will be returned.
729839 pub fn programs ( & self ) -> impl ' _ + Iterator < Item = Cow < ' _ , Program < N > > > {
@@ -733,6 +843,13 @@ impl<N: Network, D: DeploymentStorage<N>> DeploymentStore<N, D> {
733843 } )
734844 }
735845
846+ /// Returns an iterator over the programs and editions, for all deployments.
847+ pub fn programs_and_editions (
848+ & self ,
849+ ) -> impl ' _ + Iterator < Item = ( Cow < ' _ , ProgramIDEdition < N > > , Cow < ' _ , Program < N > > ) > {
850+ self . storage . program_map ( ) . iter_confirmed ( )
851+ }
852+
736853 /// Returns an iterator over the `((program ID, function name, edition), verifying key)`, for all deployments.
737854 pub fn verifying_keys ( & self ) -> impl ' _ + Iterator < Item = ( Cow < ' _ , ProgramTriplet < N > > , Cow < ' _ , VerifyingKey < N > > ) > {
738855 self . storage . verifying_key_map ( ) . iter_confirmed ( )
0 commit comments