From 30286a254e95d4b2659e787e52bacc7ae0317b3b Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 16:55:58 +0100 Subject: [PATCH 01/20] remove account creation fee --- CHANGELOG.md | 1 + src/lib/mina.ts | 6 ------ src/lib/mina/local-blockchain.ts | 4 ---- src/lib/mina/mina-instance.ts | 14 -------------- 4 files changed, 1 insertion(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e691085dbd..1a52cef5b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 + - Remove `Mina.accountCreationFee` (use `Mina.getNetworkConstants().accountCreationFee`) - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/mina.ts b/src/lib/mina.ts index 2086d6629a..5b56f5873b 100644 --- a/src/lib/mina.ts +++ b/src/lib/mina.ts @@ -25,7 +25,6 @@ import { getNetworkId, getNetworkConstants, getNetworkState, - accountCreationFee, fetchEvents, fetchActions, getActions, @@ -73,7 +72,6 @@ export { getNetworkId, getNetworkConstants, getNetworkState, - accountCreationFee, fetchEvents, fetchActions, getActions, @@ -173,10 +171,6 @@ function Network( return { getNetworkId: () => minaNetworkId, - /** - * @deprecated use {@link Mina.getNetworkConstants} - */ - accountCreationFee: () => defaultNetworkConstants.accountCreationFee, getNetworkConstants() { if (currentTransaction()?.fetchMode === 'test') { Fetch.markNetworkToBeFetched(minaGraphqlEndpoint); diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index 3f65348929..5cb803a6f0 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -81,10 +81,6 @@ function LocalBlockchain({ return { getNetworkId: () => minaNetworkId, proofsEnabled, - /** - * @deprecated use {@link Mina.getNetworkConstants} - */ - accountCreationFee: () => defaultNetworkConstants.accountCreationFee, getNetworkConstants() { return { ...defaultNetworkConstants, diff --git a/src/lib/mina/mina-instance.ts b/src/lib/mina/mina-instance.ts index b713a2b99f..bdaea799b7 100644 --- a/src/lib/mina/mina-instance.ts +++ b/src/lib/mina/mina-instance.ts @@ -32,7 +32,6 @@ export { getNetworkId, getNetworkConstants, getNetworkState, - accountCreationFee, fetchEvents, fetchActions, getActions, @@ -104,10 +103,6 @@ type Mina = { getAccount(publicKey: PublicKey, tokenId?: Field): Account; getNetworkState(): NetworkValue; getNetworkConstants(): NetworkConstants; - /** - * @deprecated use {@link getNetworkConstants} - */ - accountCreationFee(): UInt64; sendTransaction(transaction: Transaction): Promise; fetchEvents: ( publicKey: PublicKey, @@ -129,7 +124,6 @@ type Mina = { }; let activeInstance: Mina = { - accountCreationFee: () => defaultNetworkConstants.accountCreationFee, getNetworkConstants: () => defaultNetworkConstants, currentSlot: noActiveInstance, hasAccount: noActiveInstance, @@ -204,14 +198,6 @@ function getBalance(publicKey: PublicKey, tokenId?: Field) { return activeInstance.getAccount(publicKey, tokenId).balance; } -/** - * Returns the default account creation fee. - * @deprecated use {@link Mina.getNetworkConstants} - */ -function accountCreationFee() { - return activeInstance.accountCreationFee(); -} - /** * @return A list of emitted events associated to the given public key. */ From 61178adeaa1e70b7124525e58bf20fbbf2643763 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 17:08:22 +0100 Subject: [PATCH 02/20] remove deprecated fee payer spec --- CHANGELOG.md | 2 +- src/lib/mina.ts | 15 ++---------- src/lib/mina/local-blockchain.ts | 4 ++-- src/lib/mina/mina-instance.ts | 28 ++-------------------- src/lib/mina/transaction.ts | 40 +++++--------------------------- 5 files changed, 13 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a52cef5b5..24cabe2919 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee` (use `Mina.getNetworkConstants().accountCreationFee`) + - Remove `Mina.accountCreationFee` (use `Mina.getNetworkConstants().accountCreationFee`), `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/mina.ts b/src/lib/mina.ts index 5b56f5873b..14ec9243e8 100644 --- a/src/lib/mina.ts +++ b/src/lib/mina.ts @@ -11,7 +11,6 @@ import { NetworkId } from '../mina-signer/src/types.js'; import { currentTransaction } from './mina/transaction-context.js'; import { type FeePayerSpec, - type DeprecatedFeePayerSpec, type ActionStates, type NetworkConstants, activeInstance, @@ -52,7 +51,6 @@ import { import { LocalBlockchain } from './mina/local-blockchain.js'; export { - BerkeleyQANet, LocalBlockchain, Network, currentTransaction, @@ -88,7 +86,7 @@ export { // patch active instance so that we can still create basic transactions without giving Mina network details setActiveInstance({ ...activeInstance, - async transaction(sender: DeprecatedFeePayerSpec, f: () => Promise) { + async transaction(sender: FeePayerSpec, f: () => Promise) { return await createTransaction(sender, f, 0); }, }); @@ -368,7 +366,7 @@ function Network( safeWait, }; }, - async transaction(sender: DeprecatedFeePayerSpec, f: () => Promise) { + async transaction(sender: FeePayerSpec, f: () => Promise) { // TODO we run the transcation twice to be able to fetch data in between let tx = await createTransaction(sender, f, 0, { fetchMode: 'test', @@ -454,15 +452,6 @@ function Network( }; } -/** - * - * @deprecated This is deprecated in favor of {@link Mina.Network}, which is exactly the same function. - * The name `BerkeleyQANet` was misleading because it suggested that this is specific to a particular network. - */ -function BerkeleyQANet(graphqlEndpoint: string) { - return Network(graphqlEndpoint); -} - /** * Returns the public key of the current transaction's sender account. * diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index 5cb803a6f0..2a8bb9d692 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -26,7 +26,7 @@ import { PendingTransactionStatus, } from './transaction.js'; import { - type DeprecatedFeePayerSpec, + type FeePayerSpec, type ActionStates, Mina, defaultNetworkConstants, @@ -301,7 +301,7 @@ function LocalBlockchain({ safeWait, }; }, - async transaction(sender: DeprecatedFeePayerSpec, f: () => Promise) { + async transaction(sender: FeePayerSpec, f: () => Promise) { // TODO we run the transaction twice to match the behaviour of `Network.transaction` let tx = await createTransaction(sender, f, 0, { isFinalRunOutsideCircuit: false, diff --git a/src/lib/mina/mina-instance.ts b/src/lib/mina/mina-instance.ts index bdaea799b7..5b73af5947 100644 --- a/src/lib/mina/mina-instance.ts +++ b/src/lib/mina/mina-instance.ts @@ -6,11 +6,7 @@ import { UInt64, UInt32 } from '../int.js'; import { PublicKey, PrivateKey } from '../signature.js'; import type { EventActionFilterOptions } from '././../mina/graphql.js'; import type { NetworkId } from '../../mina-signer/src/types.js'; -import type { - Transaction, - PendingTransaction, - RejectedTransaction, -} from '../mina.js'; +import type { Transaction, PendingTransaction } from '../mina.js'; import type { Account } from './account.js'; import type { NetworkValue } from '../precondition.js'; import type * as Fetch from '../fetch.js'; @@ -18,7 +14,6 @@ import type * as Fetch from '../fetch.js'; export { Mina, FeePayerSpec, - DeprecatedFeePayerSpec, ActionStates, NetworkConstants, defaultNetworkConstants, @@ -60,25 +55,6 @@ type FeePayerSpec = } | undefined; -type DeprecatedFeePayerSpec = - | PublicKey - | PrivateKey - | (( - | { - feePayerKey: PrivateKey; - sender?: PublicKey; - } - | { - feePayerKey?: PrivateKey; - sender: PublicKey; - } - ) & { - fee?: number | string | UInt64; - memo?: string; - nonce?: number; - }) - | undefined; - type ActionStates = { fromActionState?: Field; endActionState?: Field; @@ -95,7 +71,7 @@ type NetworkConstants = { type Mina = { transaction( - sender: DeprecatedFeePayerSpec, + sender: FeePayerSpec, f: () => Promise ): Promise; currentSlot(): UInt32; diff --git a/src/lib/mina/transaction.ts b/src/lib/mina/transaction.ts index a4b719cc34..4057a359d3 100644 --- a/src/lib/mina/transaction.ts +++ b/src/lib/mina/transaction.ts @@ -8,7 +8,6 @@ import { TokenId, addMissingProofs, } from '../account-update.js'; -import { prettifyStacktrace } from '../errors.js'; import { Field } from '../core.js'; import { PrivateKey, PublicKey } from '../signature.js'; import { UInt32, UInt64 } from '../int.js'; @@ -17,11 +16,7 @@ import { currentTransaction } from './transaction-context.js'; import { Provable } from '../provable.js'; import { assertPreconditionInvariants } from '../precondition.js'; import { Account } from './account.js'; -import { - type DeprecatedFeePayerSpec, - type FeePayerSpec, - activeInstance, -} from './mina-instance.js'; +import { type FeePayerSpec, activeInstance } from './mina-instance.js'; import * as Fetch from '../fetch.js'; import { type SendZkAppResponse, sendZkappQuery } from './graphql.js'; import { type FetchMode } from './transaction-context.js'; @@ -282,7 +277,7 @@ type RejectedTransaction = Pick< }; async function createTransaction( - feePayer: DeprecatedFeePayerSpec, + feePayer: FeePayerSpec, f: () => Promise, numberOfRuns: 0 | 1 | undefined, { @@ -296,23 +291,18 @@ async function createTransaction( } let feePayerSpec: { sender?: PublicKey; - feePayerKey?: PrivateKey; fee?: number | string | UInt64; memo?: string; nonce?: number; }; if (feePayer === undefined) { feePayerSpec = {}; - } else if (feePayer instanceof PrivateKey) { - feePayerSpec = { feePayerKey: feePayer, sender: feePayer.toPublicKey() }; } else if (feePayer instanceof PublicKey) { feePayerSpec = { sender: feePayer }; } else { feePayerSpec = feePayer; - if (feePayerSpec.sender === undefined) - feePayerSpec.sender = feePayerSpec.feePayerKey?.toPublicKey(); } - let { feePayerKey, sender, fee, memo = '', nonce } = feePayerSpec; + let { sender, fee, memo = '', nonce } = feePayerSpec; let transactionId = currentTransaction.enter({ sender, @@ -368,8 +358,6 @@ async function createTransaction( Fetch.addCachedAccount(senderAccount); } feePayerAccountUpdate = AccountUpdate.defaultFeePayer(sender, nonce_); - if (feePayerKey !== undefined) - feePayerAccountUpdate.lazyAuthorization!.privateKey = feePayerKey; if (fee !== undefined) { feePayerAccountUpdate.body.fee = fee instanceof UInt64 ? fee : UInt64.from(String(fee)); @@ -456,30 +444,14 @@ function transaction( f: () => Promise ): Promise; function transaction(f: () => Promise): Promise; -/** - * @deprecated It's deprecated to pass in the fee payer's private key. Pass in the public key instead. - * ``` - * // good - * Mina.transaction(publicKey, ...); - * Mina.transaction({ sender: publicKey }, ...); - * - * // deprecated - * Mina.transaction(privateKey, ...); - * Mina.transaction({ feePayerKey: privateKey }, ...); - * ``` - */ -function transaction( - sender: DeprecatedFeePayerSpec, - f: () => Promise -): Promise; function transaction( - senderOrF: DeprecatedFeePayerSpec | (() => Promise), + senderOrF: FeePayerSpec | (() => Promise), fOrUndefined?: () => Promise ): Promise { - let sender: DeprecatedFeePayerSpec; + let sender: FeePayerSpec; let f: () => Promise; if (fOrUndefined !== undefined) { - sender = senderOrF as DeprecatedFeePayerSpec; + sender = senderOrF as FeePayerSpec; f = fOrUndefined; } else { sender = undefined; From 476ff8c8415045232473539a7096d6989441b265 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 17:34:39 +0100 Subject: [PATCH 03/20] remove deprecated APIs in account-uptate.ts and remove private key from lazy signature --- CHANGELOG.md | 2 +- .../internals/advanced-provable-types.ts | 5 +- src/examples/nullifier.ts | 4 +- src/examples/simple-zkapp.web.ts | 4 +- .../zkapps/simple-zkapp-with-proof.ts | 4 +- src/examples/zkapps/voting/demo.ts | 10 - src/examples/zkapps/voting/test.ts | 12 +- src/examples/zkapps/voting/voting-lib.ts | 6 +- src/index.ts | 1 - src/lib/account-update.ts | 171 ++++-------------- src/lib/provable-types/struct.unit-test.ts | 4 +- src/lib/zkapp.ts | 17 +- 12 files changed, 60 insertions(+), 180 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24cabe2919..4f61f053a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee` (use `Mina.getNetworkConstants().accountCreationFee`), `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers + - Remove `Mina.accountCreationFee` (use `Mina.getNetworkConstants().accountCreationFee`), `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol` - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/examples/internals/advanced-provable-types.ts b/src/examples/internals/advanced-provable-types.ts index bae47f1115..e771206359 100644 --- a/src/examples/internals/advanced-provable-types.ts +++ b/src/examples/internals/advanced-provable-types.ts @@ -21,10 +21,7 @@ console.log(`an account update has ${AccountUpdate.sizeInFields()} fields`); let address = PrivateKey.random().toPublicKey(); let accountUpdate = AccountUpdate.defaultAccountUpdate(address); accountUpdate.body.callDepth = 5; -accountUpdate.lazyAuthorization = { - kind: 'lazy-signature', - privateKey: PrivateKey.random(), -}; +accountUpdate.lazyAuthorization = { kind: 'lazy-signature' }; /** * Every provable type can be disassembled into its provable/in-circuit part (fields) diff --git a/src/examples/nullifier.ts b/src/examples/nullifier.ts index 5478bcd64f..11845eb8e2 100644 --- a/src/examples/nullifier.ts +++ b/src/examples/nullifier.ts @@ -75,13 +75,13 @@ console.log('deploy'); let tx = await Mina.transaction(sender, async () => { let senderUpdate = AccountUpdate.fundNewAccount(sender); senderUpdate.send({ to: zkappAddress, amount: initialBalance }); - await zkapp.deploy({ zkappKey }); + await zkapp.deploy(); zkapp.nullifierRoot.set(NullifierTree.getRoot()); zkapp.nullifierMessage.set(nullifierMessage); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([senderKey, zkappKey]).send(); console.log(`zkapp balance: ${zkapp.account.balance.get().div(1e9)} MINA`); diff --git a/src/examples/simple-zkapp.web.ts b/src/examples/simple-zkapp.web.ts index 9cd65b839d..2007df4d90 100644 --- a/src/examples/simple-zkapp.web.ts +++ b/src/examples/simple-zkapp.web.ts @@ -92,10 +92,10 @@ console.log('deploy'); let tx = await Mina.transaction(sender, async () => { let senderUpdate = AccountUpdate.fundNewAccount(sender); senderUpdate.send({ to: zkappAddress, amount: initialBalance }); - await zkapp.deploy({ zkappKey }); + await zkapp.deploy(); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([senderKey, zkappKey]).send(); console.log('initial state: ' + zkapp.x.get()); console.log(`initial balance: ${zkapp.account.balance.get().div(1e9)} MINA`); diff --git a/src/examples/zkapps/simple-zkapp-with-proof.ts b/src/examples/zkapps/simple-zkapp-with-proof.ts index 43c611f330..aa098a19ce 100644 --- a/src/examples/zkapps/simple-zkapp-with-proof.ts +++ b/src/examples/zkapps/simple-zkapp-with-proof.ts @@ -83,10 +83,10 @@ let zkapp = new NotSoSimpleZkapp(zkappAddress); console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy({ zkappKey }); + await zkapp.deploy(); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayerKey, zkappKey]).send(); console.log('initialize'); tx = await Mina.transaction(feePayer, async () => { diff --git a/src/examples/zkapps/voting/demo.ts b/src/examples/zkapps/voting/demo.ts index 1356fbce84..0a529e9eeb 100644 --- a/src/examples/zkapps/voting/demo.ts +++ b/src/examples/zkapps/voting/demo.ts @@ -93,7 +93,6 @@ tx = await Mina.transaction(feePayer, async () => { ); contracts.voting.voterRegistration(m); - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); await tx.sign([feePayerKey]).send(); @@ -113,8 +112,6 @@ tx = await Mina.transaction(feePayer, async () => { ); contracts.voting.voterRegistration(m); - - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); await tx.sign([feePayerKey]).send(); @@ -134,8 +131,6 @@ tx = await Mina.transaction(feePayer, async () => { ); contracts.voting.voterRegistration(m); - - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); await tx.sign([feePayerKey]).send(); @@ -169,7 +164,6 @@ tx = await Mina.transaction(feePayer, async () => { ); contracts.voting.candidateRegistration(m); - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); @@ -189,7 +183,6 @@ tx = await Mina.transaction(feePayer, async () => { ); contracts.voting.candidateRegistration(m); - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); @@ -232,7 +225,6 @@ console.log( tx = await Mina.transaction(feePayer, async () => { contracts.voting.approveRegistrations(); - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); @@ -268,7 +260,6 @@ tx = await Mina.transaction(feePayer, async () => { c.votesWitness = new MyMerkleWitness(votesStore.getWitness(0n)); // we are voting for candidate c, 0n, with voter 2n contracts.voting.vote(c, voterStore.get(2n)!); - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); @@ -288,7 +279,6 @@ console.log( */ tx = await Mina.transaction(feePayer, async () => { contracts.voting.countVotes(); - if (!params.doProofs) contracts.voting.sign(votingKey); }); await tx.prove(); diff --git a/src/examples/zkapps/voting/test.ts b/src/examples/zkapps/voting/test.ts index 3849a1f599..3e63c586ab 100644 --- a/src/examples/zkapps/voting/test.ts +++ b/src/examples/zkapps/voting/test.ts @@ -96,13 +96,15 @@ export async function testSet( await assertValidTx( true, async () => { - let vkUpdate = AccountUpdate.createSigned(params.votingKey); + let vkUpdate = AccountUpdate.createSigned( + params.votingKey.toPublicKey() + ); vkUpdate.account.verificationKey.set({ ...verificationKey, hash: Field(verificationKey.hash), }); }, - verificationKeySet.feePayer + [verificationKeySet.feePayer, params.votingKey] ); m = Member.from(PrivateKey.random().toPublicKey(), UInt64.from(15)); @@ -167,7 +169,9 @@ export async function testSet( await assertValidTx( true, async () => { - let permUpdate = AccountUpdate.createSigned(params.voterKey); + let permUpdate = AccountUpdate.createSigned( + params.voterKey.toPublicKey() + ); permUpdate.account.permissions.set({ ...Permissions.default(), @@ -175,7 +179,7 @@ export async function testSet( editActionState: Permissions.impossible(), }); }, - permissionedSet.feePayer + [permissionedSet.feePayer, params.voterKey] ); console.log('trying to invoke method with invalid permissions...'); diff --git a/src/examples/zkapps/voting/voting-lib.ts b/src/examples/zkapps/voting/voting-lib.ts index 818fdd15d7..ece6d5f03e 100644 --- a/src/examples/zkapps/voting/voting-lib.ts +++ b/src/examples/zkapps/voting/voting-lib.ts @@ -73,15 +73,17 @@ export function getResults( export async function assertValidTx( expectToBeValid: boolean, cb: () => Promise, - feePayer: PrivateKey, + signers: PrivateKey | [PrivateKey, ...PrivateKey[]], msg?: string ) { let failed = false; let err; + if (!Array.isArray(signers)) signers = [signers]; + let [feePayer] = signers; try { let tx = await Mina.transaction(feePayer.toPublicKey(), cb); await tx.prove(); - await tx.sign([feePayer]).send(); + await tx.sign(signers).send(); } catch (e: any) { failed = true; err = e; diff --git a/src/index.ts b/src/index.ts index 0c23cb7404..921c63e488 100644 --- a/src/index.ts +++ b/src/index.ts @@ -67,7 +67,6 @@ export { export { Cache, CacheHeader } from './lib/proof-system/cache.js'; export { - Token, TokenId, AccountUpdate, Permissions, diff --git a/src/lib/account-update.ts b/src/lib/account-update.ts index 7477c85a4b..dc4f9a376d 100644 --- a/src/lib/account-update.ts +++ b/src/lib/account-update.ts @@ -94,7 +94,6 @@ export { Events, Actions, TokenId, - Token, CallForest, zkAppProver, dummySignature, @@ -534,10 +533,7 @@ type Control = Types.AccountUpdate['authorization']; type LazyNone = { kind: 'lazy-none'; }; -type LazySignature = { - kind: 'lazy-signature'; - privateKey?: PrivateKey; -}; +type LazySignature = { kind: 'lazy-signature' }; type LazyProof = { kind: 'lazy-proof'; methodName: string; @@ -562,38 +558,6 @@ const TokenId = { }, }; -/** - * @deprecated use `TokenId` instead of `Token.Id` and `TokenId.derive()` instead of `Token.getId()` - */ -class Token { - static Id = TokenId; - - static getId(tokenOwner: PublicKey, parentTokenId = TokenId.default) { - return TokenId.derive(tokenOwner, parentTokenId); - } - - readonly id: Field; - readonly parentTokenId: Field; - readonly tokenOwner: PublicKey; - constructor({ - tokenOwner, - parentTokenId = TokenId.default, - }: { - tokenOwner: PublicKey; - parentTokenId?: Field; - }) { - this.parentTokenId = parentTokenId; - this.tokenOwner = tokenOwner; - try { - this.id = TokenId.derive(tokenOwner, parentTokenId); - } catch (e) { - throw new Error( - `Could not create a custom token id:\nError: ${(e as Error).message}` - ); - } - } -} - /** * An {@link AccountUpdate} is a set of instructions for the Mina network. * It includes {@link Preconditions} and a list of state updates, which need to @@ -651,19 +615,6 @@ class AccountUpdate implements Types.AccountUpdate { return this.body.tokenId; } - /** - * @deprecated use `this.account.tokenSymbol` - */ - get tokenSymbol() { - let accountUpdate = this; - - return { - set(tokenSymbol: string) { - accountUpdate.account.tokenSymbol.set(tokenSymbol); - }, - }; - } - send({ to, amount, @@ -827,12 +778,6 @@ class AccountUpdate implements Types.AccountUpdate { * be (can be) authorized by a signature. */ requireSignature() { - this.sign(); - } - /** - * @deprecated `.sign()` is deprecated in favor of `.requireSignature()` - */ - sign(privateKey?: PrivateKey) { let { nonce, isSameAsFeePayer } = AccountUpdate.getSigningInfo(this); // if this account is the same as the fee payer, we use the "full commitment" for replay protection this.body.useFullCommitment = isSameAsFeePayer; @@ -847,16 +792,13 @@ class AccountUpdate implements Types.AccountUpdate { this.body.preconditions.account.nonce.value.lower = lower; this.body.preconditions.account.nonce.value.upper = upper; // set lazy signature - Authorization.setLazySignature(this, { privateKey }); + Authorization.setLazySignature(this); } - static signFeePayerInPlace( - feePayer: FeePayerUnsigned, - privateKey?: PrivateKey - ) { + static signFeePayerInPlace(feePayer: FeePayerUnsigned) { feePayer.body.nonce = this.getNonce(feePayer); feePayer.authorization = dummySignature(); - feePayer.lazyAuthorization = { kind: 'lazy-signature', privateKey }; + feePayer.lazyAuthorization = { kind: 'lazy-signature' }; } static getNonce(accountUpdate: AccountUpdate | FeePayerUnsigned) { @@ -1077,24 +1019,13 @@ class AccountUpdate implements Types.AccountUpdate { * Note that an account's {@link Permissions} determine which updates have to * be (can be) authorized by a signature. */ - static createSigned(signer: PublicKey, tokenId?: Field): AccountUpdate; - /** - * @deprecated in favor of calling this function with a `PublicKey` as `signer` - */ - static createSigned(signer: PrivateKey, tokenId?: Field): AccountUpdate; - static createSigned(signer: PrivateKey | PublicKey, tokenId?: Field) { - let publicKey = - signer instanceof PrivateKey ? signer.toPublicKey() : signer; + static createSigned(publicKey: PublicKey, tokenId?: Field) { let accountUpdate = AccountUpdate.create(publicKey, tokenId); accountUpdate.label = accountUpdate.label.replace( '.create()', '.createSigned()' ); - if (signer instanceof PrivateKey) { - accountUpdate.sign(signer); - } else { - accountUpdate.requireSignature(); - } + accountUpdate.requireSignature(); return accountUpdate; } @@ -1109,32 +1040,11 @@ class AccountUpdate implements Types.AccountUpdate { * @param numberOfAccounts the number of new accounts to fund (default: 1) * @returns they {@link AccountUpdate} for the account which pays the fee */ - static fundNewAccount( - feePayer: PublicKey, - numberOfAccounts?: number - ): AccountUpdate; - /** - * @deprecated Call this function with a `PublicKey` as `feePayer`, and remove the `initialBalance` option. - * To send an initial balance to the new account, you can use the returned account update: - * ``` - * let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer); - * feePayerUpdate.send({ to: receiverAddress, amount: initialBalance }); - * ``` - */ - static fundNewAccount( - feePayer: PrivateKey | PublicKey, - options?: { initialBalance: number | string | UInt64 } | number - ): AccountUpdate; - static fundNewAccount( - feePayer: PrivateKey | PublicKey, - numberOfAccounts?: number | { initialBalance: number | string | UInt64 } - ) { - let accountUpdate = AccountUpdate.createSigned(feePayer as PrivateKey); + static fundNewAccount(feePayer: PublicKey, numberOfAccounts = 1) { + let accountUpdate = AccountUpdate.createSigned(feePayer); accountUpdate.label = 'AccountUpdate.fundNewAccount()'; let fee = activeInstance.getNetworkConstants().accountCreationFee; - numberOfAccounts ??= 1; - if (typeof numberOfAccounts === 'number') fee = fee.mul(numberOfAccounts); - else fee = fee.add(UInt64.from(numberOfAccounts.initialBalance ?? 0)); + fee = fee.mul(numberOfAccounts); accountUpdate.balance.subInPlace(fee); return accountUpdate; } @@ -1877,18 +1787,14 @@ const Authorization = { accountUpdate.lazyAuthorization = undefined; return accountUpdate as AccountUpdateProved; }, - setLazySignature( - accountUpdate: AccountUpdate, - signature?: Omit - ) { - signature ??= {}; + setLazySignature(accountUpdate: AccountUpdate) { accountUpdate.body.authorizationKind.isSigned = Bool(true); accountUpdate.body.authorizationKind.isProved = Bool(false); accountUpdate.body.authorizationKind.verificationKeyHash = Field( mocks.dummyVerificationKeyHash ); accountUpdate.authorization = {}; - accountUpdate.lazyAuthorization = { ...signature, kind: 'lazy-signature' }; + accountUpdate.lazyAuthorization = { kind: 'lazy-signature' }; }, setLazyNone(accountUpdate: AccountUpdate) { accountUpdate.body.authorizationKind.isSigned = Bool(false); @@ -1915,20 +1821,19 @@ function addMissingSignatures( let { body, authorization, lazyAuthorization } = cloneCircuitValue(accountUpdate); if (lazyAuthorization === undefined) return { body, authorization }; - let { privateKey } = lazyAuthorization; - if (privateKey === undefined) { - let i = additionalPublicKeys.findIndex((pk) => - pk.equals(accountUpdate.body.publicKey).toBoolean() - ); - if (i === -1) { - // private key is missing, but we are not throwing an error here - // there is a change signature will be added by the wallet - // if not, error will be thrown by verifyAccountUpdate - // while .send() execution - return { body, authorization: dummySignature() }; - } - privateKey = additionalKeys[i]; + + let i = additionalPublicKeys.findIndex((pk) => + pk.equals(accountUpdate.body.publicKey).toBoolean() + ); + if (i === -1) { + // private key is missing, but we are not throwing an error here + // there is a change signature will be added by the wallet + // if not, error will be thrown by verifyAccountUpdate + // while .send() execution + return { body, authorization: dummySignature() }; } + let privateKey = additionalKeys[i]; + let signature = signFieldElement( fullCommitment, privateKey.toBigInt(), @@ -1942,23 +1847,21 @@ function addMissingSignatures( if (accountUpdate.lazyAuthorization?.kind !== 'lazy-signature') { return accountUpdate as AccountUpdate & { lazyAuthorization?: LazyProof }; } - let { privateKey } = accountUpdate.lazyAuthorization; - if (privateKey === undefined) { - let i = additionalPublicKeys.findIndex((pk) => - pk.equals(accountUpdate.body.publicKey).toBoolean() - ); - if (i === -1) { - // private key is missing, but we are not throwing an error here - // there is a change signature will be added by the wallet - // if not, error will be thrown by verifyAccountUpdate - // while .send() execution - Authorization.setSignature(accountUpdate, dummySignature()); - return accountUpdate as AccountUpdate & { - lazyAuthorization: undefined; - }; - } - privateKey = additionalKeys[i]; + let i = additionalPublicKeys.findIndex((pk) => + pk.equals(accountUpdate.body.publicKey).toBoolean() + ); + if (i === -1) { + // private key is missing, but we are not throwing an error here + // there is a change signature will be added by the wallet + // if not, error will be thrown by verifyAccountUpdate + // while .send() execution + Authorization.setSignature(accountUpdate, dummySignature()); + return accountUpdate as AccountUpdate & { + lazyAuthorization: undefined; + }; } + let privateKey = additionalKeys[i]; + let transactionCommitment = accountUpdate.body.useFullCommitment.toBoolean() ? fullCommitment : commitment; diff --git a/src/lib/provable-types/struct.unit-test.ts b/src/lib/provable-types/struct.unit-test.ts index f3628b1bbb..98cbacf0fe 100644 --- a/src/lib/provable-types/struct.unit-test.ts +++ b/src/lib/provable-types/struct.unit-test.ts @@ -131,8 +131,6 @@ class MyContract extends SmartContract { // check if we can pass in account updates if (update.lazyAuthorization?.kind !== 'lazy-signature') throw Error(err); - if (update.lazyAuthorization.privateKey?.toBase58() !== key.toBase58()) - throw Error(err); // check if we can pass in unconstrained values if (unconstrained.get() !== targetBigint) throw Error(err); @@ -148,7 +146,7 @@ let address = key.toPublicKey(); let contract = new MyContract(address); let tx = await transaction(async () => { - let accountUpdate = AccountUpdate.createSigned(key); + let accountUpdate = AccountUpdate.createSigned(address); await contract.myMethod( { diff --git a/src/lib/zkapp.ts b/src/lib/zkapp.ts index eea39b9448..b9083e4c8e 100644 --- a/src/lib/zkapp.ts +++ b/src/lib/zkapp.ts @@ -695,10 +695,8 @@ class SmartContract extends SmartContractBase { */ async deploy({ verificationKey, - zkappKey, }: { verificationKey?: { data: string; hash: Field | string }; - zkappKey?: PrivateKey; } = {}) { let accountUpdate = this.newSelf('deploy'); verificationKey ??= (this.constructor as typeof SmartContract) @@ -718,7 +716,7 @@ class SmartContract extends SmartContractBase { let hash = Field.from(hash_); accountUpdate.account.verificationKey.set({ hash, data }); accountUpdate.account.permissions.set(Permissions.default()); - accountUpdate.sign(zkappKey); + accountUpdate.requireSignature(); AccountUpdate.attachToTransaction(accountUpdate); // init if this account is not yet deployed or has no verification key on it @@ -788,12 +786,7 @@ super.init(); requireSignature() { this.self.requireSignature(); } - /** - * @deprecated `this.sign()` is deprecated in favor of `this.requireSignature()` - */ - sign(zkappKey?: PrivateKey) { - this.self.sign(zkappKey); - } + /** * Use this command if the account update created by this SmartContract should have no authorization on it, * instead of being authorized with a proof. @@ -952,12 +945,6 @@ super.init(); return this.self.send(args); } - /** - * @deprecated use `this.account.tokenSymbol` - */ - get tokenSymbol() { - return this.self.tokenSymbol; - } /** * Balance of this {@link SmartContract}. */ From 738747df8acb60c4bd38e876be0e2677682cffb3 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 17:54:14 +0100 Subject: [PATCH 04/20] remove .token --- CHANGELOG.md | 2 +- src/lib/mina/token/token-methods.ts | 17 +-------- src/lib/token.test.ts | 55 +++++++++++++++-------------- src/lib/zkapp.ts | 12 ------- 4 files changed, 30 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f61f053a7..5040576621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee` (use `Mina.getNetworkConstants().accountCreationFee`), `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol` + - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.token` - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/mina/token/token-methods.ts b/src/lib/mina/token/token-methods.ts index 701bf36d36..58d96ca1f4 100644 --- a/src/lib/mina/token/token-methods.ts +++ b/src/lib/mina/token/token-methods.ts @@ -5,7 +5,7 @@ import type { SmartContract } from '../../zkapp.js'; import { UInt64 } from '../../int.js'; import { Bool, Field } from '../../core.js'; -export { tokenMethods, deprecatedToken }; +export { tokenMethods }; function tokenMethods(self: AccountUpdate) { return { @@ -95,18 +95,3 @@ function getApprovedUpdate( if (!child.label) child.label = `${self.label ?? 'Unlabeled'}.${label}`; return child; } - -// deprecated token interface for `SmartContract` - -function deprecatedToken(self: AccountUpdate) { - let tokenOwner = self.publicKey; - let parentTokenId = self.tokenId; - let id = TokenId.derive(tokenOwner, parentTokenId); - - return { - id, - parentTokenId, - tokenOwner, - ...tokenMethods(self), - }; -} diff --git a/src/lib/token.test.ts b/src/lib/token.test.ts index 4c0edc95bd..01c6c1751a 100644 --- a/src/lib/token.test.ts +++ b/src/lib/token.test.ts @@ -14,16 +14,22 @@ import { Field, Int64, TokenId, + TokenContract as TokenContractBase, + AccountUpdateForest, } from 'o1js'; const tokenSymbol = 'TOKEN'; -// TODO: Refactor to `TokenContract` +// TODO: Refactor to use `TokenContract.approveBase()` -class TokenContract extends SmartContract { +class TokenContract extends TokenContractBase { SUPPLY = UInt64.from(10n ** 18n); @state(UInt64) totalAmountInCirculation = State(); + async approveBase(_: AccountUpdateForest) { + throw Error('Not used'); + } + /** * This deploy method lets a another token account deploy their zkApp and verification key as a child of this token contract. * This is important since we want the native token id of the deployed zkApp to be the token id of the token contract. @@ -32,7 +38,7 @@ class TokenContract extends SmartContract { address: PublicKey, verificationKey: VerificationKey ) { - let tokenId = this.token.id; + let tokenId = this.deriveTokenId(); let zkapp = AccountUpdate.defaultAccountUpdate(address, tokenId); this.approve(zkapp); zkapp.account.permissions.set(Permissions.default()); @@ -43,13 +49,14 @@ class TokenContract extends SmartContract { init() { super.init(); let address = this.address; - let receiver = this.token.mint({ - address, - amount: this.SUPPLY, - }); - receiver.account.isNew.assertEquals(Bool(true)); + let receiver = this.internal.mint({ address, amount: this.SUPPLY }); + receiver.account.isNew.requireEquals(Bool(true)); this.balance.subInPlace(Mina.getNetworkConstants().accountCreationFee); this.totalAmountInCirculation.set(this.SUPPLY.sub(100_000_000)); + } + + async deploy() { + await super.deploy(); this.account.permissions.set({ ...Permissions.default(), editState: Permissions.proofOrSignature(), @@ -60,16 +67,13 @@ class TokenContract extends SmartContract { @method async mint(receiverAddress: PublicKey, amount: UInt64) { let totalAmountInCirculation = this.totalAmountInCirculation.get(); - this.totalAmountInCirculation.assertEquals(totalAmountInCirculation); + this.totalAmountInCirculation.requireEquals(totalAmountInCirculation); let newTotalAmountInCirculation = totalAmountInCirculation.add(amount); newTotalAmountInCirculation.value.assertLessThanOrEqual( this.SUPPLY.value, "Can't mint more than the total supply" ); - this.token.mint({ - address: receiverAddress, - amount, - }); + this.internal.mint({ address: receiverAddress, amount }); this.totalAmountInCirculation.set(newTotalAmountInCirculation); } @@ -81,10 +85,7 @@ class TokenContract extends SmartContract { UInt64.from(0).value, "Can't burn less than 0" ); - this.token.burn({ - address: receiverAddress, - amount, - }); + this.internal.burn({ address: receiverAddress, amount }); this.totalAmountInCirculation.set(newTotalAmountInCirculation); } @@ -97,7 +98,7 @@ class TokenContract extends SmartContract { this.approve(senderAccountUpdate); let negativeAmount = senderAccountUpdate.balanceChange; negativeAmount.assertEquals(Int64.from(amount).neg()); - let tokenId = this.token.id; + let tokenId = this.deriveTokenId(); senderAccountUpdate.body.tokenId.assertEquals(tokenId); senderAccountUpdate.body.publicKey.assertEquals(senderAddress); let receiverAccountUpdate = AccountUpdate.create(receiverAddress, tokenId); @@ -151,7 +152,7 @@ function setupAccounts() { tokenZkappAddress = tokenZkappKey.toPublicKey(); tokenZkapp = new TokenContract(tokenZkappAddress); - tokenId = tokenZkapp.token.id; + tokenId = tokenZkapp.deriveTokenId(); zkAppBKey = Local.testAccounts[1].privateKey; zkAppBAddress = zkAppBKey.toPublicKey(); @@ -166,12 +167,12 @@ function setupAccounts() { async function setupLocal() { setupAccounts(); let tx = await Mina.transaction(feePayer, async () => { + await tokenZkapp.deploy(); let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer); feePayerUpdate.send({ - to: tokenZkappAddress, + to: tokenZkapp.self, amount: Mina.getNetworkConstants().accountCreationFee, }); - await tokenZkapp.deploy(); }); tx.sign([tokenZkappKey, feePayerKey]); await tx.send(); @@ -183,12 +184,12 @@ async function setupLocalProofs() { // don't use proofs for the setup, takes too long to do this every time Local.setProofsEnabled(false); let tx = await Mina.transaction({ sender: feePayer }, async () => { + await tokenZkapp.deploy(); let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 3); feePayerUpdate.send({ - to: tokenZkappAddress, + to: tokenZkapp.self, amount: Mina.getNetworkConstants().accountCreationFee, }); - await tokenZkapp.deploy(); await tokenZkapp.deployZkapp(zkAppBAddress, ZkAppB._verificationKey!); await tokenZkapp.deployZkapp(zkAppCAddress, ZkAppC._verificationKey!); }); @@ -358,7 +359,7 @@ describe('Token', () => { tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - tokenZkapp.token.send({ + tokenZkapp.internal.send({ from: zkAppBAddress, to: zkAppCAddress, amount: UInt64.from(10_000), @@ -389,7 +390,7 @@ describe('Token', () => { .send(); let tx = ( await Mina.transaction(feePayer, async () => { - tokenZkapp.token.send({ + tokenZkapp.internal.send({ from: zkAppBAddress, to: zkAppCAddress, amount: UInt64.from(10_000), @@ -414,7 +415,7 @@ describe('Token', () => { .send(); let tx = ( await Mina.transaction(feePayer, async () => { - tokenZkapp.token.send({ + tokenZkapp.internal.send({ from: zkAppBAddress, to: zkAppCAddress, amount: UInt64.from(100_000), @@ -578,7 +579,7 @@ describe('Token', () => { test('should reject tx if user bypasses the token contract by using an empty account update', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - tokenZkapp.token.mint({ + tokenZkapp.internal.mint({ address: zkAppBAddress, amount: UInt64.from(100_000), }); diff --git a/src/lib/zkapp.ts b/src/lib/zkapp.ts index b9083e4c8e..58721967f3 100644 --- a/src/lib/zkapp.ts +++ b/src/lib/zkapp.ts @@ -68,8 +68,6 @@ import { accountUpdateLayout, smartContractContext, } from './mina/smart-contract-context.js'; -import { deprecatedToken } from './mina/token/token-methods.js'; -import type { TokenContract } from './mina/token/token-contract.js'; import { assertPromise } from './util/assert.js'; import { ProvablePure } from './provable-types/provable-intf.js'; @@ -902,16 +900,6 @@ super.init(); get currentSlot() { return this.self.currentSlot; } - /** - * @deprecated - * `SmartContract.token` will be removed, and token methods will only be available on `TokenContract.internal`. - * Instead of `SmartContract.token.id`, use `TokenContract.deriveTokenId()`. - * - * For security reasons, it is recommended to use {@link TokenContract} as the base contract for all tokens. - */ - get token() { - return deprecatedToken(this.self); - } /** * Approve an account update or tree / forest of updates. Doing this means you include the account update in the zkApp's public input, From 11cac967abd936b68d7d38d963b9848ee9ad69e0 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 17:57:06 +0100 Subject: [PATCH 05/20] remove remaining deprecated stuff in zkapp.ts --- CHANGELOG.md | 2 +- src/lib/zkapp.ts | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5040576621..1c24927364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.token` + - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}` - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/zkapp.ts b/src/lib/zkapp.ts index 58721967f3..33135d6c92 100644 --- a/src/lib/zkapp.ts +++ b/src/lib/zkapp.ts @@ -1154,20 +1154,6 @@ super.init(); } return methodMetadata; } - - /** - * @deprecated use `this.account..set()` - */ - setValue(maybeValue: SetOrKeep, value: T) { - AccountUpdate.setValue(maybeValue, value); - } - - /** - * @deprecated use `this.account.permissions.set()` - */ - setPermissions(permissions: Permissions) { - this.self.account.permissions.set(permissions); - } } type Reducer = { From d6ec3a2b14741cc34985b5c89079f2bc5c67feb1 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:06:04 +0100 Subject: [PATCH 06/20] remove assert* for preconditions --- src/lib/precondition.test.ts | 129 +---------------------------------- src/lib/precondition.ts | 88 ++---------------------- src/lib/state.ts | 26 +------ src/lib/token.test.ts | 8 +-- 4 files changed, 8 insertions(+), 243 deletions(-) diff --git a/src/lib/precondition.test.ts b/src/lib/precondition.test.ts index 7692807552..0cf906e9d3 100644 --- a/src/lib/precondition.test.ts +++ b/src/lib/precondition.test.ts @@ -57,21 +57,6 @@ describe('preconditions', () => { await expect(() => MyContract.compile()).rejects.toThrow('precondition'); }); - it('get + assertEquals should not throw', async () => { - let nonce = zkapp.account.nonce.get(); - let tx = await Mina.transaction(feePayer, async () => { - zkapp.requireSignature(); - for (let precondition of implemented) { - let p = precondition().get(); - precondition().assertEquals(p as any); - } - AccountUpdate.attachToTransaction(zkapp.self); - }); - await tx.sign([feePayerKey, zkappKey]).send(); - // check that tx was applied, by checking nonce was incremented - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); - }); - it('get + requireEquals should not throw', async () => { let nonce = zkapp.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { @@ -87,18 +72,6 @@ describe('preconditions', () => { expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); - it('get + assertEquals should throw for unimplemented fields', async () => { - for (let precondition of unimplemented) { - await expect( - Mina.transaction(feePayer, async () => { - let p = precondition(); - p.assertEquals(p.get() as any); - AccountUpdate.attachToTransaction(zkapp.self); - }) - ).rejects.toThrow(/not implemented/); - } - }); - it('get + requireEquals should throw for unimplemented fields', async () => { for (let precondition of unimplemented) { await expect( @@ -111,21 +84,6 @@ describe('preconditions', () => { } }); - it('get + assertBetween should not throw', async () => { - let nonce = zkapp.account.nonce.get(); - let tx = await Mina.transaction(feePayer, async () => { - for (let precondition of implementedWithRange) { - let p: any = precondition().get(); - precondition().assertBetween(p.constructor.zero, p); - } - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await tx.sign([feePayerKey, zkappKey]).send(); - // check that tx was applied, by checking nonce was incremented - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); - }); - it('get + requireBetween should not throw', async () => { let nonce = zkapp.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { @@ -141,20 +99,6 @@ describe('preconditions', () => { expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); - it('satisfied currentSlot.assertBetween should not throw', async () => { - let nonce = zkapp.account.nonce.get(); - let tx = await Mina.transaction(feePayer, async () => { - zkapp.currentSlot.assertBetween( - UInt32.from(0), - UInt32.from(UInt32.MAXINT()) - ); - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await tx.sign([feePayerKey, zkappKey]).send(); - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); - }); - it('satisfied currentSlot.requireBetween should not throw', async () => { let nonce = zkapp.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { @@ -169,21 +113,6 @@ describe('preconditions', () => { expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); - it('get + assertNothing should not throw', async () => { - let nonce = zkapp.account.nonce.get(); - let tx = await Mina.transaction(feePayer, async () => { - for (let precondition of implemented) { - precondition().get(); - precondition().assertNothing(); - } - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await tx.sign([feePayerKey, zkappKey]).send(); - // check that tx was applied, by checking nonce was incremented - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); - }); - it('get + requireNothing should not throw', async () => { let nonce = zkapp.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { @@ -226,19 +155,6 @@ describe('preconditions', () => { expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); - it('unsatisfied assertEquals should be rejected (numbers)', async () => { - for (let precondition of implementedNumber) { - await expect(async () => { - let tx = await Mina.transaction(feePayer, async () => { - let p = precondition().get(); - precondition().assertEquals(p.add(1) as any); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await tx.sign([feePayerKey]).send(); - }).rejects.toThrow(/unsatisfied/); - } - }); - it('unsatisfied requireEquals should be rejected (numbers)', async () => { for (let precondition of implementedNumber) { await expect(async () => { @@ -252,19 +168,6 @@ describe('preconditions', () => { } }); - it('unsatisfied assertEquals should be rejected (booleans)', async () => { - for (let precondition of implementedBool) { - let tx = await Mina.transaction(feePayer, async () => { - let p = precondition().get(); - precondition().assertEquals(p.not()); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow( - /unsatisfied/ - ); - } - }); - it('unsatisfied requireEquals should be rejected (booleans)', async () => { for (let precondition of implementedBool) { let tx = await Mina.transaction(feePayer, async () => { @@ -278,15 +181,6 @@ describe('preconditions', () => { } }); - it('unsatisfied assertEquals should be rejected (public key)', async () => { - let publicKey = PublicKey.from({ x: Field(-1), isOdd: Bool(false) }); - let tx = await Mina.transaction(feePayer, async () => { - zkapp.account.delegate.assertEquals(publicKey); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow(/unsatisfied/); - }); - it('unsatisfied requireEquals should be rejected (public key)', async () => { let publicKey = PublicKey.from({ x: Field(-1), isOdd: Bool(false) }); let tx = await Mina.transaction(feePayer, async () => { @@ -296,19 +190,6 @@ describe('preconditions', () => { await expect(tx.sign([feePayerKey]).send()).rejects.toThrow(/unsatisfied/); }); - it('unsatisfied assertBetween should be rejected', async () => { - for (let precondition of implementedWithRange) { - let tx = await Mina.transaction(feePayer, async () => { - let p: any = precondition().get(); - precondition().assertBetween(p.add(20), p.add(30)); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow( - /unsatisfied/ - ); - } - }); - it('unsatisfied requireBetween should be rejected', async () => { for (let precondition of implementedWithRange) { let tx = await Mina.transaction(feePayer, async () => { @@ -322,14 +203,6 @@ describe('preconditions', () => { } }); - it('unsatisfied currentSlot.assertBetween should be rejected', async () => { - let tx = await Mina.transaction(feePayer, async () => { - zkapp.currentSlot.assertBetween(UInt32.from(20), UInt32.from(30)); - AccountUpdate.attachToTransaction(zkapp.self); - }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow(/unsatisfied/); - }); - it('unsatisfied currentSlot.requireBetween should be rejected', async () => { let tx = await Mina.transaction(feePayer, async () => { zkapp.currentSlot.requireBetween(UInt32.from(20), UInt32.from(30)); @@ -343,7 +216,7 @@ describe('preconditions', () => { // however, this is just because `zkapp.sign()` overwrites the nonce precondition with one that is satisfied it.skip('unsatisfied nonce precondition should be rejected', async () => { let tx = await Mina.transaction(feePayer, async () => { - zkapp.account.nonce.assertEquals(UInt32.from(1e8)); + zkapp.account.nonce.requireEquals(UInt32.from(1e8)); zkapp.requireSignature(); AccountUpdate.attachToTransaction(zkapp.self); }); diff --git a/src/lib/precondition.ts b/src/lib/precondition.ts index 0b685a5490..0f57b426aa 100644 --- a/src/lib/precondition.ts +++ b/src/lib/precondition.ts @@ -99,34 +99,6 @@ const uint32 = () => ({ lower: UInt32.from(0), upper: UInt32.MAXINT() }); */ const uint64 = () => ({ lower: UInt64.from(0), upper: UInt64.MAXINT() }); -/** - * Fix a property to a certain value. - * - * @param property The property to constrain - * @param value The value it is fixed to - * - * Example: To fix the account nonce of a SmartContract to 0, you can use - * - * ```ts - * \@method onlyRunsWhenNonceIsZero() { - * AccountUpdate.assertEquals(this.self.body.preconditions.account.nonce, UInt32.zero); - * // ... - * } - * ``` - */ -function assertEquals( - property: OrIgnore | T>, - value: T -) { - property.isSome = Bool(true); - if ('lower' in property.value && 'upper' in property.value) { - property.value.lower = value; - property.value.upper = value; - } else { - property.value = value; - } -} - type AccountPrecondition = Preconditions['account']; const AccountPrecondition = { ignoreAll(): AccountPrecondition { @@ -145,11 +117,6 @@ const AccountPrecondition = { isNew: ignore(Bool(false)), }; }, - nonce(nonce: UInt32): AccountPrecondition { - let p = AccountPrecondition.ignoreAll(); - assertEquals(p.nonce, nonce); - return p; - }, }; type GlobalSlotPrecondition = Preconditions['validWhile']; @@ -200,9 +167,6 @@ function Network(accountUpdate: AccountUpdate): Network { let slot = network.globalSlotSinceGenesis.getAndRequireEquals(); return globalSlotToTimestamp(slot); }, - getAndAssertEquals() { - return this.getAndRequireEquals(); - }, requireEquals(value: UInt64) { let { genesisTimestamp, slotTime } = Mina.getNetworkConstants(); let slot = timestampToGlobalSlot( @@ -212,9 +176,6 @@ function Network(accountUpdate: AccountUpdate): Network { ); return network.globalSlotSinceGenesis.requireEquals(slot); }, - assertEquals(value: UInt64) { - return this.requireEquals(value); - }, requireBetween(lower: UInt64, upper: UInt64) { let [slotLower, slotUpper] = timestampToGlobalSlotRange(lower, upper); return network.globalSlotSinceGenesis.requireBetween( @@ -222,15 +183,9 @@ function Network(accountUpdate: AccountUpdate): Network { slotUpper ); }, - assertBetween(lower: UInt64, upper: UInt64) { - return this.requireBetween(lower, upper); - }, requireNothing() { return network.globalSlotSinceGenesis.requireNothing(); }, - assertNothing() { - return this.requireNothing(); - }, }; return { ...network, timestamp }; } @@ -287,9 +242,6 @@ function CurrentSlot(accountUpdate: AccountUpdate): CurrentSlot { property.value.lower = lower; property.value.upper = upper; }, - assertBetween(lower: UInt32, upper: UInt32) { - this.requireBetween(lower, upper); - }, }; } @@ -367,9 +319,6 @@ function preconditionSubClassWithRange< property.value.lower = lower; property.value.upper = upper; }, - assertBetween(lower: any, upper: any) { - this.requireBetween(lower, upper); - }, }; } @@ -404,9 +353,6 @@ function preconditionSubclass< obj.requireEquals(value); return value; }, - getAndAssertEquals() { - return this.getAndRequireEquals(); - }, requireEquals(value: U) { context.constrained.add(longKey); let property = getPath( @@ -425,9 +371,6 @@ function preconditionSubclass< setPath(accountUpdate.body.preconditions, longKey, value); } }, - assertEquals(value: U) { - this.requireEquals(value); - }, requireNothing() { let property = getPath( accountUpdate.body.preconditions, @@ -438,9 +381,6 @@ function preconditionSubclass< } context.constrained.add(longKey); }, - assertNothing() { - this.requireNothing(); - }, }; return obj; } @@ -578,14 +518,14 @@ function assertPreconditionInvariants(accountUpdate: AccountUpdate) { if (!circuitValueEquals(precondition, dummy)) continue; // we accessed a precondition field but not constrained it explicitly - throw an error - let hasAssertBetween = isRangeCondition(precondition); + let hasRequireBetween = isRangeCondition(precondition); let shortPath = preconditionPath.split('.').pop(); let errorMessage = `You used \`${self}.${preconditionPath}.get()\` without adding a precondition that links it to the actual ${shortPath}. Consider adding this line to your code: -${self}.${preconditionPath}.assertEquals(${self}.${preconditionPath}.get());${ - hasAssertBetween +${self}.${preconditionPath}.requireEquals(${self}.${preconditionPath}.get());${ + hasRequireBetween ? ` -You can also add more flexible preconditions with \`${self}.${preconditionPath}.assertBetween(...)\`.` +You can also add more flexible preconditions with \`${self}.${preconditionPath}.requireBetween(...)\`.` : '' }`; throw Error(errorMessage); @@ -617,10 +557,6 @@ type Account = PreconditionClassType & Update; type CurrentSlotPrecondition = Preconditions['validWhile']; type CurrentSlot = { requireBetween(lower: UInt32, upper: UInt32): void; - /** - * @deprecated use `requireBetween(lower: UInt32, upper: UInt32)` which is equivalent - */ - assertBetween(lower: UInt32, upper: UInt32): void; }; type PreconditionBaseTypes = { @@ -636,27 +572,11 @@ type PreconditionBaseTypes = { type PreconditionSubclassType = { get(): U; getAndRequireEquals(): U; - /** - * @deprecated use `getAndRequireEquals()` which is equivalent - */ - getAndAssertEquals(): U; requireEquals(value: U): void; - /** - * @deprecated use `requireEquals(value: U)` which is equivalent - */ - assertEquals(value: U): void; requireNothing(): void; - /** - * @deprecated use `requireNothing()` which is equivalent - */ - assertNothing(): void; }; type PreconditionSubclassRangeType = PreconditionSubclassType & { requireBetween(lower: U, upper: U): void; - /** - * @deprecated use `requireBetween(lower: U, upper: U)` which is equivalent - */ - assertBetween(lower: U, upper: U): void; }; type PreconditionClassType = { diff --git a/src/lib/state.ts b/src/lib/state.ts index 82dff11c25..b57cfc31d0 100644 --- a/src/lib/state.ts +++ b/src/lib/state.ts @@ -41,10 +41,6 @@ type State = { * by adding a precondition which the verifying Mina node will check before accepting this transaction. */ getAndRequireEquals(): A; - /** - * @deprecated use `this.state.getAndRequireEquals()` which is equivalent - */ - getAndAssertEquals(): A; /** * Set the on-chain state to a new value. */ @@ -58,18 +54,10 @@ type State = { * by adding a precondition which the verifying Mina node will check before accepting this transaction. */ requireEquals(a: A): void; - /** - * @deprecated use `this.state.requireEquals()` which is equivalent - */ - assertEquals(a: A): void; /** * **DANGER ZONE**: Override the error message that warns you when you use `.get()` without adding a precondition. */ requireNothing(): void; - /** - * @deprecated use `this.state.requireNothing()` which is equivalent - */ - assertNothing(): void; /** * Get the state from the raw list of field elements on a zkApp account, for example: * @@ -232,10 +220,6 @@ function createState(): InternalStateType { this._contract.wasConstrained = true; }, - assertEquals(state: T) { - this.requireEquals(state); - }, - requireNothing() { if (this._contract === undefined) throw Error( @@ -244,10 +228,6 @@ function createState(): InternalStateType { this._contract.wasConstrained = true; }, - assertNothing() { - this.requireNothing(); - }, - get() { if (this._contract === undefined) throw Error( @@ -320,10 +300,6 @@ function createState(): InternalStateType { return state; }, - getAndAssertEquals() { - return this.getAndRequireEquals(); - }, - async fetch() { if (this._contract === undefined) throw Error( @@ -417,7 +393,7 @@ function assertStatePrecondition(sc: SmartContract) { // we accessed a precondition field but not constrained it explicitly - throw an error let errorMessage = `You used \`this.${key}.get()\` without adding a precondition that links it to the actual on-chain state. Consider adding this line to your code: -this.${key}.assertEquals(this.${key}.get());`; +this.${key}.requireEquals(this.${key}.get());`; throw Error(errorMessage); } } finally { diff --git a/src/lib/token.test.ts b/src/lib/token.test.ts index 01c6c1751a..eafa963a35 100644 --- a/src/lib/token.test.ts +++ b/src/lib/token.test.ts @@ -78,13 +78,9 @@ class TokenContract extends TokenContractBase { } @method async burn(receiverAddress: PublicKey, amount: UInt64) { - let totalAmountInCirculation = this.totalAmountInCirculation.get(); - this.totalAmountInCirculation.assertEquals(totalAmountInCirculation); + let totalAmountInCirculation = + this.totalAmountInCirculation.getAndRequireEquals(); let newTotalAmountInCirculation = totalAmountInCirculation.sub(amount); - totalAmountInCirculation.value.assertGreaterThanOrEqual( - UInt64.from(0).value, - "Can't burn less than 0" - ); this.internal.burn({ address: receiverAddress, amount }); this.totalAmountInCirculation.set(newTotalAmountInCirculation); } From ecfdad00fca0767acb06243c10c812813212e998 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:10:59 +0100 Subject: [PATCH 07/20] remove deprecated stuff on MerkleTree and Scalar --- CHANGELOG.md | 2 +- src/lib/provable-types/merkle-tree.ts | 27 ++------------------------- src/lib/scalar.ts | 7 ------- 3 files changed, 3 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c24927364..f45274e228 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}` + - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/provable-types/merkle-tree.ts b/src/lib/provable-types/merkle-tree.ts index 7f1b8a7a87..6bb3197644 100644 --- a/src/lib/provable-types/merkle-tree.ts +++ b/src/lib/provable-types/merkle-tree.ts @@ -11,7 +11,7 @@ import { Provable } from '../provable.js'; export { Witness, MerkleTree, MerkleWitness, BaseMerkleWitness }; // internal API -export { maybeSwap, maybeSwapBad }; +export { maybeSwap }; type Witness = { isLeft: boolean; sibling: Field }[]; @@ -194,23 +194,6 @@ class BaseMerkleWitness extends CircuitValue { return hash; } - /** - * Calculates a root depending on the leaf value. - * @deprecated This is a less efficient version of {@link calculateRoot} which was added for compatibility with existing deployed contracts - */ - calculateRootSlow(leaf: Field): Field { - let hash = leaf; - let n = this.height(); - - for (let i = 1; i < n; ++i) { - let isLeft = this.isLeft[i - 1]; - const [left, right] = maybeSwapBad(isLeft, hash, this.path[i - 1]); - hash = Poseidon.hash([left, right]); - } - - return hash; - } - /** * Calculates the index of the leaf node that belongs to this Witness. * @returns Index of the leaf. @@ -243,13 +226,7 @@ function MerkleWitness(height: number): typeof BaseMerkleWitness { return MerkleWitness_; } -function maybeSwapBad(b: Bool, x: Field, y: Field): [Field, Field] { - const x_ = Provable.if(b, x, y); // y + b*(x - y) - const y_ = Provable.if(b, y, x); // x + b*(y - x) - return [x_, y_]; -} - -// more efficient version of `maybeSwapBad` which reuses an intermediate variable +// more efficient than 2x `Provable.if()` by reusing an intermediate variable function maybeSwap(b: Bool, x: Field, y: Field): [Field, Field] { let m = b.toField().mul(x.sub(y)); // b*(x - y) const x_ = y.add(m); // y + b*(x - y) diff --git a/src/lib/scalar.ts b/src/lib/scalar.ts index deea9a4163..fa5a03b222 100644 --- a/src/lib/scalar.ts +++ b/src/lib/scalar.ts @@ -79,13 +79,6 @@ class Scalar { return new Scalar([0, ...constBits]) as ConstantScalar; } - /** - * @deprecated use {@link Scalar.from} - */ - static fromBigInt(x: bigint) { - return Scalar.from(x); - } - /** * Convert this {@link Scalar} into a bigint */ From 559364dc47d2d91d695bd7fb1e3cc9ffd9e8bd56 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:13:36 +0100 Subject: [PATCH 08/20] fixup --- src/lib/provable-types/merkle-tree.unit-test.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/lib/provable-types/merkle-tree.unit-test.ts b/src/lib/provable-types/merkle-tree.unit-test.ts index 05d6f0f028..ea2d4620c4 100644 --- a/src/lib/provable-types/merkle-tree.unit-test.ts +++ b/src/lib/provable-types/merkle-tree.unit-test.ts @@ -1,15 +1,10 @@ import { Bool, Field } from '../core.js'; -import { maybeSwap, maybeSwapBad } from './merkle-tree.js'; +import { maybeSwap } from './merkle-tree.js'; import { Random, test } from '../testing/property.js'; import { expect } from 'expect'; test(Random.bool, Random.field, Random.field, (b, x, y) => { let [x0, y0] = maybeSwap(Bool(!!b), Field(x), Field(y)); - let [x1, y1] = maybeSwapBad(Bool(!!b), Field(x), Field(y)); - - // both versions of `maybeSwap` should behave the same - expect(x0).toEqual(x1); - expect(y0).toEqual(y1); // if the boolean is true, it shouldn't swap the fields; otherwise, it should if (b) { From 872ceeee0477a47861d4647f0d4876a5d91874ee Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:15:00 +0100 Subject: [PATCH 09/20] fixup --- src/examples/zkapps/voting/membership.ts | 4 ++-- src/examples/zkapps/voting/voting.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/examples/zkapps/voting/membership.ts b/src/examples/zkapps/voting/membership.ts index 5bed4e3012..78c8ee947b 100644 --- a/src/examples/zkapps/voting/membership.ts +++ b/src/examples/zkapps/voting/membership.ts @@ -159,7 +159,7 @@ export class Membership_ extends SmartContract { this.committedMembers.requireEquals(committedMembers); return member.witness - .calculateRootSlow(member.getHash()) + .calculateRoot(member.getHash()) .equals(committedMembers); } @@ -195,7 +195,7 @@ export class Membership_ extends SmartContract { // otherwise, we simply return the unmodified state - this is our way of branching return Provable.if( isRealMember, - action.witness.calculateRootSlow(action.getHash()), + action.witness.calculateRoot(action.getHash()), state ); }, diff --git a/src/examples/zkapps/voting/voting.ts b/src/examples/zkapps/voting/voting.ts index 87d2bc9c9c..e1bf0b189c 100644 --- a/src/examples/zkapps/voting/voting.ts +++ b/src/examples/zkapps/voting/voting.ts @@ -283,7 +283,7 @@ export class Voting_ extends SmartContract { // apply one vote action = action.addVote(); // this is the new root after we added one vote - return action.votesWitness.calculateRootSlow(action.getHash()); + return action.votesWitness.calculateRoot(action.getHash()); }, // initial state { state: committedVotes, actionState: accumulatedVotes } From f016e9dc3d511f0bcd930c0edd94661c42ca563d Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:15:16 +0100 Subject: [PATCH 10/20] remove lt, assertLt etc --- CHANGELOG.md | 2 +- src/lib/int.ts | 181 ------------------------------------------- src/lib/signature.ts | 10 +-- 3 files changed, 5 insertions(+), 188 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f45274e228..07aa1e4628 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, + - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/int.ts b/src/lib/int.ts index eb9ad9d547..430bb82c72 100644 --- a/src/lib/int.ts +++ b/src/lib/int.ts @@ -395,34 +395,6 @@ class UInt64 extends CircuitValue { return new UInt64(Bitwise.and(this.value, x.value, UInt64.NUM_BITS).value); } - /** - * @deprecated Use {@link lessThanOrEqual} instead. - * - * Checks if a {@link UInt64} is less than or equal to another one. - */ - lte(y: UInt64) { - if (this.value.isConstant() && y.value.isConstant()) { - return Bool(this.value.toBigInt() <= y.value.toBigInt()); - } else { - let xMinusY = this.value.sub(y.value).seal(); - let yMinusX = xMinusY.neg(); - - let xMinusYFits = RangeCheck.isDefinitelyInRangeN( - UInt64.NUM_BITS, - xMinusY - ); - - let yMinusXFits = RangeCheck.isDefinitelyInRangeN( - UInt64.NUM_BITS, - yMinusX - ); - - xMinusYFits.or(yMinusXFits).assertEquals(true); - // x <= y if y - x fits in 64 bits - return yMinusXFits; - } - } - /** * Checks if a {@link UInt64} is less than or equal to another one. */ @@ -449,15 +421,6 @@ class UInt64 extends CircuitValue { } } - /** - * @deprecated Use {@link assertLessThanOrEqual} instead. - * - * Asserts that a {@link UInt64} is less than or equal to another one. - */ - assertLte(y: UInt64, message?: string) { - this.assertLessThanOrEqual(y, message); - } - /** * Asserts that a {@link UInt64} is less than or equal to another one. */ @@ -475,15 +438,6 @@ class UInt64 extends CircuitValue { RangeCheck.rangeCheckN(UInt64.NUM_BITS, yMinusX, message); } - /** - * @deprecated Use {@link lessThan} instead. - * - * Checks if a {@link UInt64} is less than another one. - */ - lt(y: UInt64) { - return this.lessThanOrEqual(y).and(this.value.equals(y.value).not()); - } - /** * * Checks if a {@link UInt64} is less than another one. @@ -492,16 +446,6 @@ class UInt64 extends CircuitValue { return this.lessThanOrEqual(y).and(this.value.equals(y.value).not()); } - /** - * - * @deprecated Use {@link assertLessThan} instead. - * - * Asserts that a {@link UInt64} is less than another one. - */ - assertLt(y: UInt64, message?: string) { - this.lessThan(y).assertEquals(true, message); - } - /** * Asserts that a {@link UInt64} is less than another one. */ @@ -509,15 +453,6 @@ class UInt64 extends CircuitValue { this.lessThan(y).assertEquals(true, message); } - /** - * @deprecated Use {@link greaterThan} instead. - * - * Checks if a {@link UInt64} is greater than another one. - */ - gt(y: UInt64) { - return y.lessThan(this); - } - /** * Checks if a {@link UInt64} is greater than another one. */ @@ -525,15 +460,6 @@ class UInt64 extends CircuitValue { return y.lessThan(this); } - /** - * @deprecated Use {@link assertGreaterThan} instead. - * - * Asserts that a {@link UInt64} is greater than another one. - */ - assertGt(y: UInt64, message?: string) { - y.assertLessThan(this, message); - } - /** * Asserts that a {@link UInt64} is greater than another one. */ @@ -541,15 +467,6 @@ class UInt64 extends CircuitValue { y.assertLessThan(this, message); } - /** - * @deprecated Use {@link greaterThanOrEqual} instead. - * - * Checks if a {@link UInt64} is greater than or equal to another one. - */ - gte(y: UInt64) { - return this.lessThan(y).not(); - } - /** * Checks if a {@link UInt64} is greater than or equal to another one. */ @@ -557,15 +474,6 @@ class UInt64 extends CircuitValue { return this.lessThan(y).not(); } - /** - * @deprecated Use {@link assertGreaterThanOrEqual} instead. - * - * Asserts that a {@link UInt64} is greater than or equal to another one. - */ - assertGte(y: UInt64, message?: string) { - y.assertLessThanOrEqual(this, message); - } - /** * Asserts that a {@link UInt64} is greater than or equal to another one. */ @@ -938,31 +846,6 @@ class UInt32 extends CircuitValue { return new UInt32(Bitwise.and(this.value, x.value, UInt32.NUM_BITS).value); } - /** - * @deprecated Use {@link lessThanOrEqual} instead. - * - * Checks if a {@link UInt32} is less than or equal to another one. - */ - lte(y: UInt32) { - if (this.value.isConstant() && y.value.isConstant()) { - return Bool(this.value.toBigInt() <= y.value.toBigInt()); - } else { - let xMinusY = this.value.sub(y.value).seal(); - let yMinusX = xMinusY.neg(); - let xMinusYFits = RangeCheck.isDefinitelyInRangeN( - UInt32.NUM_BITS, - xMinusY - ); - let yMinusXFits = RangeCheck.isDefinitelyInRangeN( - UInt32.NUM_BITS, - yMinusX - ); - xMinusYFits.or(yMinusXFits).assertEquals(true); - // x <= y if y - x fits in 64 bits - return yMinusXFits; - } - } - /** * Checks if a {@link UInt32} is less than or equal to another one. */ @@ -986,15 +869,6 @@ class UInt32 extends CircuitValue { } } - /** - * @deprecated Use {@link assertLessThanOrEqual} instead. - * - * Asserts that a {@link UInt32} is less than or equal to another one. - */ - assertLte(y: UInt32, message?: string) { - this.assertLessThanOrEqual(y, message); - } - /** * Asserts that a {@link UInt32} is less than or equal to another one. */ @@ -1012,15 +886,6 @@ class UInt32 extends CircuitValue { RangeCheck.rangeCheckN(UInt32.NUM_BITS, yMinusX, message); } - /** - * @deprecated Use {@link lessThan} instead. - * - * Checks if a {@link UInt32} is less than another one. - */ - lt(y: UInt32) { - return this.lessThanOrEqual(y).and(this.value.equals(y.value).not()); - } - /** * Checks if a {@link UInt32} is less than another one. */ @@ -1028,15 +893,6 @@ class UInt32 extends CircuitValue { return this.lessThanOrEqual(y).and(this.value.equals(y.value).not()); } - /** - * @deprecated Use {@link assertLessThan} instead. - * - * Asserts that a {@link UInt32} is less than another one. - */ - assertLt(y: UInt32, message?: string) { - this.lessThan(y).assertEquals(true, message); - } - /** * Asserts that a {@link UInt32} is less than another one. */ @@ -1044,15 +900,6 @@ class UInt32 extends CircuitValue { this.lessThan(y).assertEquals(true, message); } - /** - * @deprecated Use {@link greaterThan} instead. - * - * Checks if a {@link UInt32} is greater than another one. - */ - gt(y: UInt32) { - return y.lessThan(this); - } - /** * Checks if a {@link UInt32} is greater than another one. */ @@ -1060,15 +907,6 @@ class UInt32 extends CircuitValue { return y.lessThan(this); } - /** - * @deprecated Use {@link assertGreaterThan} instead. - * - * Asserts that a {@link UInt32} is greater than another one. - */ - assertGt(y: UInt32, message?: string) { - y.assertLessThan(this, message); - } - /** * Asserts that a {@link UInt32} is greater than another one. */ @@ -1076,15 +914,6 @@ class UInt32 extends CircuitValue { y.assertLessThan(this, message); } - /** - * @deprecated Use {@link greaterThanOrEqual} instead. - * - * Checks if a {@link UInt32} is greater than or equal to another one. - */ - gte(y: UInt32) { - return this.lessThan(y).not(); - } - /** * Checks if a {@link UInt32} is greater than or equal to another one. */ @@ -1092,16 +921,6 @@ class UInt32 extends CircuitValue { return this.lessThan(y).not(); } - /** - * @deprecated Use {@link assertGreaterThanOrEqual} instead. - - * - * Asserts that a {@link UInt32} is greater than or equal to another one. - */ - assertGte(y: UInt32, message?: string) { - y.assertLessThanOrEqual(this, message); - } - /** * Asserts that a {@link UInt32} is greater than or equal to another one. */ diff --git a/src/lib/signature.ts b/src/lib/signature.ts index e652ccd7bb..3a41920a15 100644 --- a/src/lib/signature.ts +++ b/src/lib/signature.ts @@ -256,7 +256,7 @@ class Signature extends CircuitValue { // we chose an arbitrary prefix for the signature, and it happened to be 'testnet' // there's no consequences in practice and the signatures can be used with any network // if there needs to be a custom nonce, include it in the message itself - const kPrime = Scalar.fromBigInt( + const kPrime = Scalar.from( deriveNonce( { fields: msg.map((f) => f.toBigInt()) }, { x: publicKey.x.toBigInt(), y: publicKey.y.toBigInt() }, @@ -320,16 +320,14 @@ class Signature extends CircuitValue { // performs scalar multiplication s*G assuming that instead of s, we got s' = 2s + 1 + 2^255 // cost: 2x scale by constant, 1x scale by variable function scaleShifted(point: Group, shiftedScalar: Scalar) { - let oneHalfGroup = point.scale(Scalar.fromBigInt(oneHalf)); - let shiftGroup = oneHalfGroup.scale(Scalar.fromBigInt(shift)); + let oneHalfGroup = point.scale(Scalar.from(oneHalf)); + let shiftGroup = oneHalfGroup.scale(Scalar.from(shift)); return oneHalfGroup.scale(shiftedScalar).sub(shiftGroup); } // returns s, assuming that instead of s, we got s' = 2s + 1 + 2^255 // (only works out of snark) function unshift(shiftedScalar: Scalar) { - return shiftedScalar - .sub(Scalar.fromBigInt(shift)) - .mul(Scalar.fromBigInt(oneHalf)); + return shiftedScalar.sub(Scalar.from(shift)).mul(Scalar.from(oneHalf)); } let shift = Fq.mod(1n + 2n ** 255n); From 7c66479ef27cc75efd58465a067eb22067ae6daf Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:17:20 +0100 Subject: [PATCH 11/20] remove static methods on group --- CHANGELOG.md | 2 +- src/lib/group.ts | 73 -------------------------------------------- src/lib/nullifier.ts | 2 +- 3 files changed, 2 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07aa1e4628..9d4a1ab35f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, + - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group` - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/group.ts b/src/lib/group.ts index f80782070a..ad016cdd72 100644 --- a/src/lib/group.ts +++ b/src/lib/group.ts @@ -268,79 +268,6 @@ class Group { return new Group({ x, y }); } - /** - * @deprecated Please use the method `.add` on the instance instead - * - * Adds a {@link Group} element to another one. - */ - static add(g1: Group, g2: Group) { - return g1.add(g2); - } - - /** - * @deprecated Please use the method `.sub` on the instance instead - * - * Subtracts a {@link Group} element from another one. - */ - static sub(g1: Group, g2: Group) { - return g1.sub(g2); - } - - /** - * @deprecated Please use the method `.neg` on the instance instead - * - * Negates a {@link Group} element. Under the hood, it simply negates the `y` coordinate and leaves the `x` coordinate as is. - * - * ```typescript - * let gNeg = Group.neg(g); - * ``` - */ - static neg(g: Group) { - return g.neg(); - } - - /** - * @deprecated Please use the method `.scale` on the instance instead - * - * Elliptic curve scalar multiplication. Scales a {@link Group} element `n`-times by itself, where `n` is the {@link Scalar}. - * - * ```typescript - * let s = Scalar(5); - * let 5g = Group.scale(g, s); - * ``` - */ - static scale(g: Group, s: Scalar) { - return g.scale(s); - } - - /** - * @deprecated Please use the method `.assertEqual` on the instance instead. - * - * Assert that two {@link Group} elements are equal to another. - * Throws an error if the assertion fails. - * - * ```ts - * Group.assertEquals(g1, g2); - * ``` - */ - static assertEqual(g1: Group, g2: Group) { - g1.assertEquals(g2); - } - - /** - * @deprecated Please use the method `.equals` on the instance instead. - * - * Checks if a {@link Group} element is equal to another {@link Group} element. - * Returns a {@link Bool}. - * - * ```ts - * Group.equal(g1, g2); // Bool(true) - * ``` - */ - static equal(g1: Group, g2: Group) { - return g1.equals(g2); - } - /** * Part of the {@link Provable} interface. * diff --git a/src/lib/nullifier.ts b/src/lib/nullifier.ts index 3604cb8962..d8a217f030 100644 --- a/src/lib/nullifier.ts +++ b/src/lib/nullifier.ts @@ -76,7 +76,7 @@ class Nullifier extends Struct({ let g_r = G.scale(s).sub(pk_c); // h(m, pk)^s - let h_m_pk_s = Group.scale(h_m_pk, s); + let h_m_pk_s = h_m_pk.scale(s); // h_m_pk_r = h(m,pk)^s / nullifier^c let h_m_pk_s_div_nullifier_s = h_m_pk_s.sub( From 2243346dcb9aa82771014b881606d8d28232ea41 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:19:02 +0100 Subject: [PATCH 12/20] remove utility methods on Circuit --- CHANGELOG.md | 2 +- src/examples/nullifier.ts | 3 ++- src/lib/circuit.ts | 55 --------------------------------------- 3 files changed, 3 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d4a1ab35f..4ac51dcda7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group` + - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if` - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/examples/nullifier.ts b/src/examples/nullifier.ts index 11845eb8e2..9693583dcf 100644 --- a/src/examples/nullifier.ts +++ b/src/examples/nullifier.ts @@ -11,6 +11,7 @@ import { MerkleMapWitness, Mina, AccountUpdate, + Provable, } from 'o1js'; class PayoutOnlyOnce extends SmartContract { @@ -24,7 +25,7 @@ class PayoutOnlyOnce extends SmartContract { // verify the nullifier nullifier.verify([nullifierMessage]); - let nullifierWitness = Circuit.witness(MerkleMapWitness, () => + let nullifierWitness = Provable.witness(MerkleMapWitness, () => NullifierTree.getWitness(nullifier.key()) ); diff --git a/src/lib/circuit.ts b/src/lib/circuit.ts index 3b209aec57..c47d2baf51 100644 --- a/src/lib/circuit.ts +++ b/src/lib/circuit.ts @@ -83,61 +83,6 @@ class Circuit { ) ); } - - // utility namespace, moved to `Provable` - - /** - * @deprecated use {@link Provable.witness} - */ - static witness = Provable.witness; - /** - * @deprecated use {@link Provable.asProver} - */ - static asProver = Provable.asProver; - /** - * @deprecated use {@link Provable.runAndCheck} - */ - static runAndCheck = Provable.runAndCheck; - /** - * @deprecated use {@link Provable.runUnchecked} - */ - static runUnchecked = Provable.runUnchecked; - /** - * @deprecated use {@link Provable.constraintSystem} - */ - static constraintSystem = Provable.constraintSystem; - /** - * @deprecated use {@link Provable.Array} - */ - static array = Provable.Array; - /** - * @deprecated use {@link Provable.assertEqual} - */ - static assertEqual = Provable.assertEqual; - /** - * @deprecated use {@link Provable.equal} - */ - static equal = Provable.equal; - /** - * @deprecated use {@link Provable.if} - */ - static if = Provable.if; - /** - * @deprecated use {@link Provable.switch} - */ - static switch = Provable.switch; - /** - * @deprecated use {@link Provable.inProver} - */ - static inProver = Provable.inProver; - /** - * @deprecated use {@link Provable.inCheckedComputation} - */ - static inCheckedComputation = Provable.inCheckedComputation; - /** - * @deprecated use {@link Provable.log} - */ - static log = Provable.log; } class Keypair { From 21db5c94ab287143f9705b9f1a5f92402e438daf Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:45:59 +0100 Subject: [PATCH 13/20] remove Field.isZero() and improve constraints used by equals() --- CHANGELOG.md | 2 +- src/lib/field.ts | 55 ++++------ src/lib/signature.ts | 2 +- tests/vk-regression/vk-regression.json | 138 ++++++++++++------------- 4 files changed, 92 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ac51dcda7..b42a751d4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if` + - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if`, `Field.isZero()` - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) diff --git a/src/lib/field.ts b/src/lib/field.ts index 54e9e56459..510ff568b6 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -511,32 +511,6 @@ class Field { return z; } - /** - * @deprecated use `x.equals(0)` which is equivalent - */ - isZero() { - if (this.isConstant()) { - return new Bool(this.toBigInt() === 0n); - } - // create witnesses z = 1/x, or z=0 if x=0, - // and b = 1 - zx - let [b, z] = exists(2, () => { - let x = this.toBigInt(); - let z = Fp.inverse(x) ?? 0n; - let b = Fp.sub(1n, Fp.mul(z, x)); - return [b, z]; - }); - // add constraints - // b * x === 0 - assertMul(b, this, FieldVar[0]); - // z * x === 1 - b - assertMul(z, this, new Field(1).sub(b)); - // ^^^ these prove that b = Bool(x === 0): - // if x = 0, the 2nd equation implies b = 1 - // if x != 0, the 1st implies b = 0 - return Bool.Unsafe.fromField(b); - } - /** * Check if this {@link Field} is equal another "field-like" value. * Returns a {@link Bool}, which is a provable type and can be used to prove the validity of this statement. @@ -551,16 +525,29 @@ class Field { * @return A {@link Bool} representing if this {@link Field} is equal another "field-like" value. */ equals(y: Field | bigint | number | string): Bool { - // x == y is equivalent to x - y == 0 - // if one of the two is constant, we just need the two constraints in `isZero` - if (this.isConstant() || isConstant(y)) { - return this.sub(y).isZero(); + if (this.isConstant() && isConstant(y)) { + return new Bool(this.toBigInt() === toFp(y)); } - // if both are variables, we create one new variable for x-y so that `isZero` doesn't create two - let z = existsOne(() => Fp.sub(this.toBigInt(), toFp(y))); - this.sub(y).assertEquals(z); + // x == y is equivalent to x - y == 0 + let xMinusY = this.sub(y).seal(); - return z.isZero(); + // create witnesses z = 1/(x-y), or z=0 if x=y, + // and b = 1 - z(x-y) + let [b, z] = exists(2, () => { + let xmy = xMinusY.toBigInt(); + let z = Fp.inverse(xmy) ?? 0n; + let b = Fp.sub(1n, Fp.mul(z, xmy)); + return [b, z]; + }); + // add constraints + // b * (x-y) === 0 + assertMul(b, xMinusY, FieldVar[0]); + // z * (x-y) === 1 - b + assertMul(z, xMinusY, new Field(1).sub(b)); + // ^^^ these prove that b = Bool(x === y): + // if x = y, the 2nd equation implies b = 1 + // if x != y, the 1st implies b = 0 + return Bool.Unsafe.fromField(b); } /** diff --git a/src/lib/signature.ts b/src/lib/signature.ts index 3a41920a15..0462ce7820 100644 --- a/src/lib/signature.ts +++ b/src/lib/signature.ts @@ -190,7 +190,7 @@ class PublicKey extends CircuitValue { */ isEmpty() { // there are no curve points with x === 0 - return this.x.isZero(); + return this.x.equals(0); } /** diff --git a/tests/vk-regression/vk-regression.json b/tests/vk-regression/vk-regression.json index 45eee51c92..580bcd6294 100644 --- a/tests/vk-regression/vk-regression.json +++ b/tests/vk-regression/vk-regression.json @@ -1,115 +1,115 @@ { "Voting_": { - "digest": "3c75d3509d7717e33cff7e94489d8f60082ac11f7f808e10a64f703a1d096d4a", + "digest": "2689d97f83b58006eafcc9d34fefe448b969ac539a11daa4f8ee1b423594d3cc", "methods": { "voterRegistration": { - "rows": 1186, - "digest": "0edc4cddcd4513771935fb6a712add18" + "rows": 1185, + "digest": "e0a6026956ebde7c5325337742f8e0ef" }, "candidateRegistration": { - "rows": 1186, - "digest": "8c83b537e3dab168c4aa2c00b90e5f2a" + "rows": 1185, + "digest": "7eeeade1a032912a69a802c8299c2ab0" }, "approveRegistrations": { - "rows": 1148, - "digest": "08b40e8d2a9ea7369c371afd2e4e1f54" + "rows": 1146, + "digest": "f45b6638b6d99e13a7c1c05c42959286" }, "vote": { - "rows": 1527, - "digest": "259e561fb1ade3c15fedcafb7da09c87" + "rows": 1526, + "digest": "303bd21763794fcabcbe78e1bf9858a8" }, "countVotes": { - "rows": 5796, - "digest": "49bedc90e4f9004081a7cf4ec1890691" + "rows": 5732, + "digest": "9948fac874c0a5ae19ef9a3a0fec0641" } }, "verificationKey": { - "data": "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", - "hash": "24656492245991446483604357639740051536117166623025096114760294586080473547383" + "data": "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", + "hash": "28740323451263376422147195980826831705287136279743929447998060058715271242374" } }, "Membership_": { - "digest": "39966549192610ffae8df962a0f868c4079b75133664ffc710c03669724e0b8d", + "digest": "2b55770d1d71587f20baf1b7344d4fd685c04e622e0dc5890599c40a08653f67", "methods": { "addEntry": { "rows": 5530, - "digest": "db5487ca29e8e519022e1caa25fd4bcf" + "digest": "33c262bc1f79c053b99befb2534b67a5" }, "isMember": { - "rows": 433, - "digest": "8ac29f5a178a401e243e206c62dfbfaf" + "rows": 430, + "digest": "ee720ff45036c454d44980304de39821" }, "publish": { - "rows": 694, - "digest": "5c39ad497d024b86cf7b76b50cf14d6e" + "rows": 690, + "digest": "f903e5aec7a377eb3d4693681a585c0c" } }, "verificationKey": { - "data": "AACwuS3vTWCwpRIX/QlJQqJcmPO9nPm4+sCfcrqiY1NUMiV9k6Pc8kFkMsbGLst78T8uAnYwc1Ql49kq0I2GizwshS9xkBcfxRTAAMBHXhf8KDkK39AalVocKIrfWMV0MSShinj0bCxPCc10K0cya4Voy8fud4+hktDOuwjaAstpEJSbKRHMIki77xHmJWlFUYdkgPg30MU4Ta3ev/h+mcMWmofyhLSQqUbaV6hM95n3Y0Wcn2LRNxJP8TRwHndIcylleqPsGMh3P+A+N9c32N4kl29nreMJJdcUrCXK90GLPAFOB9mHIjKk9+9o3eZc3cGQ+jppXoN3zwO91DeT/GYvXqCZTAudLxIwuJU11UBThG5CKKABa9ulQ1bYGXj9Eydy0vPxfojDeFrnKMi9GKSjiSMzmOLbIw7Dt+g9ggjsHM5rPrT7dY1VV4ZT9shjlcX3029xnk3Bjz4Q9PiK+A8o6f7L6aVB07I+QY2iDtwSQWuXYPohrk85I1UbPfY+giWqFXBtHaN45PMWCyBx0TKaozETCmv0kA5KGTzesYQCECPQ8F2DM+oXz8xly+z9/Ypt/Zx9NvF7wute/1s6Q/QuAEn3HRvRYob/rqf780WfKDu+k76Fsg+6v8noW+VgHKEqvQ2wtI7e9UFi6tQdfVbXiNqzU6pIxEMLj883nrdAESy2vXswFt90jphf6jgLtFJULrvKVg+YCMNM/04QLTGcMmjjzv4LciQ6IVXth7zhVKxfL1/2peC0r/ZrP8k+Ox4LEBXWMCQE5kfK476bQgrLeKJfQ45PZfgB688DGwaYAxWbcxBV822/aAsA55ijFY1Xf7S+DiytY4a/u0bellKMDUQqTOq9VwmbDv868zXscUwKpNVR3wy2En/q9M/HJJc4BZyuuQvlQSR59m0gL4hKHf5Dci/YVvM6ACHmg+5SxCr1pUNKbyy2lsIa5Ma40ZmsTpT4/lQczmGENQSQXA9bFibT0Q+Vj885p9heLOCCXyAujC4DhAdYmT1MQ7v4IxckCGN+inX+IWc319TSYGDOIBaq190jE73i5abLSm65/A2r2QQnHYnQwWqRN41wFMgVP2ZM6W9SsDya39rzKsaHC4Ec0cHZ5v5KfCuZbV6OevmxpnN3Z/bf0MQ/eBEKmSEZXVleg/umK6tM0I3naZlj8T9BJf6wMEDFxDwMXCupoyP6l24QrqQAp0ebGEbpXqv21bhlr6dYBsculE2VU9SuGJ2g6yuuKf4+lfJ2V5TkIxFvlgw5cxTXNQ010JYug38++ZDV+MibXPzg+cODE5wfZ3jon5wVNkAiG642DzXzNj67x80zBWLdt3UKnFZs9dpa1fYpTjlJg8T+dnJJiKf2IvmvF8xyi1HAwAFyhDL2dn/w/pDE2Kl9QdpZpQYDEBQgCCkegsZszQ+2mjxU9pLXzz5GSoqz8jABW5Qo3abBAhvYKKaAs6NoRgeAD6SadFDbQmXaftE+Y1MVOtjnaZDUBdwahWiJMlkfZpxW1aubEc/GSX8WzCZ8h9HeakcRc7kcN0CR8kmfER3eiZ2JMbt5cQl/afNjwGGAmeXzTaR34AgFjiw/RlZJkhYm9jyf18M8yP94QGBMxd6Y6wrNvOmJHzEnp8aitJsDlZklm8LKbjumlSbLcbBokpIDhFBBKfwP2qsQX7eHLCZ/3mztoFKoIiYXgrHWG8m2SzIJ/ljn6Rg7AxIsPjzZyEw1eXAOC7A1FCT/757ygMsnk+rLlpDTBYLmhJtQdt61MQFDi5BuCmQ/PY9C/74/k4APl5htiNcCZty/1JElFwjuCQFjvAiMPUMyqp7/ALFapsTZqhSs1g6jd8uhuJoTNEqLDvKUUbs0kMvGy8BOG0YXNxmNccabGwBzxmijv6LF/Xinecl4aD8FCh6opY98TJnOHd3XSYL1DbLqmmc6CXEM+g5iDGnXr/CkI2Jy37OkF8X03jz4AH0Yj0+J63yH4IS+PrNpKZEXKh7PvXNaLGGKsFcKEi63/xKPKH0G4RzvFKbkp+IWqtIYjMiwIJMwzmfS1NLLXqqpFiD364eFcXINR2rrDKcoTUp1JkVZVfXfKwaRUPWSGFYIYMtwPh2w8ZfubAmXZFpyzstORhFyg9rtVAAy0lcDhQwWVlhFFkR2qbdoy0EFLBrfKqUIkd1N6vDQQYL1RGaTAv/ybregrJsFo+VP3ZatlR6LnKYWp1m7vPkGm3I6Pus/mvp1k10QGk8nhFuR31DjsG3lzZ4gXSs1oSv0qbxD2S6g5+Y6cPbITEGX3uQjsunXnQ9PHd22Mk+fqbDakTiCJh6aFqqPNShiAXkGSuC1oXJHX3zqnbn75dWO0UVhBNAbjYkSnQeyka1wnZb12sR+PlRMvWQVcd93t5L/FiE0ORo=", - "hash": "1783504200634090470775115883157449184948497438713557884110780778068634660997" + "data": "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", + "hash": "11864595870972429594206763162880715769401569611732858380593514182351096465840" } }, "HelloWorld": { - "digest": "103e8bd9af45de70a1b214377e71bd05ae464e932dbe48aeada70362fa38b05", + "digest": "375389fb51cab85f4cd4ce965dd53c2c90bb4dbf9daf5fe7f7aa009001a2a56d", "methods": { "update": { - "rows": 825, - "digest": "226ff56f432f39d8056bf7f1813669f5" + "rows": 824, + "digest": "8e3d96b838937437c386dd13d307a7d2" } }, "verificationKey": { - "data": "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", - "hash": "21868179330353774930881761197110482602042218337984430556708224781269131363222" + "data": "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", + "hash": "415559726899752466798349869887051584660923621395325655695487627339344362000" } }, "TokenContract": { - "digest": "1680d3e1357a466f906621af00d830f99b6128c5f51cf0373202620d4f6cd00d", + "digest": "1b6f6a3f11849a744203489adac62c4ac269a248093051832876edb144cf5d7e", "methods": { "init": { - "rows": 655, - "digest": "d535a589774b32cd36e2d6c3707afd30" + "rows": 654, + "digest": "0db2ee938d14cb43cfc0c4bc00c71c19" }, "init2": { - "rows": 652, - "digest": "4a781d299f945218e93f3d9235549373" + "rows": 651, + "digest": "e7895ef127423660c309d32b313741fa" }, "approveBase": { - "rows": 13243, - "digest": "ee62642f33120ab6db94da2eb1d726c9" + "rows": 13232, + "digest": "f9218123446ce86c1e984c60e9ea281c" } }, "verificationKey": { - "data": "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", - "hash": "8925803295369202411953053433348085915894172555008342243993322619248448379055" + "data": "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", + "hash": "16423344550474109119494361006460789489686824199242402624882213958195502853131" } }, "Dex": { - "digest": "1066ac3218b2f3060a9cda82daa7ff2e0b4071a4528a52ebd7b1bb21d5c419d", + "digest": "20164a4e8a983a8b6501f376ab7c0c6976e9af8054a12011b5811ea6b46caf9b", "methods": { "approveBase": { - "rows": 13243, - "digest": "ee62642f33120ab6db94da2eb1d726c9" + "rows": 13232, + "digest": "f9218123446ce86c1e984c60e9ea281c" }, "supplyLiquidityBase": { - "rows": 2856, - "digest": "69358bfab9d197e2f3ea1d658cb7fa20" + "rows": 2854, + "digest": "f76a1e9435c07f973bfcaf6a3c32e5ca" }, "swapX": { - "rows": 1513, - "digest": "a080a34bacf8c4a843d7355f9b69304c" + "rows": 1512, + "digest": "6bb063e61e00cd2ba44f5ff5f6882664" }, "swapY": { - "rows": 1513, - "digest": "4100b3543afd76189c879487c4b4f4a4" + "rows": 1512, + "digest": "ec6048a8d607a20b67eff8c67b42872a" }, "burnLiquidity": { - "rows": 705, - "digest": "04af7e1cbe986869743e78b468a13501" + "rows": 704, + "digest": "cd0def1f453d302bb5b33ff9253bee82" } }, "verificationKey": { - "data": "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", - "hash": "25039693596333908117154819221126656892469551802975690923144441585724891963362" + "data": "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", + "hash": "27861428472680659480582730203195071400017645299496499672708746624076239406640" } }, "Group Primitive": { @@ -212,29 +212,29 @@ } }, "ecdsa-only": { - "digest": "2a2beadf929015559514abb88dd77694dbe62a6a5904e5a9d05ab21a3f293c0c", + "digest": "39205ab5c3c80677719cb409d9b798a8f07dd71fde09cef6d59719bd37ecc739", "methods": { "verifySignedHash": { - "rows": 28186, - "digest": "dd43cd30a8277b5af02fd85a4762a488" + "rows": 28182, + "digest": "e75305f0564b7d2a8d5373c4c4b4f45d" } }, "verificationKey": { - "data": "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", - "hash": "16626558875595050675741741208497473516532634598762284173771479275503819571624" + "data": "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", + "hash": "24251722424479837874260221363500409460039706763291687811835114093949142046847" } }, "ecdsa": { - "digest": "2f78a9c0307e6f9c6872499c3ca7c412f5771a7ac7e7e88c351ed1b62d6ac408", + "digest": "15029f011b1ee3a18dac72dff097e9ad244b112c4e928f6dd0231dbd792c2e7c", "methods": { "verifyEcdsa": { - "rows": 42684, - "digest": "2bb042b0fa7bbbb32f7e77d392f43d2c" + "rows": 42680, + "digest": "645fe57449b2f3a8a6715de6a33c897d" } }, "verificationKey": { - "data": "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", - "hash": "13907522711254991952405567976395529829664716172124500348498751038796408381729" + "data": "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", + "hash": "28215601045091561251986150549207635700837312049267319716641606207490091416721" } }, "sha256": { @@ -251,23 +251,23 @@ } }, "diverse": { - "digest": "384e7eb44f1ad3b899aae057c48a9eab8ad72c8120ef13a1e906c91b93028828", + "digest": "1ef8986e905c798250a4072628aa5e52f3ac71e41eef87f7488a384703bb2f29", "methods": { "ecdsa": { - "rows": 28186, - "digest": "962fef399c0999d49427817cbf35f34d" + "rows": 28182, + "digest": "1c069d8ca01c3a3aad1c83ea8fc0fa64" }, "generic": { - "rows": 7, - "digest": "1496e5b8cc253c9909551a25c190ab85" + "rows": 6, + "digest": "c23e00e466878466ae8ab23bde562792" }, "pallas": { - "rows": 1610, - "digest": "0ff5537aae21b4d47b8c901aa5e71007" + "rows": 1609, + "digest": "c06c8da9154f40356aac829c9f90753f" }, "poseidon": { - "rows": 947, - "digest": "4ff5a55f56bca18bc4c12f0806e5efa4" + "rows": 946, + "digest": "6f90b741fcc6dbfd4e297bfd56a1c179" }, "recursive": { "rows": 0, @@ -279,8 +279,8 @@ } }, "verificationKey": { - "data": "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", - "hash": "25099125262785569464008872277824954042674175732318382315709475361977342159172" + "data": "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", + "hash": "21073713073974678425291625894317209524148583158680099308251167711500330246765" } } } \ No newline at end of file From 86c3a41e6ca845ffb9c34d29bfdeedce05bb8f70 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 18:48:44 +0100 Subject: [PATCH 14/20] comment --- src/lib/field.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/field.ts b/src/lib/field.ts index 510ff568b6..5f832e269f 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -528,6 +528,9 @@ class Field { if (this.isConstant() && isConstant(y)) { return new Bool(this.toBigInt() === toFp(y)); } + // TODO: this wastes a constraint on `xMinusY` if one of them is constant + // to fix, make assertMul() smart about constant terms and only `seal()` if the two inputs are both variables + // x == y is equivalent to x - y == 0 let xMinusY = this.sub(y).seal(); From 00fbaf7f03cce28339832374067a8f8afd8426a3 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 19:01:40 +0100 Subject: [PATCH 15/20] remove isReady and shutdown --- src/examples/circuit-string.ts | 10 +--------- src/examples/encoding-bijective.ts | 5 +---- src/examples/encryption.ts | 11 +---------- src/examples/fetch.ts | 5 ----- src/examples/simple-zkapp.js | 6 ------ src/examples/zkapps/local-events-zkapp.ts | 4 ---- src/index.ts | 13 ------------- src/lib/hash-input.unit-test.ts | 5 ----- src/lib/mina.unit-test.ts | 2 -- src/lib/primitives.test.ts | 13 +------------ src/lib/provable-types/merkle-map.test.ts | 9 +-------- src/lib/provable-types/merkle-tree.test.ts | 16 +--------------- src/lib/provable-types/string.test.ts | 13 +------------ .../javascript/on-chain-state-mgmt-zkapp-ui.js | 11 +---------- 14 files changed, 8 insertions(+), 115 deletions(-) diff --git a/src/examples/circuit-string.ts b/src/examples/circuit-string.ts index a16f9d4ebf..c48ac339d0 100644 --- a/src/examples/circuit-string.ts +++ b/src/examples/circuit-string.ts @@ -1,11 +1,4 @@ -import { - isReady, - CircuitString, - SmartContract, - method, - Mina, - PrivateKey, -} from 'o1js'; +import { CircuitString, SmartContract, method, Mina, PrivateKey } from 'o1js'; import * as assert from 'assert/strict'; // circuit which tests a couple of string features @@ -19,7 +12,6 @@ class MyContract extends SmartContract { } } -await isReady; let address = PrivateKey.random().toPublicKey(); console.log('compile...'); diff --git a/src/examples/encoding-bijective.ts b/src/examples/encoding-bijective.ts index 6e1ad318c8..789baa8740 100644 --- a/src/examples/encoding-bijective.ts +++ b/src/examples/encoding-bijective.ts @@ -1,6 +1,5 @@ -import { Field, isReady, shutdown, Encoding } from 'o1js'; +import { Field, Encoding } from 'o1js'; -await isReady; let n = 1000; let { toBytes, fromBytes } = Encoding.Bijective.Fp; @@ -21,8 +20,6 @@ let bytesEqual = arrayEqual([...bytes], [...newBytes]); if (!bytesEqual) throw Error('roundtrip bytes -> fields -> bytes failed'); else console.log('bytes -> fields -> bytes: ok'); -shutdown(); - function arrayEqual(a: T[], b: T[], isEqual?: (a: T, b: T) => boolean) { if (isEqual === undefined) isEqual = (a, b) => a === b; if (a.length !== b.length) return false; diff --git a/src/examples/encryption.ts b/src/examples/encryption.ts index e6c0b84d7c..74107e49d9 100644 --- a/src/examples/encryption.ts +++ b/src/examples/encryption.ts @@ -1,13 +1,4 @@ -import { - Encryption, - Encoding, - PrivateKey, - isReady, - Circuit, - Provable, -} from 'o1js'; - -await isReady; +import { Encryption, Encoding, PrivateKey, Provable } from 'o1js'; // generate keys let privateKey = PrivateKey.random(); diff --git a/src/examples/fetch.ts b/src/examples/fetch.ts index 4b71cbf8a0..87fece718d 100644 --- a/src/examples/fetch.ts +++ b/src/examples/fetch.ts @@ -1,14 +1,11 @@ import { fetchAccount, - isReady, setGraphqlEndpoints, - shutdown, fetchLastBlock, PublicKey, Types, } from 'o1js'; -await isReady; setGraphqlEndpoints([ 'https://proxy.berkeley.minaexplorer.com/graphql', 'https://berkeley.minascan.io/graphql', @@ -25,5 +22,3 @@ console.log('account', Types.Account.toJSON(account!)); let block = await fetchLastBlock(); console.log('last block', JSON.stringify(block, null, 2)); - -await shutdown(); diff --git a/src/examples/simple-zkapp.js b/src/examples/simple-zkapp.js index a5c79990d9..108fd0913a 100644 --- a/src/examples/simple-zkapp.js +++ b/src/examples/simple-zkapp.js @@ -10,14 +10,10 @@ import { SmartContract, Mina, AccountUpdate, - isReady, declareState, declareMethods, - shutdown, } from 'o1js'; -await isReady; - class SimpleZkapp extends SmartContract { constructor(address) { super(address); @@ -72,5 +68,3 @@ tx = await Mina.transaction(feePayer, () => zkapp.update(Field(3))); await tx.prove(); await tx.sign([feePayerKey]).send(); console.log('final state: ' + zkapp.x.get()); - -shutdown(); diff --git a/src/examples/zkapps/local-events-zkapp.ts b/src/examples/zkapps/local-events-zkapp.ts index 38d1bf490b..e3daf2b574 100644 --- a/src/examples/zkapps/local-events-zkapp.ts +++ b/src/examples/zkapps/local-events-zkapp.ts @@ -3,12 +3,10 @@ import { state, State, method, - UInt64, PrivateKey, SmartContract, Mina, AccountUpdate, - isReady, UInt32, PublicKey, Struct, @@ -16,8 +14,6 @@ import { const doProofs = false; -await isReady; - class Event extends Struct({ pub: PublicKey, value: Field }) {} class SimpleZkapp extends SmartContract { diff --git a/src/index.ts b/src/index.ts index 921c63e488..b9fb2cb520 100644 --- a/src/index.ts +++ b/src/index.ts @@ -129,16 +129,3 @@ namespace Experimental { } Error.stackTraceLimit = 100000; - -// deprecated stuff -export { isReady, shutdown }; - -/** - * @deprecated `await isReady` is no longer needed. Remove it from your code. - */ -let isReady = Promise.resolve(); - -/** - * @deprecated `shutdown()` is no longer needed, and is a no-op. Remove it from your code. - */ -function shutdown() {} diff --git a/src/lib/hash-input.unit-test.ts b/src/lib/hash-input.unit-test.ts index 5b5f357dca..123fd2f436 100644 --- a/src/lib/hash-input.unit-test.ts +++ b/src/lib/hash-input.unit-test.ts @@ -1,9 +1,7 @@ import { - isReady, AccountUpdate, Types, Permissions, - shutdown, ProvableExtended, } from '../index.js'; import { expect } from 'expect'; @@ -20,8 +18,6 @@ import { Test } from '../snarky.js'; let { hashInputFromJson } = Test; -await isReady; - // types type Body = Types.AccountUpdate['body']; type Update = Body['update']; @@ -96,7 +92,6 @@ test(Random.json.accountUpdate, (accountUpdateJson) => { }); console.log('all hash inputs are consistent! 🎉'); -shutdown(); function testInput( Module: ProvableExtended, diff --git a/src/lib/mina.unit-test.ts b/src/lib/mina.unit-test.ts index 682b453de3..d55d136909 100644 --- a/src/lib/mina.unit-test.ts +++ b/src/lib/mina.unit-test.ts @@ -1,6 +1,5 @@ import { filterGroups } from './mina.js'; import { expect } from 'expect'; -import { shutdown } from '../index.js'; let S = { isProved: false, isSigned: true }; let N = { isProved: false, isSigned: false }; @@ -101,4 +100,3 @@ expect(filterGroups([S, S])).toEqual({ signedPair: 1, signedSingle: 0, }); -shutdown(); diff --git a/src/lib/primitives.test.ts b/src/lib/primitives.test.ts index ce0b5cd24c..3a723c5a15 100644 --- a/src/lib/primitives.test.ts +++ b/src/lib/primitives.test.ts @@ -1,16 +1,5 @@ -import { isReady, shutdown, Field, Bool, Provable } from 'o1js'; +import { Field, Bool, Provable } from 'o1js'; describe('bool', () => { - beforeAll(async () => { - await isReady; - return; - }); - - afterAll(async () => { - setTimeout(async () => { - await shutdown(); - }, 0); - }); - describe('inside circuit', () => { describe('toField', () => { it('should return a Field', async () => { diff --git a/src/lib/provable-types/merkle-map.test.ts b/src/lib/provable-types/merkle-map.test.ts index 45375307d8..3623328ca4 100644 --- a/src/lib/provable-types/merkle-map.test.ts +++ b/src/lib/provable-types/merkle-map.test.ts @@ -1,13 +1,6 @@ -import { isReady, shutdown, Field, MerkleMap } from 'o1js'; +import { Field, MerkleMap } from 'o1js'; describe('Merkle Map', () => { - beforeAll(async () => { - await isReady; - }); - afterAll(async () => { - setTimeout(shutdown, 0); - }); - it('set and get a value from a key', () => { const map = new MerkleMap(); diff --git a/src/lib/provable-types/merkle-tree.test.ts b/src/lib/provable-types/merkle-tree.test.ts index 8416a1b13c..900a7fda70 100644 --- a/src/lib/provable-types/merkle-tree.test.ts +++ b/src/lib/provable-types/merkle-tree.test.ts @@ -1,20 +1,6 @@ -import { - isReady, - shutdown, - Poseidon, - Field, - MerkleTree, - MerkleWitness, -} from 'o1js'; +import { Poseidon, Field, MerkleTree, MerkleWitness } from 'o1js'; describe('Merkle Tree', () => { - beforeAll(async () => { - await isReady; - }); - afterAll(async () => { - setTimeout(shutdown, 0); - }); - it('root of empty tree of size 1', () => { const tree = new MerkleTree(1); expect(tree.getRoot().toString()).toEqual(Field(0).toString()); diff --git a/src/lib/provable-types/string.test.ts b/src/lib/provable-types/string.test.ts index 9a55e10d84..9f2a43bc5f 100644 --- a/src/lib/provable-types/string.test.ts +++ b/src/lib/provable-types/string.test.ts @@ -1,17 +1,6 @@ -import { - Bool, - Character, - Provable, - CircuitString, - Field, - shutdown, - isReady, -} from 'o1js'; +import { Bool, Character, Provable, CircuitString, Field } from 'o1js'; describe('Circuit String', () => { - beforeEach(() => isReady); - afterAll(() => setTimeout(shutdown, 0)); - describe('#equals', () => { test('returns true when values are equal', () => { const str = CircuitString.fromString( diff --git a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js index 583c3b2191..e6942519a5 100644 --- a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js +++ b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js @@ -3,16 +3,7 @@ import { adminPrivateKey, HelloWorld, } from './examples/zkapps/hello-world/hello-world.js'; -import { - AccountUpdate, - Field, - isReady, - Mina, - PrivateKey, - verify, -} from './index.js'; - -await isReady; +import { AccountUpdate, Field, Mina, PrivateKey, verify } from './index.js'; const deployButton = document.querySelector('#deployButton'); const updateButton = document.querySelector('#updateButton'); From 3f3a3dc6933906cbbeb4ac1c8e3db9172da85117 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 19:02:43 +0100 Subject: [PATCH 16/20] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b42a751d4a..a58f433f43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee`, `Mina.BerkeleyQANet`, APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if`, `Field.isZero()` + - Remove `Mina.accountCreationFee()`, `Mina.BerkeleyQANet`, all APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if()`, `Field.isZero()`, `isReady` and `shutdown()` - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) From 0c2283308e7896e697912e3cd9595007de97e78e Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 20:42:23 +0100 Subject: [PATCH 17/20] remove runAndCheckSync --- CHANGELOG.md | 1 - src/lib/group.test.ts | 288 ++-- src/lib/group.unit-test.ts | 3 +- src/lib/int.test.ts | 1780 +++++++++++-------------- src/lib/ml/consistency.unit-test.ts | 3 +- src/lib/primitives.test.ts | 245 ++-- src/lib/provable-types/string.test.ts | 40 +- src/lib/provable.test.ts | 12 +- src/lib/provable.ts | 5 - src/lib/scalar.test.ts | 46 +- src/lib/testing/equivalent.ts | 3 +- 11 files changed, 1081 insertions(+), 1345 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a58f433f43..a3695e1113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Require the callback to `Mina.transaction()` to be async https://github.com/o1-labs/o1js/pull/1468 - Change `{SmartContract,ZkProgram}.analyzeMethods()` to be async https://github.com/o1-labs/o1js/pull/1450 - `Provable.runAndCheck()`, `Provable.constraintSystem()` and `{SmartContract,ZkProgram}.digest()` are also async now - - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - Remove `Mina.accountCreationFee()`, `Mina.BerkeleyQANet`, all APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if()`, `Field.isZero()`, `isReady` and `shutdown()` diff --git a/src/lib/group.test.ts b/src/lib/group.test.ts index e01e736275..fce7372f35 100644 --- a/src/lib/group.test.ts +++ b/src/lib/group.test.ts @@ -8,201 +8,163 @@ describe('group', () => { describe('Inside circuit', () => { describe('group membership', () => { - it('valid element does not throw', () => { - expect(() => { - Provable.runAndCheckSync(() => { - Provable.witness(Group, () => g); - }); - }).not.toThrow(); + it('valid element does not throw', async () => { + await Provable.runAndCheck(() => { + Provable.witness(Group, () => g); + }); }); - it('valid element does not throw', () => { - expect(() => { - Provable.runAndCheckSync(() => { - Provable.witness(Group, () => Group.generator); - }); - }).not.toThrow(); + it('valid element does not throw', async () => { + await Provable.runAndCheck(() => { + Provable.witness(Group, () => Group.generator); + }); }); - it('Group.zero element does not throw', () => { - expect(() => { - Provable.runAndCheckSync(() => { - Provable.witness(Group, () => Group.zero); - }); - }).not.toThrow(); + it('Group.zero element does not throw', async () => { + await Provable.runAndCheck(() => { + Provable.witness(Group, () => Group.zero); + }); }); - it('invalid group element throws', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('invalid group element throws', async () => { + await expect( + Provable.runAndCheck(() => { Provable.witness(Group, () => Group({ x: 2, y: 2 })); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('add', () => { - it('g+g does not throw', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const y = Provable.witness(Group, () => g); - x.add(y); - }); - }).not.toThrow(); + it('g+g does not throw', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const y = Provable.witness(Group, () => g); + x.add(y); + }); }); - it('g+zero = g', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const zero = Provable.witness(Group, () => Group.zero); - x.add(zero).assertEquals(x); - }); - }).not.toThrow(); + it('g+zero = g', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const zero = Provable.witness(Group, () => Group.zero); + x.add(zero).assertEquals(x); + }); }); - it('zero+g = g', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const zero = Provable.witness(Group, () => Group.zero); - zero.add(x).assertEquals(x); - }); - }).not.toThrow(); + it('zero+g = g', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const zero = Provable.witness(Group, () => Group.zero); + zero.add(x).assertEquals(x); + }); }); - it('g+(-g) = zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const zero = Provable.witness(Group, () => Group.zero); - x.add(x.neg()).assertEquals(zero); - }); - }).not.toThrow(); + it('g+(-g) = zero', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const zero = Provable.witness(Group, () => Group.zero); + x.add(x.neg()).assertEquals(zero); + }); }); - it('(-g)+g = zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const zero = Provable.witness(Group, () => Group.zero); - x.neg().add(x).assertEquals(zero); - }); - }).not.toThrow(); + it('(-g)+g = zero', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const zero = Provable.witness(Group, () => Group.zero); + x.neg().add(x).assertEquals(zero); + }); }); - it('zero + zero = zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const zero = Provable.witness(Group, () => Group.zero); - zero.add(zero).assertEquals(zero); - }); - }).not.toThrow(); + it('zero + zero = zero', async () => { + await Provable.runAndCheck(() => { + const zero = Provable.witness(Group, () => Group.zero); + zero.add(zero).assertEquals(zero); + }); }); }); describe('sub', () => { - it('g-g does not throw', () => { - expect(() => { - Provable.runAndCheckSync(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const y = Provable.witness(Group, () => g); - x.sub(y); - }); - }); - }).not.toThrow(); + it('g-g does not throw', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const y = Provable.witness(Group, () => g); + x.sub(y); + }); }); - it('g-zero = g', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const zero = Provable.witness(Group, () => Group.zero); - x.sub(zero).assertEquals(x); - }); - }).not.toThrow(); + it('g-zero = g', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const zero = Provable.witness(Group, () => Group.zero); + x.sub(zero).assertEquals(x); + }); }); - it('zero - g = -g', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - const zero = Provable.witness(Group, () => Group.zero); - zero.sub(x).assertEquals(x.neg()); - }); - }).not.toThrow(); + it('zero - g = -g', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + const zero = Provable.witness(Group, () => Group.zero); + zero.sub(x).assertEquals(x.neg()); + }); }); - it('zero - zero = zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const zero = Provable.witness(Group, () => Group.zero); - zero.sub(zero).assertEquals(zero); - }); - }).not.toThrow(); + it('zero - zero = zero', async () => { + await Provable.runAndCheck(() => { + const zero = Provable.witness(Group, () => Group.zero); + zero.sub(zero).assertEquals(zero); + }); }); }); describe('neg', () => { - it('neg(g) not to throw', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - x.neg(); - }); - }).not.toThrow(); + it('neg(g) not to throw', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + x.neg(); + }); }); - it('neg(zero) = zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const zero = Provable.witness(Group, () => Group.zero); - zero.neg().assertEquals(zero); - }); - }).not.toThrow(); + it('neg(zero) = zero', async () => { + await Provable.runAndCheck(() => { + const zero = Provable.witness(Group, () => Group.zero); + zero.neg().assertEquals(zero); + }); }); }); describe('scale', () => { - it('scaling with random Scalar does not throw', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => g); - x.scale(Scalar.random()); - }); - }).not.toThrow(); + it('scaling with random Scalar does not throw', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => g); + x.scale(Scalar.random()); + }); }); - it('x*g+y*g = (x+y)*g', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Scalar.from(2); - const y = Scalar.from(3); - const left = g.scale(x).add(g.scale(y)); - const right = g.scale(x.add(y)); - left.assertEquals(right); - }); - }).not.toThrow(); + it('x*g+y*g = (x+y)*g', async () => { + await Provable.runAndCheck(() => { + const x = Scalar.from(2); + const y = Scalar.from(3); + const left = g.scale(x).add(g.scale(y)); + const right = g.scale(x.add(y)); + left.assertEquals(right); + }); }); - it('x*(y*g) = (x*y)*g', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Scalar.from(2); - const y = Scalar.from(3); - const left = g.scale(y).scale(x); - const right = g.scale(y.mul(x)); - left.assertEquals(right); - }); - }).not.toThrow(); + it('x*(y*g) = (x*y)*g', async () => { + await Provable.runAndCheck(() => { + const x = Scalar.from(2); + const y = Scalar.from(3); + const left = g.scale(y).scale(x); + const right = g.scale(y.mul(x)); + left.assertEquals(right); + }); }); }); describe('equals', () => { - it('should equal true with same group', () => { - Provable.runAndCheckSync(() => { + it('should equal true with same group', async () => { + await Provable.runAndCheck(() => { const x = Provable.witness(Group, () => Group.generator); let isEqual = x.equals(Group.generator); Provable.asProver(() => { @@ -211,8 +173,8 @@ describe('group', () => { }); }); - it('should equal false with different group', () => { - Provable.runAndCheckSync(() => { + it('should equal false with different group', async () => { + await Provable.runAndCheck(() => { const x = Provable.witness(Group, () => Group.generator); let isEqual = x.equals(g); Provable.asProver(() => { @@ -223,28 +185,26 @@ describe('group', () => { }); describe('assertEquals', () => { - it('should not throw with same group', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Group, () => Group.generator); - x.assertEquals(Group.generator); - }); - }).not.toThrow(); + it('should not throw with same group', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Group, () => Group.generator); + x.assertEquals(Group.generator); + }); }); - it('should throw with different group', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw with different group', async () => { + await expect( + Provable.runAndCheck(() => { const x = Provable.witness(Group, () => Group.generator); x.assertEquals(g); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('toJSON', () => { - it('fromJSON(g.toJSON) should be the same as g', () => { - Provable.runAndCheckSync(() => { + it('fromJSON(g.toJSON) should be the same as g', async () => { + await Provable.runAndCheck(() => { const x = Provable.witness( Group, () => Group.fromJSON(Group.generator.toJSON())! @@ -388,8 +348,8 @@ describe('group', () => { }); describe('Variable/Constant circuit equality ', () => { - it('add', () => { - Provable.runAndCheckSync(() => { + it('add', async () => { + await Provable.runAndCheck(() => { let y = Provable.witness(Group, () => g).add( Provable.witness(Group, () => Group.generator) ); diff --git a/src/lib/group.unit-test.ts b/src/lib/group.unit-test.ts index e70a292baf..12f51b68bc 100644 --- a/src/lib/group.unit-test.ts +++ b/src/lib/group.unit-test.ts @@ -2,6 +2,7 @@ import { Group } from './core.js'; import { test, Random } from './testing/property.js'; import { Provable } from './provable.js'; import { Poseidon } from '../mina-signer/src/poseidon-bigint.js'; +import { runAndCheckSync } from './provable-context.js'; console.log('group consistency tests'); @@ -54,7 +55,7 @@ function run( ) { let result_out_circuit = f(g1, g2); - Provable.runAndCheckSync(() => { + runAndCheckSync(() => { let result_in_circuit = f( Provable.witness(Group, () => g1), Provable.witness(Group, () => g2) diff --git a/src/lib/int.test.ts b/src/lib/int.test.ts index fe29d19a6a..30a05b9728 100644 --- a/src/lib/int.test.ts +++ b/src/lib/int.test.ts @@ -211,505 +211,443 @@ describe('int', () => { describe('UInt64', () => { describe('Inside circuit', () => { describe('add', () => { - it('1+1=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.add(y).assertEquals(new UInt64(2)); - }); - }).not.toThrow(); + it('1+1=2', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.add(y).assertEquals(new UInt64(2)); + }); }); - it('5000+5000=10000', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(5000)); - const y = Provable.witness(UInt64, () => new UInt64(5000)); - x.add(y).assertEquals(new UInt64(10000)); - }); - }).not.toThrow(); + it('5000+5000=10000', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(5000)); + const y = Provable.witness(UInt64, () => new UInt64(5000)); + x.add(y).assertEquals(new UInt64(10000)); + }); }); - it('(MAXINT/2+MAXINT/2) adds to MAXINT', () => { + it('(MAXINT/2+MAXINT/2) adds to MAXINT', async () => { const n = ((1n << 64n) - 2n) / 2n; - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(n)); - const y = Provable.witness(UInt64, () => new UInt64(n)); - x.add(y).add(1).assertEquals(UInt64.MAXINT()); - }); - }).not.toThrow(); + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(n)); + const y = Provable.witness(UInt64, () => new UInt64(n)); + x.add(y).add(1).assertEquals(UInt64.MAXINT()); + }); }); - it('should throw on overflow addition', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on overflow addition', async () => { + await expect( + Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); const y = Provable.witness(UInt64, () => new UInt64(1)); x.add(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('sub', () => { - it('1-1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.sub(y).assertEquals(new UInt64(0)); - }); - }).not.toThrow(); + it('1-1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.sub(y).assertEquals(new UInt64(0)); + }); }); - it('10000-5000=5000', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(10000)); - const y = Provable.witness(UInt64, () => new UInt64(5000)); - x.sub(y).assertEquals(new UInt64(5000)); - }); - }).not.toThrow(); + it('10000-5000=5000', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(10000)); + const y = Provable.witness(UInt64, () => new UInt64(5000)); + x.sub(y).assertEquals(new UInt64(5000)); + }); }); - it('should throw on sub if results in negative number', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on sub if results in negative number', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(0)); const y = Provable.witness(UInt64, () => new UInt64(1)); x.sub(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('mul', () => { - it('1x2=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(2)); - x.mul(y).assertEquals(new UInt64(2)); - }); - }).not.toThrow(); + it('1x2=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(2)); + x.mul(y).assertEquals(new UInt64(2)); + }); }); - it('1x0=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(0)); - x.mul(y).assertEquals(new UInt64(0)); - }); - }).not.toThrow(); + it('1x0=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(0)); + x.mul(y).assertEquals(new UInt64(0)); + }); }); - it('1000x1000=1000000', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1000)); - const y = Provable.witness(UInt64, () => new UInt64(1000)); - x.mul(y).assertEquals(new UInt64(1000000)); - }); - }).not.toThrow(); + it('1000x1000=1000000', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); + x.mul(y).assertEquals(new UInt64(1000000)); + }); }); - it('MAXINTx1=MAXINT', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.mul(y).assertEquals(UInt64.MAXINT()); - }); - }).not.toThrow(); + it('MAXINTx1=MAXINT', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.MAXINT()); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.mul(y).assertEquals(UInt64.MAXINT()); + }); }); - it('should throw on overflow multiplication', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on overflow multiplication', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); const y = Provable.witness(UInt64, () => new UInt64(2)); x.mul(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('div', () => { - it('2/1=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(2)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.div(y).assertEquals(new UInt64(2)); - }); - }).not.toThrow(); + it('2/1=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(2)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.div(y).assertEquals(new UInt64(2)); + }); }); - it('0/1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(0)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.div(y).assertEquals(new UInt64(0)); - }); - }).not.toThrow(); + it('0/1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(0)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.div(y).assertEquals(new UInt64(0)); + }); }); - it('2000/1000=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(2000)); - const y = Provable.witness(UInt64, () => new UInt64(1000)); - x.div(y).assertEquals(new UInt64(2)); - }); - }).not.toThrow(); + it('2000/1000=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(2000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); + x.div(y).assertEquals(new UInt64(2)); + }); }); - it('MAXINT/1=MAXINT', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.div(y).assertEquals(UInt64.MAXINT()); - }); - }).not.toThrow(); + it('MAXINT/1=MAXINT', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.MAXINT()); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.div(y).assertEquals(UInt64.MAXINT()); + }); }); - it('should throw on division by zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on division by zero', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); const y = Provable.witness(UInt64, () => new UInt64(0)); x.div(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('mod', () => { - it('1%1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.mod(y).assertEquals(new UInt64(0)); - }); - }).not.toThrow(); + it('1%1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.mod(y).assertEquals(new UInt64(0)); + }); }); - it('500%32=20', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(500)); - const y = Provable.witness(UInt64, () => new UInt64(32)); - x.mod(y).assertEquals(new UInt64(20)); - }); - }).not.toThrow(); + it('500%32=20', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(500)); + const y = Provable.witness(UInt64, () => new UInt64(32)); + x.mod(y).assertEquals(new UInt64(20)); + }); }); - it('MAXINT%7=1', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(7)); - x.mod(y).assertEquals(new UInt64(1)); - }); - }).not.toThrow(); + it('MAXINT%7=1', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.MAXINT()); + const y = Provable.witness(UInt64, () => new UInt64(7)); + x.mod(y).assertEquals(new UInt64(1)); + }); }); - it('should throw on mod by zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on mod by zero', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); const y = Provable.witness(UInt64, () => new UInt64(0)); x.mod(y).assertEquals(new UInt64(1)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertLt', () => { - it('1<2=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(2)); - x.assertLessThan(y); - }); - }).not.toThrow(); + it('1<2=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(2)); + x.assertLessThan(y); + }); }); - it('1<1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1<1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(1)); const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('2<1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('2<1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(2)); const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('1000<100000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1000)); - const y = Provable.witness(UInt64, () => new UInt64(100000)); - x.assertLessThan(y); - }); - }).not.toThrow(); + it('1000<100000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(100000)); + x.assertLessThan(y); + }); }); - it('100000<1000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('100000<1000=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(100000)); const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT { - expect(() => { - Provable.runAndCheckSync(() => { + it('MAXINT { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); const y = Provable.witness(UInt64, () => UInt64.MAXINT()); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertLte', () => { - it('1<=1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('1<=1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.assertLessThanOrEqual(y); + }); }); - it('2<=1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('2<=1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(2)); const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertLessThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('1000<=100000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1000)); - const y = Provable.witness(UInt64, () => new UInt64(100000)); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('1000<=100000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(100000)); + x.assertLessThanOrEqual(y); + }); }); - it('100000<=1000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('100000<=1000=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(100000)); const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertLessThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT<=MAXINT=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => UInt64.MAXINT()); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('MAXINT<=MAXINT=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.MAXINT()); + const y = Provable.witness(UInt64, () => UInt64.MAXINT()); + x.assertLessThanOrEqual(y); + }); }); }); describe('assertGreaterThan', () => { - it('2>1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(2)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.assertGreaterThan(y); - }); - }).not.toThrow(); + it('2>1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(2)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.assertGreaterThan(y); + }); }); - it('1>1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(1)); const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('1>2=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>2=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(1)); const y = Provable.witness(UInt64, () => new UInt64(2)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('100000>1000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(100000)); - const y = Provable.witness(UInt64, () => new UInt64(1000)); - x.assertGreaterThan(y); - }); - }).not.toThrow(); + it('100000>1000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(100000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); + x.assertGreaterThan(y); + }); }); - it('1000>100000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1000>100000=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(1000)); const y = Provable.witness(UInt64, () => new UInt64(100000)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT>MAXINT=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('MAXINT>MAXINT=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); const y = Provable.witness(UInt64, () => UInt64.MAXINT()); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertGreaterThanOrEqual', () => { - it('1<=1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(1)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('1<=1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.assertGreaterThanOrEqual(y); + }); }); - it('1>=2=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>=2=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(1)); const y = Provable.witness(UInt64, () => new UInt64(2)); x.assertGreaterThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('100000>=1000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(100000)); - const y = Provable.witness(UInt64, () => new UInt64(1000)); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('100000>=1000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => new UInt64(100000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); + x.assertGreaterThanOrEqual(y); + }); }); - it('1000>=100000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1000>=100000=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt64, () => new UInt64(1000)); const y = Provable.witness(UInt64, () => new UInt64(100000)); x.assertGreaterThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT>=MAXINT=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => UInt64.MAXINT()); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('MAXINT>=MAXINT=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.MAXINT()); + const y = Provable.witness(UInt64, () => UInt64.MAXINT()); + x.assertGreaterThanOrEqual(y); + }); }); }); describe('from() ', () => { describe('fromNumber()', () => { - it('should be the same as Field(1)', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => UInt64.from(1)); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as Field(1)', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.from(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.assertEquals(y); + }); }); - it('should be the same as 2^53-1', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => - UInt64.from(NUMBERMAX) - ); - const y = Provable.witness( - UInt64, - () => new UInt64(String(NUMBERMAX)) - ); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as 2^53-1', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.from(NUMBERMAX)); + const y = Provable.witness( + UInt64, + () => new UInt64(String(NUMBERMAX)) + ); + x.assertEquals(y); + }); }); }); describe('fromString()', () => { - it('should be the same as Field(1)', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => UInt64.from('1')); - const y = Provable.witness(UInt64, () => new UInt64(1)); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as Field(1)', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => UInt64.from('1')); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.assertEquals(y); + }); }); - it('should be the same as 2^53-1', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => - UInt64.from(String(NUMBERMAX)) - ); - const y = Provable.witness( - UInt64, - () => new UInt64(String(NUMBERMAX)) - ); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as 2^53-1', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt64, () => + UInt64.from(String(NUMBERMAX)) + ); + const y = Provable.witness( + UInt64, + () => new UInt64(String(NUMBERMAX)) + ); + x.assertEquals(y); + }); }); }); }); @@ -1121,505 +1059,435 @@ describe('int', () => { describe('Inside circuit', () => { describe('add', () => { - it('1+1=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.add(y).assertEquals(new UInt32(2)); - }); - }).not.toThrow(); + it('1+1=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.add(y).assertEquals(new UInt32(2)); + }); }); - it('5000+5000=10000', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(5000)); - const y = Provable.witness(UInt32, () => new UInt32(5000)); - x.add(y).assertEquals(new UInt32(10000)); - }); - }).not.toThrow(); + it('5000+5000=10000', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(5000)); + const y = Provable.witness(UInt32, () => new UInt32(5000)); + x.add(y).assertEquals(new UInt32(10000)); + }); }); - it('(MAXINT/2+MAXINT/2) adds to MAXINT', () => { + it('(MAXINT/2+MAXINT/2) adds to MAXINT', async () => { const n = ((1n << 32n) - 2n) / 2n; - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(n)); - const y = Provable.witness(UInt32, () => new UInt32(n)); - x.add(y).add(1).assertEquals(UInt32.MAXINT()); - }); - }).not.toThrow(); + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(n)); + const y = Provable.witness(UInt32, () => new UInt32(n)); + x.add(y).add(1).assertEquals(UInt32.MAXINT()); + }); }); - it('should throw on overflow addition', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on overflow addition', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); const y = Provable.witness(UInt32, () => new UInt32(1)); x.add(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('sub', () => { - it('1-1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.sub(y).assertEquals(new UInt32(0)); - }); - }).not.toThrow(); + it('1-1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.sub(y).assertEquals(new UInt32(0)); + }); }); - it('10000-5000=5000', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(10000)); - const y = Provable.witness(UInt32, () => new UInt32(5000)); - x.sub(y).assertEquals(new UInt32(5000)); - }); - }).not.toThrow(); + it('10000-5000=5000', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(10000)); + const y = Provable.witness(UInt32, () => new UInt32(5000)); + x.sub(y).assertEquals(new UInt32(5000)); + }); }); - it('should throw on sub if results in negative number', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on sub if results in negative number', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(0)); const y = Provable.witness(UInt32, () => new UInt32(1)); x.sub(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('mul', () => { - it('1x2=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(2)); - x.mul(y).assertEquals(new UInt32(2)); - }); - }).not.toThrow(); + it('1x2=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(2)); + x.mul(y).assertEquals(new UInt32(2)); + }); }); - it('1x0=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(0)); - x.mul(y).assertEquals(new UInt32(0)); - }); - }).not.toThrow(); + it('1x0=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(0)); + x.mul(y).assertEquals(new UInt32(0)); + }); }); - it('1000x1000=1000000', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1000)); - const y = Provable.witness(UInt32, () => new UInt32(1000)); - x.mul(y).assertEquals(new UInt32(1000000)); - }); - }).not.toThrow(); + it('1000x1000=1000000', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); + x.mul(y).assertEquals(new UInt32(1000000)); + }); }); - it('MAXINTx1=MAXINT', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.mul(y).assertEquals(UInt32.MAXINT()); - }); - }).not.toThrow(); + it('MAXINTx1=MAXINT', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.MAXINT()); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.mul(y).assertEquals(UInt32.MAXINT()); + }); }); - it('should throw on overflow multiplication', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on overflow multiplication', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); const y = Provable.witness(UInt32, () => new UInt32(2)); x.mul(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('div', () => { - it('2/1=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(2)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.div(y).assertEquals(new UInt32(2)); - }); - }).not.toThrow(); + it('2/1=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(2)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.div(y).assertEquals(new UInt32(2)); + }); }); - it('0/1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(0)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.div(y).assertEquals(new UInt32(0)); - }); - }).not.toThrow(); + it('0/1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(0)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.div(y).assertEquals(new UInt32(0)); + }); }); - it('2000/1000=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(2000)); - const y = Provable.witness(UInt32, () => new UInt32(1000)); - x.div(y).assertEquals(new UInt32(2)); - }); - }).not.toThrow(); + it('2000/1000=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(2000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); + x.div(y).assertEquals(new UInt32(2)); + }); }); - it('MAXINT/1=MAXINT', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.div(y).assertEquals(UInt32.MAXINT()); - }); - }).not.toThrow(); + it('MAXINT/1=MAXINT', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.MAXINT()); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.div(y).assertEquals(UInt32.MAXINT()); + }); }); - it('should throw on division by zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on division by zero', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); const y = Provable.witness(UInt32, () => new UInt32(0)); x.div(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('mod', () => { - it('1%1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.mod(y).assertEquals(new UInt32(0)); - }); - }).not.toThrow(); + it('1%1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.mod(y).assertEquals(new UInt32(0)); + }); }); - it('500%32=20', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(500)); - const y = Provable.witness(UInt32, () => new UInt32(32)); - x.mod(y).assertEquals(new UInt32(20)); - }); - }).not.toThrow(); + it('500%32=20', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(500)); + const y = Provable.witness(UInt32, () => new UInt32(32)); + x.mod(y).assertEquals(new UInt32(20)); + }); }); - it('MAXINT%7=3', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(7)); - x.mod(y).assertEquals(new UInt32(3)); - }); - }).not.toThrow(); + it('MAXINT%7=3', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.MAXINT()); + const y = Provable.witness(UInt32, () => new UInt32(7)); + x.mod(y).assertEquals(new UInt32(3)); + }); }); - it('should throw on mod by zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on mod by zero', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); const y = Provable.witness(UInt32, () => new UInt32(0)); x.mod(y).assertEquals(new UInt32(1)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertLt', () => { - it('1<2=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(2)); - x.assertLessThan(y); - }); - }).not.toThrow(); + it('1<2=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(2)); + x.assertLessThan(y); + }); }); - it('1<1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.assertLessThan(y); - }); - }).toThrow(); + it('1<1=false', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.assertLessThan(y); + }).catch(() => {}); }); - it('2<1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(2)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.assertLessThan(y); - }); - }).toThrow(); + it('2<1=false', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(2)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.assertLessThan(y); + }).catch(() => {}); }); - it('1000<100000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1000)); - const y = Provable.witness(UInt32, () => new UInt32(100000)); - x.assertLessThan(y); - }); - }).not.toThrow(); + it('1000<100000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(100000)); + x.assertLessThan(y); + }); }); - it('100000<1000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(100000)); - const y = Provable.witness(UInt32, () => new UInt32(1000)); - x.assertLessThan(y); - }); - }).toThrow(); + it('100000<1000=false', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(100000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); + x.assertLessThan(y); + }).catch(() => {}); }); - it('MAXINT { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => UInt32.MAXINT()); - x.assertLessThan(y); - }); - }).toThrow(); + it('MAXINT { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.MAXINT()); + const y = Provable.witness(UInt32, () => UInt32.MAXINT()); + x.assertLessThan(y); + }).catch(() => {}); }); }); describe('assertLessThanOrEqual', () => { - it('1<=1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('1<=1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.assertLessThanOrEqual(y); + }); }); - it('2<=1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('2<=1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(2)); const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertLessThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('1000<=100000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1000)); - const y = Provable.witness(UInt32, () => new UInt32(100000)); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('1000<=100000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(100000)); + x.assertLessThanOrEqual(y); + }); }); - it('100000<=1000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('100000<=1000=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(100000)); const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertLessThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT<=MAXINT=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => UInt32.MAXINT()); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('MAXINT<=MAXINT=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.MAXINT()); + const y = Provable.witness(UInt32, () => UInt32.MAXINT()); + x.assertLessThanOrEqual(y); + }); }); }); describe('assertGreaterThan', () => { - it('2>1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(2)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.assertGreaterThan(y); - }); - }).not.toThrow(); + it('2>1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(2)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.assertGreaterThan(y); + }); }); - it('1>1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(1)); const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('1>2=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>2=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(1)); const y = Provable.witness(UInt32, () => new UInt32(2)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('100000>1000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(100000)); - const y = Provable.witness(UInt32, () => new UInt32(1000)); - x.assertGreaterThan(y); - }); - }).not.toThrow(); + it('100000>1000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(100000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); + x.assertGreaterThan(y); + }); }); - it('1000>100000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1000>100000=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(1000)); const y = Provable.witness(UInt32, () => new UInt32(100000)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT>MAXINT=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('MAXINT>MAXINT=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); const y = Provable.witness(UInt32, () => UInt32.MAXINT()); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertGreaterThanOrEqual', () => { - it('1<=1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(1)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('1<=1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.assertGreaterThanOrEqual(y); + }); }); - it('1>=2=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>=2=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(1)); const y = Provable.witness(UInt32, () => new UInt32(2)); x.assertGreaterThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('100000>=1000=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(100000)); - const y = Provable.witness(UInt32, () => new UInt32(1000)); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('100000>=1000=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => new UInt32(100000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); + x.assertGreaterThanOrEqual(y); + }); }); - it('1000>=100000=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1000>=100000=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt32, () => new UInt32(1000)); const y = Provable.witness(UInt32, () => new UInt32(100000)); x.assertGreaterThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT>=MAXINT=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => UInt32.MAXINT()); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('MAXINT>=MAXINT=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.MAXINT()); + const y = Provable.witness(UInt32, () => UInt32.MAXINT()); + x.assertGreaterThanOrEqual(y); + }); }); }); describe('from() ', () => { describe('fromNumber()', () => { - it('should be the same as Field(1)', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.from(1)); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as Field(1)', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.from(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.assertEquals(y); + }); }); - it('should be the same as 2^53-1', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => - UInt32.from(NUMBERMAX) - ); - const y = Provable.witness( - UInt32, - () => new UInt32(String(NUMBERMAX)) - ); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as 2^53-1', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.from(NUMBERMAX)); + const y = Provable.witness( + UInt32, + () => new UInt32(String(NUMBERMAX)) + ); + x.assertEquals(y); + }); }); }); describe('fromString()', () => { - it('should be the same as Field(1)', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => UInt32.from('1')); - const y = Provable.witness(UInt32, () => new UInt32(1)); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as Field(1)', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => UInt32.from('1')); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.assertEquals(y); + }); }); - it('should be the same as 2^53-1', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => - UInt32.from(String(NUMBERMAX)) - ); - const y = Provable.witness( - UInt32, - () => new UInt32(String(NUMBERMAX)) - ); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as 2^53-1', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt32, () => + UInt32.from(String(NUMBERMAX)) + ); + const y = Provable.witness( + UInt32, + () => new UInt32(String(NUMBERMAX)) + ); + x.assertEquals(y); + }); }); }); }); @@ -2031,464 +1899,410 @@ describe('int', () => { describe('Inside circuit', () => { describe('add', () => { - it('1+1=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.add(y).assertEquals(2); - }); - }).not.toThrow(); + it('1+1=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.add(y).assertEquals(2); + }); }); - it('100+100=200', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(100)); - const y = Provable.witness(UInt8, () => new UInt8(100)); - x.add(y).assertEquals(new UInt8(200)); - }); - }).not.toThrow(); + it('100+100=200', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(100)); + const y = Provable.witness(UInt8, () => new UInt8(100)); + x.add(y).assertEquals(new UInt8(200)); + }); }); - it('(MAXINT/2+MAXINT/2) adds to MAXINT', () => { + it('(MAXINT/2+MAXINT/2) adds to MAXINT', async () => { const n = ((1n << 8n) - 2n) / 2n; - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(n)); - const y = Provable.witness(UInt8, () => new UInt8(n)); - x.add(y).add(1).assertEquals(UInt8.MAXINT()); - }); - }).not.toThrow(); + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(n)); + const y = Provable.witness(UInt8, () => new UInt8(n)); + x.add(y).add(1).assertEquals(UInt8.MAXINT()); + }); }); - it('should throw on overflow addition', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on overflow addition', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => UInt8.MAXINT()); const y = Provable.witness(UInt8, () => new UInt8(1)); x.add(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('sub', () => { - it('1-1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.sub(y).assertEquals(new UInt8(0)); - }); - }).not.toThrow(); + it('1-1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.sub(y).assertEquals(new UInt8(0)); + }); }); - it('100-50=50', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(100)); - const y = Provable.witness(UInt8, () => new UInt8(50)); - x.sub(y).assertEquals(new UInt8(50)); - }); - }).not.toThrow(); + it('100-50=50', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(100)); + const y = Provable.witness(UInt8, () => new UInt8(50)); + x.sub(y).assertEquals(new UInt8(50)); + }); }); - it('should throw on sub if results in negative number', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on sub if results in negative number', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(0)); const y = Provable.witness(UInt8, () => new UInt8(1)); x.sub(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('mul', () => { - it('1x2=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(2)); - x.mul(y).assertEquals(new UInt8(2)); - }); - }).not.toThrow(); + it('1x2=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(2)); + x.mul(y).assertEquals(new UInt8(2)); + }); }); - it('1x0=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(0)); - x.mul(y).assertEquals(new UInt8(0)); - }); - }).not.toThrow(); + it('1x0=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(0)); + x.mul(y).assertEquals(new UInt8(0)); + }); }); - it('12x20=240', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(12)); - const y = Provable.witness(UInt8, () => new UInt8(20)); - x.mul(y).assertEquals(new UInt8(240)); - }); - }).not.toThrow(); + it('12x20=240', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(12)); + const y = Provable.witness(UInt8, () => new UInt8(20)); + x.mul(y).assertEquals(new UInt8(240)); + }); }); - it('MAXINTx1=MAXINT', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => UInt8.MAXINT()); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.mul(y).assertEquals(UInt8.MAXINT()); - }); - }).not.toThrow(); + it('MAXINTx1=MAXINT', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => UInt8.MAXINT()); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.mul(y).assertEquals(UInt8.MAXINT()); + }); }); - it('should throw on overflow multiplication', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on overflow multiplication', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => UInt8.MAXINT()); const y = Provable.witness(UInt8, () => new UInt8(2)); x.mul(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('div', () => { - it('2/1=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(2)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.div(y).assertEquals(new UInt8(2)); - }); - }).not.toThrow(); + it('2/1=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(2)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.div(y).assertEquals(new UInt8(2)); + }); }); - it('0/1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(0)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.div(y).assertEquals(new UInt8(0)); - }); - }).not.toThrow(); + it('0/1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(0)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.div(y).assertEquals(new UInt8(0)); + }); }); - it('20/10=2', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(20)); - const y = Provable.witness(UInt8, () => new UInt8(10)); - x.div(y).assertEquals(new UInt8(2)); - }); - }).not.toThrow(); + it('20/10=2', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(20)); + const y = Provable.witness(UInt8, () => new UInt8(10)); + x.div(y).assertEquals(new UInt8(2)); + }); }); - it('MAXINT/1=MAXINT', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => UInt8.MAXINT()); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.div(y).assertEquals(UInt8.MAXINT()); - }); - }).not.toThrow(); + it('MAXINT/1=MAXINT', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => UInt8.MAXINT()); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.div(y).assertEquals(UInt8.MAXINT()); + }); }); - it('should throw on division by zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on division by zero', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => UInt8.MAXINT()); const y = Provable.witness(UInt8, () => new UInt8(0)); x.div(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('mod', () => { - it('1%1=0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.mod(y).assertEquals(new UInt8(0)); - }); - }).not.toThrow(); + it('1%1=0', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.mod(y).assertEquals(new UInt8(0)); + }); }); - it('50%32=18', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(50)); - const y = Provable.witness(UInt8, () => new UInt8(32)); - x.mod(y).assertEquals(new UInt8(18)); - }); - }).not.toThrow(); + it('50%32=18', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(50)); + const y = Provable.witness(UInt8, () => new UInt8(32)); + x.mod(y).assertEquals(new UInt8(18)); + }); }); - it('MAXINT%7=3', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => UInt8.MAXINT()); - const y = Provable.witness(UInt8, () => new UInt8(7)); - x.mod(y).assertEquals(new UInt8(3)); - }); - }).not.toThrow(); + it('MAXINT%7=3', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => UInt8.MAXINT()); + const y = Provable.witness(UInt8, () => new UInt8(7)); + x.mod(y).assertEquals(new UInt8(3)); + }); }); - it('should throw on mod by zero', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw on mod by zero', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => UInt8.MAXINT()); const y = Provable.witness(UInt8, () => new UInt8(0)); x.mod(y).assertEquals(new UInt8(1)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertLt', () => { - it('1<2=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(2)); - x.assertLessThan(y); - }); - }).not.toThrow(); + it('1<2=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(2)); + x.assertLessThan(y); + }); }); - it('1<1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1<1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(1)); const y = Provable.witness(UInt8, () => new UInt8(1)); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('2<1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('2<1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(2)); const y = Provable.witness(UInt8, () => new UInt8(1)); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('10<100=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(10)); - const y = Provable.witness(UInt8, () => new UInt8(100)); - x.assertLessThan(y); - }); - }).not.toThrow(); + it('10<100=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(10)); + const y = Provable.witness(UInt8, () => new UInt8(100)); + x.assertLessThan(y); + }); }); - it('100<10=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('100<10=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(100)); const y = Provable.witness(UInt8, () => new UInt8(10)); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT { - expect(() => { - Provable.runAndCheckSync(() => { + it('MAXINT { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => UInt8.MAXINT()); const y = Provable.witness(UInt8, () => UInt8.MAXINT()); x.assertLessThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertLessThanOrEqual', () => { - it('1<=1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('1<=1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.assertLessThanOrEqual(y); + }); }); - it('2<=1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('2<=1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(2)); const y = Provable.witness(UInt8, () => new UInt8(1)); x.assertLessThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('10<=100=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(10)); - const y = Provable.witness(UInt8, () => new UInt8(100)); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('10<=100=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(10)); + const y = Provable.witness(UInt8, () => new UInt8(100)); + x.assertLessThanOrEqual(y); + }); }); - it('100<=10=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('100<=10=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(100)); const y = Provable.witness(UInt8, () => new UInt8(10)); x.assertLessThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT<=MAXINT=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => UInt8.MAXINT()); - const y = Provable.witness(UInt8, () => UInt8.MAXINT()); - x.assertLessThanOrEqual(y); - }); - }).not.toThrow(); + it('MAXINT<=MAXINT=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => UInt8.MAXINT()); + const y = Provable.witness(UInt8, () => UInt8.MAXINT()); + x.assertLessThanOrEqual(y); + }); }); }); describe('assertGreaterThan', () => { - it('2>1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(2)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.assertGreaterThan(y); - }); - }).not.toThrow(); + it('2>1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(2)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.assertGreaterThan(y); + }); }); - it('1>1=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>1=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(1)); const y = Provable.witness(UInt8, () => new UInt8(1)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('1>2=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>2=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(1)); const y = Provable.witness(UInt8, () => new UInt8(2)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('100>10=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(100)); - const y = Provable.witness(UInt8, () => new UInt8(10)); - x.assertGreaterThan(y); - }); - }).not.toThrow(); + it('100>10=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(100)); + const y = Provable.witness(UInt8, () => new UInt8(10)); + x.assertGreaterThan(y); + }); }); - it('10>100=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('10>100=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(1000)); const y = Provable.witness(UInt8, () => new UInt8(100000)); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT>MAXINT=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('MAXINT>MAXINT=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => UInt8.MAXINT()); const y = Provable.witness(UInt8, () => UInt8.MAXINT()); x.assertGreaterThan(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('assertGreaterThanOrEqual', () => { - it('1<=1=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(1)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('1<=1=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(1)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.assertGreaterThanOrEqual(y); + }); }); - it('1>=2=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('1>=2=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(1)); const y = Provable.witness(UInt8, () => new UInt8(2)); x.assertGreaterThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('100>=10=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => new UInt8(100)); - const y = Provable.witness(UInt8, () => new UInt8(10)); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('100>=10=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => new UInt8(100)); + const y = Provable.witness(UInt8, () => new UInt8(10)); + x.assertGreaterThanOrEqual(y); + }); }); - it('10>=100=false', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('10>=100=false', async () => { + await expect( + Provable.runAndCheck(async () => { const x = Provable.witness(UInt8, () => new UInt8(10)); const y = Provable.witness(UInt8, () => new UInt8(100)); x.assertGreaterThanOrEqual(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('MAXINT>=MAXINT=true', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => UInt8.MAXINT()); - const y = Provable.witness(UInt8, () => UInt8.MAXINT()); - x.assertGreaterThanOrEqual(y); - }); - }).not.toThrow(); + it('MAXINT>=MAXINT=true', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => UInt8.MAXINT()); + const y = Provable.witness(UInt8, () => UInt8.MAXINT()); + x.assertGreaterThanOrEqual(y); + }); }); }); describe('from() ', () => { describe('fromNumber()', () => { - it('should be the same as Field(1)', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt8, () => UInt8.from(1)); - const y = Provable.witness(UInt8, () => new UInt8(1)); - x.assertEquals(y); - }); - }).not.toThrow(); + it('should be the same as Field(1)', async () => { + await Provable.runAndCheck(async () => { + const x = Provable.witness(UInt8, () => UInt8.from(1)); + const y = Provable.witness(UInt8, () => new UInt8(1)); + x.assertEquals(y); + }); }); }); }); diff --git a/src/lib/ml/consistency.unit-test.ts b/src/lib/ml/consistency.unit-test.ts index 821c53e047..738884b05f 100644 --- a/src/lib/ml/consistency.unit-test.ts +++ b/src/lib/ml/consistency.unit-test.ts @@ -7,6 +7,7 @@ import { Ml } from './conversion.js'; import { expect } from 'expect'; import { FieldConst } from '../provable-core/fieldvar.js'; import { Provable } from '../provable.js'; +import { runAndCheckSync } from '../provable-context.js'; // PrivateKey.toBase58, fromBase58 @@ -94,7 +95,7 @@ test(Random.publicKey, randomTokenId, (publicKey, field) => { }); let parentTokenId = Field(field); - Provable.runAndCheckSync(() => { + runAndCheckSync(() => { tokenOwner = Provable.witness(PublicKey, () => tokenOwner); parentTokenId = Provable.witness(Field, () => parentTokenId); diff --git a/src/lib/primitives.test.ts b/src/lib/primitives.test.ts index 3a723c5a15..a8ffcebf95 100644 --- a/src/lib/primitives.test.ts +++ b/src/lib/primitives.test.ts @@ -2,254 +2,225 @@ import { Field, Bool, Provable } from 'o1js'; describe('bool', () => { describe('inside circuit', () => { describe('toField', () => { - it('should return a Field', async () => { - expect(true).toEqual(true); - }); - it('should convert false to Field element 0', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xFalse = Provable.witness(Bool, () => new Bool(false)); + it('should convert false to Field element 0', async () => { + await Provable.runAndCheck(() => { + const xFalse = Provable.witness(Bool, () => new Bool(false)); - xFalse.toField().assertEquals(new Field(0)); - }); - }).not.toThrow(); + xFalse.toField().assertEquals(new Field(0)); + }); }); - it('should throw when false toString is compared to Field element other than 0 ', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw when false toString is compared to Field element other than 0 ', async () => { + await expect( + Provable.runAndCheck(() => { const xFalse = Provable.witness(Bool, () => new Bool(false)); xFalse.toField().assertEquals(new Field(1)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); - it('should convert true to Field element 1', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xTrue = Provable.witness(Bool, () => new Bool(true)); - xTrue.toField().assertEquals(new Field(1)); - }); - }).not.toThrow(); + it('should convert true to Field element 1', async () => { + await Provable.runAndCheck(() => { + const xTrue = Provable.witness(Bool, () => new Bool(true)); + xTrue.toField().assertEquals(new Field(1)); + }); }); - it('should throw when true toField is compared to Field element other than 1 ', () => { - expect(() => { - Provable.runAndCheckSync(() => { + it('should throw when true toField is compared to Field element other than 1 ', async () => { + await expect( + Provable.runAndCheck(() => { const xTrue = Provable.witness(Bool, () => new Bool(true)); xTrue.toField().assertEquals(new Field(0)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('toFields', () => { - it('should return an array of Fields', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Bool, () => new Bool(false)); - const fieldArr = x.toFields(); - const isArr = Array.isArray(fieldArr); - expect(isArr).toBe(true); - fieldArr[0].assertEquals(new Field(0)); - }); - }).not.toThrow(); + it('should return an array of Fields', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Bool, () => new Bool(false)); + const fieldArr = x.toFields(); + const isArr = Array.isArray(fieldArr); + expect(isArr).toBe(true); + fieldArr[0].assertEquals(new Field(0)); + }); }); }); describe('and', () => { it('true "and" true should return true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xTrue = Provable.witness(Bool, () => new Bool(true)); - const yTrue = Provable.witness(Bool, () => new Bool(true)); + await Provable.runAndCheck(() => { + const xTrue = Provable.witness(Bool, () => new Bool(true)); + const yTrue = Provable.witness(Bool, () => new Bool(true)); - xTrue.and(yTrue).assertEquals(new Bool(true)); - }); - }).not.toThrow(); + xTrue.and(yTrue).assertEquals(new Bool(true)); + }); }); it('should throw if true "and" true is compared to false', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + await expect( + Provable.runAndCheck(() => { const xTrue = Provable.witness(Bool, () => new Bool(true)); const yTrue = Provable.witness(Bool, () => new Bool(true)); xTrue.and(yTrue).assertEquals(new Bool(false)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); it('false "and" false should return false', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xFalse = Provable.witness(Bool, () => new Bool(false)); - const yFalse = Provable.witness(Bool, () => new Bool(false)); + await Provable.runAndCheck(() => { + const xFalse = Provable.witness(Bool, () => new Bool(false)); + const yFalse = Provable.witness(Bool, () => new Bool(false)); - xFalse.and(yFalse).assertEquals(new Bool(false)); - }); - }).not.toThrow(); + xFalse.and(yFalse).assertEquals(new Bool(false)); + }); }); it('should throw if false "and" false is compared to true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + await expect( + Provable.runAndCheck(() => { const xFalse = Provable.witness(Bool, () => new Bool(false)); const yFalse = Provable.witness(Bool, () => new Bool(false)); xFalse.and(yFalse).assertEquals(new Bool(true)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); it('false "and" true should return false', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xFalse = Provable.witness(Bool, () => new Bool(false)); - const yTrue = Provable.witness(Bool, () => new Bool(true)); + await Provable.runAndCheck(() => { + const xFalse = Provable.witness(Bool, () => new Bool(false)); + const yTrue = Provable.witness(Bool, () => new Bool(true)); - xFalse.and(yTrue).assertEquals(new Bool(false)); - }); - }).not.toThrow(); + xFalse.and(yTrue).assertEquals(new Bool(false)); + }); }); it('should throw if false "and" true is compared to true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + await expect( + Provable.runAndCheck(() => { const xFalse = Provable.witness(Bool, () => new Bool(false)); const yTrue = Provable.witness(Bool, () => new Bool(true)); xFalse.and(yTrue).assertEquals(new Bool(true)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('not', () => { it('should return true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xTrue = Provable.witness(Bool, () => new Bool(true)); - xTrue.toField().assertEquals(new Field(1)); - }); - }).not.toThrow(); + await Provable.runAndCheck(() => { + const xTrue = Provable.witness(Bool, () => new Bool(true)); + xTrue.toField().assertEquals(new Field(1)); + }); }); it('should return a new bool that is the negation of the input', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xTrue = Provable.witness(Bool, () => new Bool(true)); - const yFalse = Provable.witness(Bool, () => new Bool(false)); - xTrue.not().assertEquals(new Bool(false)); - yFalse.not().assertEquals(new Bool(true)); - }); - }).not.toThrow(); + await Provable.runAndCheck(() => { + const xTrue = Provable.witness(Bool, () => new Bool(true)); + const yFalse = Provable.witness(Bool, () => new Bool(false)); + xTrue.not().assertEquals(new Bool(false)); + yFalse.not().assertEquals(new Bool(true)); + }); }); it('should throw if input.not() is compared to input', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + expect( + Provable.runAndCheck(() => { const xTrue = Provable.witness(Bool, () => new Bool(true)); xTrue.not().assertEquals(xTrue); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('or', () => { it('true "or" true should return true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xTrue = Provable.witness(Bool, () => new Bool(true)); - const yTrue = Provable.witness(Bool, () => new Bool(true)); + await Provable.runAndCheck(() => { + const xTrue = Provable.witness(Bool, () => new Bool(true)); + const yTrue = Provable.witness(Bool, () => new Bool(true)); - xTrue.or(yTrue).assertEquals(new Bool(true)); - }); - }).not.toThrow(); + xTrue.or(yTrue).assertEquals(new Bool(true)); + }); }); it('should throw if true "or" true is compared to false', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + expect( + Provable.runAndCheck(() => { const xTrue = Provable.witness(Bool, () => new Bool(true)); const yTrue = Provable.witness(Bool, () => new Bool(true)); xTrue.or(yTrue).assertEquals(new Bool(false)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); it('false "or" false should return false', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xFalse = Provable.witness(Bool, () => new Bool(false)); - const yFalse = Provable.witness(Bool, () => new Bool(false)); + await Provable.runAndCheck(() => { + const xFalse = Provable.witness(Bool, () => new Bool(false)); + const yFalse = Provable.witness(Bool, () => new Bool(false)); - xFalse.or(yFalse).assertEquals(new Bool(false)); - }); - }).not.toThrow(); + xFalse.or(yFalse).assertEquals(new Bool(false)); + }); }); it('should throw if false "or" false is compared to true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + expect( + Provable.runAndCheck(() => { const xFalse = Provable.witness(Bool, () => new Bool(false)); const yFalse = Provable.witness(Bool, () => new Bool(false)); xFalse.or(yFalse).assertEquals(new Bool(true)); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); it('false "or" true should return true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const xFalse = Provable.witness(Bool, () => new Bool(false)); - const yTrue = Provable.witness(Bool, () => new Bool(true)); + await Provable.runAndCheck(() => { + const xFalse = Provable.witness(Bool, () => new Bool(false)); + const yTrue = Provable.witness(Bool, () => new Bool(true)); - xFalse.or(yTrue).assertEquals(new Bool(true)); - }); - }).not.toThrow(); + xFalse.or(yTrue).assertEquals(new Bool(true)); + }); }); }); describe('assertEquals', () => { it('should not throw on true "assertEqual" true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Bool, () => new Bool(true)); + await Provable.runAndCheck(() => { + const x = Provable.witness(Bool, () => new Bool(true)); - x.assertEquals(x); - }); - }).not.toThrow(); + x.assertEquals(x); + }); }); it('should throw on true "assertEquals" false', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + expect( + Provable.runAndCheck(() => { const x = Provable.witness(Bool, () => new Bool(true)); const y = Provable.witness(Bool, () => new Bool(false)); x.assertEquals(y); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); describe('equals', () => { it('should not throw on true "equals" true', async () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Bool, () => new Bool(true)); + await Provable.runAndCheck(() => { + const x = Provable.witness(Bool, () => new Bool(true)); - x.equals(x).assertEquals(true); - }); - }).not.toThrow(); + x.equals(x).assertEquals(true); + }); }); it('should throw on true "equals" false', async () => { - expect(() => { - Provable.runAndCheckSync(() => { + expect( + Provable.runAndCheck(() => { const x = Provable.witness(Bool, () => new Bool(true)); const y = Provable.witness(Bool, () => new Bool(false)); x.equals(y).assertEquals(true); - }); - }).toThrow(); + }) + ).rejects.toThrow(); }); }); }); diff --git a/src/lib/provable-types/string.test.ts b/src/lib/provable-types/string.test.ts index 9f2a43bc5f..806e9db3fd 100644 --- a/src/lib/provable-types/string.test.ts +++ b/src/lib/provable-types/string.test.ts @@ -2,7 +2,7 @@ import { Bool, Character, Provable, CircuitString, Field } from 'o1js'; describe('Circuit String', () => { describe('#equals', () => { - test('returns true when values are equal', () => { + test('returns true when values are equal', async () => { const str = CircuitString.fromString( 'Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth' ); @@ -11,7 +11,7 @@ describe('Circuit String', () => { ); expect(str.equals(same_str)).toEqual(Bool(true)); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str = CircuitString.fromString( 'Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth' ); @@ -22,12 +22,12 @@ describe('Circuit String', () => { }); }); - test('returns false when values are not equal', () => { + test('returns false when values are not equal', async () => { const str = CircuitString.fromString('Your size'); const not_same_str = CircuitString.fromString('size'); expect(str.equals(not_same_str)).toEqual(Bool(false)); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str = Provable.witness(CircuitString, () => { return CircuitString.fromString('Your size'); }); @@ -51,7 +51,7 @@ describe('Circuit String', () => { ); expect(str.contains(contained_str)).toEqual(new Bool(true)); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str = CircuitString.fromString( 'Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth' ); @@ -67,7 +67,7 @@ describe('Circuit String', () => { const not_contained_str = CircuitString.fromString('defhij'); expect(str.contains(not_contained_str)).toEqual(new Bool(false)); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str = CircuitString.fromString('abcdefghijklmnop'); const not_contained_str = CircuitString.fromString('defhij'); expect(str.contains(not_contained_str)).toEqual(new Bool(false)); @@ -80,7 +80,7 @@ describe('Circuit String', () => { const contained_str = CircuitString.fromString('ab'); expect(str.contains(contained_str)).toEqual(new Bool(true)); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str = CircuitString8.fromString('abcd'); const contained_str = CircuitString.fromString('ab'); expect(str.contains(contained_str)).toEqual(new Bool(true)); @@ -92,7 +92,7 @@ describe('Circuit String', () => { const contained_str = CircuitString8.fromString('ab'); expect(str.contains(contained_str)).toEqual(new Bool(true)); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str = CircuitString.fromString('abcd'); const contained_str = CircuitString8.fromString('ab'); expect(str.contains(contained_str)).toEqual(new Bool(true)); @@ -102,13 +102,13 @@ describe('Circuit String', () => { }); */ describe('#toString', () => { - test('serializes to string', () => { + test('serializes to string', async () => { const js_str = 'Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth'; const str = CircuitString.fromString(js_str); expect(str.toString()).toBe(js_str); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const js_str = 'Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth'; const str = CircuitString.fromString(js_str); @@ -118,7 +118,7 @@ describe('Circuit String', () => { }); describe('#substring', () => { - test('selects substring', () => { + test('selects substring', async () => { const str = CircuitString.fromString( 'Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth' ); @@ -126,7 +126,7 @@ describe('Circuit String', () => { 'Everything we see is a perspective' ); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str = CircuitString.fromString( 'Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth' ); @@ -138,12 +138,12 @@ describe('Circuit String', () => { }); describe('#append', () => { - test('appends 2 strings', () => { + test('appends 2 strings', async () => { const str1 = CircuitString.fromString('abcd'); const str2 = CircuitString.fromString('efgh'); expect(str1.append(str2).toString()).toBe('abcdefgh'); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { const str1 = CircuitString.fromString('abcd'); const str2 = CircuitString.fromString('efgh'); expect(str1.append(str2).toString()).toBe('abcdefgh'); @@ -151,10 +151,10 @@ describe('Circuit String', () => { }); }); - /* describe('CircuitString8', () => { + /* describe('CircuitString8', async () => { test('cannot create more than 8 chars', () => { expect(() => { - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { Provable.witness(CircuitString8, () => { return CircuitString8.fromString('More than eight chars'); }); @@ -164,9 +164,9 @@ describe('Circuit String', () => { }); */ describe('with invalid input', () => { - test.skip('cannot use a character out of range', () => { - expect(() => { - Provable.runAndCheckSync(() => { + test.skip('cannot use a character out of range', async () => { + await expect(async () => { + await Provable.runAndCheck(() => { const str = Provable.witness(CircuitString, () => { return CircuitString.fromCharacters([ new Character(Field(100)), @@ -175,7 +175,7 @@ describe('Circuit String', () => { ]); }); }); - }).toThrow(); + }).rejects.toThrow(); }); }); }); diff --git a/src/lib/provable.test.ts b/src/lib/provable.test.ts index b19e77e670..46ec4738e5 100644 --- a/src/lib/provable.test.ts +++ b/src/lib/provable.test.ts @@ -14,8 +14,8 @@ describe('Provable', () => { expect(x.toString()).toBe('-2'); }); - it('Provable.if in snark', () => { - Provable.runAndCheckSync(() => { + it('Provable.if in snark', async () => { + await Provable.runAndCheck(() => { let x = Provable.witness(Int64, () => Int64.from(-1)); let y = Provable.witness(Int64, () => Int64.from(-2)); let b = Provable.witness(Bool, () => Bool(true)); @@ -78,10 +78,10 @@ describe('Provable', () => { ).toThrow(/`mask` must have 0 or 1 true element, found 2/); }); - it('Provable.assertEqual', () => { + it('Provable.assertEqual', async () => { const FieldAndBool = Struct({ x: Field, b: Bool }); - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { let x = Provable.witness(Field, () => Field(1)); let b = Provable.witness(Bool, () => Bool(true)); @@ -108,7 +108,7 @@ describe('Provable', () => { }); }); - it('Provable.equal', () => { + it('Provable.equal', async () => { const FieldAndBool = Struct({ x: Field, b: Bool }); let pk1 = PublicKey.fromBase58( 'B62qoCHJ1dcGjKhdMTMuAytzRkLxRFUgq6YC5XSgmmxAt8r7FVi1DhT' @@ -123,7 +123,7 @@ describe('Provable', () => { }); } - Provable.runAndCheckSync(() => { + await Provable.runAndCheck(() => { let x = Provable.witness(Field, () => Field(1)); let b = Provable.witness(Bool, () => Bool(true)); let pk = Provable.witness(PublicKey, () => pk1); diff --git a/src/lib/provable.ts b/src/lib/provable.ts index 5d83e4ec57..27753fff97 100644 --- a/src/lib/provable.ts +++ b/src/lib/provable.ts @@ -24,7 +24,6 @@ import { asProver, constraintSystem, generateWitness, - runAndCheckSync, } from './provable-context.js'; import { exists, existsAsync } from './provable-core/exists.js'; @@ -176,10 +175,6 @@ const Provable = { async runAndCheck(f: (() => Promise) | (() => void)) { await generateWitness(f, { checkConstraints: true }); }, - /** - * @deprecated use the async `Provable.runAndCheck` instead - */ - runAndCheckSync: runAndCheckSync, /** * Runs provable code quickly, without creating a proof, and not checking whether constraints are satisfied. * @example diff --git a/src/lib/scalar.test.ts b/src/lib/scalar.test.ts index f4a0adf212..caf418c362 100644 --- a/src/lib/scalar.test.ts +++ b/src/lib/scalar.test.ts @@ -4,44 +4,38 @@ describe('scalar', () => { describe('scalar', () => { describe('Inside circuit', () => { describe('toFields', () => { - it('should return an array of Fields', () => { - expect(() => { - Provable.runAndCheckSync(() => { - const x = Provable.witness(Scalar, () => Scalar.random()); - const fieldArr = x.toFields(); - expect(Array.isArray(fieldArr)).toBe(true); - }); - }).not.toThrow(); + it('should return an array of Fields', async () => { + await Provable.runAndCheck(() => { + const x = Provable.witness(Scalar, () => Scalar.random()); + const fieldArr = x.toFields(); + expect(Array.isArray(fieldArr)).toBe(true); + }); }); }); describe('toFields / fromFields', () => { - it('should return the same', () => { - expect(() => { - let s0 = Scalar.random(); - Provable.runAndCheckSync(() => { - let s1 = Provable.witness(Scalar, () => s0); - Provable.assertEqual(Scalar.fromFields(s1.toFields()), s0); - }); - }).not.toThrow(); + it('should return the same', async () => { + let s0 = Scalar.random(); + await Provable.runAndCheck(() => { + let s1 = Provable.witness(Scalar, () => s0); + Provable.assertEqual(Scalar.fromFields(s1.toFields()), s0); + }); }); }); describe('fromBits', () => { - it('should return a Scalar', () => { - expect(() => { - Provable.runAndCheckSync(() => { - Provable.witness(Scalar, () => - Scalar.fromBits(Field.random().toBits()) - ); - }); - }).not.toThrow(); + it('should return a Scalar', async () => { + await Provable.runAndCheck(() => { + Provable.witness(Scalar, () => + Scalar.fromBits(Field.random().toBits()) + ); + }); }); }); describe('random', () => { - it('two different calls should be different', () => { - Provable.runAndCheckSync(() => { + it('two different calls should be different', async () => { + await Provable.runAndCheck(() => { const x = Provable.witness(Scalar, () => Scalar.random()); const y = Provable.witness(Scalar, () => Scalar.random()); expect(x).not.toEqual(y); diff --git a/src/lib/testing/equivalent.ts b/src/lib/testing/equivalent.ts index a11db04eaf..e44527c858 100644 --- a/src/lib/testing/equivalent.ts +++ b/src/lib/testing/equivalent.ts @@ -8,6 +8,7 @@ import { Bool, Field } from '../core.js'; import { AnyFunction, Tuple } from '../util/types.js'; import { provable } from '../provable-types/struct.js'; import { assert } from '../gadgets/common.js'; +import { runAndCheckSync } from '../provable-context.js'; export { equivalent, @@ -237,7 +238,7 @@ function equivalentProvable< ); // inside provable code - Provable.runAndCheckSync(() => { + runAndCheckSync(() => { let inputWitnesses = inputs2.map((x, i) => { let provable = from[i].provable; return provable !== undefined From 8c333dd95cb79041feda9cd5cf42b7aba250720f Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 20:58:20 +0100 Subject: [PATCH 18/20] fixup: remove private key from deploy args --- src/examples/zkapps/reducer/map.ts | 6 ++--- src/examples/zkapps/voting/demo.ts | 8 +++---- .../zkapps/voting/deploy-contracts.ts | 24 +++++++++++-------- src/examples/zkapps/voting/membership.ts | 5 ++-- src/examples/zkapps/voting/run-berkeley.ts | 12 ++++++---- src/examples/zkapps/voting/voting.ts | 5 ++-- src/lib/mina/token/token-contract.ts | 2 +- src/lib/zkapp.ts | 5 +--- 8 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/examples/zkapps/reducer/map.ts b/src/examples/zkapps/reducer/map.ts index 1521b3a12e..70d7561ca5 100644 --- a/src/examples/zkapps/reducer/map.ts +++ b/src/examples/zkapps/reducer/map.ts @@ -30,9 +30,9 @@ map.set(key, value); map.get(key); // contract -zkApp.deploy(); // ... deploy the zkapp -zkApp.set(key, value); // ... set a key-value pair -zkApp.get(key); // ... get a value by key +await zkApp.deploy(); // ... deploy the zkapp +await zkApp.set(key, value); // ... set a key-value pair +await zkApp.get(key); // ... get a value by key ``` */ diff --git a/src/examples/zkapps/voting/demo.ts b/src/examples/zkapps/voting/demo.ts index 0a529e9eeb..1d2a77248d 100644 --- a/src/examples/zkapps/voting/demo.ts +++ b/src/examples/zkapps/voting/demo.ts @@ -61,21 +61,21 @@ let initialRoot = voterStore.getRoot(); tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer, 3); - contracts.voting.deploy({ zkappKey: votingKey }); + await contracts.voting.deploy(); contracts.voting.committedVotes.set(votesStore.getRoot()); contracts.voting.accumulatedVotes.set(Reducer.initialActionState); - contracts.candidateContract.deploy({ zkappKey: candidateKey }); + await contracts.candidateContract.deploy(); contracts.candidateContract.committedMembers.set(candidateStore.getRoot()); contracts.candidateContract.accumulatedMembers.set( Reducer.initialActionState ); - contracts.voterContract.deploy({ zkappKey: voterKey }); + await contracts.voterContract.deploy(); contracts.voterContract.committedMembers.set(voterStore.getRoot()); contracts.voterContract.accumulatedMembers.set(Reducer.initialActionState); }); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayerKey, votingKey, candidateKey, voterKey]).send(); let m: Member = Member.empty(); // lets register three voters diff --git a/src/examples/zkapps/voting/deploy-contracts.ts b/src/examples/zkapps/voting/deploy-contracts.ts index 5dc5221bbb..e14546ba50 100644 --- a/src/examples/zkapps/voting/deploy-contracts.ts +++ b/src/examples/zkapps/voting/deploy-contracts.ts @@ -15,8 +15,8 @@ import { Membership_ } from './membership.js'; import { Voting_ } from './voting.js'; class InvalidContract extends SmartContract { - async deploy(args: DeployArgs) { - await super.deploy(args); + async deploy() { + await super.deploy(); this.account.permissions.set({ ...Permissions.default(), editState: Permissions.none(), @@ -66,19 +66,21 @@ export async function deployContracts( let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer, 3); - await voting.deploy({ zkappKey: params.votingKey }); + await voting.deploy(); voting.committedVotes.set(votesRoot); voting.accumulatedVotes.set(Reducer.initialActionState); - await candidateContract.deploy({ zkappKey: params.candidateKey }); + await candidateContract.deploy(); candidateContract.committedMembers.set(candidateRoot); candidateContract.accumulatedMembers.set(Reducer.initialActionState); - await voterContract.deploy({ zkappKey: params.voterKey }); + await voterContract.deploy(); voterContract.committedMembers.set(voterRoot); voterContract.accumulatedMembers.set(Reducer.initialActionState); }); - await tx.sign([feePayerKey]).send(); + await tx + .sign([feePayerKey, params.votingKey, params.candidateKey, params.voterKey]) + .send(); console.log('successfully deployed contracts'); return { @@ -130,7 +132,7 @@ export async function deployInvalidContracts( let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer, 3); - await voting.deploy({ zkappKey: params.votingKey }); + await voting.deploy(); voting.committedVotes.set(votesRoot); voting.accumulatedVotes.set(Reducer.initialActionState); @@ -140,7 +142,7 @@ export async function deployInvalidContracts( params.candidateKey.toPublicKey() ); - await invalidCandidateContract.deploy({ zkappKey: params.candidateKey }); + await invalidCandidateContract.deploy(); candidateContract = invalidCandidateContract as Membership_; @@ -148,11 +150,13 @@ export async function deployInvalidContracts( params.voterKey.toPublicKey() ); - await invalidVoterContract.deploy({ zkappKey: params.voterKey }); + await invalidVoterContract.deploy(); voterContract = invalidVoterContract as Membership_; }); - await tx.sign([feePayerKey]).send(); + await tx + .sign([feePayerKey, params.votingKey, params.candidateKey, params.voterKey]) + .send(); console.log('successfully deployed contracts'); return { diff --git a/src/examples/zkapps/voting/membership.ts b/src/examples/zkapps/voting/membership.ts index 78c8ee947b..2c18a1ad80 100644 --- a/src/examples/zkapps/voting/membership.ts +++ b/src/examples/zkapps/voting/membership.ts @@ -4,7 +4,6 @@ import { state, State, method, - DeployArgs, Permissions, Bool, PublicKey, @@ -70,8 +69,8 @@ export class Membership_ extends SmartContract { }), }; - async deploy(args: DeployArgs) { - await super.deploy(args); + async deploy() { + await super.deploy(); this.account.permissions.set({ ...Permissions.default(), editState: Permissions.proofOrSignature(), diff --git a/src/examples/zkapps/voting/run-berkeley.ts b/src/examples/zkapps/voting/run-berkeley.ts index a14808a029..38ed59b2b2 100644 --- a/src/examples/zkapps/voting/run-berkeley.ts +++ b/src/examples/zkapps/voting/run-berkeley.ts @@ -91,11 +91,11 @@ let tx = await Mina.transaction( async () => { AccountUpdate.fundNewAccount(feePayerAddress, 3); - contracts.voting.deploy({ zkappKey: params.votingKey }); + await contracts.voting.deploy(); contracts.voting.committedVotes.set(storage.votesStore.getRoot()); contracts.voting.accumulatedVotes.set(Reducer.initialActionState); - await contracts.candidateContract.deploy({ zkappKey: params.candidateKey }); + await contracts.candidateContract.deploy(); contracts.candidateContract.committedMembers.set( storage.candidatesStore.getRoot() ); @@ -103,13 +103,17 @@ let tx = await Mina.transaction( Reducer.initialActionState ); - await contracts.voterContract.deploy({ zkappKey: params.voterKey }); + await contracts.voterContract.deploy(); contracts.voterContract.committedMembers.set(storage.votersStore.getRoot()); contracts.voterContract.accumulatedMembers.set(Reducer.initialActionState); } ); await tx.prove(); -await (await tx.sign([feePayerKey]).send()).wait(); +await ( + await tx + .sign([feePayerKey, params.votingKey, params.candidateKey, params.voterKey]) + .send() +).wait(); console.log('successfully deployed contracts'); diff --git a/src/examples/zkapps/voting/voting.ts b/src/examples/zkapps/voting/voting.ts index e1bf0b189c..84f526aaec 100644 --- a/src/examples/zkapps/voting/voting.ts +++ b/src/examples/zkapps/voting/voting.ts @@ -4,7 +4,6 @@ import { state, State, method, - DeployArgs, Permissions, PublicKey, Bool, @@ -97,8 +96,8 @@ export class Voting_ extends SmartContract { }), }; - async deploy(args: DeployArgs) { - await super.deploy(args); + async deploy() { + await super.deploy(); this.account.permissions.set({ ...Permissions.default(), editState: Permissions.proofOrSignature(), diff --git a/src/lib/mina/token/token-contract.ts b/src/lib/mina/token/token-contract.ts index 89cb7c4408..ad400259c4 100644 --- a/src/lib/mina/token/token-contract.ts +++ b/src/lib/mina/token/token-contract.ts @@ -41,7 +41,7 @@ abstract class TokenContract extends SmartContract { * * If the contract needs to be re-deployed, you can switch off this behaviour by overriding the `isNew` precondition: * ```ts - * deploy() { + * async deploy() { * await super.deploy(); * // DON'T DO THIS ON THE INITIAL DEPLOYMENT! * this.account.isNew.requireNothing(); diff --git a/src/lib/zkapp.ts b/src/lib/zkapp.ts index 33135d6c92..bfa7907b68 100644 --- a/src/lib/zkapp.ts +++ b/src/lib/zkapp.ts @@ -1435,10 +1435,7 @@ const SmartContractContext = { }; type DeployArgs = - | { - verificationKey?: { data: string; hash: string | Field }; - zkappKey?: PrivateKey; - } + | { verificationKey?: { data: string; hash: string | Field } } | undefined; function Account(address: PublicKey, tokenId?: Field) { From 81c2669f7426533c8650032d57ded6a38da70807 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 25 Mar 2024 21:00:12 +0100 Subject: [PATCH 19/20] changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3695e1113..80bfc20398 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheck()`, `Provable.constraintSystem()` and `{SmartContract,ZkProgram}.digest()` are also async now - **Remove deprecated APIs** - Remove `CircuitValue`, `prop`, `arrayProp` and `matrixProp` https://github.com/o1-labs/o1js/pull/1507 - - Remove `Mina.accountCreationFee()`, `Mina.BerkeleyQANet`, all APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if()`, `Field.isZero()`, `isReady` and `shutdown()` + - Remove `Mina.accountCreationFee()`, `Mina.BerkeleyQANet`, all APIs which accept private keys for feepayers, `Token`, `AccountUpdate.tokenSymbol`, `SmartContract.{token, setValue, setPermissions}`, "assert" methods for preconditions, `MerkleTee.calculateRootSlow()`, `Scalar.fromBigInt()`, `UInt64.lt()` and friends, deprecated static methods on `Group`, utility methods on `Circuit` like `Circuit.if()`, `Field.isZero()`, `isReady` and `shutdown()` https://github.com/o1-labs/o1js/pull/1515 +- Remove `privateKey` from the accepted arguments of `SmartContract.deploy()` https://github.com/o1-labs/o1js/pull/1515 - Remove `this.sender` which unintuitively did not prove that its value was the actual sender of the transaction https://github.com/o1-labs/o1js/pull/1464 [@julio4](https://github.com/julio4) Replaced by more explicit APIs: - `this.sender.getUnconstrained()` which has the old behavior of `this.sender`, and returns an unconstrained value (which means that the prover can set it to any value they want) From 558099461edf824a947043b8ef92b8fb05074570 Mon Sep 17 00:00:00 2001 From: Gregor Date: Tue, 26 Mar 2024 08:30:47 +0100 Subject: [PATCH 20/20] make `tx.sign()` require keys, since the keys where there are none is a no-op now. Remove no-op signs from transaction sending --- src/lib/account-update.ts | 8 ++++---- src/lib/account-update.unit-test.ts | 2 +- src/lib/mina.ts | 2 -- src/lib/mina/local-blockchain.ts | 2 -- src/lib/mina/transaction.ts | 8 ++++---- src/lib/precondition.test.ts | 2 +- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/lib/account-update.ts b/src/lib/account-update.ts index dc4f9a376d..7dd256d9ef 100644 --- a/src/lib/account-update.ts +++ b/src/lib/account-update.ts @@ -1809,9 +1809,9 @@ const Authorization = { function addMissingSignatures( zkappCommand: ZkappCommand, - additionalKeys = [] as PrivateKey[] + privateKeys: PrivateKey[] ): ZkappCommandSigned { - let additionalPublicKeys = additionalKeys.map((sk) => sk.toPublicKey()); + let additionalPublicKeys = privateKeys.map((sk) => sk.toPublicKey()); let { commitment, fullCommitment } = transactionCommitments( TypesBigint.ZkappCommand.fromJSON(ZkappCommand.toJSON(zkappCommand)), activeInstance.getNetworkId() @@ -1832,7 +1832,7 @@ function addMissingSignatures( // while .send() execution return { body, authorization: dummySignature() }; } - let privateKey = additionalKeys[i]; + let privateKey = privateKeys[i]; let signature = signFieldElement( fullCommitment, @@ -1860,7 +1860,7 @@ function addMissingSignatures( lazyAuthorization: undefined; }; } - let privateKey = additionalKeys[i]; + let privateKey = privateKeys[i]; let transactionCommitment = accountUpdate.body.useFullCommitment.toBoolean() ? fullCommitment diff --git a/src/lib/account-update.unit-test.ts b/src/lib/account-update.unit-test.ts index 67f8b65700..5f1e61a1b0 100644 --- a/src/lib/account-update.unit-test.ts +++ b/src/lib/account-update.unit-test.ts @@ -115,7 +115,7 @@ function createAccountUpdate() { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); }); - tx.sign(); + tx.sign([]); await expect(tx.send()).rejects.toThrow( 'Check signature: Invalid signature on fee payer for key' ); diff --git a/src/lib/mina.ts b/src/lib/mina.ts index 14ec9243e8..430cb63e10 100644 --- a/src/lib/mina.ts +++ b/src/lib/mina.ts @@ -253,8 +253,6 @@ function Network( ); }, async sendTransaction(txn: Transaction): Promise { - txn.sign(); - verifyTransactionLimits(txn.transaction); let [response, error] = await Fetch.sendZkapp(txn.toJSON()); diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index 2a8bb9d692..689991d983 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -117,8 +117,6 @@ function LocalBlockchain({ return networkState; }, async sendTransaction(txn: Transaction): Promise { - txn.sign(); - let zkappCommandJson = ZkappCommand.toJSON(txn.transaction); let commitments = transactionCommitments( TypesBigint.ZkappCommand.fromJSON(zkappCommandJson), diff --git a/src/lib/mina/transaction.ts b/src/lib/mina/transaction.ts index 4057a359d3..030e15fe99 100644 --- a/src/lib/mina/transaction.ts +++ b/src/lib/mina/transaction.ts @@ -65,7 +65,7 @@ type Transaction = { /** * Signs all {@link AccountUpdate}s included in the {@link Transaction} that require a signature. * {@link AccountUpdate}s that require a signature can be specified with `{AccountUpdate|SmartContract}.requireSignature()`. - * @param additionalKeys The list of keys that should be used to sign the {@link Transaction} + * @param privateKeys The list of keys that should be used to sign the {@link Transaction} * @returns The {@link Transaction} instance with all required signatures applied. * @example * ```ts @@ -73,7 +73,7 @@ type Transaction = { * console.log('Transaction signed successfully.'); * ``` */ - sign(additionalKeys?: PrivateKey[]): Transaction; + sign(privateKeys: PrivateKey[]): Transaction; /** * Initiates the proof generation process for the {@link Transaction}. This asynchronous operation is * crucial for zero-knowledge-based transactions, where proofs are required to validate state transitions. @@ -380,8 +380,8 @@ async function createTransaction( function newTransaction(transaction: ZkappCommand, proofsEnabled?: boolean) { let self: Transaction = { transaction, - sign(additionalKeys?: PrivateKey[]) { - self.transaction = addMissingSignatures(self.transaction, additionalKeys); + sign(privateKeys: PrivateKey[]) { + self.transaction = addMissingSignatures(self.transaction, privateKeys); return self; }, async prove() { diff --git a/src/lib/precondition.test.ts b/src/lib/precondition.test.ts index 0cf906e9d3..34b441629c 100644 --- a/src/lib/precondition.test.ts +++ b/src/lib/precondition.test.ts @@ -213,7 +213,7 @@ describe('preconditions', () => { // TODO: is this a gotcha that should be addressed? // the test below fails, so it seems that nonce is applied successfully with a WRONG precondition.. - // however, this is just because `zkapp.sign()` overwrites the nonce precondition with one that is satisfied + // however, this is just because `zkapp.requireSignature()` overwrites the nonce precondition with one that is satisfied it.skip('unsatisfied nonce precondition should be rejected', async () => { let tx = await Mina.transaction(feePayer, async () => { zkapp.account.nonce.requireEquals(UInt32.from(1e8));