From b8c589da2070ab8a42cca9a2c7751810c2362cc8 Mon Sep 17 00:00:00 2001 From: Dennis Kuhnert Date: Tue, 20 Mar 2018 21:44:22 +0100 Subject: [PATCH 1/3] Add Jenkinsfile; Fix Warnings --- .gitignore | 1 + Jenkinsfile | 38 ++++++++++++++++++++++ README.md | 7 ++--- build.rs | 2 +- lib/wraplibsnark.cpp | 6 ++-- src/semantics.rs | 75 ++++++++++++++++++++++---------------------- 6 files changed, 82 insertions(+), 47 deletions(-) create mode 100644 Jenkinsfile diff --git a/.gitignore b/.gitignore index 7acc80e6..013db82c 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ witness # Cargo.lock .DS_Store +.idea diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..ed877f8c --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,38 @@ +#!/usr/bin/env groovy + +pipeline { + agent any + stages { + stage('Build & Test') { + steps { + withDockerContainer('kyroy/zokrates-test') { + sh 'RUSTFLAGS="-D warnings" cargo build' + sh 'RUSTFLAGS="-D warnings" cargo test' + } + } + } + + stage('Docker Build & Push') { + when { + environment name: 'BRANCH_NAME', value: 'master' + } + steps { + script { + def dockerImage = docker.build("kyroy/zokrates") + docker.withRegistry('https://registry.hub.docker.com', 'dockerhub-kyroy') { + dockerImage.push("latest") + } + } + } + } + } + post { + always { + // junit allowEmptyResults: true, testResults: '*test.xml' + deleteDir() + } + changed { + notifyStatusChange notificationRecipients: 'mail@kyroy.com', componentName: 'ZoKrates' + } + } +} diff --git a/README.md b/README.md index ec1373a7..dcc1c982 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Zokrates [![Join the chat at https://gitter.im/ZoKrates/Lobby](https://badges.gitter.im/ZoKrates/Lobby.svg)](https://gitter.im/ZoKrates/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://jenkins.kyroy.com/job/ZoKrates/job/master/badge/icon)](https://jenkins.kyroy.com/job/ZoKrates/job/master/) Zokrates is a toolbox for zkSNARKs on Ethereum. @@ -18,11 +19,7 @@ Zokrates bridges this gap. It helps you create offchain programs and link them t Using Docker is currently the recommended way to get started with Zokrates. ``` -git clone https://github.com/JacobEberhardt/ZoKrates -cd ZoKrates -docker build -t zokrates . -docker run -ti zokrates /bin/bash -cd ZoKrates/target/release +docker run -ti kyroy/zokrates /bin/bash ``` # Example diff --git a/build.rs b/build.rs index 3f1493e3..a714cb04 100644 --- a/build.rs +++ b/build.rs @@ -4,7 +4,7 @@ extern crate gcc; fn main() { #[cfg(not(feature = "nolibsnark"))] { - gcc::Config::new() + gcc::Build::new() .cpp(true) .debug(true) .include("/usr/local/include") diff --git a/lib/wraplibsnark.cpp b/lib/wraplibsnark.cpp index 1c28c9fd..c720ed03 100644 --- a/lib/wraplibsnark.cpp +++ b/lib/wraplibsnark.cpp @@ -246,9 +246,9 @@ bool _setup(const uint8_t* A, const uint8_t* B, const uint8_t* C, int constraint r1cs_constraint_system> cs; cs = createConstraintSystem(A, B ,C , constraints, variables, inputs); - assert(cs.num_variables() >= inputs); - assert(cs.num_inputs() == inputs); - assert(cs.num_constraints() == constraints); + assert(cs.num_variables() >= (unsigned)inputs); + assert(cs.num_inputs() == (unsigned)inputs); + assert(cs.num_constraints() == (unsigned)constraints); // create keypair r1cs_ppzksnark_keypair keypair = r1cs_ppzksnark_generator(cs); diff --git a/src/semantics.rs b/src/semantics.rs index 7ea70c72..7df69ddd 100644 --- a/src/semantics.rs +++ b/src/semantics.rs @@ -39,15 +39,6 @@ impl Checker { } } - #[test] - pub fn new_with_args(scope: HashSet, level: usize, functions: HashSet) -> Checker { - Checker { - scope: scope, - functions: functions, - level: level, - } - } - pub fn check_program(&mut self, prog: Prog) -> Result<(), String> { for func in prog.functions { self.check_function(&func)?; @@ -64,8 +55,8 @@ impl Checker { fn check_single_main(&mut self) -> Result<(), String> { match self.functions.clone().into_iter().filter(|fun| fun.id == "main").count() { 1 => Ok(()), - 0 => Err((format!("No main function found"))), - n => Err((format!("Only one main function allowed, found {}", n))) + 0 => Err(format!("No main function found")), + n => Err(format!("Only one main function allowed, found {}", n)) } } @@ -177,7 +168,7 @@ impl Checker { Ok(()) } Expression::IfElse(box condition, box consequence, box alternative) => { - self.check_condition(condition)?; + self.check_condition(condition)?; self.check_expression(consequence)?; self.check_expression(alternative)?; Ok(()) @@ -232,6 +223,14 @@ mod tests { use super::*; use field::FieldPrime; + pub fn new_with_args(scope: HashSet, level: usize, functions: HashSet) -> Checker { + Checker { + scope: scope, + functions: functions, + level: level, + } + } + #[test] fn undefined_variable_in_statement() { // a = b @@ -257,7 +256,7 @@ mod tests { id: String::from("b"), level: 0 }); - let mut checker = Checker::new_with_args(scope, 1, HashSet::new()); + let mut checker = new_with_args(scope, 1, HashSet::new()); assert_eq!(checker.check_statement(statement), Ok(())); } @@ -286,7 +285,7 @@ mod tests { bar_statements.push(Statement::Return( ExpressionList { expressions: vec![Expression::Identifier(String::from("a"))] - } + } )); let bar = Function { id: "bar".to_string(), @@ -441,7 +440,7 @@ mod tests { // c = foo() // should fail let bar_statements: Vec> = vec![Statement::MultipleDefinition( - vec!["c".to_string()], + vec!["c".to_string()], Expression::FunctionCall("foo".to_string(), vec![]) )]; @@ -461,8 +460,8 @@ mod tests { return_count: 1 }; - let mut checker = Checker::new_with_args(HashSet::new(), 0, functions); - assert_eq!(checker.check_function(bar), Err("foo returns 2 values but left side is of size 1".to_string())); + let mut checker = new_with_args(HashSet::new(), 0, functions); + assert_eq!(checker.check_function(&bar), Err("foo returns 2 values but left side is of size 1".to_string())); } #[test] @@ -493,8 +492,8 @@ mod tests { return_count: 1 }; - let mut checker = Checker::new_with_args(HashSet::new(), 0, functions); - assert_eq!(checker.check_function(bar), Err("foo returns 2 values but is called outside of a definition".to_string())); + let mut checker = new_with_args(HashSet::new(), 0, functions); + assert_eq!(checker.check_function(&bar), Err("foo returns 2 values but is called outside of a definition".to_string())); } #[test] @@ -503,7 +502,7 @@ mod tests { // c = foo() // should fail let bar_statements: Vec> = vec![Statement::MultipleDefinition( - vec!["c".to_string()], + vec!["c".to_string()], Expression::FunctionCall("foo".to_string(), vec![]) )]; @@ -514,8 +513,8 @@ mod tests { return_count: 1 }; - let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new()); - assert_eq!(checker.check_function(bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string())); + let mut checker = new_with_args(HashSet::new(), 0, HashSet::new()); + assert_eq!(checker.check_function(&bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string())); } #[test] @@ -524,7 +523,7 @@ mod tests { // 1 = foo() // should fail let bar_statements: Vec> = vec![Statement::Condition( - Expression::Number(FieldPrime::from(1)), + Expression::Number(FieldPrime::from(1)), Expression::FunctionCall("foo".to_string(), vec![]) )]; @@ -535,8 +534,8 @@ mod tests { return_count: 1 }; - let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new()); - assert_eq!(checker.check_function(bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string())); + let mut checker = new_with_args(HashSet::new(), 0, HashSet::new()); + assert_eq!(checker.check_function(&bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string())); } #[test] @@ -558,8 +557,8 @@ mod tests { return_count: 2 }; - let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new()); - assert_eq!(checker.check_function(bar), Err("a is undefined".to_string())); + let mut checker = new_with_args(HashSet::new(), 0, HashSet::new()); + assert_eq!(checker.check_function(&bar), Err("a is undefined".to_string())); } #[test] @@ -573,13 +572,13 @@ mod tests { // should pass let bar_statements: Vec> = vec![ Statement::MultipleDefinition( - vec!["a".to_string(), "b".to_string()], + vec!["a".to_string(), "b".to_string()], Expression::FunctionCall("foo".to_string(), vec![]) ), Statement::Return( ExpressionList { expressions: vec![ Expression::Add( - box Expression::Identifier("a".to_string()), + box Expression::Identifier("a".to_string()), box Expression::Identifier("b".to_string()) )] } @@ -602,7 +601,7 @@ mod tests { return_count: 1 }; - let mut checker = Checker::new_with_args(HashSet::new(), 0, functions); + let mut checker = new_with_args(HashSet::new(), 0, functions); assert_eq!(checker.check_function(&bar), Ok(())); } @@ -616,7 +615,7 @@ mod tests { // should fail let foo2_statements: Vec> = vec![ Statement::Return( - ExpressionList { + ExpressionList { expressions: vec![ Expression::Number(FieldPrime::from(1)) ] @@ -625,7 +624,7 @@ mod tests { ]; let foo2_arguments = vec![ - Parameter { id: 'c'.to_string(), private: true }, + Parameter { id: 'c'.to_string(), private: true }, Parameter { id: 'd'.to_string(), private: true } ]; @@ -645,8 +644,8 @@ mod tests { return_count: 1 }; - let mut checker = Checker::new_with_args(HashSet::new(), 0, functions); - assert_eq!(checker.check_function(&foo2), Err(("Duplicate definition for function foo with 2 arguments".to_string()))); + let mut checker = new_with_args(HashSet::new(), 0, functions); + assert_eq!(checker.check_function(&foo2), Err("Duplicate definition for function foo with 2 arguments".to_string())); } #[test] @@ -659,7 +658,7 @@ mod tests { // should fail let main1_statements: Vec> = vec![ Statement::Return( - ExpressionList { + ExpressionList { expressions: vec![ Expression::Number(FieldPrime::from(1)) ] @@ -671,7 +670,7 @@ mod tests { let main2_statements: Vec> = vec![ Statement::Return( - ExpressionList { + ExpressionList { expressions: vec![ Expression::Number(FieldPrime::from(1)) ] @@ -700,6 +699,6 @@ mod tests { }; let mut checker = Checker::new(); - assert_eq!(checker.check_program(prog), Err(("Only one main function allowed, found 2".to_string()))); + assert_eq!(checker.check_program(prog), Err("Only one main function allowed, found 2".to_string())); } -} \ No newline at end of file +} From a432b059c6f62438d1af3ee49b60461a0f0d97aa Mon Sep 17 00:00:00 2001 From: Dennis Kuhnert Date: Wed, 21 Mar 2018 08:10:50 +0100 Subject: [PATCH 2/3] Split build & test, add integration tests --- Jenkinsfile | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ed877f8c..e4527e51 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -3,18 +3,36 @@ pipeline { agent any stages { - stage('Build & Test') { + stage('Build') { steps { withDockerContainer('kyroy/zokrates-test') { sh 'RUSTFLAGS="-D warnings" cargo build' + } + } + } + + stage('Test') { + steps { + withDockerContainer('kyroy/zokrates-test') { sh 'RUSTFLAGS="-D warnings" cargo test' } } } + stage('Integration Test') { + when { + expression { env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'develop' } + } + steps { + withDockerContainer('kyroy/zokrates-test') { + sh 'RUSTFLAGS="-D warnings" cargo test -- --ignored' + } + } + } + stage('Docker Build & Push') { when { - environment name: 'BRANCH_NAME', value: 'master' + expression { env.BRANCH_NAME == 'master' } } steps { script { From bc88fae5c7692c67bcc5c0178d85229e165a69fd Mon Sep 17 00:00:00 2001 From: Dennis Kuhnert Date: Thu, 22 Mar 2018 11:20:43 +0100 Subject: [PATCH 3/3] Add build yourself instructions; add master/develop badge --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dcc1c982..bb4ab7a6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Zokrates [![Join the chat at https://gitter.im/ZoKrates/Lobby](https://badges.gitter.im/ZoKrates/Lobby.svg)](https://gitter.im/ZoKrates/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://jenkins.kyroy.com/job/ZoKrates/job/master/badge/icon)](https://jenkins.kyroy.com/job/ZoKrates/job/master/) +![Jenkins](https://img.shields.io/jenkins/s/https/jenkins.kyroy.com/ZoKrates/job/master.svg?label=master) +![Jenkins](https://img.shields.io/jenkins/s/https/jenkins.kyroy.com/ZoKrates/job/develop.svg?label=develop) + Zokrates is a toolbox for zkSNARKs on Ethereum. @@ -18,9 +20,19 @@ Zokrates bridges this gap. It helps you create offchain programs and link them t Using Docker is currently the recommended way to get started with Zokrates. -``` +```bash docker run -ti kyroy/zokrates /bin/bash ``` +Or build yourself with the following commands. +```bash +git clone https://github.com/JacobEberhardt/ZoKrates +cd ZoKrates +docker build -t zokrates . +docker run -ti zokrates /bin/bash +cd ZoKrates/target/release +``` + + # Example To execute the program, perform the setup for the program, generate a proof