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

Bring V2 up to date #1802

Closed
wants to merge 60 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
1083d82
chore(bindings): update subproject commit reference to 7705ca8e99bbe0…
ymekuria Jul 16, 2024
810bf31
chore(bindings): update subproject commit reference to a98e6cfa0fd91b…
ymekuria Jul 26, 2024
a107b42
chore(bindings): update subproject commit reference to 1f9522301 for …
ymekuria Jul 29, 2024
edc91bf
Merge branch 'main' into feature/tofields-array-handling
ymekuria Jul 29, 2024
5736917
chore(mina): update subproject commit reference to fe1761756 for cons…
ymekuria Jul 29, 2024
de8f46b
Validation.
shimkiv Jul 29, 2024
d9a6abf
Refactoring.
shimkiv Jul 29, 2024
f9f317e
Revert changes and comment.
shimkiv Jul 29, 2024
816e5f2
Update foreign-field constructor comment.
shimkiv Jul 30, 2024
9c87a7e
Addressing review comments.
shimkiv Jul 30, 2024
afa7558
Addressing review comments.
shimkiv Jul 30, 2024
0cbecd7
Update src/lib/provable/crypto/foreign-curve.ts
shimkiv Jul 30, 2024
22b15ea
Update src/lib/provable/crypto/foreign-ecdsa.ts
shimkiv Jul 30, 2024
807c9b3
Update src/lib/provable/foreign-field.ts
shimkiv Jul 30, 2024
84e4d5a
Remove type importing for JSDoc links.
shimkiv Jul 30, 2024
75f148b
Addressing review comments.
shimkiv Jul 31, 2024
17e1a1f
proposed fix for multiple actions issue
45930 Jul 31, 2024
5b1a071
rm erroneous changes
45930 Jul 31, 2024
f498251
adding a test
45930 Jul 31, 2024
9d6fbec
clean up
45930 Jul 31, 2024
5925904
Addressing review comments.
shimkiv Aug 1, 2024
fe63c18
Addressing review comments.
shimkiv Aug 1, 2024
fa9d7bc
Merge remote-tracking branch 'origin/main' into feat/foreign-field-re…
shimkiv Aug 1, 2024
72a2779
Merge pull request #1779 from o1-labs/feat/foreign-field-reduction
shimkiv Aug 1, 2024
dce77b1
formatting changes from PR review
45930 Aug 1, 2024
d2c9320
trying sort order based on account update id
45930 Aug 2, 2024
332f371
fix typing of sender spec in test
45930 Aug 2, 2024
b0a59da
more CI fixes
45930 Aug 2, 2024
5af8a2d
Merge branch 'main' into multi-actions-order
45930 Aug 2, 2024
6a00445
fix name typo in ci script
45930 Aug 2, 2024
aab8760
release lightnet accounts upon completion
45930 Aug 2, 2024
01cae16
await specif txs in ci
45930 Aug 2, 2024
7b6be89
chore(bindings): update subproject commit reference to 9c3001268 for …
ymekuria Aug 14, 2024
a6510ff
chore(mina): update subproject commit reference in mina submodule
ymekuria Aug 14, 2024
fa1c30f
Merge branch 'main' into feature/tofields-array-handling
ymekuria Aug 14, 2024
f476b3a
PR comments / cleanup
45930 Aug 14, 2024
599fe06
update bindings
45930 Aug 14, 2024
0feea17
update submodules
Trivo25 Aug 19, 2024
721ca6a
Merge pull request #1784 from o1-labs/multi-actions-order
45930 Aug 19, 2024
5adc752
feat(dex.ts): update UInt64x2 Struct layout
ymekuria Aug 20, 2024
fa67c3f
feat(dex.ts): update `redeemLiquidityPartialchange` method to return …
ymekuria Aug 20, 2024
cd55a51
feat(dex.ts): update `redeemLiquidity` method to return new UInt64x2 …
ymekuria Aug 20, 2024
55fe21b
refactor(dex.ts): destructure values from the result of redeemLiquidi…
ymekuria Aug 20, 2024
8821411
refactor(dex.ts): destructure the return value of dexX.redeemLiquidit…
ymekuria Aug 20, 2024
0617674
Merge pull request #1792 from o1-labs/chore-fix-build
Trivo25 Aug 21, 2024
78175fe
fix int64 mod when the input is negative and result = 0
mitschabaude Aug 21, 2024
ac03ac5
changelog
mitschabaude Aug 21, 2024
ecac253
int64 to bigint
mitschabaude Aug 21, 2024
a0d2f4b
chore(bindings): update subproject commit reference to 35b2a6135cdc0e…
ymekuria Aug 21, 2024
87cdba6
Merge branch 'main' into feature/tofields-array-handling
ymekuria Aug 21, 2024
def8e4f
chore(mina): update subproject commit reference to 02accb5bc5bd152b5b…
ymekuria Aug 21, 2024
9b57f3d
Merge pull request #1797 from o1-labs/fix/mod-int64
mitschabaude Aug 21, 2024
23e02cb
Merge pull request #1791 from o1-labs/feature/tofields-array-handling
ymekuria Aug 21, 2024
fa8462f
fix this.sender vulnerability
mitschabaude Aug 22, 2024
21e4940
changelog
mitschabaude Aug 22, 2024
a8df62c
also deprecate getUnconstrained
mitschabaude Aug 22, 2024
b733460
upgrade examples
mitschabaude Aug 22, 2024
bb1577f
missed two
mitschabaude Aug 22, 2024
8429474
dump vks
mitschabaude Aug 22, 2024
d94206d
Merge pull request #1799 from o1-labs/fix/this-sender
mitschabaude Aug 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased](https://github.com/o1-labs/o1js/compare/d6abf1d97...HEAD)

### Deprecated

- `this.sender.getAndRequireSignature()` / `getUnconstrained()` deprecated in favor of `V2` versions due to a vulnerability https://github.com/o1-labs/o1js/pull/1799

### Fixes

- Fix behavior of `Int64.modV2()` when the input is negative and the remainder should be 0 https://github.com/o1-labs/o1js/pull/1797

## [1.6.0](https://github.com/o1-labs/o1js/compare/1ad7333e9e...d6abf1d97) - 2024-07-23

### Added
Expand Down
9 changes: 9 additions & 0 deletions run-ci-live-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ echo ""

./run src/examples/zkapps/hello-world/run-live.ts --bundle | add_prefix "HELLO_WORLD" &
HELLO_WORLD_PROC=$!
./run src/examples/zkapps/reducer/run-live.ts --bundle | add_prefix "REDUCER" &
REDUCER_FLOW_PROC=$!
./run src/examples/zkapps/dex/run-live.ts --bundle | add_prefix "DEX" &
DEX_PROC=$!
./run src/examples/fetch-live.ts --bundle | add_prefix "FETCH" &
Expand Down Expand Up @@ -52,6 +54,13 @@ if [ $? -ne 0 ]; then
echo ""
FAILURE=1
fi
wait $REDUCER_FLOW_PROC
if [ $? -ne 0 ]; then
echo ""
echo "REDUCER_FLOW test failed."
echo ""
FAILURE=1
fi

# Exit with failure if any process failed
if [ $FAILURE -ne 0 ]; then
Expand Down
3 changes: 1 addition & 2 deletions run-ci-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ case $TEST_TYPE in

"Reducer integration tests")
echo "Running reducer integration tests"
./run src/examples/zkapps/reducer/actions-as-merkle-list.ts --bundle
./run src/examples/zkapps/reducer/actions-as-merkle-list-iterator.ts --bundle
./run src/examples/zkapps/reducer/run.ts --bundle
;;

"Voting integration tests")
Expand Down
2 changes: 1 addition & 1 deletion src/bindings
9 changes: 9 additions & 0 deletions src/examples/utils/network-configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export {
DEFAULT_LIGHTNET_CONFIG
}

const DEFAULT_LIGHTNET_CONFIG = {
mina: 'http://localhost:8080/graphql',
archive: 'http://localhost:8282',
lightnetAccountManager: 'http://localhost:8181',
}
23 changes: 23 additions & 0 deletions src/examples/utils/random-accounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { PrivateKey, PublicKey } from 'o1js';

export {
randomAccounts
}

/**
* Predefined accounts keys, labeled by the input strings. Useful for testing/debugging with consistent keys.
*/
function randomAccounts<K extends string>(
...names: [K, ...K[]]
): { keys: Record<K, PrivateKey>; addresses: Record<K, PublicKey> } {
let base58Keys = Array(names.length)
.fill('')
.map(() => PrivateKey.random().toBase58());
let keys = Object.fromEntries(
names.map((name, idx) => [name, PrivateKey.fromBase58(base58Keys[idx])])
) as Record<K, PrivateKey>;
let addresses = Object.fromEntries(
names.map((name) => [name, keys[name].toPublicKey()])
) as Record<K, PublicKey>;
return { keys, addresses };
}
18 changes: 9 additions & 9 deletions src/examples/zkapps/dex/dex-with-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
* This DEX implementation differs from ./dex.ts in two ways:
* - More minimal & realistic; stuff designed only for testing protocol features was removed
* - Uses an async pattern with actions that lets users claim funds later and reduces account updates
*
* Warning: The reducer API in o1js is currently not safe to use in production applications. The `reduce()`
* method breaks if more than the hard-coded number (default: 32) of actions are pending. Work is actively
*
* Warning: The reducer API in o1js is currently not safe to use in production applications. The `reduce()`
* method breaks if more than the hard-coded number (default: 32) of actions are pending. Work is actively
* in progress to mitigate this limitation.
*/
*/
import {
Account,
AccountUpdate,
Expand Down Expand Up @@ -86,7 +86,7 @@ class Dex extends TokenContract {
@method async createAccount() {
this.internal.mint({
// unconstrained because we don't care which account is created
address: this.sender.getUnconstrained(),
address: this.sender.getUnconstrainedV2(),
amount: UInt64.from(0),
});
}
Expand All @@ -104,7 +104,7 @@ class Dex extends TokenContract {
@method.returns(UInt64)
async supplyLiquidityBase(dx: UInt64, dy: UInt64) {
// unconstrained because `transfer()` requires sender signature anyway
let user = this.sender.getUnconstrained();
let user = this.sender.getUnconstrainedV2();
let tokenX = new TrivialCoin(this.tokenX);
let tokenY = new TrivialCoin(this.tokenY);

Expand Down Expand Up @@ -175,7 +175,7 @@ class Dex extends TokenContract {
* contracts pay you tokens when reducing the action.
*/
@method async redeemInitialize(dl: UInt64) {
let sender = this.sender.getUnconstrained(); // unconstrained because `burn()` requires sender signature anyway
let sender = this.sender.getUnconstrainedV2(); // unconstrained because `burn()` requires sender signature anyway
this.reducer.dispatch(new RedeemAction({ address: sender, dl }));
this.internal.burn({ address: sender, amount: dl });
// TODO: preconditioning on the state here ruins concurrent interactions,
Expand Down Expand Up @@ -209,7 +209,7 @@ class Dex extends TokenContract {
* the called methods which requires proof authorization.
*/
async swapX(dx: UInt64) {
let user = this.sender.getUnconstrained(); // unconstrained because `swap()` requires sender signature anyway
let user = this.sender.getUnconstrainedV2(); // unconstrained because `swap()` requires sender signature anyway
let tokenY = new TrivialCoin(this.tokenY);
let dexY = new DexTokenHolder(this.address, tokenY.deriveTokenId());
let dy = await dexY.swap(user, dx, this.tokenX);
Expand All @@ -228,7 +228,7 @@ class Dex extends TokenContract {
* the called methods which requires proof authorization.
*/
async swapY(dy: UInt64) {
let user = this.sender.getUnconstrained(); // unconstrained because `swap()` requires sender signature anyway
let user = this.sender.getUnconstrainedV2(); // unconstrained because `swap()` requires sender signature anyway
let tokenX = new TrivialCoin(this.tokenX);
let dexX = new DexTokenHolder(this.address, tokenX.deriveTokenId());
let dx = await dexX.swap(user, dy, this.tokenY);
Expand Down
28 changes: 16 additions & 12 deletions src/examples/zkapps/dex/dex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {

export { TokenContract, addresses, createDex, keys, randomAccounts, tokenIds };

class UInt64x2 extends Struct([UInt64, UInt64]) {}
class UInt64x2 extends Struct({ values: [UInt64, UInt64] }) {}

function createDex({
lockedLiquiditySlots,
Expand Down Expand Up @@ -56,7 +56,7 @@ function createDex({
*/
@method.returns(UInt64)
async supplyLiquidityBase(dx: UInt64, dy: UInt64) {
let user = this.sender.getUnconstrained(); // unconstrained because transfer() requires the signature anyway
let user = this.sender.getUnconstrainedV2(); // unconstrained because transfer() requires the signature anyway
let tokenX = new TokenContract(this.tokenX);
let tokenY = new TokenContract(this.tokenY);

Expand Down Expand Up @@ -155,10 +155,14 @@ function createDex({
*/
async redeemLiquidity(dl: UInt64) {
// call the token X holder inside a token X-approved callback
let sender = this.sender.getUnconstrained(); // unconstrained because redeemLiquidity() requires the signature anyway
let sender = this.sender.getUnconstrainedV2(); // unconstrained because redeemLiquidity() requires the signature anyway
let tokenX = new TokenContract(this.tokenX);
let dexX = new DexTokenHolder(this.address, tokenX.deriveTokenId());
let dxdy = await dexX.redeemLiquidity(sender, dl, this.tokenY);
let { values: dxdy } = await dexX.redeemLiquidity(
sender,
dl,
this.tokenY
);
let dx = dxdy[0];
await tokenX.transfer(dexX.self, sender, dx);
return dxdy;
Expand All @@ -173,7 +177,7 @@ function createDex({
*/
@method.returns(UInt64)
async swapX(dx: UInt64) {
let sender = this.sender.getUnconstrained(); // unconstrained because swap() requires the signature anyway
let sender = this.sender.getUnconstrainedV2(); // unconstrained because swap() requires the signature anyway
let tokenY = new TokenContract(this.tokenY);
let dexY = new DexTokenHolder(this.address, tokenY.deriveTokenId());
let dy = await dexY.swap(sender, dx, this.tokenX);
Expand All @@ -190,7 +194,7 @@ function createDex({
*/
@method.returns(UInt64)
async swapY(dy: UInt64) {
let sender = this.sender.getUnconstrained(); // unconstrained because swap() requires the signature anyway
let sender = this.sender.getUnconstrainedV2(); // unconstrained because swap() requires the signature anyway
let tokenX = new TokenContract(this.tokenX);
let dexX = new DexTokenHolder(this.address, tokenX.deriveTokenId());
let dx = await dexX.swap(sender, dy, this.tokenY);
Expand Down Expand Up @@ -229,7 +233,7 @@ function createDex({

@method.returns(UInt64)
async swapX(dx: UInt64) {
let sender = this.sender.getUnconstrained(); // unconstrained because swap() requires the signature anyway
let sender = this.sender.getUnconstrainedV2(); // unconstrained because swap() requires the signature anyway
let tokenY = new TokenContract(this.tokenY);
let dexY = new ModifiedDexTokenHolder(
this.address,
Expand Down Expand Up @@ -264,7 +268,7 @@ function createDex({
this.self.body.mayUseToken = AccountUpdate.MayUseToken.ParentsOwnToken;

// return l, dy so callers don't have to walk their child account updates to get it
return [l, dy];
return { values: [l, dy] };
}

// more complicated circuit, where we trigger the Y(other)-lqXY trade in our child account updates and then add the X(our) part
Expand All @@ -277,9 +281,9 @@ function createDex({
// first call the Y token holder, approved by the Y token contract; this makes sure we get dl, the user's lqXY
let tokenY = new TokenContract(otherTokenAddress);
let dexY = new DexTokenHolder(this.address, tokenY.deriveTokenId());
let result = await dexY.redeemLiquidityPartial(user, dl);
let l = result[0];
let dy = result[1];
let { values } = await dexY.redeemLiquidityPartial(user, dl);
let l = values[0];
let dy = values[1];
await tokenY.transfer(dexY.self, user, dy);

// in return for dl, we give back dx, the X token part
Expand All @@ -289,7 +293,7 @@ function createDex({
// just subtract the balance, user gets their part one level higher
this.balance.subInPlace(dx);

return [dx, dy];
return { values: [dx, dy] };
}

// this works for both directions (in our case where both tokens use the same contract)
Expand Down
2 changes: 1 addition & 1 deletion src/examples/zkapps/escrow/token-escrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class TokenEscrow extends SmartContract {
*/
@method async withdraw(amount: UInt64) {
// only the admin can withdraw
this.sender.getAndRequireSignature().assertEquals(admin);
this.sender.getAndRequireSignatureV2().assertEquals(admin);

// withdraw the amount
let receiverAU = this.send({ to: admin, amount });
Expand Down
72 changes: 38 additions & 34 deletions src/examples/zkapps/reducer/actions-as-merkle-list-iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
*
* This is mainly intended as an example for using `Iterator` and `MerkleList`, but it might also be useful as
* a blueprint for processing actions in a custom and more explicit way.
*
* Warning: The reducer API in o1js is currently not safe to use in production applications. The `reduce()`
* method breaks if more than the hard-coded number (default: 32) of actions are pending. Work is actively
*
* Warning: The reducer API in o1js is currently not safe to use in production applications. The `reduce()`
* method breaks if more than the hard-coded number (default: 32) of actions are pending. Work is actively
* in progress to mitigate this limitation.
*/
*/
import {
Field,
Mina,
Expand All @@ -20,6 +20,8 @@ import {
assert,
} from 'o1js';

export { ActionsContract, testLocal };

// constants for our static-sized provable code
const MAX_UPDATES_WITH_ACTIONS = 100;
const MAX_ACTIONS_PER_UPDATE = 2;
Expand Down Expand Up @@ -81,44 +83,46 @@ class ActionsContract extends SmartContract {

// TESTS

// set up a local blockchain
async function testLocal() {
// set up a local blockchain

let Local = await Mina.LocalBlockchain({ proofsEnabled: false });
Mina.setActiveInstance(Local);
let Local = await Mina.LocalBlockchain({ proofsEnabled: true });
Mina.setActiveInstance(Local);

let [sender, contractAddress] = Local.testAccounts;
let [sender, contractAddress] = Local.testAccounts.slice(4);

let contract = new ActionsContract(contractAddress);
let contract = new ActionsContract(contractAddress);

// deploy the contract
// deploy the contract

await ActionsContract.compile();
console.log(
`rows for ${MAX_UPDATES_WITH_ACTIONS} updates with actions`,
(await ActionsContract.analyzeMethods()).accumulate.rows
);
let deployTx = await Mina.transaction(sender, async () => contract.deploy());
await deployTx.sign([sender.key, contractAddress.key]).send();
await ActionsContract.compile();
console.log(
`rows for ${MAX_UPDATES_WITH_ACTIONS} updates with actions`,
(await ActionsContract.analyzeMethods()).accumulate.rows
);
let deployTx = await Mina.transaction(sender, async () => contract.deploy());
await deployTx.sign([sender.key, contractAddress.key]).send();

// push some actions
// push some actions

let dispatchTx = await Mina.transaction(sender, async () => {
await contract.increment(Field(1));
await contract.increment(Field(3));
await contract.increment(Field(5));
await contract.increment(Field(9));
await contract.twoIncrements(Field(18), Field(19));
});
await dispatchTx.prove();
await dispatchTx.sign([sender.key]).send();
let dispatchTx = await Mina.transaction(sender, async () => {
await contract.increment(Field(1));
await contract.increment(Field(3));
await contract.increment(Field(5));
await contract.increment(Field(9));
await contract.twoIncrements(Field(18), Field(19));
});
await dispatchTx.prove();
await dispatchTx.sign([sender.key]).send();

assert(contract.reducer.getActions().data.get().length === 5);
assert(contract.reducer.getActions().data.get().length === 5);

// accumulate actions
// accumulate actions

Local.setProofsEnabled(true);
let accTx = await Mina.transaction(sender, () => contract.accumulate());
await accTx.prove();
await accTx.sign([sender.key]).send();
Local.setProofsEnabled(true);
let accTx = await Mina.transaction(sender, () => contract.accumulate());
await accTx.prove();
await accTx.sign([sender.key]).send();

assert(contract.counter.get().toBigInt() === 55n);
assert(contract.counter.get().toBigInt() === 55n);
}
Loading
Loading