/ synthesizer / src / vm / authorize.rs
authorize.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaVM 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  impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
 19      /// Authorizes a call to the program function for the given inputs.
 20      #[inline]
 21      pub fn authorize<R: Rng + CryptoRng>(
 22          &self,
 23          private_key: &PrivateKey<N>,
 24          program_id: impl TryInto<ProgramID<N>>,
 25          function_name: impl TryInto<Identifier<N>>,
 26          inputs: impl IntoIterator<IntoIter = impl ExactSizeIterator<Item = impl TryInto<Value<N>>>>,
 27          rng: &mut R,
 28      ) -> Result<Authorization<N>> {
 29          let timer = timer!("VM::authorize");
 30  
 31          // Prepare the program ID.
 32          let program_id = program_id.try_into().map_err(|_| anyhow!("Invalid program ID"))?;
 33          // Prepare the function name.
 34          let function_name = function_name.try_into().map_err(|_| anyhow!("Invalid function name"))?;
 35          // Prepare the inputs.
 36          let inputs = inputs
 37              .into_iter()
 38              .enumerate()
 39              .map(|(index, input)| {
 40                  input
 41                      .try_into()
 42                      .map_err(|_| anyhow!("Failed to parse input #{index} for '{program_id}/{function_name}'"))
 43              })
 44              .collect::<Result<Vec<_>>>()?;
 45          lap!(timer, "Prepare inputs");
 46  
 47          // Authorize the call.
 48          let result = self.authorize_raw(private_key, program_id, function_name, inputs, rng);
 49          finish!(timer, "Authorize the call");
 50          result
 51      }
 52  
 53      /// Authorizes the fee given the credits record, the fee amount (in microcredits),
 54      /// and the deployment or execution ID.
 55      #[inline]
 56      pub fn authorize_fee_private<R: Rng + CryptoRng>(
 57          &self,
 58          private_key: &PrivateKey<N>,
 59          credits: Record<N, Plaintext<N>>,
 60          base_fee_in_microcredits: u64,
 61          priority_fee_in_microcredits: u64,
 62          deployment_or_execution_id: Field<N>,
 63          rng: &mut R,
 64      ) -> Result<Authorization<N>> {
 65          macro_rules! logic {
 66              ($process:expr, $network:path, $aleo:path) => {{
 67                  // Compute the authorization.
 68                  let authorization = $process.authorize_fee_private::<$aleo, _>(
 69                      cast_ref!(&private_key as PrivateKey<$network>),
 70                      cast_ref!(credits as Record<$network, Plaintext<$network>>).clone(),
 71                      base_fee_in_microcredits,
 72                      priority_fee_in_microcredits,
 73                      *cast_ref!(deployment_or_execution_id as Field<$network>),
 74                      rng,
 75                  )?;
 76                  // Prepare the authorization.
 77                  Ok(cast_ref!(authorization as Authorization<N>).clone())
 78              }};
 79          }
 80  
 81          // Compute the authorization.
 82          let timer = timer!("VM::authorize_fee_private");
 83          let result = process!(self, logic);
 84          finish!(timer, "Compute the authorization");
 85          result
 86      }
 87  
 88      /// Authorizes the fee given the the fee amount (in microcredits) and the deployment or execution ID.
 89      #[inline]
 90      pub fn authorize_fee_public<R: Rng + CryptoRng>(
 91          &self,
 92          private_key: &PrivateKey<N>,
 93          base_fee_in_microcredits: u64,
 94          priority_fee_in_microcredits: u64,
 95          deployment_or_execution_id: Field<N>,
 96          rng: &mut R,
 97      ) -> Result<Authorization<N>> {
 98          macro_rules! logic {
 99              ($process:expr, $network:path, $aleo:path) => {{
100                  // Compute the authorization.
101                  let authorization = $process.authorize_fee_public::<$aleo, _>(
102                      cast_ref!(&private_key as PrivateKey<$network>),
103                      base_fee_in_microcredits,
104                      priority_fee_in_microcredits,
105                      *cast_ref!(deployment_or_execution_id as Field<$network>),
106                      rng,
107                  )?;
108                  // Prepare the authorization.
109                  Ok(cast_ref!(authorization as Authorization<N>).clone())
110              }};
111          }
112  
113          // Compute the authorization.
114          let timer = timer!("VM::authorize_fee_public");
115          let result = process!(self, logic);
116          finish!(timer, "Compute the authorization");
117          result
118      }
119  }
120  
121  impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
122      /// Authorizes a call to the program function for the given inputs.
123      #[inline]
124      fn authorize_raw<R: Rng + CryptoRng>(
125          &self,
126          private_key: &PrivateKey<N>,
127          program_id: ProgramID<N>,
128          function_name: Identifier<N>,
129          inputs: Vec<Value<N>>,
130          rng: &mut R,
131      ) -> Result<Authorization<N>> {
132          macro_rules! logic {
133              ($process:expr, $network:path, $aleo:path) => {{
134                  // Compute the authorization.
135                  let authorization = $process.authorize::<$aleo, _>(
136                      cast_ref!(&private_key as PrivateKey<$network>),
137                      cast_ref!(program_id as ProgramID<$network>),
138                      cast_ref!(function_name as Identifier<$network>),
139                      cast_ref!(inputs as Vec<Value<$network>>).iter(),
140                      rng,
141                  )?;
142                  // Prepare the authorization.
143                  Ok(cast_ref!(authorization as Authorization<N>).clone())
144              }};
145          }
146  
147          // Compute the authorization.
148          let timer = timer!("VM::authorize_raw");
149          let result = process!(self, logic);
150          finish!(timer, "Compute the authorization");
151          result
152      }
153  }