1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

Merge pull request #932 from Zokrates/refactor-abi-parsing

Refactor abi parsing
This commit is contained in:
Thibaut Schaeffer 2021-07-10 12:56:46 +02:00 committed by GitHub
commit 5e6c8f09bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 318 additions and 337 deletions

View file

@ -0,0 +1 @@
Allow field inputs in hexadecimal form in case the abi specification is used

View file

@ -2,7 +2,7 @@
pub enum Inputs<T> {
Raw(Vec<T>),
Abi(CheckedValues<T>),
Abi(Values<T>),
}
impl<T: From<usize>> Encode<T> for Inputs<T> {
@ -15,7 +15,6 @@ impl<T: From<usize>> Encode<T> for Inputs<T> {
}
use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::fmt;
use zokrates_core::typed_absy::types::{ConcreteType, UBitwidth};
@ -41,7 +40,7 @@ impl fmt::Display for Error {
}
#[derive(PartialEq, Debug)]
enum Value<T> {
pub enum Value<T> {
U8(u8),
U16(u16),
U32(u32),
@ -53,19 +52,7 @@ enum Value<T> {
}
#[derive(PartialEq, Debug)]
enum CheckedValue<T> {
U8(u8),
U16(u16),
U32(u32),
U64(u64),
Field(T),
Boolean(bool),
Array(Vec<CheckedValue<T>>),
Struct(Vec<(String, CheckedValue<T>)>),
}
#[derive(PartialEq, Debug)]
pub struct CheckedValues<T>(Vec<CheckedValue<T>>);
pub struct Values<T>(Vec<Value<T>>);
impl<T: Field> fmt::Display for Value<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -96,59 +83,6 @@ impl<T: Field> fmt::Display for Value<T> {
}
}
impl<T: Field> Value<T> {
fn check(self, ty: ConcreteType) -> Result<CheckedValue<T>, String> {
match (self, ty) {
(Value::Field(f), ConcreteType::FieldElement) => Ok(CheckedValue::Field(f)),
(Value::U8(f), ConcreteType::Uint(UBitwidth::B8)) => Ok(CheckedValue::U8(f)),
(Value::U16(f), ConcreteType::Uint(UBitwidth::B16)) => Ok(CheckedValue::U16(f)),
(Value::U32(f), ConcreteType::Uint(UBitwidth::B32)) => Ok(CheckedValue::U32(f)),
(Value::U64(f), ConcreteType::Uint(UBitwidth::B64)) => Ok(CheckedValue::U64(f)),
(Value::Boolean(b), ConcreteType::Boolean) => Ok(CheckedValue::Boolean(b)),
(Value::Array(a), ConcreteType::Array(array_type)) => {
let size = array_type.size;
if a.len() != size as usize {
Err(format!(
"Expected array of size {}, found array of size {}",
size,
a.len()
))
} else {
let a = a
.into_iter()
.map(|val| val.check(*array_type.ty.clone()))
.collect::<Result<Vec<_>, _>>()?;
Ok(CheckedValue::Array(a))
}
}
(Value::Struct(mut s), ConcreteType::Struct(struc)) => {
if s.len() != struc.members_count() {
Err(format!(
"Expected {} member(s), found {}",
struc.members_count(),
s.len()
))
} else {
let s = struc
.members
.into_iter()
.map(|member| {
s.remove(&member.id)
.ok_or_else(|| format!("Member with id `{}` not found", member.id))
.map(|v| v.check(*member.ty.clone()).map(|v| (member.id, v)))
})
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.collect::<Result<_, _>>()?;
Ok(CheckedValue::Struct(s))
}
}
(v, t) => Err(format!("Value `{}` doesn't match expected type `{}`", v, t)),
}
}
}
pub trait Encode<T> {
fn encode(self) -> Vec<T>;
}
@ -159,31 +93,31 @@ pub trait Decode<T> {
fn decode(raw: Vec<T>, expected: Self::Expected) -> Self;
}
impl<T: From<usize>> Encode<T> for CheckedValue<T> {
impl<T: From<usize>> Encode<T> for Value<T> {
fn encode(self) -> Vec<T> {
match self {
CheckedValue::Field(t) => vec![t],
CheckedValue::U8(t) => vec![T::from(t as usize)],
CheckedValue::U16(t) => vec![T::from(t as usize)],
CheckedValue::U32(t) => vec![T::from(t as usize)],
CheckedValue::U64(t) => vec![T::from(t as usize)],
CheckedValue::Boolean(b) => vec![if b { 1.into() } else { 0.into() }],
CheckedValue::Array(a) => a.into_iter().flat_map(|v| v.encode()).collect(),
CheckedValue::Struct(s) => s.into_iter().flat_map(|(_, v)| v.encode()).collect(),
Value::Field(t) => vec![t],
Value::U8(t) => vec![T::from(t as usize)],
Value::U16(t) => vec![T::from(t as usize)],
Value::U32(t) => vec![T::from(t as usize)],
Value::U64(t) => vec![T::from(t as usize)],
Value::Boolean(b) => vec![if b { 1.into() } else { 0.into() }],
Value::Array(a) => a.into_iter().flat_map(|v| v.encode()).collect(),
Value::Struct(s) => s.into_iter().flat_map(|(_, v)| v.encode()).collect(),
}
}
}
impl<T: Field> Decode<T> for CheckedValues<T> {
impl<T: Field> Decode<T> for Values<T> {
type Expected = Vec<ConcreteType>;
fn decode(raw: Vec<T>, expected: Self::Expected) -> Self {
CheckedValues(
Values(
expected
.into_iter()
.scan(0, |state, e| {
let new_state = *state + e.get_primitive_count();
let res = CheckedValue::decode(raw[*state..new_state].to_vec(), e);
let res = Value::decode(raw[*state..new_state].to_vec(), e);
*state = new_state;
Some(res)
})
@ -192,7 +126,7 @@ impl<T: Field> Decode<T> for CheckedValues<T> {
}
}
impl<T: Field> Decode<T> for CheckedValue<T> {
impl<T: Field> Decode<T> for Value<T> {
type Expected = ConcreteType;
fn decode(raw: Vec<T>, expected: Self::Expected) -> Self {
@ -200,22 +134,22 @@ impl<T: Field> Decode<T> for CheckedValue<T> {
match expected {
ConcreteType::Int => unreachable!(),
ConcreteType::FieldElement => CheckedValue::Field(raw.pop().unwrap()),
ConcreteType::FieldElement => Value::Field(raw.pop().unwrap()),
ConcreteType::Uint(UBitwidth::B8) => {
CheckedValue::U8(raw.pop().unwrap().to_dec_string().parse().unwrap())
Value::U8(raw.pop().unwrap().to_dec_string().parse().unwrap())
}
ConcreteType::Uint(UBitwidth::B16) => {
CheckedValue::U16(raw.pop().unwrap().to_dec_string().parse().unwrap())
Value::U16(raw.pop().unwrap().to_dec_string().parse().unwrap())
}
ConcreteType::Uint(UBitwidth::B32) => {
CheckedValue::U32(raw.pop().unwrap().to_dec_string().parse().unwrap())
Value::U32(raw.pop().unwrap().to_dec_string().parse().unwrap())
}
ConcreteType::Uint(UBitwidth::B64) => {
CheckedValue::U64(raw.pop().unwrap().to_dec_string().parse().unwrap())
Value::U64(raw.pop().unwrap().to_dec_string().parse().unwrap())
}
ConcreteType::Boolean => {
let v = raw.pop().unwrap();
CheckedValue::Boolean(if v == 0.into() {
Value::Boolean(if v == 0.into() {
false
} else if v == 1.into() {
true
@ -223,17 +157,17 @@ impl<T: Field> Decode<T> for CheckedValue<T> {
unreachable!()
})
}
ConcreteType::Array(array_type) => CheckedValue::Array(
ConcreteType::Array(array_type) => Value::Array(
raw.chunks(array_type.ty.get_primitive_count())
.map(|c| CheckedValue::decode(c.to_vec(), *array_type.ty.clone()))
.map(|c| Value::decode(c.to_vec(), *array_type.ty.clone()))
.collect(),
),
ConcreteType::Struct(members) => CheckedValue::Struct(
ConcreteType::Struct(members) => Value::Struct(
members
.into_iter()
.scan(0, |state, member| {
let new_state = *state + member.ty.get_primitive_count();
let res = CheckedValue::decode(raw[*state..new_state].to_vec(), *member.ty);
let res = Value::decode(raw[*state..new_state].to_vec(), *member.ty);
*state = new_state;
Some((member.id, res))
})
@ -243,86 +177,25 @@ impl<T: Field> Decode<T> for CheckedValue<T> {
}
}
impl<T: From<usize>> Encode<T> for CheckedValues<T> {
impl<T: From<usize>> Encode<T> for Values<T> {
fn encode(self) -> Vec<T> {
self.0.into_iter().flat_map(|v| v.encode()).collect()
}
}
#[derive(PartialEq, Debug)]
struct Values<T>(Vec<Value<T>>);
impl<T: Field> TryFrom<serde_json::Value> for Values<T> {
type Error = String;
fn try_from(v: serde_json::Value) -> Result<Values<T>, Self::Error> {
match v {
serde_json::Value::Array(a) => a
.into_iter()
.map(Value::try_from)
.collect::<Result<_, _>>()
.map(Values),
v => Err(format!("Expected an array of values, found `{}`", v)),
}
}
}
impl<T: Field> TryFrom<serde_json::Value> for Value<T> {
type Error = String;
fn try_from(v: serde_json::Value) -> Result<Value<T>, Self::Error> {
match v {
serde_json::Value::String(s) => {
T::try_from_dec_str(&s)
.map(Value::Field)
.or_else(|_| match s.len() {
4 => u8::from_str_radix(&s[2..], 16)
.map(Value::U8)
.map_err(|_| format!("Expected u8 value, found {}", s)),
6 => u16::from_str_radix(&s[2..], 16)
.map(Value::U16)
.map_err(|_| format!("Expected u16 value, found {}", s)),
10 => u32::from_str_radix(&s[2..], 16)
.map(Value::U32)
.map_err(|_| format!("Expected u32 value, found {}", s)),
18 => u64::from_str_radix(&s[2..], 16)
.map(Value::U64)
.map_err(|_| format!("Expected u64 value, found {}", s)),
_ => Err(format!("Cannot parse {} to any type", s)),
})
}
serde_json::Value::Bool(b) => Ok(Value::Boolean(b)),
serde_json::Value::Number(n) => Err(format!(
"Value `{}` isn't allowed, did you mean `\"{}\"`?",
n, n
)),
serde_json::Value::Array(a) => a
.into_iter()
.map(Value::try_from)
.collect::<Result<_, _>>()
.map(Value::Array),
serde_json::Value::Object(o) => o
.into_iter()
.map(|(k, v)| Value::try_from(v).map(|v| (k, v)))
.collect::<Result<Map<_, _>, _>>()
.map(Value::Struct),
v => Err(format!("Value `{}` isn't allowed", v)),
}
}
}
impl<T: Field> CheckedValue<T> {
impl<T: Field> Value<T> {
pub fn into_serde_json(self) -> serde_json::Value {
match self {
CheckedValue::Field(f) => serde_json::Value::String(f.to_dec_string()),
CheckedValue::U8(u) => serde_json::Value::String(format!("{:#04x}", u)),
CheckedValue::U16(u) => serde_json::Value::String(format!("{:#06x}", u)),
CheckedValue::U32(u) => serde_json::Value::String(format!("{:#010x}", u)),
CheckedValue::U64(u) => serde_json::Value::String(format!("{:#018x}", u)),
CheckedValue::Boolean(b) => serde_json::Value::Bool(b),
CheckedValue::Array(a) => {
Value::Field(f) => serde_json::Value::String(f.to_dec_string()),
Value::U8(u) => serde_json::Value::String(format!("{:#04x}", u)),
Value::U16(u) => serde_json::Value::String(format!("{:#06x}", u)),
Value::U32(u) => serde_json::Value::String(format!("{:#010x}", u)),
Value::U64(u) => serde_json::Value::String(format!("{:#018x}", u)),
Value::Boolean(b) => serde_json::Value::Bool(b),
Value::Array(a) => {
serde_json::Value::Array(a.into_iter().map(|e| e.into_serde_json()).collect())
}
CheckedValue::Struct(s) => serde_json::Value::Object(
Value::Struct(s) => serde_json::Value::Object(
s.into_iter()
.map(|(k, v)| (k, v.into_serde_json()))
.collect(),
@ -331,50 +204,145 @@ impl<T: Field> CheckedValue<T> {
}
}
impl<T: Field> CheckedValues<T> {
impl<T: Field> Values<T> {
pub fn into_serde_json(self) -> serde_json::Value {
serde_json::Value::Array(self.0.into_iter().map(|e| e.into_serde_json()).collect())
}
}
fn parse<T: Field>(s: &str) -> Result<Values<T>, Error> {
let json_values: serde_json::Value =
serde_json::from_str(s).map_err(|e| Error::Json(e.to_string()))?;
Values::try_from(json_values).map_err(Error::Conversion)
fn parse_value<T: Field>(
value: serde_json::Value,
expected_type: ConcreteType,
) -> Result<Value<T>, Error> {
match (&expected_type, value) {
(ConcreteType::FieldElement, serde_json::Value::String(s)) => {
T::try_from_dec_str(s.as_str())
.or_else(|_| T::try_from_str(s.as_str().trim_start_matches("0x"), 16))
.map(Value::Field)
.map_err(|_| Error::Type(format!("Could not parse `{}` to field type", s)))
}
(ConcreteType::Uint(UBitwidth::B8), serde_json::Value::String(s)) => s
.as_str()
.parse::<u8>()
.or_else(|_| u8::from_str_radix(s.as_str().trim_start_matches("0x"), 16))
.map(Value::U8)
.map_err(|_| Error::Type(format!("Could not parse `{}` to u8 type", s))),
(ConcreteType::Uint(UBitwidth::B16), serde_json::Value::String(s)) => s
.as_str()
.parse::<u16>()
.or_else(|_| u16::from_str_radix(s.as_str().trim_start_matches("0x"), 16))
.map(Value::U16)
.map_err(|_| Error::Type(format!("Could not parse `{}` to u16 type", s))),
(ConcreteType::Uint(UBitwidth::B32), serde_json::Value::String(s)) => s
.as_str()
.parse::<u32>()
.or_else(|_| u32::from_str_radix(s.as_str().trim_start_matches("0x"), 16))
.map(Value::U32)
.map_err(|_| Error::Type(format!("Could not parse `{}` to u32 type", s))),
(ConcreteType::Uint(UBitwidth::B64), serde_json::Value::String(s)) => s
.as_str()
.parse::<u64>()
.or_else(|_| u64::from_str_radix(s.as_str().trim_start_matches("0x"), 16))
.map(Value::U64)
.map_err(|_| Error::Type(format!("Could not parse `{}` to u64 type", s))),
(ConcreteType::Boolean, serde_json::Value::Bool(b)) => Ok(Value::Boolean(b)),
(ConcreteType::Array(array_type), serde_json::Value::Array(a)) => {
let size = array_type.size;
if a.len() != size as usize {
Err(Error::Type(format!(
"Expected array of size {}, found array of size {}",
size,
a.len()
)))
} else {
a.into_iter()
.map(|v| parse_value(v, *array_type.ty.clone()))
.collect::<Result<_, _>>()
.map(Value::Array)
}
}
(ConcreteType::Struct(struct_type), serde_json::Value::Object(mut o)) => {
if o.len() != struct_type.members_count() {
Err(Error::Type(format!(
"Expected {} member(s), found {}",
struct_type.members_count(),
o.len()
)))
} else {
Ok(Value::Struct(
struct_type
.members
.iter()
.map(|m| {
o.remove(&m.id)
.ok_or_else(|| {
Error::Type(format!("Member with id `{}` not found", m.id))
})
.map(|v| parse_value(v, *m.ty.clone()).map(|v| (m.id.clone(), v)))
})
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.collect::<Result<_, _>>()?,
))
}
}
(_, serde_json::Value::Number(n)) => Err(Error::Conversion(format!(
"Value `{}` isn't allowed, did you mean `\"{}\"`?",
n, n
))),
(_, v) => Err(Error::Type(format!(
"Value `{}` doesn't match expected type `{}`",
v, expected_type
))),
}
}
pub fn parse_strict<T: Field>(
s: &str,
types: Vec<ConcreteType>,
) -> Result<CheckedValues<T>, Error> {
let parsed = parse(s)?;
if parsed.0.len() != types.len() {
return Err(Error::Type(format!(
"Expected {} inputs, found {}",
types.len(),
parsed.0.len()
)));
pub fn parse_strict<T: Field>(s: &str, types: Vec<ConcreteType>) -> Result<Values<T>, Error> {
let values: serde_json::Value =
serde_json::from_str(s).map_err(|e| Error::Json(e.to_string()))?;
match values {
serde_json::Value::Array(values) => {
if values.len() != types.len() {
return Err(Error::Type(format!(
"Expected {} inputs, found {}",
types.len(),
values.len()
)));
}
Ok(Values(
types
.into_iter()
.zip(values.into_iter())
.map(|(ty, v)| parse_value(v, ty))
.collect::<Result<_, _>>()?,
))
}
_ => Err(Error::Type(format!(
"Expected an array of values, found `{}`",
values
))),
}
let checked = parsed
.0
.into_iter()
.zip(types.into_iter())
.map(|(v, ty)| v.check(ty))
.collect::<Result<Vec<_>, _>>()
.map_err(Error::Type)?;
Ok(CheckedValues(checked))
}
#[cfg(test)]
mod tests {
use super::*;
use std::iter::FromIterator;
use zokrates_core::typed_absy::types::{
ConcreteStructMember, ConcreteStructType, ConcreteType,
};
use zokrates_field::Bn128Field;
#[test]
fn numbers() {
let s = "[1, 2]";
assert_eq!(
parse::<Bn128Field>(s).unwrap_err(),
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::FieldElement, ConcreteType::FieldElement]
)
.unwrap_err(),
Error::Conversion(String::from(
"Value `1` isn't allowed, did you mean `\"1\"`?"
))
@ -383,10 +351,49 @@ mod tests {
#[test]
fn fields() {
let s = r#"["1", "2"]"#;
let s = r#"["1", "0x42"]"#;
assert_eq!(
parse::<Bn128Field>(s).unwrap(),
Values(vec![Value::Field(1.into()), Value::Field(2.into())])
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::FieldElement, ConcreteType::FieldElement]
)
.unwrap(),
Values(vec![Value::Field(1.into()), Value::Field(66.into())])
);
}
#[test]
fn uints() {
let s = r#"["0x12", "0x1234", "0x12345678", "0x1234567812345678"]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![
ConcreteType::Uint(UBitwidth::B8),
ConcreteType::Uint(UBitwidth::B16),
ConcreteType::Uint(UBitwidth::B32),
ConcreteType::Uint(UBitwidth::B64)
]
)
.unwrap(),
Values(vec![
Value::U8(18u8),
Value::U16(4660u16),
Value::U32(305419896u32),
Value::U64(1311768465173141112u64)
])
);
let s = r#"["0x1234"]"#;
assert_eq!(
parse_strict::<Bn128Field>(s, vec![ConcreteType::Uint(UBitwidth::B32)]).unwrap(),
Values(vec![Value::U32(4660u32)])
);
let s = r#"["0x1234"]"#;
assert_eq!(
parse_strict::<Bn128Field>(s, vec![ConcreteType::Uint(UBitwidth::B8)]).unwrap_err(),
Error::Type("Could not parse `0x1234` to u8 type".into())
);
}
@ -394,7 +401,8 @@ mod tests {
fn bools() {
let s = "[true, false]";
assert_eq!(
parse::<Bn128Field>(s).unwrap(),
parse_strict::<Bn128Field>(s, vec![ConcreteType::Boolean, ConcreteType::Boolean])
.unwrap(),
Values(vec![Value::Boolean(true), Value::Boolean(false)])
);
}
@ -403,7 +411,11 @@ mod tests {
fn array() {
let s = "[[true, false]]";
assert_eq!(
parse::<Bn128Field>(s).unwrap(),
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::array((ConcreteType::Boolean, 2usize))]
)
.unwrap(),
Values(vec![Value::Array(vec![
Value::Boolean(true),
Value::Boolean(false)
@ -415,140 +427,111 @@ mod tests {
fn struc() {
let s = r#"[{"a": "42"}]"#;
assert_eq!(
parse::<Bn128Field>(s).unwrap(),
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap(),
Values(vec![Value::Struct(
vec![("a".to_string(), Value::Field(42.into()))]
.into_iter()
.collect()
)])
);
let s = r#"[{"b": "42"}]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap_err(),
Error::Type("Member with id `a` not found".into())
);
let s = r#"[{}]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap_err(),
Error::Type("Expected 1 member(s), found 0".into())
);
let s = r#"[{"a": false}]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap_err(),
Error::Type("Value `false` doesn't match expected type `field`".into())
);
}
mod strict {
use super::*;
use zokrates_core::typed_absy::types::{
ConcreteStructMember, ConcreteStructType, ConcreteType,
};
#[test]
fn into_serde() {
let values = Values::<Bn128Field>(vec![
Value::Field(1.into()),
Value::U8(2u8),
Value::U16(3u16),
Value::U32(4u32),
Value::U64(5u64),
Value::Boolean(true),
Value::Array(vec![Value::Field(1.into()), Value::Field(2.into())]),
Value::Struct(BTreeMap::from_iter(vec![
("a".to_string(), Value::Field(1.into())),
("b".to_string(), Value::Field(2.into())),
])),
]);
#[test]
fn fields() {
let s = r#"["1", "2"]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::FieldElement, ConcreteType::FieldElement]
)
.unwrap(),
CheckedValues(vec![
CheckedValue::Field(1.into()),
CheckedValue::Field(2.into())
])
);
}
let serde_value = values.into_serde_json();
#[test]
fn bools() {
let s = "[true, false]";
assert_eq!(
parse_strict::<Bn128Field>(s, vec![ConcreteType::Boolean, ConcreteType::Boolean])
.unwrap(),
CheckedValues(vec![
CheckedValue::Boolean(true),
CheckedValue::Boolean(false)
])
);
}
#[test]
fn array() {
let s = "[[true, false]]";
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::array((ConcreteType::Boolean, 2usize))]
)
.unwrap(),
CheckedValues(vec![CheckedValue::Array(vec![
CheckedValue::Boolean(true),
CheckedValue::Boolean(false)
])])
);
}
#[test]
fn struc() {
let s = r#"[{"a": "42"}]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap(),
CheckedValues(vec![CheckedValue::Struct(
vec![("a".to_string(), CheckedValue::Field(42.into()))]
.into_iter()
.collect()
)])
);
let s = r#"[{"b": "42"}]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap_err(),
Error::Type("Member with id `a` not found".into())
);
let s = r#"[{}]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap_err(),
Error::Type("Expected 1 member(s), found 0".into())
);
let s = r#"[{"a": false}]"#;
assert_eq!(
parse_strict::<Bn128Field>(
s,
vec![ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"".into(),
vec![ConcreteStructMember::new(
"a".into(),
ConcreteType::FieldElement
)]
))]
)
.unwrap_err(),
Error::Type("Value `false` doesn't match expected type `field`".into())
);
}
assert_eq!(
serde_value,
serde_json::Value::Array(vec![
serde_json::Value::String("1".into()),
serde_json::Value::String("0x02".into()),
serde_json::Value::String("0x0003".into()),
serde_json::Value::String("0x00000004".into()),
serde_json::Value::String("0x0000000000000005".into()),
serde_json::Value::Bool(true),
serde_json::Value::Array(vec![
serde_json::Value::String("1".into()),
serde_json::Value::String("2".into())
]),
serde_json::json!({ "a": "1", "b": "2" })
])
)
}
mod encode {
@ -556,38 +539,35 @@ mod tests {
#[test]
fn fields() {
let v = CheckedValues(vec![CheckedValue::Field(1), CheckedValue::Field(2)]);
let v = Values(vec![Value::Field(1), Value::Field(2)]);
assert_eq!(v.encode(), vec![1, 2]);
}
#[test]
fn u8s() {
let v = CheckedValues::<usize>(vec![CheckedValue::U8(1), CheckedValue::U8(2)]);
let v = Values::<usize>(vec![Value::U8(1), Value::U8(2)]);
assert_eq!(v.encode(), vec![1, 2]);
}
#[test]
fn bools() {
let v: CheckedValues<usize> = CheckedValues(vec![
CheckedValue::Boolean(true),
CheckedValue::Boolean(false),
]);
let v: Values<usize> = Values(vec![Value::Boolean(true), Value::Boolean(false)]);
assert_eq!(v.encode(), vec![1, 0]);
}
#[test]
fn array() {
let v: CheckedValues<usize> = CheckedValues(vec![CheckedValue::Array(vec![
CheckedValue::Boolean(true),
CheckedValue::Boolean(false),
let v: Values<usize> = Values(vec![Value::Array(vec![
Value::Boolean(true),
Value::Boolean(false),
])]);
assert_eq!(v.encode(), vec![1, 0]);
}
#[test]
fn struc() {
let v: CheckedValues<usize> = CheckedValues(vec![CheckedValue::Struct(
vec![("a".to_string(), CheckedValue::Field(42))]
let v: Values<usize> = Values(vec![Value::Struct(
vec![("a".to_string(), Value::Field(42))]
.into_iter()
.collect(),
)]);

View file

@ -171,8 +171,7 @@ fn cli_compute<T: Field>(ir_prog: ir::Prog<T>, sub_matches: &ArgMatches) -> Resu
use zokrates_abi::Decode;
let results_json_value: serde_json::Value =
zokrates_abi::CheckedValues::decode(witness.return_values(), signature.outputs)
.into_serde_json();
zokrates_abi::Values::decode(witness.return_values(), signature.outputs).into_serde_json();
if verbose {
println!("\nWitness: \n{}\n", results_json_value);

View file

@ -204,6 +204,7 @@ impl FlatEmbed {
// util to convert a vector of `(variable_id, coefficient)` to a flat_expression
// we build a binary tree of additions by splitting the vector recursively
#[cfg(any(feature = "ark", feature = "bellman"))]
fn flat_expression_from_vec<T: Field>(v: &[(usize, T)]) -> FlatExpression<T> {
match v.len() {
0 => FlatExpression::Number(T::zero()),

View file

@ -17,7 +17,7 @@ use std::path::{Path, PathBuf};
use crate::absy::types::UnresolvedType;
use typed_arena::Arena;
use zokrates_common::Resolver;
use zokrates_field::{Bn128Field, Bw6_761Field, Field};
use zokrates_field::Field;
#[derive(PartialEq, Debug)]
pub struct Error {
@ -104,6 +104,7 @@ impl Importer {
"EMBED" => match symbol.id {
#[cfg(feature = "bellman")]
"sha256round" => {
use zokrates_field::Bn128Field;
if T::id() != Bn128Field::id() {
return Err(CompileErrorInner::ImportError(
Error::new(format!(
@ -124,6 +125,7 @@ impl Importer {
}
#[cfg(feature = "ark")]
"snark_verify_bls12_377" => {
use zokrates_field::Bw6_761Field;
if T::id() != Bw6_761Field::id() {
return Err(CompileErrorInner::ImportError(
Error::new(format!(

View file

@ -2,13 +2,9 @@ use crate::flat_absy::flat_variable::FlatVariable;
use crate::ir::Directive;
use crate::ir::{LinComb, Prog, QuadComb, Statement, Witness};
use crate::solvers::Solver;
use pairing_ce::bn256::Bn256;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt;
use zokrates_embed::ark::generate_verify_witness;
#[cfg(feature = "bellman")]
use zokrates_embed::bellman::generate_sha256_round_witness;
use zokrates_field::Field;
pub type ExecutionResult<T> = Result<Witness<T>, Error>;
@ -216,6 +212,8 @@ impl Interpreter {
}
#[cfg(feature = "bellman")]
Solver::Sha256Round => {
use pairing_ce::bn256::Bn256;
use zokrates_embed::bellman::generate_sha256_round_witness;
use zokrates_field::Bn128Field;
assert_eq!(T::id(), Bn128Field::id());
let i = &inputs[0..512];
@ -240,6 +238,7 @@ impl Interpreter {
}
#[cfg(feature = "ark")]
Solver::SnarkVerifyBls12377(n) => {
use zokrates_embed::ark::generate_verify_witness;
use zokrates_field::Bw6_761Field;
assert_eq!(T::id(), Bw6_761Field::id());

View file

@ -150,8 +150,7 @@ pub fn compute_witness(program: &[u8], abi: JsValue, args: JsValue) -> Result<Js
.map_err(|err| JsValue::from_str(&format!("Execution failed: {}", err)))?;
let return_values: serde_json::Value =
zokrates_abi::CheckedValues::decode(witness.return_values(), signature.outputs)
.into_serde_json();
zokrates_abi::Values::decode(witness.return_values(), signature.outputs).into_serde_json();
let result = ComputationResult {
witness: format!("{}", witness),