snarkvm_synthesizer_debug/vm/
deploy.rs

1// Copyright (C) 2019-2023 Aleo Systems 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// http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use super::*;
16
17impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
18    /// Returns a new deploy transaction.
19    ///
20    /// If a `fee_record` is provided, then a private fee will be included in the transaction;
21    /// otherwise, a public fee will be included in the transaction.
22    ///
23    /// The `priority_fee_in_microcredits` is an additional fee **on top** of the deployment fee.
24    pub fn deploy<R: Rng + CryptoRng>(
25        &self,
26        private_key: &PrivateKey<N>,
27        program: &Program<N>,
28        fee_record: Option<Record<N, Plaintext<N>>>,
29        priority_fee_in_microcredits: u64,
30        query: Option<Query<N, C::BlockStorage>>,
31        rng: &mut R,
32    ) -> Result<Transaction<N>> {
33        // Compute the deployment.
34        let deployment = self.deploy_raw(program, rng)?;
35        // Ensure the transaction is not empty.
36        ensure!(!deployment.program().functions().is_empty(), "Attempted to create an empty transaction deployment");
37        // Compute the deployment ID.
38        let deployment_id = deployment.to_deployment_id()?;
39        // Construct the owner.
40        let owner = ProgramOwner::new(private_key, deployment_id, rng)?;
41
42        // Compute the minimum deployment cost.
43        let (minimum_deployment_cost, (_, _)) = deployment_cost(&deployment)?;
44        // Authorize the fee.
45        let fee_authorization = match fee_record {
46            Some(record) => self.authorize_fee_private(
47                private_key,
48                record,
49                minimum_deployment_cost,
50                priority_fee_in_microcredits,
51                deployment_id,
52                rng,
53            )?,
54            None => self.authorize_fee_public(
55                private_key,
56                minimum_deployment_cost,
57                priority_fee_in_microcredits,
58                deployment_id,
59                rng,
60            )?,
61        };
62        // Compute the fee.
63        let fee = self.execute_fee_authorization(fee_authorization, query, rng)?;
64
65        // Return the deploy transaction.
66        Transaction::from_deployment(owner, deployment, fee)
67    }
68}
69
70impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
71    /// Returns a deployment for the given program.
72    #[inline]
73    pub(super) fn deploy_raw<R: Rng + CryptoRng>(&self, program: &Program<N>, rng: &mut R) -> Result<Deployment<N>> {
74        macro_rules! logic {
75            ($process:expr, $network:path, $aleo:path) => {{
76                // Prepare the program.
77                let program = cast_ref!(&program as Program<$network>);
78                // Compute the deployment.
79                let deployment = $process.deploy::<$aleo, _>(program, rng)?;
80                // Prepare the deployment.
81                Ok(cast_ref!(deployment as Deployment<N>).clone())
82            }};
83        }
84
85        // Compute the deployment.
86        let timer = timer!("VM::deploy_raw");
87        let result = process!(self, logic);
88        finish!(timer, "Compute the deployment");
89        result
90    }
91}