Debug and test circuits
The most common error you may get while trying to create a proof is:
constraint is not satisfied: [(.. * ..) != (.. * ..) + (.. * ..) + (.. * ..)]
The error means the solver couldn't satisfy at least one of the constraints with the provided witness.
In some cases, you may encounter a
couldn't solve computational constraint error, which means the solver couldn't perform an operation needed to verify a constraint. For example, a division by 0.
You can run the program with
-tags=debug to display a more verbose stack trace.
For a faster development workflow, it is possible (and recommended) to execute a circuit without running a zk-SNARK prover.
err := test.IsSolved(circuit, witness, field)
Under the hood it executes the instructions in the circuit, in plain Go, without generating a constraint system and calling a solver.
The easiest way to debug a circuit is to use
api.Println(), which behaves like
fmt.Println, except it outputs the values when they are solved. For example:
With solving errors and
gnark outputs a stack trace which contain the exact line number to refer to in the circuit definition.
You can implement tests as Go unit tests, in a
_test.go file. For example:
// assert object wrapping testing.T
assert := test.NewAssert(t)
// declare the circuit
var cubicCircuit Circuit
See the test package documentation for more details.
In particular, the default behavior of the assert helper is to test the circuit across all supported curves and backends, ensure correct serialization, and cross-test the constraint system solver against a
big.Int test execution engine.