-
Notifications
You must be signed in to change notification settings - Fork 134
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
Flexible circuit values #416
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great
I think we should take this opportunity to rename AsFields*
to something better since we’re making big changes to those types here. I also still dislike CircuitValue
as circuit couples our nomenclature too much to proof systems that have circuits as their backend (which in this case is just an implementation detail subject to change).
To start the conversation on this: How about ProvableValue
(for circuit value) and Provable
(for AsFieldsAndAux
)? And then adding a “pure” modifier as relevant like you did in this PR.
it’s also probably a good time to make the circuitValue constructors more discoverable as you’ve suggested (like under the Provable
namespace? Examples: Provable.Value
, Provable.value
). Up to you if you think this would be too big in scope to include as part of this PR, but probably we should avoid a snarkyjs release until making these changes.
and then we’d include doccoments on all the Provable stuff
@bkase good idea to do the name changes in this PR! I think I wonder whether having Another idea: Should we even call it a "value", or might it be even clearer if we call it a "type"? What about |
I like this UX too, but prefer the term
|
@@ -43,6 +43,9 @@ type NonMethodKeys<T> = { | |||
}[keyof T]; | |||
type NonMethods<T> = Pick<T, NonMethodKeys<T>>; | |||
|
|||
/** | |||
* @deprecated `CircuitValue` is deprecated in favor of `Struct`, which features a simpler API and better typing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Should you link to Struct
in the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How should we link? the [[ Struct ]]
thing wasn't working
The first aspect this changes regards the default "circuit type" in snarkyjs, which is now more general:
AsFieldElements<T>
to now require anAsFieldsAndAux<T>
, the more general type which allows non-circuit ("auxiliary") contents, like strings. This makes our system of "circuit values" similar to the one in OCaml, where atyp
holds both field elements and auxiliary data.AsFieldElements<T>
so that it extendsAsFieldsAndAux<T>
. Thus, a circuit type which only consists of field elements is now a special case of a general circuit type.AsFieldElements<T>
can be passed in whereverAsFieldsAndAux<T>
is required. But not the other way around.ofFields
is now calledfromFields
ofBits
->fromBits
for consistencyAsFieldElements<T>
for a reason: For example, the type for events and actions, because the protocol requires to send events as an array of field elements, so it must not contain auxiliary data, because we wouldn't be able to recover them from fetched eventsCircuit.witness
to witness anAsFieldsAndAux<T>
(in compile mode, this means it creates field elements which are zero and aux values which have a default value, e.g. an empty string if the type isString
)CircuitValue
class and built-in types likeUInt32
as is, still being anAsFieldElements<T>
. Thus, our public API is mostly unaffected by this batch of changesMore general circuit types can, for now, be generated with not very discoverable helpers
circuitValue
andcircuitValueClass
. I think it's worthy of discussion whether we want to make those the "default" / easily discoverable way of creating circuit types. However, I don't want to block the PR by these discussions.circuitValue
support the following non-Field types: String, Number, Boolean, BigInt, null,, undefinedcircuitValue
have very good typing, using recursive type inference:{x: Field, s: String}
{x: Field, s: string}
AsFieldsAndAux<T>
, which has static methods liketoFields
,toAuxiliary
,toJSON
, all of which are precisely-typed{x: string: s: string}
circuitValueClass
which wrapscircuitValue
in a class, thus providing a new way to declareCircuitValue
s which can be used as method arguments. This class tries to be usable just as if it were the plain anonymous object:Finally, we use
circuiValueClass
to provide a newVerificationKey
class which can be used to pass verification keys into methods.VerificationKey
type which was related to plainCircuit
s and not really used right now