-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(integration-test): add test scenarios
- Loading branch information
Showing
11 changed files
with
455 additions
and
223 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,3 +23,4 @@ export { | |
serializeHeader, | ||
serializeBody, | ||
} from './block' | ||
export { L1Contract } from './layer1' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
packages/integration-test/tests/helper/1_create_accounts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* eslint-disable jest/no-export */ | ||
/* eslint-disable jest/no-hooks */ | ||
/* eslint-disable jest/require-top-level-describe */ | ||
|
||
import { toWei } from 'web3-utils' | ||
import { Provider } from './context' | ||
|
||
export const testAliceAccount = (ctx: Provider) => async () => { | ||
const { web3, accounts } = ctx() | ||
expect( | ||
await web3.eth.getBalance(accounts.alice.ethAccount.address), | ||
).toStrictEqual(toWei('100')) | ||
} | ||
export const testBobAccount = (ctx: Provider) => async () => { | ||
const { web3, accounts } = ctx() | ||
expect( | ||
await web3.eth.getBalance(accounts.bob.ethAccount.address), | ||
).toStrictEqual(toWei('100')) | ||
} | ||
|
||
export const testCarlAccount = (ctx: Provider) => async () => { | ||
const { web3, accounts } = ctx() | ||
expect( | ||
await web3.eth.getBalance(accounts.carl.ethAccount.address), | ||
).toStrictEqual(toWei('100')) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* eslint-disable jest/no-standalone-expect */ | ||
/* eslint-disable jest/require-tothrow-message */ | ||
/* eslint-disable jest/no-export */ | ||
/* eslint-disable jest/require-top-level-describe */ | ||
|
||
import { Provider } from './context' | ||
|
||
export const testRegisterVKs = (ctx: Provider) => async () => { | ||
const { contract, vks, accounts } = ctx() | ||
const nIn = Object.keys(vks) | ||
const nOut = Object.keys(vks[1]) | ||
const registerVKs: (() => Promise<void>)[] = [] | ||
let registeredNum = 0 | ||
nIn.forEach(i => { | ||
nOut.forEach(j => { | ||
registerVKs.push(async () => { | ||
const tx = contract.setup.methods.registerVk( | ||
i, | ||
j, | ||
vks[i][j].vk_alfa_1.slice(0, 2), | ||
vks[i][j].vk_beta_2.slice(0, 2), | ||
vks[i][j].vk_gamma_2.slice(0, 2), | ||
vks[i][j].vk_delta_2.slice(0, 2), | ||
vks[i][j].IC.map((arr: string[][]) => arr.slice(0, 2)), | ||
) | ||
const estimatedGas = await tx.estimateGas() | ||
const receipt = await tx.send({ | ||
from: accounts.coordinator.address, | ||
gas: estimatedGas, | ||
}) | ||
registeredNum += 1 | ||
expect(receipt).toBeDefined() | ||
}) | ||
}) | ||
}) | ||
await Promise.all(registerVKs.map(f => f())) | ||
expect(registeredNum).toStrictEqual(16) | ||
} | ||
|
||
export const testRegisterVKFails = (ctx: Provider) => async () => { | ||
const { contract, vks, accounts } = ctx() | ||
const sampleVk = vks[4][4] | ||
const tx = contract.setup.methods.registerVk( | ||
5, | ||
5, | ||
sampleVk.vk_alfa_1.slice(0, 2), | ||
sampleVk.vk_beta_2.slice(0, 2), | ||
sampleVk.vk_gamma_2.slice(0, 2), | ||
sampleVk.vk_delta_2.slice(0, 2), | ||
sampleVk.IC.map((arr: string[][]) => arr.slice(0, 2)), | ||
) | ||
const estimatedGas = await tx.estimateGas() | ||
await expect( | ||
tx.send({ from: accounts.alice.address, gas: estimatedGas }), | ||
).rejects.toThrow() | ||
await expect( | ||
tx.send({ from: accounts.bob.address, gas: estimatedGas }), | ||
).rejects.toThrow() | ||
await expect( | ||
tx.send({ from: accounts.carl.address, gas: estimatedGas }), | ||
).rejects.toThrow() | ||
} |
33 changes: 33 additions & 0 deletions
33
packages/integration-test/tests/helper/3_complete_setup.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* eslint-disable jest/no-expect-resolves */ | ||
/* eslint-disable jest/require-tothrow-message */ | ||
/* eslint-disable jest/no-export */ | ||
/* eslint-disable jest/require-top-level-describe */ | ||
|
||
import { Provider } from './context' | ||
|
||
export const testCompleteSetup = (ctx: Provider) => async () => { | ||
const { accounts, contract } = ctx() | ||
const tx = contract.setup.methods.completeSetup() | ||
const gas = await tx.estimateGas() | ||
await expect(tx.send({ from: accounts.alice.address, gas })).rejects.toThrow() | ||
await expect(tx.send({ from: accounts.bob.address, gas })).rejects.toThrow() | ||
await expect(tx.send({ from: accounts.carl.address, gas })).rejects.toThrow() | ||
await expect( | ||
tx.send({ from: accounts.coordinator.address, gas }), | ||
).resolves.toHaveProperty('transactionHash') | ||
} | ||
|
||
export const testRejectVkRegistration = (ctx: Provider) => async () => { | ||
const { accounts, contract } = ctx() | ||
const tx = contract.setup.methods.completeSetup() | ||
await expect( | ||
tx.estimateGas({ from: accounts.alice.address }), | ||
).rejects.toThrow() | ||
await expect(tx.estimateGas({ from: accounts.bob.address })).rejects.toThrow() | ||
await expect( | ||
tx.estimateGas({ from: accounts.carl.address }), | ||
).rejects.toThrow() | ||
await expect( | ||
tx.estimateGas({ from: accounts.coordinator.address }), | ||
).rejects.toThrow() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import { ZkAccount, HDWallet } from '@zkopru/account' | ||
import { schema } from '@zkopru/database' | ||
import { sleep, readFromContainer } from '@zkopru/utils' | ||
import { L1Contract } from '@zkopru/core' | ||
import { Docker } from 'node-docker-api' | ||
import { nSQL, InanoSQLInstance } from '@nano-sql/core' | ||
import { Container } from 'node-docker-api/lib/container' | ||
import Web3 from 'web3' | ||
|
||
type VKs = { [nIn: number]: { [nOut: number]: any } } | ||
|
||
export interface Context { | ||
layer1Container: Container | ||
circuitArtifactContainer: Container | ||
accounts: { | ||
coordinator: ZkAccount | ||
alice: ZkAccount | ||
bob: ZkAccount | ||
carl: ZkAccount | ||
} | ||
web3: Web3 | ||
zkopruAddress: string | ||
db: InanoSQLInstance | ||
contract: L1Contract | ||
vks: VKs | ||
} | ||
|
||
export type Provider = () => Context | ||
|
||
export async function initContext() { | ||
const docker = new Docker({ socketPath: '/var/run/docker.sock' }) | ||
const layer1Container = await docker.container.create({ | ||
Image: 'zkopru:contract', | ||
name: Math.random() | ||
.toString(36) | ||
.substring(2, 16), | ||
rm: true, | ||
}) | ||
const circuitArtifactContainer = await docker.container.create({ | ||
Image: 'zkopru:circuits', | ||
name: Math.random() | ||
.toString(36) | ||
.substring(2, 16), | ||
rm: true, | ||
}) | ||
await Promise.all([layer1Container.start(), circuitArtifactContainer.start()]) | ||
const deployed = await readFromContainer( | ||
layer1Container, | ||
'/proj/build/deployed/ZkOptimisticRollUp.json', | ||
) | ||
const zkopruAddress = JSON.parse(deployed.toString()).address | ||
const status = await layer1Container.status() | ||
const containerIP = (status.data as { | ||
NetworkSettings: { IPAddress: string } | ||
}).NetworkSettings.IPAddress | ||
sleep(2000) | ||
console.log('Running testnet on ', `${containerIP}:5000`) | ||
const provider = new Web3.providers.WebsocketProvider( | ||
`ws://${containerIP}:5000`, | ||
{ reconnect: { auto: true } }, | ||
) | ||
async function waitConnection() { | ||
return new Promise<void>(res => { | ||
if (provider.connected) res() | ||
provider.on('connect', res) | ||
}) | ||
} | ||
await waitConnection() | ||
console.log('Websocket connection with ', `${containerIP}:5000`) | ||
const web3 = new Web3(provider) | ||
const contract = new L1Contract(web3, zkopruAddress) | ||
const dbName = 'zkopruFullNodeTester' | ||
await nSQL().createDatabase({ | ||
id: dbName, | ||
mode: 'TEMP', | ||
tables: [ | ||
schema.utxo, | ||
schema.utxoTree, | ||
schema.withdrawal, | ||
schema.withdrawalTree, | ||
schema.nullifiers, | ||
schema.nullifierTreeNode, | ||
schema.migration, | ||
schema.deposit, | ||
schema.massDeposit, | ||
schema.chain, | ||
schema.keystore, | ||
schema.hdWallet, | ||
], | ||
version: 3, | ||
}) | ||
const db = nSQL().useDatabase(dbName) | ||
const hdWallet = new HDWallet(db) | ||
const mnemonic = | ||
'myth like bonus scare over problem client lizard pioneer submit female collect' | ||
await hdWallet.init(mnemonic, 'samplepassword') | ||
const coordinator = await hdWallet.createAccount(0) | ||
const alice = await hdWallet.createAccount(1) | ||
const bob = await hdWallet.createAccount(2) | ||
const carl = await hdWallet.createAccount(3) | ||
const accounts = { coordinator, alice, bob, carl } | ||
const vks: VKs = { | ||
1: {}, | ||
2: {}, | ||
3: {}, | ||
4: {}, | ||
} | ||
const nIn = [1, 2, 3, 4] | ||
const nOut = [1, 2, 3, 4] | ||
const readVKs: (() => Promise<void>)[] = [] | ||
nIn.forEach(i => { | ||
nOut.forEach(j => { | ||
const readVK = async () => { | ||
const vk = JSON.parse( | ||
( | ||
await readFromContainer( | ||
circuitArtifactContainer, | ||
'/proj/build/vks/zk_transaction_1_1.vk.json', | ||
) | ||
).toString('utf8'), | ||
) | ||
vks[i][j] = vk | ||
} | ||
readVKs.push(readVK) | ||
}) | ||
}) | ||
await Promise.all(readVKs.map(f => f())) | ||
return { | ||
layer1Container, | ||
circuitArtifactContainer, | ||
accounts, | ||
web3, | ||
zkopruAddress, | ||
db, | ||
contract, | ||
vks, | ||
} | ||
} |
Oops, something went wrong.