mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-27 12:17:35 +03:00
serialize program into bytes file
This commit is contained in:
parent
a85d831eb9
commit
504480b3d7
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -511,6 +511,7 @@ dependencies = [
|
||||
name = "leo-compiler"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"hex",
|
||||
"leo-ast",
|
||||
"leo-inputs",
|
||||
|
@ -14,6 +14,7 @@ snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0", default-fea
|
||||
snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0", default-features = false }
|
||||
snarkos-models = { path = "../../snarkOS/models", version = "0.8.0", default-features = false }
|
||||
|
||||
bincode = { version = "1.0" }
|
||||
hex = { version = "0.4.2" }
|
||||
log = { version = "0.4" }
|
||||
pest = { version = "2.0" }
|
||||
|
@ -40,15 +40,15 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
|
||||
let mut program = Self::new(package_name);
|
||||
program.set_path(main_file_path);
|
||||
pub fn new_from_path(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
|
||||
let mut compiler = Self::new(package_name);
|
||||
compiler.set_path(main_file_path);
|
||||
|
||||
// Generate the abstract syntax tree and assemble the program
|
||||
let program_string = program.load_program()?;
|
||||
program.parse_program(&program_string)?;
|
||||
let program_string = compiler.load_program()?;
|
||||
compiler.parse_program(&program_string)?;
|
||||
|
||||
Ok(program)
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
pub fn set_path(&mut self, main_file_path: PathBuf) {
|
||||
@ -116,6 +116,23 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, CompilerError> {
|
||||
Ok(bincode::serialize(&self.program)?)
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CompilerError> {
|
||||
let program: Program = bincode::deserialize(bytes)?;
|
||||
|
||||
Ok(Self {
|
||||
package_name: program.name.clone(),
|
||||
main_file_path: PathBuf::new(),
|
||||
program,
|
||||
program_inputs: Inputs::new(),
|
||||
output: None,
|
||||
_engine: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
|
@ -2,6 +2,7 @@ use crate::errors::{FunctionError, ImportError};
|
||||
use leo_ast::ParserError;
|
||||
use leo_inputs::InputParserError;
|
||||
|
||||
use bincode::Error as SerdeError;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -26,6 +27,9 @@ pub enum CompilerError {
|
||||
|
||||
#[error("{}", _0)]
|
||||
ParserError(#[from] ParserError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SerdeError(#[from] SerdeError),
|
||||
}
|
||||
|
||||
impl CompilerError {
|
||||
|
@ -10,6 +10,7 @@ use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||
use snarkos_algorithms::snark::KeypairAssembly;
|
||||
use snarkos_curves::{bls12_377::Bls12_377, edwards_bls12::Fq};
|
||||
|
||||
use crate::files::BytesFile;
|
||||
use clap::ArgMatches;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
@ -59,8 +60,32 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Check if the program bytes exist
|
||||
let existing_bytes = BytesFile::new(&package_name).exists_at(&path);
|
||||
|
||||
let program = if existing_bytes {
|
||||
// Load the program ast from stored bytes
|
||||
let bytes = BytesFile::new(&package_name).read_from(&path)?;
|
||||
|
||||
let mut program = Compiler::<Fq, EdwardsGroupType>::from_bytes(bytes.as_slice())?;
|
||||
|
||||
program.set_path(main_file_path.clone());
|
||||
|
||||
program
|
||||
} else {
|
||||
// Load the program at `main_file_path`
|
||||
let program =
|
||||
Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), main_file_path.clone())?;
|
||||
|
||||
// Store the program ast as bytes
|
||||
let bytes = program.to_bytes()?;
|
||||
|
||||
BytesFile::new(&package_name).write_to(&path, bytes)?;
|
||||
|
||||
program
|
||||
};
|
||||
|
||||
// Compute the current program checksum
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program_checksum = program.checksum()?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
|
@ -57,7 +57,7 @@ impl CLI for TestCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Compute the current program checksum
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), main_file_path.clone())?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
{
|
||||
|
@ -5,6 +5,9 @@ pub enum CLIError {
|
||||
#[error("{}", _0)]
|
||||
BuildError(BuildError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BytesFileError(BytesFileError),
|
||||
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
@ -54,6 +57,13 @@ pub enum CLIError {
|
||||
VerificationKeyFileError(VerificationKeyFileError),
|
||||
}
|
||||
|
||||
impl From<BytesFileError> for CLIError {
|
||||
fn from(error: BytesFileError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
CLIError::BytesFileError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BuildError> for CLIError {
|
||||
fn from(error: BuildError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
|
22
leo/errors/files/bytes.rs
Normal file
22
leo/errors/files/bytes.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BytesFileError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for BytesFileError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
BytesFileError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
pub mod bytes;
|
||||
pub use self::bytes::*;
|
||||
|
||||
pub mod checksum;
|
||||
pub use self::checksum::*;
|
||||
|
||||
|
60
leo/files/bytes.rs
Normal file
60
leo/files/bytes.rs
Normal file
@ -0,0 +1,60 @@
|
||||
//! The program bytes file.
|
||||
|
||||
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::BytesFileError};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
pub static BYTES_FILE_EXTENSION: &str = ".bytes";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct BytesFile {
|
||||
pub package_name: String,
|
||||
}
|
||||
|
||||
impl BytesFile {
|
||||
pub fn new(package_name: &str) -> Self {
|
||||
Self {
|
||||
package_name: package_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists_at(&self, path: &PathBuf) -> bool {
|
||||
let path = self.setup_file_path(path);
|
||||
path.exists()
|
||||
}
|
||||
|
||||
/// Reads the program bytes from the given file path if it exists.
|
||||
pub fn read_from(&self, path: &PathBuf) -> Result<Vec<u8>, BytesFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
Ok(fs::read(&path).map_err(|_| BytesFileError::FileReadError(path.clone()))?)
|
||||
}
|
||||
|
||||
/// Writes the given program bytes to a file.
|
||||
pub fn write_to(&self, path: &PathBuf, bytes: Vec<u8>) -> Result<(), BytesFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
let mut file = File::create(&path)?;
|
||||
file.write_all(bytes.as_slice())?;
|
||||
|
||||
log::info!("program bytes stored to {:?}", path);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_file_path(&self, path: &PathBuf) -> PathBuf {
|
||||
let mut path = path.to_owned();
|
||||
if path.is_dir() {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, BYTES_FILE_EXTENSION)));
|
||||
}
|
||||
path
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
pub mod bytes;
|
||||
pub use self::bytes::*;
|
||||
|
||||
pub mod checksum;
|
||||
pub use self::checksum::*;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user