mirror of https://github.com/zcash/halo2.git
Allow halo2 constraint names to have non static names (#156)
* static ref to String type in Gates, Constraints, VirtualCell, Argument * 'lookup'.to_string() * return &str for gate name and constriant_name, also run fmt * Update halo2_gadgets/Cargo.toml Co-authored-by: Han <tinghan0110@gmail.com> * upgrade rust-toochain --------- Co-authored-by: Carlos Pérez <37264926+CPerezz@users.noreply.github.com> Co-authored-by: Han <tinghan0110@gmail.com>
This commit is contained in:
parent
0d56c57a07
commit
b739b543d6
|
@ -586,13 +586,13 @@ mod tests {
|
|||
assert_eq!(
|
||||
prover.verify(),
|
||||
Err(vec![VerifyFailure::Lookup {
|
||||
name: "lookup",
|
||||
name: "lookup".to_string(),
|
||||
lookup_index: 0,
|
||||
location: FailureLocation::InRegion {
|
||||
region: (1, "Range check 6 bits").into(),
|
||||
offset: 1,
|
||||
},
|
||||
}])
|
||||
}]),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -607,7 +607,7 @@ mod tests {
|
|||
prover.verify(),
|
||||
Err(vec![
|
||||
VerifyFailure::Lookup {
|
||||
name: "lookup",
|
||||
name: "lookup".to_string(),
|
||||
lookup_index: 0,
|
||||
location: FailureLocation::InRegion {
|
||||
region: (1, "Range check 6 bits").into(),
|
||||
|
@ -615,7 +615,7 @@ mod tests {
|
|||
},
|
||||
},
|
||||
VerifyFailure::Lookup {
|
||||
name: "lookup",
|
||||
name: "lookup".to_string(),
|
||||
lookup_index: 0,
|
||||
location: FailureLocation::InRegion {
|
||||
region: (1, "Range check 6 bits").into(),
|
||||
|
@ -645,7 +645,7 @@ mod tests {
|
|||
assert_eq!(
|
||||
prover.verify(),
|
||||
Err(vec![VerifyFailure::Lookup {
|
||||
name: "lookup",
|
||||
name: "lookup".to_string(),
|
||||
lookup_index: 0,
|
||||
location: FailureLocation::InRegion {
|
||||
region: (1, "Range check 6 bits").into(),
|
||||
|
|
|
@ -986,7 +986,7 @@ impl<F: FromUniformBytes<64> + Ord> MockProver<F> {
|
|||
assert!(table.binary_search(input).is_err());
|
||||
|
||||
Some(VerifyFailure::Lookup {
|
||||
name: lookup.name,
|
||||
name: lookup.name.clone(),
|
||||
lookup_index,
|
||||
location: FailureLocation::find_expressions(
|
||||
&self.cs,
|
||||
|
@ -1347,7 +1347,7 @@ impl<F: FromUniformBytes<64> + Ord> MockProver<F> {
|
|||
.filter_map(move |(input, input_row)| {
|
||||
if table.binary_search(input).is_err() {
|
||||
Some(VerifyFailure::Lookup {
|
||||
name: lookup.name,
|
||||
name: lookup.name.clone(),
|
||||
lookup_index,
|
||||
location: FailureLocation::find_expressions(
|
||||
&self.cs,
|
||||
|
@ -1774,7 +1774,7 @@ mod tests {
|
|||
assert_eq!(
|
||||
prover.verify(),
|
||||
Err(vec![VerifyFailure::Lookup {
|
||||
name: "lookup",
|
||||
name: "lookup".to_string(),
|
||||
lookup_index: 0,
|
||||
location: FailureLocation::InRegion {
|
||||
region: (1, "Faulty synthesis").into(),
|
||||
|
@ -1908,7 +1908,7 @@ mod tests {
|
|||
assert_eq!(
|
||||
prover.verify(),
|
||||
Err(vec![VerifyFailure::Lookup {
|
||||
name: "lookup",
|
||||
name: "lookup".to_string(),
|
||||
lookup_index: 0,
|
||||
location: FailureLocation::InRegion {
|
||||
region: (2, "Faulty synthesis").into(),
|
||||
|
|
|
@ -159,7 +159,7 @@ pub enum VerifyFailure {
|
|||
/// A lookup input did not exist in its corresponding table.
|
||||
Lookup {
|
||||
/// The name of the lookup that is not satisfied.
|
||||
name: &'static str,
|
||||
name: String,
|
||||
/// The index of the lookup that is not satisfied. These indices are assigned in
|
||||
/// the order in which `ConstraintSystem::lookup` is called during
|
||||
/// `Circuit::configure`.
|
||||
|
@ -277,7 +277,7 @@ impl Debug for VerifyFailure {
|
|||
};
|
||||
|
||||
let debug = ConstraintCaseDebug {
|
||||
constraint: *constraint,
|
||||
constraint: constraint.clone(),
|
||||
location: location.clone(),
|
||||
cell_values: cell_values
|
||||
.iter()
|
||||
|
|
|
@ -15,14 +15,14 @@ use crate::{
|
|||
|
||||
#[derive(Debug)]
|
||||
struct Constraint {
|
||||
name: &'static str,
|
||||
name: String,
|
||||
expression: String,
|
||||
queries: BTreeSet<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Gate {
|
||||
name: &'static str,
|
||||
name: String,
|
||||
constraints: Vec<Constraint>,
|
||||
}
|
||||
|
||||
|
@ -122,13 +122,13 @@ impl CircuitGates {
|
|||
.gates
|
||||
.iter()
|
||||
.map(|gate| Gate {
|
||||
name: gate.name(),
|
||||
name: gate.name().to_string(),
|
||||
constraints: gate
|
||||
.polynomials()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, constraint)| Constraint {
|
||||
name: gate.constraint_name(i),
|
||||
name: gate.constraint_name(i).to_string(),
|
||||
expression: constraint.evaluate(
|
||||
&util::format_value,
|
||||
&|selector| format!("S{}", selector.0),
|
||||
|
|
|
@ -75,7 +75,7 @@ impl fmt::Display for DebugColumn {
|
|||
/// within a custom gate.
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct VirtualCell {
|
||||
name: &'static str,
|
||||
name: String,
|
||||
pub(super) column: Column,
|
||||
pub(super) rotation: i32,
|
||||
}
|
||||
|
@ -83,17 +83,17 @@ pub struct VirtualCell {
|
|||
impl From<(Column, i32)> for VirtualCell {
|
||||
fn from((column, rotation): (Column, i32)) -> Self {
|
||||
VirtualCell {
|
||||
name: "",
|
||||
name: "".to_string(),
|
||||
column,
|
||||
rotation,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(&'static str, Column, i32)> for VirtualCell {
|
||||
fn from((name, column, rotation): (&'static str, Column, i32)) -> Self {
|
||||
impl<S: AsRef<str>> From<(S, Column, i32)> for VirtualCell {
|
||||
fn from((name, column, rotation): (S, Column, i32)) -> Self {
|
||||
VirtualCell {
|
||||
name,
|
||||
name: name.as_ref().to_string(),
|
||||
column,
|
||||
rotation,
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ impl From<(&'static str, Column, i32)> for VirtualCell {
|
|||
impl From<plonk::VirtualCell> for VirtualCell {
|
||||
fn from(c: plonk::VirtualCell) -> Self {
|
||||
VirtualCell {
|
||||
name: "",
|
||||
name: "".to_string(),
|
||||
column: c.column.into(),
|
||||
rotation: c.rotation.0,
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ impl fmt::Display for VirtualCell {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}@{}", self.column, self.rotation)?;
|
||||
if !self.name.is_empty() {
|
||||
write!(f, "({})", self.name)?;
|
||||
write!(f, "({})", self.name.as_str())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ impl fmt::Display for VirtualCell {
|
|||
/// Helper structure used to be able to inject Column annotations inside a `Display` or `Debug` call.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(super) struct DebugVirtualCell {
|
||||
name: &'static str,
|
||||
name: String,
|
||||
column: DebugColumn,
|
||||
rotation: i32,
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ pub(super) struct DebugVirtualCell {
|
|||
impl From<(&VirtualCell, Option<&HashMap<Column, String>>)> for DebugVirtualCell {
|
||||
fn from(info: (&VirtualCell, Option<&HashMap<Column, String>>)) -> Self {
|
||||
DebugVirtualCell {
|
||||
name: info.0.name,
|
||||
name: info.0.name.clone(),
|
||||
column: DebugColumn::from((info.0.column, info.1)),
|
||||
rotation: info.0.rotation,
|
||||
}
|
||||
|
@ -149,30 +149,33 @@ impl fmt::Display for DebugVirtualCell {
|
|||
}
|
||||
|
||||
/// Metadata about a configured gate within a circuit.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Gate {
|
||||
/// The index of the active gate. These indices are assigned in the order in which
|
||||
/// `ConstraintSystem::create_gate` is called during `Circuit::configure`.
|
||||
pub(super) index: usize,
|
||||
/// The name of the active gate. These are specified by the gate creator (such as
|
||||
/// a chip implementation), and is not enforced to be unique.
|
||||
pub(super) name: &'static str,
|
||||
pub(super) name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for Gate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Gate {} ('{}')", self.index, self.name)
|
||||
write!(f, "Gate {} ('{}')", self.index, self.name.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(usize, &'static str)> for Gate {
|
||||
fn from((index, name): (usize, &'static str)) -> Self {
|
||||
Gate { index, name }
|
||||
impl<S: AsRef<str>> From<(usize, S)> for Gate {
|
||||
fn from((index, name): (usize, S)) -> Self {
|
||||
Gate {
|
||||
index,
|
||||
name: name.as_ref().to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata about a configured constraint within a circuit.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Constraint {
|
||||
/// The gate containing the constraint.
|
||||
pub(super) gate: Gate,
|
||||
|
@ -182,7 +185,7 @@ pub struct Constraint {
|
|||
pub(super) index: usize,
|
||||
/// The name of the constraint. This is specified by the gate creator (such as a chip
|
||||
/// implementation), and is not enforced to be unique.
|
||||
pub(super) name: &'static str,
|
||||
pub(super) name: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for Constraint {
|
||||
|
@ -194,7 +197,7 @@ impl fmt::Display for Constraint {
|
|||
if self.name.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
format!(" ('{}')", self.name)
|
||||
format!(" ('{}')", self.name.as_str())
|
||||
},
|
||||
self.gate.index,
|
||||
self.gate.name,
|
||||
|
@ -202,9 +205,13 @@ impl fmt::Display for Constraint {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<(Gate, usize, &'static str)> for Constraint {
|
||||
fn from((gate, index, name): (Gate, usize, &'static str)) -> Self {
|
||||
Constraint { gate, index, name }
|
||||
impl<S: AsRef<str>> From<(Gate, usize, S)> for Constraint {
|
||||
fn from((gate, index, name): (Gate, usize, S)) -> Self {
|
||||
Constraint {
|
||||
gate,
|
||||
index,
|
||||
name: name.as_ref().to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,7 +257,7 @@ impl Debug for Region {
|
|||
|
||||
impl fmt::Display for Region {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Region {} ('{}')", self.index, self.name)
|
||||
write!(f, "Region {} ('{}')", self.index, self.name.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1234,25 +1234,34 @@ impl<Col: Into<Column<Any>>> From<(Col, Rotation)> for VirtualCell {
|
|||
/// These are returned by the closures passed to `ConstraintSystem::create_gate`.
|
||||
#[derive(Debug)]
|
||||
pub struct Constraint<F: Field> {
|
||||
name: &'static str,
|
||||
name: String,
|
||||
poly: Expression<F>,
|
||||
}
|
||||
|
||||
impl<F: Field> From<Expression<F>> for Constraint<F> {
|
||||
fn from(poly: Expression<F>) -> Self {
|
||||
Constraint { name: "", poly }
|
||||
Constraint {
|
||||
name: "".to_string(),
|
||||
poly,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> From<(&'static str, Expression<F>)> for Constraint<F> {
|
||||
fn from((name, poly): (&'static str, Expression<F>)) -> Self {
|
||||
Constraint { name, poly }
|
||||
impl<F: Field, S: AsRef<str>> From<(S, Expression<F>)> for Constraint<F> {
|
||||
fn from((name, poly): (S, Expression<F>)) -> Self {
|
||||
Constraint {
|
||||
name: name.as_ref().to_string(),
|
||||
poly,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> From<Expression<F>> for Vec<Constraint<F>> {
|
||||
fn from(poly: Expression<F>) -> Self {
|
||||
vec![Constraint { name: "", poly }]
|
||||
vec![Constraint {
|
||||
name: "".to_string(),
|
||||
poly,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1342,8 +1351,8 @@ impl<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> IntoIterato
|
|||
/// Gate
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Gate<F: Field> {
|
||||
name: &'static str,
|
||||
constraint_names: Vec<&'static str>,
|
||||
name: String,
|
||||
constraint_names: Vec<String>,
|
||||
polys: Vec<Expression<F>>,
|
||||
/// We track queried selectors separately from other cells, so that we can use them to
|
||||
/// trigger debug checks on gates.
|
||||
|
@ -1352,12 +1361,12 @@ pub struct Gate<F: Field> {
|
|||
}
|
||||
|
||||
impl<F: Field> Gate<F> {
|
||||
pub(crate) fn name(&self) -> &'static str {
|
||||
self.name
|
||||
pub(crate) fn name(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
pub(crate) fn constraint_name(&self, constraint_index: usize) -> &'static str {
|
||||
self.constraint_names[constraint_index]
|
||||
pub(crate) fn constraint_name(&self, constraint_index: usize) -> &str {
|
||||
self.constraint_names[constraint_index].as_str()
|
||||
}
|
||||
|
||||
/// Returns constraints of this gate
|
||||
|
@ -1550,9 +1559,9 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
///
|
||||
/// `table_map` returns a map between input expressions and the table columns
|
||||
/// they need to match.
|
||||
pub fn lookup(
|
||||
pub fn lookup<S: AsRef<str>>(
|
||||
&mut self,
|
||||
name: &'static str,
|
||||
name: S,
|
||||
table_map: impl FnOnce(&mut VirtualCells<'_, F>) -> Vec<(Expression<F>, TableColumn)>,
|
||||
) -> usize {
|
||||
let mut cells = VirtualCells::new(self);
|
||||
|
@ -1571,7 +1580,8 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
|
||||
let index = self.lookups.len();
|
||||
|
||||
self.lookups.push(lookup::Argument::new(name, table_map));
|
||||
self.lookups
|
||||
.push(lookup::Argument::new(name.as_ref(), table_map));
|
||||
|
||||
index
|
||||
}
|
||||
|
@ -1580,9 +1590,9 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
///
|
||||
/// `table_map` returns a map between input expressions and the table expressions
|
||||
/// they need to match.
|
||||
pub fn lookup_any(
|
||||
pub fn lookup_any<S: AsRef<str>>(
|
||||
&mut self,
|
||||
name: &'static str,
|
||||
name: S,
|
||||
table_map: impl FnOnce(&mut VirtualCells<'_, F>) -> Vec<(Expression<F>, Expression<F>)>,
|
||||
) -> usize {
|
||||
let mut cells = VirtualCells::new(self);
|
||||
|
@ -1590,7 +1600,8 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
|
||||
let index = self.lookups.len();
|
||||
|
||||
self.lookups.push(lookup::Argument::new(name, table_map));
|
||||
self.lookups
|
||||
.push(lookup::Argument::new(name.as_ref(), table_map));
|
||||
|
||||
index
|
||||
}
|
||||
|
@ -1710,9 +1721,9 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
///
|
||||
/// A gate is required to contain polynomial constraints. This method will panic if
|
||||
/// `constraints` returns an empty iterator.
|
||||
pub fn create_gate<C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>>(
|
||||
pub fn create_gate<C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>, S: AsRef<str>>(
|
||||
&mut self,
|
||||
name: &'static str,
|
||||
name: S,
|
||||
constraints: impl FnOnce(&mut VirtualCells<'_, F>) -> Iter,
|
||||
) {
|
||||
let mut cells = VirtualCells::new(self);
|
||||
|
@ -1732,7 +1743,7 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
);
|
||||
|
||||
self.gates.push(Gate {
|
||||
name,
|
||||
name: name.as_ref().to_string(),
|
||||
constraint_names,
|
||||
polys,
|
||||
queried_selectors,
|
||||
|
|
|
@ -7,7 +7,7 @@ pub(crate) mod verifier;
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct Argument<F: Field> {
|
||||
pub(crate) name: &'static str,
|
||||
pub(crate) name: String,
|
||||
pub(crate) input_expressions: Vec<Expression<F>>,
|
||||
pub(crate) table_expressions: Vec<Expression<F>>,
|
||||
}
|
||||
|
@ -25,10 +25,10 @@ impl<F: Field> Argument<F> {
|
|||
/// Constructs a new lookup argument.
|
||||
///
|
||||
/// `table_map` is a sequence of `(input, table)` tuples.
|
||||
pub fn new(name: &'static str, table_map: Vec<(Expression<F>, Expression<F>)>) -> Self {
|
||||
pub fn new<S: AsRef<str>>(name: S, table_map: Vec<(Expression<F>, Expression<F>)>) -> Self {
|
||||
let (input_expressions, table_expressions) = table_map.into_iter().unzip();
|
||||
Argument {
|
||||
name,
|
||||
name: name.as_ref().to_string(),
|
||||
input_expressions,
|
||||
table_expressions,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue