Merge branch 'develop' of github.com:Zokrates/ZoKrates into u8-playground
This commit is contained in:
commit
19be8c463c
10 changed files with 13 additions and 1183 deletions
|
@ -42,9 +42,9 @@ jobs:
|
|||
- restore_cache:
|
||||
keys:
|
||||
- v4-cargo-cache-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||
# - run:
|
||||
# name: Check format
|
||||
# command: rustup component add rustfmt; cargo fmt --all -- --check
|
||||
- run:
|
||||
name: Check format
|
||||
command: rustup component add rustfmt; cargo fmt --all -- --check
|
||||
- run:
|
||||
name: Install libsnark prerequisites
|
||||
command: ./scripts/install_libsnark_prerequisites.sh
|
||||
|
|
908
Cargo.lock
generated
908
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,6 @@ members = [
|
|||
"zokrates_core",
|
||||
"zokrates_cli",
|
||||
"zokrates_fs_resolver",
|
||||
"zokrates_github_resolver",
|
||||
"zokrates_stdlib",
|
||||
"zokrates_embed",
|
||||
"zokrates_abi",
|
||||
|
|
|
@ -6,10 +6,9 @@ repository = "https://github.com/JacobEberhardt/ZoKrates.git"
|
|||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = ["github"]
|
||||
default = []
|
||||
libsnark = ["zokrates_core/libsnark"]
|
||||
wasm = ["zokrates_core/wasm"]
|
||||
github = ["zokrates_github_resolver"]
|
||||
|
||||
[dependencies]
|
||||
clap = "2.26.2"
|
||||
|
@ -19,7 +18,6 @@ zokrates_field = { version = "0.3", path = "../zokrates_field" }
|
|||
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
|
||||
zokrates_core = { version = "0.4", path = "../zokrates_core" }
|
||||
zokrates_fs_resolver = { version = "0.4", path = "../zokrates_fs_resolver"}
|
||||
zokrates_github_resolver = { version = "0.1", path = "../zokrates_github_resolver", optional = true}
|
||||
serde_json = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -7,19 +7,17 @@
|
|||
use bincode::{deserialize_from, serialize_into, Infinite};
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
use serde_json::Value;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufReader, BufWriter, Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::string::String;
|
||||
use std::{env, io};
|
||||
use zokrates_abi::Encode;
|
||||
use zokrates_core::compile::compile;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_field::field::{Field, FieldPrime};
|
||||
use zokrates_fs_resolver::resolve as fs_resolve;
|
||||
#[cfg(feature = "github")]
|
||||
use zokrates_github_resolver::{is_github_import, resolve as github_resolve};
|
||||
|
||||
fn main() {
|
||||
cli().unwrap_or_else(|e| {
|
||||
|
@ -28,19 +26,6 @@ fn main() {
|
|||
})
|
||||
}
|
||||
|
||||
fn resolve<'a>(
|
||||
location: Option<String>,
|
||||
source: &'a str,
|
||||
) -> Result<(BufReader<File>, String, &'a str), io::Error> {
|
||||
#[cfg(feature = "github")]
|
||||
{
|
||||
if is_github_import(source) {
|
||||
return github_resolve(location, source);
|
||||
};
|
||||
}
|
||||
fs_resolve(location, source)
|
||||
}
|
||||
|
||||
fn cli() -> Result<(), String> {
|
||||
const FLATTENED_CODE_DEFAULT_PATH: &str = "out";
|
||||
const VERIFICATION_KEY_DEFAULT_PATH: &str = "verification.key";
|
||||
|
@ -287,7 +272,7 @@ fn cli() -> Result<(), String> {
|
|||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_flattened: ir::Prog<FieldPrime> =
|
||||
compile(&mut reader, Some(location), Some(resolve))
|
||||
compile(&mut reader, Some(location), Some(fs_resolve))
|
||||
.map_err(|e| format!("Compilation failed:\n\n {}", e))?;
|
||||
|
||||
// number of constraints the flattened program will translate to.
|
||||
|
@ -604,7 +589,7 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
let _: ir::Prog<FieldPrime> =
|
||||
compile(&mut reader, Some(location), Some(resolve)).unwrap();
|
||||
compile(&mut reader, Some(location), Some(fs_resolve)).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -631,7 +616,7 @@ mod tests {
|
|||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_flattened: ir::Prog<FieldPrime> =
|
||||
compile(&mut reader, Some(location), Some(resolve)).unwrap();
|
||||
compile(&mut reader, Some(location), Some(fs_resolve)).unwrap();
|
||||
|
||||
let _ = program_flattened
|
||||
.execute(&vec![FieldPrime::from(0)])
|
||||
|
@ -663,7 +648,7 @@ mod tests {
|
|||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_flattened: ir::Prog<FieldPrime> =
|
||||
compile(&mut reader, Some(location), Some(resolve)).unwrap();
|
||||
compile(&mut reader, Some(location), Some(fs_resolve)).unwrap();
|
||||
|
||||
let _ = program_flattened
|
||||
.execute(&vec![FieldPrime::from(0)])
|
||||
|
|
|
@ -1446,7 +1446,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
let ebytes_be = e.to_be_bytes();
|
||||
// convert the bytes to bits, remove leading zeroes (we only need powers up to the highest non-zero bit)
|
||||
let ebits_be: Vec<_> = ebytes_be
|
||||
.into_iter()
|
||||
.iter()
|
||||
.flat_map(|byte| (0..8).rev().map(move |i| byte & (1 << i) != 0)) // byte to bit, big endian
|
||||
.skip_while(|b| !b) // skip trailing false bits
|
||||
.collect();
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
[package]
|
||||
name = "zokrates_github_resolver"
|
||||
version = "0.1.1"
|
||||
authors = ["Evgenii P. <eupn@protonmail.com>", "schaeff <thibaut@schaeff.fr>"]
|
||||
repository = "https://github.com/eupn/ZoKrates.git"
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
reqwest = "0.9"
|
||||
tempfile = "3"
|
||||
|
||||
[dev-dependencies]
|
||||
mockito = "0.17"
|
||||
|
||||
[lib]
|
|
@ -1,224 +0,0 @@
|
|||
//! # GitHub import resolver
|
||||
//!
|
||||
//! GitHub import resolver allows to import files located in github.com repos.
|
||||
//!
|
||||
//! To import file from github, use following syntax:
|
||||
//! ```zokrates
|
||||
//! import "github:user/repo/branch/path/to/file"
|
||||
//! ```
|
||||
//!
|
||||
//! For example:
|
||||
//! ```zokrates
|
||||
//! import "github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/merkleTree/sha256PathProof3" as merkleTreeProof
|
||||
//! ```
|
||||
//!
|
||||
//! Example above imports file `zokrates_cli/examples/merkleTree/sha256PathProof3.zok` located at ZoKrates
|
||||
//! repository's `master` branch by downloading from URL:
|
||||
//! https://raw.githubusercontent.com/Zokrates/ZoKrates/master/zokrates_cli/examples/merkleTree/sha256PathProof3.zok
|
||||
//!
|
||||
|
||||
use reqwest;
|
||||
use std::fs::File;
|
||||
use std::io::{self, copy, BufReader};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
#[cfg(test)]
|
||||
use mockito::{self, Mock};
|
||||
|
||||
/// Prefix for github import source to be distinguished.
|
||||
const GITHUB_IMPORT_PREFIX: &str = "github.com/";
|
||||
|
||||
/// GitHub download URL base
|
||||
#[cfg(not(test))]
|
||||
const GITHUB_URL_BASE: &str = "https://raw.githubusercontent.com";
|
||||
|
||||
/// Resolves import from the Github.
|
||||
/// This importer needs to be provided with location since relative paths could be used inside the
|
||||
/// files that are imported from github.
|
||||
pub fn resolve<'a>(
|
||||
location: Option<String>,
|
||||
path: &'a str,
|
||||
) -> Result<(BufReader<File>, String, &'a str), io::Error> {
|
||||
if let Some(location) = location {
|
||||
let path = Path::new(path);
|
||||
let (root, repo, branch, file_path) = parse_input_path(&path)?;
|
||||
|
||||
#[cfg(not(test))]
|
||||
let url = GITHUB_URL_BASE;
|
||||
#[cfg(test)]
|
||||
let url = mockito::server_url();
|
||||
|
||||
let pb = download_from_github(&url, &root, &repo, &branch, &file_path)?;
|
||||
let file = File::open(&pb)?;
|
||||
let br = BufReader::new(file);
|
||||
|
||||
let alias = path.file_stem().unwrap().to_str().unwrap();
|
||||
|
||||
Ok((br, location.to_owned(), &alias))
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "No location provided"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that import source is using github import location.
|
||||
pub fn is_github_import(source: &str) -> bool {
|
||||
source.starts_with(GITHUB_IMPORT_PREFIX)
|
||||
}
|
||||
|
||||
/// Parses github import syntax: "github.com/<root>/<repo>/<branch>/<path/to/file>"
|
||||
/// Where:
|
||||
/// - <root> is the user or organization name
|
||||
/// - <repo> is the repository name
|
||||
/// - <branch> is the branch/snapshot name, e.g. `master`
|
||||
/// - <path/to/file> is the absolute path to file in the specified branch of the repository
|
||||
fn parse_input_path<'a>(path: &'a Path) -> Result<(&'a str, &'a str, &'a str, &'a str), io::Error> {
|
||||
//let path_owned = path.replacen(GITHUB_IMPORT_PREFIX, "", 1);
|
||||
if path.to_str().unwrap().contains("..") {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Invalid github import syntax. It must not contain '..'",
|
||||
));
|
||||
}
|
||||
|
||||
let mut components = path.components();
|
||||
|
||||
// Check that root, repo, branch & path are specified
|
||||
if components.clone().count() < 5 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!(
|
||||
"Invalid github import syntax. Should be: {}<root>/<repo>/<branch>/<path>",
|
||||
GITHUB_IMPORT_PREFIX
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
let _ = components.next().unwrap().as_os_str().to_str().unwrap();
|
||||
let root = components.next().unwrap().as_os_str().to_str().unwrap();
|
||||
let repo = components.next().unwrap().as_os_str().to_str().unwrap();
|
||||
let branch = components.next().unwrap().as_os_str().to_str().unwrap();
|
||||
let path = components.as_path().to_str().unwrap(); // Collect the rest of the import path into single string
|
||||
|
||||
Ok((root, repo, branch, path))
|
||||
}
|
||||
|
||||
/// Downloads the file from github by specific root (user/org), repository, branch and path.
|
||||
fn download_from_github(
|
||||
github: &str,
|
||||
root: &str,
|
||||
repo: &str,
|
||||
branch: &str,
|
||||
path: &str,
|
||||
) -> Result<PathBuf, io::Error> {
|
||||
let url = format!(
|
||||
"{github}/{root}/{repo}/{branch}/{path}{extension}",
|
||||
github = github,
|
||||
root = root,
|
||||
repo = repo,
|
||||
branch = branch,
|
||||
path = path,
|
||||
extension = ".zok"
|
||||
);
|
||||
|
||||
download_url(&url)
|
||||
}
|
||||
|
||||
fn download_url(url: &str) -> Result<PathBuf, io::Error> {
|
||||
let mut response = reqwest::get(url).map_err(|e| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Unable to access github: {}", e.to_string()),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Unable to access github: {}", response.status()),
|
||||
));
|
||||
}
|
||||
|
||||
let (mut dest, pb) = NamedTempFile::new()?.keep()?;
|
||||
copy(&mut response, &mut dest)?;
|
||||
|
||||
Ok(pb)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Initializes github.com mocks for `import_github` example to run from `examples` tests.
|
||||
/// Note that returned mock objects should be alive prior to github requests.
|
||||
fn init_github_mock() -> (Mock, Mock) {
|
||||
let m1 = mockito::mock(
|
||||
"GET",
|
||||
"/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/foo.zok",
|
||||
)
|
||||
.with_status(200)
|
||||
.with_body_from_file("./static/foo.zok")
|
||||
.create();
|
||||
|
||||
let m2 = mockito::mock(
|
||||
"GET",
|
||||
"/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/notfound.zok",
|
||||
)
|
||||
.with_status(404)
|
||||
.create();
|
||||
|
||||
(m1, m2)
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn import_simple() {
|
||||
let res = parse_input_path(Path::new(
|
||||
"github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/import",
|
||||
))
|
||||
.unwrap();
|
||||
let (root, repo, branch, path) = res;
|
||||
|
||||
assert_eq!(root, "Zokrates");
|
||||
assert_eq!(repo, "ZoKrates");
|
||||
assert_eq!(branch, "master");
|
||||
assert_eq!(path, "zokrates_cli/examples/imports/import");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
pub fn import_no_branch() {
|
||||
// Correct syntax should be: github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/import
|
||||
// but branch name is not specified
|
||||
parse_input_path(Path::new("github.com/Zokrates/ZoKrates/test")).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
pub fn import_relative_paths() {
|
||||
// Relative paths should not be allowed
|
||||
parse_input_path(Path::new(
|
||||
"github.com/Zokrates/ZoKrates/master/examples/../imports",
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn resolve_ok() {
|
||||
let (_m0, _m1) = init_github_mock();
|
||||
let res = resolve(
|
||||
Some("".to_string()),
|
||||
&"github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/foo",
|
||||
);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn resolve_err() {
|
||||
let (_m0, _m1) = init_github_mock();
|
||||
assert!(resolve(
|
||||
Some("".to_string()),
|
||||
&"github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/notfound"
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
}
|
|
@ -122,8 +122,6 @@ WHITESPACE = _{ " " | "\t" | "\\" ~ NEWLINE}
|
|||
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
||||
|
||||
// TODO: Order by alphabet
|
||||
keyword = @{"for" | "endfor" | "as" | "in" | "return" | "byte" | "field" | "bool" | "if" | "do" | "else" | "export" | "false" |
|
||||
"def" | "for" | "import" | "uint" |
|
||||
"in" | "public" | "private" | "return" |
|
||||
"struct" | "true"
|
||||
}
|
||||
keyword = @{"as"|"bool"|"byte"|"def"|"do"|"else"|"endfor"|"export"|"false"|"field"|"for"|"if"|"import"|
|
||||
"in"|"private"|"public"|"return"|"struct"|"true"|"uint"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue