mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-10-26 15:13:13 +03:00
modularize
This commit is contained in:
parent
9eaddfcea9
commit
275e837030
@ -416,6 +416,6 @@ create_messages!(
|
|||||||
execution_error {
|
execution_error {
|
||||||
args: (error: impl Display),
|
args: (error: impl Display),
|
||||||
msg: format!("❌ Execution error: {error}"),
|
msg: format!("❌ Execution error: {error}"),
|
||||||
help: None,
|
help: Some("Make sure that you are using the right network. Use `--network testnet` to switch to testnet.".to_string()),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -65,7 +65,7 @@ create_messages!(
|
|||||||
network_error {
|
network_error {
|
||||||
args: (url: impl Display, status: impl Display),
|
args: (url: impl Display, status: impl Display),
|
||||||
msg: format!("Failed network request to {url}. Status: {status}"),
|
msg: format!("Failed network request to {url}. Status: {status}"),
|
||||||
help: None,
|
help: Some("Make sure that you are using the right network and endpoint. Use `--network testnet` to switch to testnet.".to_string()),
|
||||||
}
|
}
|
||||||
|
|
||||||
@formatted
|
@formatted
|
||||||
|
@ -126,7 +126,7 @@ pub fn run_with_args(cli: CLI) -> Result<()> {
|
|||||||
|
|
||||||
// Get custom root folder and create context for it.
|
// Get custom root folder and create context for it.
|
||||||
// If not specified, default context will be created in cwd.
|
// If not specified, default context will be created in cwd.
|
||||||
let context = handle_error(Context::new(cli.path, cli.home));
|
let context = handle_error(Context::new(cli.path, cli.home, false));
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::Add { command } => command.try_execute(context),
|
Commands::Add { command } => command.try_execute(context),
|
||||||
|
@ -128,15 +128,17 @@ fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
|
|||||||
let vm = VM::from(store)?;
|
let vm = VM::from(store)?;
|
||||||
|
|
||||||
// Compute the minimum deployment cost.
|
// Compute the minimum deployment cost.
|
||||||
let (total_cost, (storage_cost, synthesis_cost, namespace_cost)) = deployment_cost(&deployment)?;
|
let (mut total_cost, (storage_cost, synthesis_cost, namespace_cost)) = deployment_cost(&deployment)?;
|
||||||
|
|
||||||
// Display the deployment cost breakdown using `credit` denomination.
|
// Display the deployment cost breakdown using `credit` denomination.
|
||||||
|
total_cost += command.fee_options.priority_fee;
|
||||||
deploy_cost_breakdown(
|
deploy_cost_breakdown(
|
||||||
name,
|
name,
|
||||||
total_cost as f64 / 1_000_000.0,
|
total_cost as f64 / 1_000_000.0,
|
||||||
storage_cost as f64 / 1_000_000.0,
|
storage_cost as f64 / 1_000_000.0,
|
||||||
synthesis_cost as f64 / 1_000_000.0,
|
synthesis_cost as f64 / 1_000_000.0,
|
||||||
namespace_cost as f64 / 1_000_000.0,
|
namespace_cost as f64 / 1_000_000.0,
|
||||||
|
command.fee_options.priority_fee as f64 / 1_000_000.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Initialize an RNG.
|
// Initialize an RNG.
|
||||||
@ -157,6 +159,8 @@ fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
|
|||||||
vm.execute_fee_authorization(fee_authorization, Some(query.clone()), rng)?
|
vm.execute_fee_authorization(fee_authorization, Some(query.clone()), rng)?
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
// Make sure the user has enough public balance to pay for the deployment.
|
||||||
|
check_balance(&private_key, &command.options.endpoint, &command.options.network, context.clone(), total_cost)?;
|
||||||
let fee_authorization = vm.authorize_fee_public(
|
let fee_authorization = vm.authorize_fee_public(
|
||||||
&private_key,
|
&private_key,
|
||||||
total_cost,
|
total_cost,
|
||||||
@ -193,7 +197,7 @@ fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A helper function to display a cost breakdown of the deployment.
|
// A helper function to display a cost breakdown of the deployment.
|
||||||
fn deploy_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, synthesis_cost: f64, namespace_cost: f64) {
|
fn deploy_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, synthesis_cost: f64, namespace_cost: f64, priority_fee: f64) {
|
||||||
println!("Base deployment cost for '{}' is {} credits.", name.bold(), total_cost);
|
println!("Base deployment cost for '{}' is {} credits.", name.bold(), total_cost);
|
||||||
// Display the cost breakdown in a table.
|
// Display the cost breakdown in a table.
|
||||||
let data = [
|
let data = [
|
||||||
@ -207,6 +211,7 @@ fn deploy_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, synt
|
|||||||
"Namespace",
|
"Namespace",
|
||||||
&format!("{:.6}", namespace_cost),
|
&format!("{:.6}", namespace_cost),
|
||||||
],
|
],
|
||||||
|
["Priority Fee", &format!("{:.6}", priority_fee)],
|
||||||
["Total", &format!("{:.6}", total_cost)],
|
["Total", &format!("{:.6}", total_cost)],
|
||||||
];
|
];
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
|
@ -186,35 +186,25 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Check the transaction cost.
|
// Check the transaction cost.
|
||||||
let (total_cost, (storage_cost, finalize_cost)) = if let ExecuteTransaction(_, execution, _) = &transaction {
|
let (mut total_cost, (storage_cost, finalize_cost)) = if let ExecuteTransaction(_, execution, _) = &transaction {
|
||||||
execution_cost(&vm.process().read(), execution)?
|
execution_cost(&vm.process().read(), execution)?
|
||||||
} else {
|
} else {
|
||||||
panic!("All transactions should be of type Execute.")
|
panic!("All transactions should be of type Execute.")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Print the cost breakdown.
|
||||||
|
total_cost += command.fee_options.priority_fee;
|
||||||
|
execution_cost_breakdown(
|
||||||
|
&program_name,
|
||||||
|
total_cost as f64 / 1_000_000.0,
|
||||||
|
storage_cost as f64 / 1_000_000.0,
|
||||||
|
finalize_cost as f64 / 1_000_000.0,
|
||||||
|
command.fee_options.priority_fee as f64 / 1_000_000.0,
|
||||||
|
);
|
||||||
|
|
||||||
// Check if the public balance is sufficient.
|
// Check if the public balance is sufficient.
|
||||||
if fee_record.is_none() {
|
if fee_record.is_none() {
|
||||||
// Derive the account address.
|
check_balance::<A::Network>(&private_key, &command.compiler_options.endpoint, &command.compiler_options.network, context, total_cost)?;
|
||||||
let address = Address::<A::Network>::try_from(ViewKey::try_from(&private_key)?)?;
|
|
||||||
// Query the public balance of the address on the `account` mapping from `credits.aleo`.
|
|
||||||
let mut public_balance = Query {
|
|
||||||
endpoint: command.compiler_options.endpoint.clone(),
|
|
||||||
network: command.compiler_options.network.clone(),
|
|
||||||
command: QueryCommands::Program {
|
|
||||||
command: crate::cli::commands::query::Program {
|
|
||||||
name: "credits".to_string(),
|
|
||||||
mappings: false,
|
|
||||||
mapping_value: Some(vec!["account".to_string(), address.to_string()]),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.execute(context.clone())?;
|
|
||||||
// Check balance.
|
|
||||||
// Remove the last 3 characters since they represent the `u64` suffix.
|
|
||||||
public_balance.truncate(public_balance.len() - 3);
|
|
||||||
if public_balance.parse::<u64>().unwrap() < total_cost {
|
|
||||||
return Err(PackageError::insufficient_balance(public_balance, total_cost).into());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("✅ Created execution transaction for '{}'", program_id.to_string().bold());
|
println!("✅ Created execution transaction for '{}'", program_id.to_string().bold());
|
||||||
@ -331,7 +321,7 @@ fn load_program_from_network<N: Network>(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
.execute(context.clone())?;
|
.execute(Context::new(context.path.clone(), context.home.clone(), true)?)?;
|
||||||
let program = SnarkVMProgram::<N>::from_str(&program_src).unwrap();
|
let program = SnarkVMProgram::<N>::from_str(&program_src).unwrap();
|
||||||
|
|
||||||
// Return early if the program is already loaded.
|
// Return early if the program is already loaded.
|
||||||
@ -357,7 +347,7 @@ fn load_program_from_network<N: Network>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A helper function to display a cost breakdown of the execution.
|
// A helper function to display a cost breakdown of the execution.
|
||||||
fn execution_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, finalize_cost: f64) {
|
fn execution_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, finalize_cost: f64, priority_fee: f64) {
|
||||||
println!("Base execution cost for '{}' is {} credits.", name.bold(), total_cost);
|
println!("Base execution cost for '{}' is {} credits.", name.bold(), total_cost);
|
||||||
// Display the cost breakdown in a table.
|
// Display the cost breakdown in a table.
|
||||||
let data = [
|
let data = [
|
||||||
@ -370,6 +360,10 @@ fn execution_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, f
|
|||||||
"On-chain Execution",
|
"On-chain Execution",
|
||||||
&format!("{:.6}", finalize_cost),
|
&format!("{:.6}", finalize_cost),
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"Priority Fee",
|
||||||
|
&format!("{:.6}", priority_fee),
|
||||||
|
],
|
||||||
["Total", &format!("{:.6}", total_cost)],
|
["Total", &format!("{:.6}", total_cost)],
|
||||||
];
|
];
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
|
@ -57,7 +57,7 @@ use super::*;
|
|||||||
use crate::cli::helpers::context::*;
|
use crate::cli::helpers::context::*;
|
||||||
use leo_errors::{emitter::Handler, CliError, PackageError, Result};
|
use leo_errors::{emitter::Handler, CliError, PackageError, Result};
|
||||||
use leo_package::{build::*, outputs::OutputsDirectory, package::*};
|
use leo_package::{build::*, outputs::OutputsDirectory, package::*};
|
||||||
use snarkvm::prelude::{block::Transaction, Ciphertext, Plaintext, PrivateKey, Record, ViewKey};
|
use snarkvm::prelude::{Address, block::Transaction, Ciphertext, Plaintext, PrivateKey, Record, ViewKey};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
@ -65,6 +65,7 @@ use std::str::FromStr;
|
|||||||
use tracing::span::Span;
|
use tracing::span::Span;
|
||||||
|
|
||||||
use snarkvm::console::network::Network;
|
use snarkvm::console::network::Network;
|
||||||
|
use crate::cli::query::QueryCommands;
|
||||||
|
|
||||||
/// Base trait for the Leo CLI, see methods and their documentation for details.
|
/// Base trait for the Leo CLI, see methods and their documentation for details.
|
||||||
pub trait Command {
|
pub trait Command {
|
||||||
@ -238,6 +239,32 @@ pub fn parse_record<N: Network>(private_key: &PrivateKey<N>, record: &str) -> Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_balance<N: Network>(private_key: &PrivateKey<N>, endpoint: &String, network: &String, context: Context, total_cost: u64) -> Result<()> {
|
||||||
|
// Derive the account address.
|
||||||
|
let address = Address::<N>::try_from(ViewKey::try_from(private_key)?)?;
|
||||||
|
// Query the public balance of the address on the `account` mapping from `credits.aleo`.
|
||||||
|
let mut public_balance = Query {
|
||||||
|
endpoint: endpoint.clone(),
|
||||||
|
network: network.clone(),
|
||||||
|
command: QueryCommands::Program {
|
||||||
|
command: crate::cli::commands::query::Program {
|
||||||
|
name: "credits".to_string(),
|
||||||
|
mappings: false,
|
||||||
|
mapping_value: Some(vec!["account".to_string(), address.to_string()]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.execute(Context::new(context.path.clone(), context.home.clone(), true)?)?;
|
||||||
|
// Remove the last 3 characters since they represent the `u64` suffix.
|
||||||
|
public_balance.truncate(public_balance.len() - 3);
|
||||||
|
// Compare balance.
|
||||||
|
if public_balance.parse::<u64>().unwrap() < total_cost {
|
||||||
|
return Err(PackageError::insufficient_balance(public_balance, total_cost).into());
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Determine if the transaction should be broadcast or displayed to user.
|
/// Determine if the transaction should be broadcast or displayed to user.
|
||||||
fn handle_broadcast<N: Network>(endpoint: &String, transaction: Transaction<N>, operation: &String) -> Result<()> {
|
fn handle_broadcast<N: Network>(endpoint: &String, transaction: Transaction<N>, operation: &String) -> Result<()> {
|
||||||
println!("Broadcasting transaction to {}...", endpoint.clone());
|
println!("Broadcasting transaction to {}...", endpoint.clone());
|
||||||
|
@ -72,6 +72,7 @@ impl Command for Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
|
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
|
||||||
|
let recursive = context.recursive;
|
||||||
let output = match self.command {
|
let output = match self.command {
|
||||||
QueryCommands::Block { command } => command.apply(context, ())?,
|
QueryCommands::Block { command } => command.apply(context, ())?,
|
||||||
QueryCommands::Transaction { command } => command.apply(context, ())?,
|
QueryCommands::Transaction { command } => command.apply(context, ())?,
|
||||||
@ -103,10 +104,12 @@ impl Command for Query {
|
|||||||
.call()
|
.call()
|
||||||
.map_err(|err| UtilError::failed_to_retrieve_from_endpoint(err, Default::default()))?;
|
.map_err(|err| UtilError::failed_to_retrieve_from_endpoint(err, Default::default()))?;
|
||||||
if response.status() == 200 {
|
if response.status() == 200 {
|
||||||
tracing::info!("✅ Successfully retrieved data from '{url}'.\n");
|
|
||||||
// Unescape the newlines.
|
// Unescape the newlines.
|
||||||
let result = response.into_string().unwrap().replace("\\n", "\n").replace('\"', "");
|
let result = response.into_string().unwrap().replace("\\n", "\n").replace('\"', "");
|
||||||
println!("{}\n", result);
|
if !recursive {
|
||||||
|
tracing::info!("✅ Successfully retrieved data from '{url}'.\n");
|
||||||
|
println!("{}\n", result);
|
||||||
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
} else {
|
} else {
|
||||||
Err(UtilError::network_error(url, response.status(), Default::default()).into())
|
Err(UtilError::network_error(url, response.status(), Default::default()).into())
|
||||||
|
@ -39,11 +39,13 @@ pub struct Context {
|
|||||||
pub path: Option<PathBuf>,
|
pub path: Option<PathBuf>,
|
||||||
/// Path to use for the Aleo registry, None when default
|
/// Path to use for the Aleo registry, None when default
|
||||||
pub home: Option<PathBuf>,
|
pub home: Option<PathBuf>,
|
||||||
|
/// Recursive flag.
|
||||||
|
pub recursive: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new(path: Option<PathBuf>, home: Option<PathBuf>) -> Result<Context> {
|
pub fn new(path: Option<PathBuf>, home: Option<PathBuf>, recursive: bool) -> Result<Context> {
|
||||||
Ok(Context { path, home })
|
Ok(Context { path, home, recursive })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path of the parent directory to the Leo package.
|
/// Returns the path of the parent directory to the Leo package.
|
||||||
|
Loading…
Reference in New Issue
Block a user