From b41ba14117f444a8bd9a7a3f16aa0ca9033adb52 Mon Sep 17 00:00:00 2001 From: Youtpout Date: Fri, 22 Nov 2024 11:58:29 +0100 Subject: [PATCH 1/6] add enforceTransactionLimits parameter for network --- src/lib/mina/mina.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/lib/mina/mina.ts b/src/lib/mina/mina.ts index 2dc41d5422..339e6e2717 100644 --- a/src/lib/mina/mina.ts +++ b/src/lib/mina/mina.ts @@ -104,21 +104,24 @@ function Network(options: { mina: string | string[]; archive?: string | string[]; lightnetAccountManager?: string; + enforceTransactionLimits?: boolean; }): Mina; function Network( options: | { - networkId?: NetworkId; - mina: string | string[]; - archive?: string | string[]; - lightnetAccountManager?: string; - } + networkId?: NetworkId; + mina: string | string[]; + archive?: string | string[]; + lightnetAccountManager?: string; + enforceTransactionLimits?: boolean; + } | string ): Mina { let minaNetworkId: NetworkId = 'testnet'; let minaGraphqlEndpoint: string; let archiveEndpoint: string; let lightnetAccountManagerEndpoint: string; + let enforceTransactionLimits: boolean = true; if (options && typeof options === 'string') { minaGraphqlEndpoint = options; @@ -158,6 +161,10 @@ function Network( lightnetAccountManagerEndpoint = options.lightnetAccountManager; Fetch.setLightnetAccountManagerEndpoint(lightnetAccountManagerEndpoint); } + + if (options.enforceTransactionLimits) { + enforceTransactionLimits = options.enforceTransactionLimits; + } } else { throw new Error( "Network: malformed input. Please provide a string or an object with 'mina' and 'archive' endpoints." @@ -251,7 +258,7 @@ function Network( }, sendTransaction(txn) { return toPendingTransactionPromise(async () => { - verifyTransactionLimits(txn.transaction); + if (enforceTransactionLimits) verifyTransactionLimits(txn.transaction); let [response, error] = await Fetch.sendZkapp(txn.toJSON()); let errors: string[] = []; From 0fee0090d1a1d8d50b2290c76fc22dc87de5eedb Mon Sep 17 00:00:00 2001 From: youtpout Date: Mon, 25 Nov 2024 11:14:49 +0100 Subject: [PATCH 2/6] add test transaction --- src/lib/mina/transaction.test.ts | 215 +++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 src/lib/mina/transaction.test.ts diff --git a/src/lib/mina/transaction.test.ts b/src/lib/mina/transaction.test.ts new file mode 100644 index 0000000000..4e95bdbbcc --- /dev/null +++ b/src/lib/mina/transaction.test.ts @@ -0,0 +1,215 @@ +import { + State, + state, + UInt64, + Bool, + SmartContract, + Mina, + AccountUpdate, + method, + PublicKey, + Permissions, + VerificationKey, + Field, + Int64, + TokenId, + TokenContract as TokenContractBase, + AccountUpdateForest, + PrivateKey, +} from 'o1js'; + + + +const defaultNetwork = Mina.Network({ + networkId: "testnet", + mina: "https://example.com/graphql", + archive: "https://example.com//graphql" +}); + +const enforcedNetwork = Mina.Network({ + networkId: "testnet", + mina: "https://example.com/graphql", + archive: "https://example.com//graphql", + enforceTransactionLimits: true +}); + +const unlimitedNetwork = Mina.Network({ + networkId: "testnet", + mina: "https://unlimited.com/graphql", + archive: "https://unlimited.com//graphql", + enforceTransactionLimits: false +}); + +describe('Test default network', () => { + let bobAccount: PublicKey, + bobKey: PrivateKey; + + beforeAll(async () => { + + Mina.setActiveInstance(defaultNetwork); + bobKey = PrivateKey.random(); + bobAccount = bobKey.toPublicKey(); + }); + + + it('Simple account update', async () => { + + let txn = await Mina.transaction(async () => { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(1)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + }); + console.log("Simple account update", txn.toPretty()); + console.log("Simple account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await txn.sign([bobKey]).safeSend(); + + }); + + it('Multiple account update', async () => { + + let txn = await Mina.transaction(async () => { + for (let index = 0; index < 2; index++) { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(index)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + } + }); + console.log("Multiple account update", txn.toPretty()); + console.log("Multiple account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await txn.sign([bobKey]).safeSend(); + + }); + + it('More than limit account update', async () => { + + let txn = await Mina.transaction(async () => { + for (let index = 0; index < 12; index++) { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(index)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + } + }); + console.log("More than limit account update", txn.toPretty()); + console.log("More than limit account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await expect(txn.sign([bobKey]).safeSend()).rejects.toThrow(); + }); +}); + +describe('Test enforced network', () => { + let bobAccount: PublicKey, + bobKey: PrivateKey; + + beforeAll(async () => { + + Mina.setActiveInstance(enforcedNetwork); + bobKey = PrivateKey.random(); + bobAccount = bobKey.toPublicKey(); + }); + + + it('Simple account update', async () => { + + let txn = await Mina.transaction(async () => { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(1)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + }); + console.log("Simple account update", txn.toPretty()); + console.log("Simple account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await txn.sign([bobKey]).safeSend(); + + }); + + it('Multiple account update', async () => { + + let txn = await Mina.transaction(async () => { + for (let index = 0; index < 2; index++) { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(index)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + } + }); + console.log("Multiple account update", txn.toPretty()); + console.log("Multiple account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await txn.sign([bobKey]).safeSend(); + + }); + + it('More than limit account update', async () => { + + let txn = await Mina.transaction(async () => { + for (let index = 0; index < 12; index++) { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(index)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + } + }); + console.log("More than limit account update", txn.toPretty()); + console.log("More than limit account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await expect(txn.sign([bobKey]).safeSend()).rejects.toThrow(); + }); +}); + +describe('Test unlimited network', () => { + let bobAccount: PublicKey, + bobKey: PrivateKey; + + beforeAll(async () => { + + Mina.setActiveInstance(unlimitedNetwork); + bobKey = PrivateKey.random(); + bobAccount = bobKey.toPublicKey(); + }); + + + it('Simple account update', async () => { + + let txn = await Mina.transaction(async () => { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(1)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + }); + console.log("Simple account update", txn.toPretty()); + console.log("Simple account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await txn.sign([bobKey]).safeSend(); + + }); + + it('Multiple account update', async () => { + + let txn = await Mina.transaction(async () => { + for (let index = 0; index < 2; index++) { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(index)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + } + }); + console.log("Multiple account update", txn.toPretty()); + console.log("Multiple account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await txn.sign([bobKey]).safeSend(); + + }); + + it('More than limit account update', async () => { + + let txn = await Mina.transaction(async () => { + for (let index = 0; index < 12; index++) { + const accountUpdateBob = AccountUpdate.create(bobAccount, Field.from(index)); + accountUpdateBob.account.balance.requireEquals(UInt64.zero); + accountUpdateBob.balance.addInPlace(UInt64.one); + } + }); + console.log("More than limit account update", txn.toPretty()); + console.log("More than limit account update", txn.transaction.accountUpdates.length); + await txn.prove(); + await txn.sign([bobKey]).safeSend(); + }); +}); \ No newline at end of file From 3b4361481a47cd482adc0571ed694c9f9b6def13 Mon Sep 17 00:00:00 2001 From: youtpout Date: Mon, 25 Nov 2024 15:26:36 +0100 Subject: [PATCH 3/6] update enforce variable verification --- src/lib/mina/mina.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/mina/mina.ts b/src/lib/mina/mina.ts index 339e6e2717..aba1599b2c 100644 --- a/src/lib/mina/mina.ts +++ b/src/lib/mina/mina.ts @@ -162,7 +162,8 @@ function Network( Fetch.setLightnetAccountManagerEndpoint(lightnetAccountManagerEndpoint); } - if (options.enforceTransactionLimits) { + if (options.enforceTransactionLimits !== undefined && + typeof options.enforceTransactionLimits === 'boolean') { enforceTransactionLimits = options.enforceTransactionLimits; } } else { From b6e9023d6f4e891fdc31593d2b9edf983de68f53 Mon Sep 17 00:00:00 2001 From: youtpout Date: Mon, 25 Nov 2024 16:00:22 +0100 Subject: [PATCH 4/6] remove console log from tests --- src/lib/mina/transaction.test.ts | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/lib/mina/transaction.test.ts b/src/lib/mina/transaction.test.ts index 4e95bdbbcc..580e2afa5e 100644 --- a/src/lib/mina/transaction.test.ts +++ b/src/lib/mina/transaction.test.ts @@ -59,8 +59,6 @@ describe('Test default network', () => { accountUpdateBob.account.balance.requireEquals(UInt64.zero); accountUpdateBob.balance.addInPlace(UInt64.one); }); - console.log("Simple account update", txn.toPretty()); - console.log("Simple account update", txn.transaction.accountUpdates.length); await txn.prove(); await txn.sign([bobKey]).safeSend(); @@ -75,8 +73,6 @@ describe('Test default network', () => { accountUpdateBob.balance.addInPlace(UInt64.one); } }); - console.log("Multiple account update", txn.toPretty()); - console.log("Multiple account update", txn.transaction.accountUpdates.length); await txn.prove(); await txn.sign([bobKey]).safeSend(); @@ -91,9 +87,8 @@ describe('Test default network', () => { accountUpdateBob.balance.addInPlace(UInt64.one); } }); - console.log("More than limit account update", txn.toPretty()); - console.log("More than limit account update", txn.transaction.accountUpdates.length); await txn.prove(); + // failure with default enforceTransactionLimits await expect(txn.sign([bobKey]).safeSend()).rejects.toThrow(); }); }); @@ -117,8 +112,6 @@ describe('Test enforced network', () => { accountUpdateBob.account.balance.requireEquals(UInt64.zero); accountUpdateBob.balance.addInPlace(UInt64.one); }); - console.log("Simple account update", txn.toPretty()); - console.log("Simple account update", txn.transaction.accountUpdates.length); await txn.prove(); await txn.sign([bobKey]).safeSend(); @@ -133,8 +126,6 @@ describe('Test enforced network', () => { accountUpdateBob.balance.addInPlace(UInt64.one); } }); - console.log("Multiple account update", txn.toPretty()); - console.log("Multiple account update", txn.transaction.accountUpdates.length); await txn.prove(); await txn.sign([bobKey]).safeSend(); @@ -149,9 +140,8 @@ describe('Test enforced network', () => { accountUpdateBob.balance.addInPlace(UInt64.one); } }); - console.log("More than limit account update", txn.toPretty()); - console.log("More than limit account update", txn.transaction.accountUpdates.length); await txn.prove(); + // failure with enforceTransactionLimits = true await expect(txn.sign([bobKey]).safeSend()).rejects.toThrow(); }); }); @@ -175,8 +165,6 @@ describe('Test unlimited network', () => { accountUpdateBob.account.balance.requireEquals(UInt64.zero); accountUpdateBob.balance.addInPlace(UInt64.one); }); - console.log("Simple account update", txn.toPretty()); - console.log("Simple account update", txn.transaction.accountUpdates.length); await txn.prove(); await txn.sign([bobKey]).safeSend(); @@ -191,8 +179,6 @@ describe('Test unlimited network', () => { accountUpdateBob.balance.addInPlace(UInt64.one); } }); - console.log("Multiple account update", txn.toPretty()); - console.log("Multiple account update", txn.transaction.accountUpdates.length); await txn.prove(); await txn.sign([bobKey]).safeSend(); @@ -207,9 +193,8 @@ describe('Test unlimited network', () => { accountUpdateBob.balance.addInPlace(UInt64.one); } }); - console.log("More than limit account update", txn.toPretty()); - console.log("More than limit account update", txn.transaction.accountUpdates.length); await txn.prove(); + // success with enforceTransactionLimits = false await txn.sign([bobKey]).safeSend(); }); }); \ No newline at end of file From 0aec72bcf69d47c1f3d4e25c821379b22a3c0357 Mon Sep 17 00:00:00 2001 From: youtpout Date: Mon, 25 Nov 2024 16:28:42 +0100 Subject: [PATCH 5/6] update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da97589a32..e5e1272dd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased](https://github.com/o1-labs/o1js/compare/e1bac02...HEAD) + +### Added + +- Add `enforceTransactionLimits` parameter on Network https://github.com/o1-labs/o1js/issues/1910 + ### Fixed - Compiling stuck in the browser for recursive zkprograms https://github.com/o1-labs/o1js/pull/1906 From 7e5fb96a4625cbf10716d06fd89ed1c65e1c44a2 Mon Sep 17 00:00:00 2001 From: youtpout Date: Tue, 26 Nov 2024 13:21:56 +0100 Subject: [PATCH 6/6] rename test, change parameter name to bypassTransactionLimits --- ...ction.test.ts => mina.network.unit-test.ts} | 18 ++++++++++-------- src/lib/mina/mina.ts | 10 +++++----- 2 files changed, 15 insertions(+), 13 deletions(-) rename src/lib/mina/{transaction.test.ts => mina.network.unit-test.ts} (93%) diff --git a/src/lib/mina/transaction.test.ts b/src/lib/mina/mina.network.unit-test.ts similarity index 93% rename from src/lib/mina/transaction.test.ts rename to src/lib/mina/mina.network.unit-test.ts index 580e2afa5e..73b2a0e1d0 100644 --- a/src/lib/mina/transaction.test.ts +++ b/src/lib/mina/mina.network.unit-test.ts @@ -17,6 +17,8 @@ import { AccountUpdateForest, PrivateKey, } from 'o1js'; +import { test, describe, it, before } from 'node:test'; +import { expect } from 'expect'; @@ -30,21 +32,21 @@ const enforcedNetwork = Mina.Network({ networkId: "testnet", mina: "https://example.com/graphql", archive: "https://example.com//graphql", - enforceTransactionLimits: true + bypassTransactionLimits: false }); const unlimitedNetwork = Mina.Network({ networkId: "testnet", mina: "https://unlimited.com/graphql", archive: "https://unlimited.com//graphql", - enforceTransactionLimits: false + bypassTransactionLimits: true }); describe('Test default network', () => { let bobAccount: PublicKey, bobKey: PrivateKey; - beforeAll(async () => { + before(async () => { Mina.setActiveInstance(defaultNetwork); bobKey = PrivateKey.random(); @@ -88,7 +90,7 @@ describe('Test default network', () => { } }); await txn.prove(); - // failure with default enforceTransactionLimits + // failure with default bypassTransactionLimits value await expect(txn.sign([bobKey]).safeSend()).rejects.toThrow(); }); }); @@ -97,7 +99,7 @@ describe('Test enforced network', () => { let bobAccount: PublicKey, bobKey: PrivateKey; - beforeAll(async () => { + before(async () => { Mina.setActiveInstance(enforcedNetwork); bobKey = PrivateKey.random(); @@ -141,7 +143,7 @@ describe('Test enforced network', () => { } }); await txn.prove(); - // failure with enforceTransactionLimits = true + // failure with bypassTransactionLimits = false await expect(txn.sign([bobKey]).safeSend()).rejects.toThrow(); }); }); @@ -150,7 +152,7 @@ describe('Test unlimited network', () => { let bobAccount: PublicKey, bobKey: PrivateKey; - beforeAll(async () => { + before(async () => { Mina.setActiveInstance(unlimitedNetwork); bobKey = PrivateKey.random(); @@ -194,7 +196,7 @@ describe('Test unlimited network', () => { } }); await txn.prove(); - // success with enforceTransactionLimits = false + // success with bypassTransactionLimits = true await txn.sign([bobKey]).safeSend(); }); }); \ No newline at end of file diff --git a/src/lib/mina/mina.ts b/src/lib/mina/mina.ts index aba1599b2c..67edd659e5 100644 --- a/src/lib/mina/mina.ts +++ b/src/lib/mina/mina.ts @@ -104,7 +104,7 @@ function Network(options: { mina: string | string[]; archive?: string | string[]; lightnetAccountManager?: string; - enforceTransactionLimits?: boolean; + bypassTransactionLimits?: boolean; }): Mina; function Network( options: @@ -113,7 +113,7 @@ function Network( mina: string | string[]; archive?: string | string[]; lightnetAccountManager?: string; - enforceTransactionLimits?: boolean; + bypassTransactionLimits?: boolean; } | string ): Mina { @@ -162,9 +162,9 @@ function Network( Fetch.setLightnetAccountManagerEndpoint(lightnetAccountManagerEndpoint); } - if (options.enforceTransactionLimits !== undefined && - typeof options.enforceTransactionLimits === 'boolean') { - enforceTransactionLimits = options.enforceTransactionLimits; + if (options.bypassTransactionLimits !== undefined && + typeof options.bypassTransactionLimits === 'boolean') { + enforceTransactionLimits = !options.bypassTransactionLimits; } } else { throw new Error(