snarkos_aot/program/
cost.rs

1use anyhow::{ensure, Result};
2use clap::Args;
3use clap_stdin::FileOrStdin;
4use snarkvm::{
5    prelude::{Identifier, Value},
6    synthesizer::{process::deployment_cost, Process, Program},
7};
8
9use crate::{
10    auth::{auth_fee::estimate_cost, query},
11    Network, PrivateKey,
12};
13
14/// Compute the cost to execute a function in a given program.
15#[derive(Debug, Args)]
16pub struct CostCommand<N: Network> {
17    /// Query to load the program with.
18    #[clap(short, long)]
19    pub query: Option<String>,
20    /// Program to estimate the cost of.
21    pub program: FileOrStdin<Program<N>>,
22    /// Program ID and function name (eg. credits.aleo/transfer_public). When
23    /// not specified, the cost of deploying the program is estimated.
24    function: Option<Identifier<N>>,
25    /// Program inputs (eg. 1u64 5field)
26    #[clap(num_args = 1, value_delimiter = ' ')]
27    inputs: Vec<Value<N>>,
28}
29
30impl<N: Network> CostCommand<N> {
31    pub fn parse(self) -> Result<u64> {
32        let CostCommand {
33            query,
34            program,
35            function,
36            inputs,
37        } = self;
38
39        let program = program.contents()?;
40        let mut process = Process::load()?;
41        query::get_process_imports(&mut process, &program, query.as_deref())?;
42
43        if let Some(function) = function {
44            process.add_program(&program)?;
45            ensure!(
46                program.functions().contains_key(&function),
47                "Function {} not found in program",
48                function
49            );
50
51            let auth = process
52                .get_stack(program.id())?
53                .authorize::<N::Circuit, _>(
54                    &PrivateKey::new(&mut rand::thread_rng())?,
55                    function,
56                    inputs.iter(),
57                    &mut rand::thread_rng(),
58                )?;
59
60            estimate_cost(&process, &auth)
61        } else {
62            let deployment = process.deploy::<N::Circuit, _>(&program, &mut rand::thread_rng())?;
63            Ok(deployment_cost(&deployment)?.0)
64        }
65    }
66}