Open dfstio opened 2 months ago
It can be related to https://github.com/MinaProtocol/mina/pull/15503
Will there be any fix for this soon?
Running this test produces every time different verification key:
import { describe, expect, it } from "@jest/globals";
import { Field, SmartContract, method, state, State, Mina } from "o1js";
export class TestContract extends SmartContract {
@state(Field) value = State<Field>();
@method async setValue(value: Field) {
const timestamp = this.network.timestamp.getAndRequireEquals();
this.value.set(value);
}
}
describe("Compile v1", () => {
it(`should compile`, async () => {
const Local = await Mina.LocalBlockchain();
Mina.setActiveInstance(Local);
const vk = (await TestContract.compile()).verificationKey;
console.log("vk", vk.hash.toJSON());
});
});
Commenting the line
const timestamp = this.network.timestamp.getAndRequireEquals();
resolves this issue. In other, more complicated contracts, the verification key depends on the line where compile() is called. Moving the compile() up or down several lines changes the verification key, with the verification key being the function of the line where compile() is called - it is the same if compile() stays on the same line. Removing references to network.timestamp also resolves it.
Running this test produces every time different verification key:
thanks, that's what I expected from the error message. there must be a bug in the implementation that uses a different constant every time the circuit is compiled
After looking at the code, the problem is obvious: The genesisTimestamp
returned from Mina.getNetworkConstants()
is different depending on whether:
However, genesisTimestamp
is used as a constant in constraints when using this.network.timestamp
. So e.g., if you compile, then set the Mina instance to local blockchain, and then try to prove, you will hit a prover error (because the prover is not using the same circuit that the vk was compiled from).
The only possible fix is to hardcode a single genesisTimestamp (i.e., the one consistent with Mina mainnet) as a global constant, and use that for timestamp. It's probably best to not get that constant from networkConstants()
because that name implies that it depends on the network, which it must not when used as a circuit constant.
@mitschabaude
Can you please, when fixing it, also take into consideration that:
1) As I understand, I need to call fetchLastBlock()
to get the correct timestamp. fetchLastBlock()
works on devnet and mainnet but gives Unknown Error: {}
on the local blockchain
2) The Timestamps I see on devnet are almost two years ahead of the current time. As I understand, they are calculated from the devnet hardfork timestamp, not from the devnet genesis timestamp.
As I understand, I need to call fetchLastBlock() to get the correct timestamp.
I don't follow, why wouldn't you just get the current timestamp with Date.now()
or something?
I don't follow, why wouldn't you just get the current timestamp with
Date.now()
or something?
As I understand, if I want to compare timestamp with some time in provable code, the provable code derives the timestamp from the genesis timestamp and globalSlotSinceGenesis
, not from Date.now(), and to get the correct globalSlotSinceGenesis, I need to call await fetchLastBlock()
. Is it correct?
I don't follow, why wouldn't you just get the current timestamp with
Date.now()
or something?As I understand, if I want to compare timestamp with some time in provable code, the provable code derives the timestamp from the genesis timestamp and
globalSlotSinceGenesis
, not from Date.now(), and to get the correct globalSlotSinceGenesis, I need to callawait fetchLastBlock()
. Is it correct?
You're right it gets the global slot! It doesn't call fetchLastBlock()
for local blockchain though, instead it calls Mina.getNetworkState()
of which local blockchain has its own implementation
this.network.timestamp gives incorrect time and throw "the permutation was not constructed correctly: final value" error when calling tx.prove() on devnet:
The same code works correctly on the local blockchain.
Test used: