Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Async circuits, pt 2 - witness and transaction callback #1468

Merged
merged 12 commits into from
Mar 7, 2024
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Breaking changes

- Require the callback to `Mina.transaction()` to be async https://github.com/o1-labs/o1js/pull/1468
- This change was done in support to support async contract methods
- 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
- These changes were made to add internal support for async circuits
Expand Down Expand Up @@ -48,6 +50,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Added

- `Provable.witnessAsync()` to introduce provable values from an async callback https://github.com/o1-labs/o1js/pull/1468
- Support for custom network identifiers other than `mainnet` or `testnet` https://github.com/o1-labs/o1js/pull/1444
- `PrivateKey.randomKeypair()` to generate private and public key in one command https://github.com/o1-labs/o1js/pull/1446
- `setNumberOfWorkers()` to allow developer to override the number of workers used during compilation and proof generation/verification https://github.com/o1-labs/o1js/pull/1456
Expand Down
6 changes: 3 additions & 3 deletions src/examples/circuit-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ console.log('compile...');
await MyContract.compile();
// should work
console.log('prove...');
let tx = await Mina.transaction(() => {
let tx = await Mina.transaction(async () => {
new MyContract(address).checkString(CircuitString.fromString('a string'));
});
await tx.prove();
console.log('test 1 - ok');
// should work
tx = await Mina.transaction(() => {
tx = await Mina.transaction(async () => {
new MyContract(address).checkString(CircuitString.fromString('some string'));
});
await tx.prove();
console.log('test 2 - ok');
// should fail
let fails = await Mina.transaction(() => {
let fails = await Mina.transaction(async () => {
new MyContract(address).checkString(CircuitString.fromString('different'));
})
.then(() => false)
Expand Down
4 changes: 2 additions & 2 deletions src/examples/commonjs.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async function main() {
await SimpleZkapp.compile();

console.log('deploy');
let tx = await Mina.transaction(feePayer, () => {
let tx = await Mina.transaction(feePayer, async () => {
AccountUpdate.fundNewAccount(feePayer);
zkapp.deploy();
});
Expand All @@ -65,7 +65,7 @@ async function main() {
console.log('initial state: ' + zkapp.x.get());

console.log('update');
tx = await Mina.transaction(feePayer, () => zkapp.update(Field(3)));
tx = await Mina.transaction(feePayer, async () => zkapp.update(Field(3)));
await tx.prove();
await tx.sign([feePayerKey]).send();
console.log('final state: ' + zkapp.x.get());
Expand Down
2 changes: 1 addition & 1 deletion src/examples/fetch-live.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function checkActualNetworkConstantsFetching() {
'\nCase #2: check that actual network constants can be fetched within the transaction scope.'
);
let networkConstants: Mina.NetworkConstants | undefined;
await Mina.transaction({ sender, fee: transactionFee }, () => {
await Mina.transaction({ sender, fee: transactionFee }, async () => {
networkConstants = Mina.getNetworkConstants();
});
expect(networkConstants?.slotTime).not.toBeUndefined();
Expand Down
6 changes: 3 additions & 3 deletions src/examples/nullifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ console.log('compile');
await PayoutOnlyOnce.compile();

console.log('deploy');
let tx = await Mina.transaction(sender, () => {
let tx = await Mina.transaction(sender, async () => {
let senderUpdate = AccountUpdate.fundNewAccount(sender);
senderUpdate.send({ to: zkappAddress, amount: initialBalance });
zkapp.deploy({ zkappKey });
Expand All @@ -94,7 +94,7 @@ let jsonNullifier = Nullifier.createTestNullifier(
console.log(jsonNullifier);

console.log('pay out');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
AccountUpdate.fundNewAccount(sender);
zkapp.payout(Nullifier.fromJSON(jsonNullifier));
});
Expand All @@ -109,7 +109,7 @@ console.log(
console.log('trying second pay out');

try {
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
zkapp.payout(Nullifier.fromJSON(jsonNullifier));
});

Expand Down
4 changes: 2 additions & 2 deletions src/examples/simple-zkapp-berkeley.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ if (!isDeployed) {
// the `transaction()` interface is the same as when testing with a local blockchain
let transaction = await Mina.transaction(
{ sender: feePayerAddress, fee: transactionFee },
() => {
async () => {
AccountUpdate.fundNewAccount(feePayerAddress);
zkapp.deploy({ verificationKey });
}
Expand All @@ -102,7 +102,7 @@ if (isDeployed) {
console.log(`Found deployed zkapp, updating state ${x} -> ${x.add(10)}.`);
let transaction = await Mina.transaction(
{ sender: feePayerAddress, fee: transactionFee },
() => {
async () => {
zkapp.update(Field(10));
}
);
Expand Down
4 changes: 2 additions & 2 deletions src/examples/simple-zkapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ console.log('compile');
await SimpleZkapp.compile();

console.log('deploy');
let tx = await Mina.transaction(feePayer, () => {
let tx = await Mina.transaction(feePayer, async () => {
AccountUpdate.fundNewAccount(feePayer);
zkapp.deploy();
});
Expand All @@ -68,7 +68,7 @@ await tx.sign([feePayerKey, zkappKey]).send();
console.log('initial state: ' + zkapp.x.get());

console.log('update');
tx = await Mina.transaction(feePayer, () => zkapp.update(Field(3)));
tx = await Mina.transaction(feePayer, async () => zkapp.update(Field(3)));
await tx.prove();
await tx.sign([feePayerKey]).send();
console.log('final state: ' + zkapp.x.get());
Expand Down
12 changes: 6 additions & 6 deletions src/examples/simple-zkapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ if (doProofs) {
}

console.log('deploy');
let tx = await Mina.transaction(sender, () => {
let tx = await Mina.transaction(sender, async () => {
let senderUpdate = AccountUpdate.fundNewAccount(sender);
senderUpdate.send({ to: zkappAddress, amount: initialBalance });
zkapp.deploy();
Expand All @@ -111,22 +111,22 @@ let account = Mina.getAccount(zkappAddress);
console.log('account state is proved:', account.zkapp?.provedState.toBoolean());

console.log('update');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
zkapp.update(Field(3));
});
await tx.prove();
await tx.sign([senderKey]).send();

// pay more into the zkapp -- this doesn't need a proof
console.log('receive');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
let payerAccountUpdate = AccountUpdate.createSigned(sender);
payerAccountUpdate.send({ to: zkappAddress, amount: UInt64.from(8e9) });
});
await tx.sign([senderKey]).send();

console.log('payout');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
AccountUpdate.fundNewAccount(sender);
zkapp.payout(privilegedKey);
});
Expand All @@ -138,7 +138,7 @@ console.log('final state: ' + zkapp.x.get());
console.log(`final balance: ${zkapp.account.balance.get().div(1e9)} MINA`);

console.log('try to payout a second time..');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
zkapp.payout(privilegedKey);
});
try {
Expand All @@ -150,7 +150,7 @@ try {

console.log('try to payout to a different account..');
try {
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
zkapp.payout(Local.testAccounts[2].privateKey);
});
await tx.prove();
Expand Down
8 changes: 4 additions & 4 deletions src/examples/simple-zkapp.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ if (doProofs) {
}

console.log('deploy');
let tx = await Mina.transaction(sender, () => {
let tx = await Mina.transaction(sender, async () => {
let senderUpdate = AccountUpdate.fundNewAccount(sender);
senderUpdate.send({ to: zkappAddress, amount: initialBalance });
zkapp.deploy({ zkappKey });
Expand All @@ -104,22 +104,22 @@ let account = Mina.getAccount(zkappAddress);
console.log('account state is proved:', account.zkapp?.provedState.toBoolean());

console.log('update');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
zkapp.update(Field(3));
});
await tx.prove();
await tx.sign([senderKey]).send();

// pay more into the zkapp -- this doesn't need a proof
console.log('receive');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
let payerAccountUpdate = AccountUpdate.createSigned(sender);
payerAccountUpdate.send({ to: zkappAddress, amount: UInt64.from(8e9) });
});
await tx.sign([senderKey]).send();

console.log('payout');
tx = await Mina.transaction(sender, () => {
tx = await Mina.transaction(sender, async () => {
AccountUpdate.fundNewAccount(sender);
zkapp.payout(privilegedKey);
});
Expand Down
4 changes: 2 additions & 2 deletions src/examples/zkapps/composability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ if (doProofs) {
}

console.log('deploy');
let tx = await Mina.transaction(feePayer, () => {
let tx = await Mina.transaction(feePayer, async () => {
// TODO: enable funding multiple accounts properly
AccountUpdate.fundNewAccount(feePayer, 3);
zkapp.deploy();
Expand All @@ -95,7 +95,7 @@ let tx = await Mina.transaction(feePayer, () => {
await tx.sign([feePayerKey, zkappKey, adderKey, incrementerKey]).send();

console.log('call interaction');
tx = await Mina.transaction(feePayer, () => {
tx = await Mina.transaction(feePayer, async () => {
// we just call one contract here, nothing special to do
zkapp.callAddAndEmit(Field(5), Field(6));
});
Expand Down
18 changes: 9 additions & 9 deletions src/examples/zkapps/dex/happy-path-with-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ let dexTokenHolderX = new DexTokenHolder(addresses.dex, tokenIds.X);
let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y);

tic('deploy & init token contracts');
tx = await Mina.transaction(feePayerAddress, () => {
tx = await Mina.transaction(feePayerAddress, async () => {
tokenX.deploy();
tokenY.deploy();

Expand All @@ -58,7 +58,7 @@ toc();
console.log('account updates length', tx.transaction.accountUpdates.length);

tic('deploy dex contracts');
tx = await Mina.transaction(feePayerAddress, () => {
tx = await Mina.transaction(feePayerAddress, async () => {
// pay fees for creating 3 dex accounts
AccountUpdate.createSigned(feePayerAddress).balance.subInPlace(
Mina.getNetworkConstants().accountCreationFee.mul(3)
Expand All @@ -76,7 +76,7 @@ console.log('account updates length', tx.transaction.accountUpdates.length);

tic('transfer tokens to user');
let USER_DX = 1_000n;
tx = await Mina.transaction(feePayerAddress, () => {
tx = await Mina.transaction(feePayerAddress, async () => {
// pay fees for creating 3 user accounts
let feePayer = AccountUpdate.fundNewAccount(feePayerAddress, 3);
feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees
Expand All @@ -90,7 +90,7 @@ console.log('account updates length', tx.transaction.accountUpdates.length);

// this is done in advance to avoid account update limit in `supply`
tic("create user's lq token account");
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
AccountUpdate.fundNewAccount(addresses.user);
dex.createAccount();
});
Expand All @@ -104,7 +104,7 @@ expect(balances.user.X).toEqual(USER_DX);
console.log(balances);

tic('supply liquidity');
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
dex.supplyLiquidityBase(UInt64.from(USER_DX), UInt64.from(USER_DX));
});
await tx.prove();
Expand All @@ -117,7 +117,7 @@ console.log(balances);

tic('redeem liquidity, step 1');
let USER_DL = 100n;
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
dex.redeemInitialize(UInt64.from(USER_DL));
});
await tx.prove();
Expand All @@ -127,7 +127,7 @@ console.log('account updates length', tx.transaction.accountUpdates.length);
console.log(getTokenBalances());

tic('redeem liquidity, step 2a (get back token X)');
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
dexTokenHolderX.redeemLiquidityFinalize();
tokenX.approveAccountUpdate(dexTokenHolderX.self);
});
Expand All @@ -138,7 +138,7 @@ console.log('account updates length', tx.transaction.accountUpdates.length);
console.log(getTokenBalances());

tic('redeem liquidity, step 2b (get back token Y)');
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
dexTokenHolderY.redeemLiquidityFinalize();
tokenY.approveAccountUpdate(dexTokenHolderY.self);
});
Expand All @@ -153,7 +153,7 @@ expect(balances.user.X).toEqual(USER_DL / 2n);

tic('swap 10 X for Y');
USER_DX = 10n;
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
dex.swapX(UInt64.from(USER_DX));
});
await tx.prove();
Expand Down
12 changes: 6 additions & 6 deletions src/examples/zkapps/dex/happy-path-with-proofs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ let dexTokenHolderX = new DexTokenHolder(addresses.dex, tokenIds.X);
let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y);

tic('deploy & init token contracts');
tx = await Mina.transaction(feePayerAddress, () => {
tx = await Mina.transaction(feePayerAddress, async () => {
tokenX.deploy();
tokenY.deploy();

Expand All @@ -60,7 +60,7 @@ toc();
console.log('account updates length', tx.transaction.accountUpdates.length);

tic('deploy dex contracts');
tx = await Mina.transaction(feePayerAddress, () => {
tx = await Mina.transaction(feePayerAddress, async () => {
// pay fees for creating 3 dex accounts
AccountUpdate.createSigned(feePayerAddress).balance.subInPlace(
Mina.getNetworkConstants().accountCreationFee.mul(3)
Expand All @@ -78,7 +78,7 @@ console.log('account updates length', tx.transaction.accountUpdates.length);

tic('transfer tokens to user');
let USER_DX = 1_000n;
tx = await Mina.transaction(feePayerAddress, () => {
tx = await Mina.transaction(feePayerAddress, async () => {
// pay fees for creating 3 user accounts
let feePayer = AccountUpdate.fundNewAccount(feePayerAddress, 3);
feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees
Expand All @@ -93,7 +93,7 @@ console.log('account updates length', tx.transaction.accountUpdates.length);
expect(balances.user.X).toEqual(USER_DX);

tic('supply liquidity');
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
AccountUpdate.fundNewAccount(addresses.user);
dex.supplyLiquidityBase(UInt64.from(USER_DX), UInt64.from(USER_DX));
});
Expand All @@ -106,7 +106,7 @@ expect(balances.user.X).toEqual(0n);

tic('redeem liquidity');
let USER_DL = 100n;
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
dex.redeemLiquidity(UInt64.from(USER_DL));
});

Expand All @@ -119,7 +119,7 @@ expect(balances.user.X).toEqual(USER_DL / 2n);

tic('swap 10 X for Y');
USER_DX = 10n;
tx = await Mina.transaction(addresses.user, () => {
tx = await Mina.transaction(addresses.user, async () => {
dex.swapX(UInt64.from(USER_DX));
});
await tx.prove();
Expand Down
Loading
Loading