Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ccs.GetConstraints readable output #244

Merged
merged 9 commits into from
Jan 28, 2022
Merged

ccs.GetConstraints readable output #244

merged 9 commits into from
Jan 28, 2022

Conversation

gbotrel
Copy link
Collaborator

@gbotrel gbotrel commented Jan 28, 2022

This PR removes the ccs.ToHTML deadcode. It's not gnark job to produce HTML, the constraint system returns a list of formatted constraints in a [][]string and a user (like play.gnark.io ) can then render it.

ccs.GetConstraints returns for PlonK the constraints in the form qL⋅xa + qR⋅xb + qO⋅xc + qM⋅(xaxb) + qC == 0 (as in the paper) and for Groth16 L⋅R == O .

Additionally, this PR adds a constraint ID number in the message for a unsatisfied constraint at solving time.

@gbotrel gbotrel requested a review from ivokub January 28, 2022 03:34
@@ -14,8 +14,10 @@ import (
{{ template "import_curve" . }}
)

// ErrUnsatisfiedConstraint can be generated when solving a R1CS
var ErrUnsatisfiedConstraint = errors.New("constraint is not satisfied")
// errUnsatisfiedConstraint can be generated when solving a R1CS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, as ErrUnsatisfiedConstraint was a instantiated type, it could be checked using errors.Is. Now, it is essentially a utility function to call fmt.Errorf. When looking at the places it is called, it makes difficult to understand where the error actually happened (grepping leads here, not to the actual place the error happened).
Maybe remove this function and construct new errors where necessary? If it is necessary to assert this error, then a conventional way would be to define this as a type (satisfying the error interface), and use errors.As for assertion.

@@ -103,9 +102,9 @@ func (cs *R1CS) Solve(witness, a, b, c []fr.Element, opt backend.ProverConfig) (
if !check.Equal(&c[i]) {
if dID, ok := cs.MDebug[i]; ok {
debugInfoStr := solution.logValue(cs.DebugInfo[dID])
return solution.values, fmt.Errorf("%w: %s", ErrUnsatisfiedConstraint, debugInfoStr)
return solution.values, fmt.Errorf("%w: %s", errUnsatisfiedConstraint(i), debugInfoStr)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the error is not assertable anymore, then it doesn't make sense to wrap the error with "%w" anymore. Imo internally it returns a struct which contains the wrapped error and the message, but this overhead doesn't matter as the current function returns early.

@@ -99,9 +99,15 @@ func (cs *SparseR1CS) Solve(witness []fr.Element, opt backend.ProverConfig) ([]f
if err := cs.checkConstraint(cs.Constraints[i], &solution); err != nil {
if dID, ok := cs.MDebug[i]; ok {
debugInfoStr := solution.logValue(cs.DebugInfo[dID])
return solution.values, fmt.Errorf("%w: %s", ErrUnsatisfiedConstraint, debugInfoStr)
if debug.Debug {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the same comments as for r1cs.go.tmpl

// [1] = qR⋅xb
// [2] = qO⋅xc
// [3] = qM⋅(xaxb)
// [4] = qC
func (cs *SparseR1CS) GetConstraints() [][]string {
var r [][]string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We know the number of returned strings ahead of time. We could allocate the whole slice to reduce the number of allocations in the loop.

sbb.WriteByte('0')
return sbb.String()

sbb.Reset()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder is already initialized.

@@ -55,5 +55,5 @@ func init() {
},
}

addNewEntry("cmp", &cmpCircuit{}, good, bad, []ecc.ID{ecc.BW6_761})
addNewEntry("cmp", &cmpCircuit{}, good, bad, []ecc.ID{ecc.BN254})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for changing the curve for this test? Why not ecc.Implemented()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we missed it in PR #233 --> I like to run go test -short and with BW6 hard coded here, it takes 10x more time :)

@gbotrel gbotrel merged commit 7bfb8b7 into develop Jan 28, 2022
@gbotrel gbotrel deleted the plonk-human-readable branch January 28, 2022 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants