Skip to content

Commit

Permalink
Merge branch 'main' into feature/eddsa/twisted
Browse files Browse the repository at this point in the history
  • Loading branch information
querolita committed Dec 19, 2024
2 parents 1419a3c + 17adf4b commit d7a3812
Show file tree
Hide file tree
Showing 27 changed files with 741 additions and 291 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,11 @@ jobs:
env:
INPUT_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Configure Git
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Tag new version
if: ${{ steps.publish.outputs.type }} # https://github.com/JS-DevTools/npm-publish?tab=readme-ov-file#action-output
env:
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/build-bindings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
nix run o1js#update-bindings --max-jobs 4
#fail if this changes any files
cd src/bindings
echo If this check fails you can download a patch from the patch-upload job
echo "https://github.com/o1-labs/o1js/blob/main/README-dev.md#bindings-check-in-ci"
git diff --exit-code
- name: add build to gc-root if on main
if: github.ref == 'refs/heads/main'
Expand All @@ -39,3 +41,18 @@ jobs:
run: |
nix-store --gc --print-dead
nix-store --optimise
patch-upload:
needs: nix-build
if: ${{ failure() }}
runs-on: [sdk-self-hosted-linux-amd64-build-system]
steps:
- name: generate patch
run: |
cd src/bindings
git add .
git diff HEAD > ../../bindings.patch
- name: Upload patch
uses: actions/upload-artifact@v4
with:
name: bindings.patch
path: bindings.patch
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,19 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Added

- `ZkProgram` to support non-pure provable types as inputs and outputs https://github.com/o1-labs/o1js/pull/1828
- API for recursively proving a ZkProgram method from within another https://github.com/o1-labs/o1js/pull/1931
- `let recursive = Experimental.Recursive(program);`
- `recursive.<methodName>(...args): Promise<PublicOutput>`
- This also works within the same program, as long as the return value is type-annotated
- Add `enforceTransactionLimits` parameter on Network https://github.com/o1-labs/o1js/issues/1910
- Method for optional types to assert none https://github.com/o1-labs/o1js/pull/1922
- Increased maximum supported amount of methods in a `SmartContract` or `ZkProgram` to 30. https://github.com/o1-labs/o1js/pull/1918
- Expose low-level conversion methods `Proof.{_proofToBase64,_proofFromBase64}` https://github.com/o1-labs/o1js/pull/1928
- Expore `maxProofsVerified()` and a `Proof` class directly on ZkPrograms https://github.com/o1-labs/o1js/pull/1933

### Changed

- Changed an internal type to improve IntelliSense on ZkProgram methods https://github.com/o1-labs/o1js/pull/1933

### Fixed

Expand All @@ -38,6 +47,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [2.1.0](https://github.com/o1-labs/o1js/compare/b04520d...e1bac02) - 2024-11-13

### Added

- Support secp256r1 in elliptic curve and ECDSA gadgets https://github.com/o1-labs/o1js/pull/1885

### Fixed
Expand Down
14 changes: 14 additions & 0 deletions README-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ In addition to building the OCaml and Rust code, the build script also generates

o1js uses these types to ensure that the constants used in the protocol are consistent with the OCaml source files.

### Bindings check in ci

If the bindings check fails in CI it will upload a patch you can use to update the bindings without having to rebuild locally.
This can also be helpful when the bindings don't build identically, as unfortunately often happens.

To use this patch:
- Click details on the `Build o1js bindings / build-bindings-ubunutu` job
- Go to the `patch-upload` job and expand the logs for `Upload patch`
- Download the file linked in the last line of the logs ie.
`Artifact download URL: https://github.com/o1-labs/o1js/actions/runs/12401083741/artifacts/2339952965`
- unzip it
- navigate to `src/bindings`
- run `git apply path/to/bindings.patch`

## Development

### Branching Policy
Expand Down
2 changes: 1 addition & 1 deletion flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions run-ci-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ case $TEST_TYPE in
./run src/examples/zkapps/reducer/reducer-composite.ts --bundle
./run src/examples/zkapps/composability.ts --bundle
./run src/tests/fake-proof.ts
./run src/tests/inductive-proofs-internal.ts --bundle
./run tests/vk-regression/diverse-zk-program-run.ts --bundle
;;

Expand Down
6 changes: 0 additions & 6 deletions run-minimal-mina-tests.sh

This file was deleted.

4 changes: 1 addition & 3 deletions src/examples/zkprogram/mututal-recursion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,13 @@ const add = ZkProgram({
},
});

const AddProof = ZkProgram.Proof(add);

const multiply = ZkProgram({
name: 'multiply',
publicInput: Undefined,
publicOutput: Field,
methods: {
performMultiplication: {
privateInputs: [Field, AddProof],
privateInputs: [Field, add.Proof],
async method(field: Field, addProof: Proof<Undefined, Field>) {
addProof.verify();
const multiplicationResult = addProof.publicOutput.mul(field);
Expand Down
8 changes: 3 additions & 5 deletions src/examples/zkprogram/program-with-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ MyProgram.publicOutputType satisfies Provable<void>;
MyProgram.privateInputTypes;
MyProgram.auxiliaryOutputTypes;

let MyProof = ZkProgram.Proof(MyProgram);

console.log('program digest', await MyProgram.digest());

console.log('compiling MyProgram...');
Expand All @@ -45,7 +43,7 @@ console.log('verification key', verificationKey.data.slice(0, 10) + '..');

console.log('proving base case...');
let { proof } = await MyProgram.baseCase(Field(0));
proof = await testJsonRoundtrip(MyProof, proof);
proof = await testJsonRoundtrip(MyProgram.Proof, proof);

// type sanity check
proof satisfies Proof<Field, void>;
Expand All @@ -60,7 +58,7 @@ console.log('ok (alternative)?', ok);

console.log('proving step 1...');
let { proof: proof1 } = await MyProgram.inductiveCase(Field(1), proof);
proof1 = await testJsonRoundtrip(MyProof, proof1);
proof1 = await testJsonRoundtrip(MyProgram.Proof, proof1);

console.log('verify...');
ok = await verify(proof1, verificationKey);
Expand All @@ -72,7 +70,7 @@ console.log('ok (alternative)?', ok);

console.log('proving step 2...');
let { proof: proof2 } = await MyProgram.inductiveCase(Field(2), proof1);
proof2 = await testJsonRoundtrip(MyProof, proof2);
proof2 = await testJsonRoundtrip(MyProgram.Proof, proof2);

console.log('verify...');
ok = await verify(proof2.toJSON(), verificationKey);
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ import * as OffchainState_ from './lib/mina/actions/offchain-state.js';
import * as BatchReducer_ from './lib/mina/actions/batch-reducer.js';
import { Actionable } from './lib/mina/actions/offchain-state-serialization.js';
import { InferProvable } from './lib/provable/types/struct.js';
import { Recursive as Recursive_ } from './lib/proof-system/recursive.js';
export { Experimental };

const Experimental_ = {
Expand All @@ -162,6 +163,8 @@ const Experimental_ = {
namespace Experimental {
export let memoizeWitness = Experimental_.memoizeWitness;

export let Recursive = Recursive_;

// indexed merkle map
export let IndexedMerkleMap = Experimental_.IndexedMerkleMap;
export type IndexedMerkleMap = IndexedMerkleMapBase;
Expand Down
18 changes: 5 additions & 13 deletions src/lib/mina/account-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ interface Body extends AccountUpdateBody {
* Events can be collected by archive nodes.
*
* [Check out our documentation about
* Events!](https://docs.minaprotocol.com/zkapps/advanced-o1js/events)
* Events!](https://docs.minaprotocol.com/zkapps/writing-a-zkapp/feature-overview/events)
*/
events: Events;
/**
Expand All @@ -561,7 +561,7 @@ interface Body extends AccountUpdateBody {
* a {@link Reducer}.
*
* [Check out our documentation about
* Actions!](https://docs.minaprotocol.com/zkapps/advanced-o1js/actions-and-reducer)
* Actions!](https://docs.minaprotocol.com/zkapps/writing-a-zkapp/feature-overview/actions-and-reducer)
*/
actions: Events;
/**
Expand Down Expand Up @@ -655,7 +655,6 @@ type LazyProof = {
kind: 'lazy-proof';
methodName: string;
args: any[];
previousProofs: Pickles.Proof[];
ZkappClass: typeof SmartContract;
memoized: { fields: Field[]; aux: any[] }[];
blindingValue: Field;
Expand Down Expand Up @@ -2116,14 +2115,7 @@ async function addProof(

async function createZkappProof(
prover: Pickles.Prover,
{
methodName,
args,
previousProofs,
ZkappClass,
memoized,
blindingValue,
}: LazyProof,
{ methodName, args, ZkappClass, memoized, blindingValue }: LazyProof,
{ transaction, accountUpdate, index }: ZkappProverData
): Promise<Proof<ZkappPublicInput, Empty>> {
let publicInput = accountUpdate.toPublicInput(transaction);
Expand All @@ -2141,7 +2133,7 @@ async function createZkappProof(
blindingValue,
});
try {
return await prover(publicInputFields, MlArray.to(previousProofs));
return await prover(publicInputFields);
} catch (err) {
console.error(`Error when proving ${ZkappClass.name}.${methodName}()`);
throw err;
Expand All @@ -2151,7 +2143,7 @@ async function createZkappProof(
}
);

let maxProofsVerified = ZkappClass._maxProofsVerified!;
let maxProofsVerified = await ZkappClass.getMaxProofsVerified();
const Proof = ZkappClass.Proof();
return new Proof({
publicInput,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/mina/actions/offchain-state-rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ function OffchainStateRollup({
},
});

let RollupProof = ZkProgram.Proof(offchainStateRollup);
let RollupProof = offchainStateRollup.Proof;

let isCompiled = false;

Expand Down
33 changes: 20 additions & 13 deletions src/lib/mina/zkapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ import {
import {
analyzeMethod,
compileProgram,
computeMaxProofsVerified,
Empty,
getPreviousProofsForProver,
MethodInterface,
sortMethodArguments,
VerificationKey,
} from '../proof-system/zkprogram.js';
import { Proof } from '../proof-system/proof.js';
import { Proof, ProofClass } from '../proof-system/proof.js';
import { PublicKey } from '../provable/crypto/signature.js';
import {
InternalStateType,
Expand Down Expand Up @@ -154,11 +154,6 @@ function method<K extends string, T extends SmartContract>(
// FIXME: overriding a method implies pushing a separate method entry here, yielding two entries with the same name
// this should only be changed once we no longer share the _methods array with the parent class (otherwise a subclass declaration messes up the parent class)
ZkappClass._methods.push(methodEntry);
ZkappClass._maxProofsVerified ??= 0;
ZkappClass._maxProofsVerified = Math.max(
ZkappClass._maxProofsVerified,
methodEntry.numberOfProofs
) as 0 | 1 | 2;
let func = descriptor.value as AsyncFunction;
descriptor.value = wrapMethod(func, ZkappClass, internalMethodEntry);
}
Expand Down Expand Up @@ -341,8 +336,6 @@ function wrapMethod(
{
methodName: methodIntf.methodName,
args: clonedArgs,
// proofs actually don't have to be cloned
previousProofs: getPreviousProofsForProver(actualArgs),
ZkappClass,
memoized,
blindingValue,
Expand Down Expand Up @@ -433,7 +426,6 @@ function wrapMethod(
{
methodName: methodIntf.methodName,
args: constantArgs,
previousProofs: getPreviousProofsForProver(constantArgs),
ZkappClass,
memoized,
blindingValue: constantBlindingValue,
Expand Down Expand Up @@ -593,10 +585,10 @@ class SmartContract extends SmartContractBase {
rows: number;
digest: string;
gates: Gate[];
proofs: ProofClass[];
}
>; // keyed by method name
static _provers?: Pickles.Prover[];
static _maxProofsVerified?: 0 | 1 | 2;
static _verificationKey?: { data: string; hash: Field };

/**
Expand Down Expand Up @@ -644,6 +636,7 @@ class SmartContract extends SmartContractBase {
forceRecompile = false,
} = {}) {
let methodIntfs = this._methods ?? [];
let methodKeys = methodIntfs.map(({ methodName }) => methodName);
let methods = methodIntfs.map(({ methodName }) => {
return async (
publicInput: unknown,
Expand All @@ -657,13 +650,15 @@ class SmartContract extends SmartContractBase {
});
// run methods once to get information that we need already at compile time
let methodsMeta = await this.analyzeMethods();
let gates = methodIntfs.map((intf) => methodsMeta[intf.methodName].gates);
let gates = methodKeys.map((k) => methodsMeta[k].gates);
let proofs = methodKeys.map((k) => methodsMeta[k].proofs);
let { verificationKey, provers, verify } = await compileProgram({
publicInputType: ZkappPublicInput,
publicOutputType: Empty,
methodIntfs,
methods,
gates,
proofs,
proofSystemTag: this,
cache,
forceRecompile,
Expand All @@ -689,6 +684,17 @@ class SmartContract extends SmartContractBase {
return hash.toBigInt().toString(16);
}

/**
* The maximum number of proofs that are verified by any of the zkApp methods.
* This is an internal parameter needed by the proof system.
*/
static async getMaxProofsVerified() {
let methodData = await this.analyzeMethods();
return computeMaxProofsVerified(
Object.values(methodData).map((d) => d.proofs.length)
);
}

/**
* Deploys a {@link SmartContract}.
*
Expand Down Expand Up @@ -1189,7 +1195,7 @@ super.init();
try {
for (let methodIntf of methodIntfs) {
let accountUpdate: AccountUpdate;
let { rows, digest, gates, summary } = await analyzeMethod(
let { rows, digest, gates, summary, proofs } = await analyzeMethod(
ZkappPublicInput,
methodIntf,
async (publicInput, publicKey, tokenId, ...args) => {
Expand All @@ -1207,6 +1213,7 @@ super.init();
rows,
digest,
gates,
proofs,
};
if (printSummary) console.log(methodIntf.methodName, summary());
}
Expand Down
Loading

0 comments on commit d7a3812

Please sign in to comment.