Error `to_affine_exn: Got identity` when using public key retrieved from on-chain state
garethtdavies opened this issue · comments
I am using an on-chain public key variable in a zkApp for use in signature verification.
The public key is stored onchain and retrieved via let oraclePublicKey = this.oraclePublicKey.get();
However, when using oraclePublicKey
it errors with:
/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:7565
throw err;
Error: to_affine_exn: Got identity
at failwith (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:75528:50)
at to_affine_exn (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:160233:36)
at caml_call1 (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:7610:28)
at scale$3 (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:337731:34)
at /workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:420296:49
at caml_call_gen (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:2081:17)
at Object.scale (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:3651:16)
at Signature.verify (file:///workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/lib/signature.js:126:23)
at DelegationOracle.verify (file:///workspace/zkAppPool/oracle/build/src/DelegationOracleVerifier.js:46:42)
at file:///workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/lib/zkapp.js:152:32
If I simply override the oraclePublicKey
with the following, it works just fine:
oraclePublicKey = PublicKey.fromBase58("B62qphyUJg3TjMKi74T2rF8Yer5rQjBr1UyEG7Wg9XEYAHjaSiSqFv1");
Code example here, with the above hack: https://github.com/garethtdavies/zkAppPool/blob/5176a050c469ebab978fcf9631c7ac6bfd590970/oracle/src/DelegationOracleVerifier.ts#L44
Could it be that the public key is not initialized yet, so it's all zeroes? That's what the error message sounds like
Do you mean it's not on-chain yet? It is stored in this account: B62qmLWZfcbqrQPMky44w6K6Myj9aydbHKE5fG2N6wrXxFbkfEUWdRM
You can see there the fields are 13117991216867267972578094433946611068215850158296483053051446309883779846074
and 0
. Manually decoding that via https://github.com/garethtdavies/zkAppPool/blob/main/oracle/src/debug-events.ts gives B62qphyUJg3TjMKi74T2rF8Yer5rQjBr1UyEG7Wg9XEYAHjaSiSqFv1
as expected.
Query to get on-chain state:
{
account(publicKey: "B62qmLWZfcbqrQPMky44w6K6Myj9aydbHKE5fG2N6wrXxFbkfEUWdRM") {
publicKey
zkappState
}
}
I understand the error now - it's because of running stuff multiple times, the first one with fake values. We should address this soon
So the goal would be to run it the first time in an environment where assertions don't throw
@garethtdavies you could use the following workaround for now:
You can pass in the oraclePublicKey
as an additional parameter to your method, to avoid .get()
which gives you the wrong result. Then, to check that it matches the on-chain one, you can do this.oraclePublicKey.assertEquals(oraclePublicKey);
as before.
So this would be the diff in pseudo code
+ // oraclePublicKey gets passed in as argument
- let oraclePublicKey = this.oraclePublicKey.get();
this.oraclePublicKey.assertEquals(oraclePublicKey);
Oh! An even simpler workaround would be to warm the cache before doing the transaction:
await Mina.fetchAccount(zkAppAddress);
let tx = await Mina.transaction(...)