Skip to content

Commit

Permalink
Merge pull request #1911 from o1-labs/test/recursive-zkprogram-web
Browse files Browse the repository at this point in the history
Add recursive ZkProgram to e2e testing
  • Loading branch information
boray authored Nov 21, 2024
2 parents 5c50f6f + 6260b56 commit a0f0f34
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 11 deletions.
39 changes: 28 additions & 11 deletions src/build/e2e-tests-build-helper.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import replace from 'replace-in-file';

const options = {
files: './dist/web/examples/zkapps/**/*.js',
from: /from 'o1js'/g,
to: "from '../../../index.js'",
};

try {
const results = await replace(options);
console.log('Replacement results:', results);
} catch (error) {
console.error('Error occurred:', error);
const replaceOptions = [
{
files: './dist/web/examples/zkapps/**/*.js',
from: /from 'o1js'/g,
to: "from '../../../index.js'",
},
{
files: './dist/web/examples/zkprogram/*.js',
from: /from 'o1js'/g,
to: "from '../../index.js'",
},
];

async function performReplacement(options) {
try {
const results = await replace(options);
console.log(`Replacement results for ${options.files}:`, results);
} catch (error) {
console.error(`Error occurred while replacing in ${options.files}:`, error);
}
}

async function main() {
for (const options of replaceOptions) {
await performReplacement(options);
}
}

main();
23 changes: 23 additions & 0 deletions src/examples/zkprogram/recursive-program.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { SelfProof, Field, ZkProgram } from 'o1js';

export const RecursiveProgram = ZkProgram({
name: 'recursive-program',
publicInput: Field,

methods: {
baseCase: {
privateInputs: [],
async method(input: Field) {
input.assertEquals(Field(0));
},
},

inductiveCase: {
privateInputs: [SelfProof],
async method(input: Field, earlierProof: SelfProof<Field, void>) {
earlierProof.verify();
earlierProof.publicInput.add(1).assertEquals(input);
},
},
},
});
4 changes: 4 additions & 0 deletions tests/artifacts/html/on-chain-state-mgmt-zkapp-ui.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ <h3>UI for the On-Chain State Management zkApp</h3>
</div>
<hr />
<div>
<h4>zkProgram Management</h4>
<div>
<button type="button" id="compileButton">Compile ZkProgram</button>
</div>
<h4>zkApp Management</h4>
<div>
<button type="button" id="deployButton">Deploy zkApp</button>
Expand Down
18 changes: 18 additions & 0 deletions tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import {
adminPrivateKey,
HelloWorld,
} from './examples/zkapps/hello-world/hello-world.js';
import { RecursiveProgram } from './examples/zkprogram/recursive-program.js';
import { AccountUpdate, Field, Mina, verify } from './index.js';

const compileButton = document.querySelector('#compileButton');
const deployButton = document.querySelector('#deployButton');
const updateButton = document.querySelector('#updateButton');
const clearEventsButton = document.querySelector('#clearEventsButton');
Expand All @@ -25,6 +27,22 @@ const contractAddress = Mina.TestPublicKey.random();
const contract = new HelloWorld(contractAddress);
let verificationKey = null;

compileButton.addEventListener('click', async () => {
compileButton.disabled = true;

logEvents('Compiling ZkProgram', eventsContainer);

try {
await RecursiveProgram.compile();
logEvents('ZkProgram compiled successfully!', eventsContainer);
} catch (exception) {
logEvents(`Compilation failure: ${exception.message}`, eventsContainer);
console.log(exception);
}

compileButton.disabled = false;
});

deployButton.addEventListener('click', async () => {
deployButton.disabled = true;

Expand Down
10 changes: 10 additions & 0 deletions tests/on-chain-state-mgmt-zkapp-ui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ test.describe('On-Chain State Management zkApp UI', () => {
await onChainStateMgmtZkAppPage.checkO1jsInitialization();
});

test('should compile zkProgram', async ({
onChainStateMgmtZkAppPage,
}) => {
await onChainStateMgmtZkAppPage.goto();
await onChainStateMgmtZkAppPage.checkO1jsInitialization();
await onChainStateMgmtZkAppPage.compileZkProgram();
await onChainStateMgmtZkAppPage.checkZkProgramCompilation();
});


test('should fail to update account state since zkApp was not yet deployed', async ({
onChainStateMgmtZkAppPage,
}) => {
Expand Down
13 changes: 13 additions & 0 deletions tests/pages/on-chain-state-mgmt-zkapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { expect, type Locator, type Page } from '@playwright/test';

export class OnChainStateMgmtZkAppPage {
readonly page: Page;
readonly compileButton: Locator;
readonly deployButton: Locator;
readonly updateButton: Locator;
readonly clearEventsButton: Locator;
Expand All @@ -11,6 +12,7 @@ export class OnChainStateMgmtZkAppPage {

constructor(page: Page) {
this.page = page;
this.compileButton = page.locator('button[id="compileButton"]');
this.deployButton = page.locator('button[id="deployButton"]');
this.updateButton = page.locator('button[id="updateButton"]');
this.clearEventsButton = page.locator('button[id="clearEventsButton"]');
Expand All @@ -23,6 +25,10 @@ export class OnChainStateMgmtZkAppPage {
await this.page.goto('/on-chain-state-mgmt-zkapp-ui.html');
}

async compileZkProgram() {
await this.compileButton.click();
}

async compileAndDeployZkApp() {
await this.deployButton.click();
}
Expand All @@ -40,6 +46,13 @@ export class OnChainStateMgmtZkAppPage {
await expect(this.eventsContainer).toContainText('o1js initialized after');
}

async checkZkProgramCompilation() {
await expect(this.eventsContainer).toContainText('Compiling ZkProgram');
await expect(this.eventsContainer).toContainText(
'ZkProgram compiled successfully!'
);
}

async checkDeployedZkApp() {
await expect(this.eventsContainer).toContainText('Deploying');
await expect(this.eventsContainer).toContainText('Initial state: 2');
Expand Down

0 comments on commit a0f0f34

Please sign in to comment.