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

Encode how to map provables to normal values #1271

Merged
merged 43 commits into from
Apr 19, 2024
Merged

Conversation

mitschabaude
Copy link
Member

@mitschabaude mitschabaude commented Nov 27, 2023

bindings: o1-labs/o1js-bindings#213

this adds a new generic type argument and two new functions to Provable<T>:

type Provable<T, V> = {
  // ...
  toValue(t: T): V;
  fromValue(v: V): T;
}

the idea is that we can automatically convert between provable types and their normal JS equivalents, and stop leaking provable types outside actual provable code.

Motivation:

  • we can make many interfaces more ergonomic by accepting JS values, in an automated way
  • we hope to reduce confusion about provable constants, because people hopefully will never have to use them (they just use JS values), so the constant version of provable types become an internal detail

Some notes:

  • There is a new From<Provable<T>> type, e.g. From<typeof Field> = Field | bigint | string | number, which is automatically derived from deeply inspecting provable types and their fromValue() methods. The DX of using it is surprisingly nice -- the type is fully resolved in Intellisense

image

  • The PR uses fromValue for making the return value of the witness() callback accept JS values. This is super nice IMO and hints at what we could do with this going forward. For example, we could have a wrapper for all gadgets / provable methods which takes both a provable implementation (as before) and a constant implementation which receives js values, and the result takes the flexible From<> type

image

  • To make the example above work, I reimplemented CircuitString with Struct and a JS type of string. It also works with CircuitValue but I wanted to have an example for how to override the JS value type for Structs, it's a bit more involved since Struct wants to infer everything for you (while CircuitValue is somewhat weakly typed)

  • For backwards compatibility, the V type parameter is optional in the exported Provable, so you can still write Provable<T> in situations where the JS value doesn't matter

@mitschabaude mitschabaude marked this pull request as ready for review April 17, 2024 16:20
@@ -71,6 +71,7 @@ function inCompileMode() {

function asProver(f: () => void) {
if (inCheckedComputation()) {
// TODO make this start a "witness block" context
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you make an issue and reference it to the comment to tackle later? (if you don't mind, of course)

I'd like to see more issues in TODO comments like this to make it easier to pick up :D

fromValue(symbol: string | TokenSymbol) {
if (typeof symbol !== 'string') return symbol;
let bytesLength = new TextEncoder().encode(symbol).length;
if (bytesLength > 6)
Copy link
Contributor

Choose a reason for hiding this comment

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

If you think it's a better idea, can you put 6 into https://github.com/o1-labs/o1js/blob/main/src/lib/mina/constants.ts? It's a minor change, but it could really help explain later why it's this value.

@mitschabaude mitschabaude merged commit f9286db into main Apr 19, 2024
14 checks passed
@mitschabaude mitschabaude deleted the feature/to-value branch April 19, 2024 07:29
@mitschabaude
Copy link
Member Author

TODO: forgot to add changelog for this

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.

None yet

2 participants