UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

131 lines (116 loc) 4.11 kB
import { AccountUpdate, Types, Permissions, ProvableExtended, } from '../../index.js'; import { expect } from 'expect'; import { jsLayout } from '../../bindings/mina-transaction/gen/js-layout.js'; import { Json, provableFromLayout, } from '../../bindings/mina-transaction/gen/transaction.js'; import { packToFields } from '../provable/crypto/poseidon.js'; import { Random, test } from '../testing/property.js'; import { MlHashInput } from '../ml/conversion.js'; import { MlFieldConstArray } from '../ml/fields.js'; import { Test } from '../../snarky.js'; let { hashInputFromJson } = await Test(); // types type Body = Types.AccountUpdate['body']; type Update = Body['update']; type Timing = Update['timing']['value']; type AccountPrecondition = Body['preconditions']['account']; type NetworkPrecondition = Body['preconditions']['network']; // provables let bodyLayout = jsLayout.AccountUpdate.entries.body; let Timing = provableFromLayout<Timing, any, any>( bodyLayout.entries.update.entries.timing.inner as any ); let Permissions_ = provableFromLayout<Permissions, any, any>( bodyLayout.entries.update.entries.permissions.inner as any ); let Update = provableFromLayout<Update, any, any>( bodyLayout.entries.update as any ); let AccountPrecondition = provableFromLayout<AccountPrecondition, any, any>( bodyLayout.entries.preconditions.entries.account as any ); let NetworkPrecondition = provableFromLayout<NetworkPrecondition, any, any>( bodyLayout.entries.preconditions.entries.network as any ); let Body = provableFromLayout<Body, any, any>(bodyLayout as any); // test with random account updates test(Random.json.accountUpdate, (accountUpdateJson) => { fixVerificationKey(accountUpdateJson); let accountUpdate = AccountUpdate.fromJSON(accountUpdateJson); // timing let timing = accountUpdate.body.update.timing.value; testInput(Timing, hashInputFromJson.timing, timing); // permissions let permissions = accountUpdate.body.update.permissions.value; testInput(Permissions_, hashInputFromJson.permissions, permissions); // update // TODO non ascii strings in zkapp uri and token symbol fail let update = accountUpdate.body.update; testInput(Update, hashInputFromJson.update, update); // account precondition let account = accountUpdate.body.preconditions.account; testInput( AccountPrecondition, hashInputFromJson.accountPrecondition, account ); // network precondition let network = accountUpdate.body.preconditions.network; testInput( NetworkPrecondition, hashInputFromJson.networkPrecondition, network ); // body let body = accountUpdate.body; testInput(Body, hashInputFromJson.body, body); // accountUpdate (should be same as body) testInput( Types.AccountUpdate, (accountUpdateJson) => hashInputFromJson.body( JSON.stringify(JSON.parse(accountUpdateJson).body) ), accountUpdate ); }); console.log('all hash inputs are consistent! 🎉'); function testInput<T, TJson>( Module: ProvableExtended<T, TJson>, toInputOcaml: (json: string) => MlHashInput, value: T ) { let json = Module.toJSON(value); // console.log('json', json); let input1 = MlHashInput.from(toInputOcaml(JSON.stringify(json))); let input2 = Module.toInput(value); let input1Json = JSON.stringify(input1); let input2Json = JSON.stringify(input2); // console.log('o1js', input2Json); // console.log(); // console.log('protocol', input1Json); let ok1 = input1Json === input2Json; expect(input2Json).toEqual(input1Json); // console.log('ok?', ok1); let fields1 = MlFieldConstArray.from( hashInputFromJson.packInput(MlHashInput.to(input1)) ); let fields2 = packToFields(input2); let ok2 = JSON.stringify(fields1) === JSON.stringify(fields2); // console.log('packed ok?', ok2); // console.log(); if (!ok1 || !ok2) { throw Error('inconsistent toInput'); } } function fixVerificationKey(accountUpdate: Json.AccountUpdate) { // TODO we set vk to null since we can't generate a valid random one accountUpdate.body.update.verificationKey = null; }