Repository navigation
feat: cache PublicImmutable reads in the fact store - #25568
Conversation
| let cached_len = payload.len(); | ||
| let packed_len = <T as Packable>::N; | ||
| assert( | ||
| cached_len == packed_len, |
There was a problem hiding this comment.
I'm not very familiar with upgrades, but would it be possible for the contract to be upgraded and the new version to have a PublicImmutable with a different type at this slot? If so, should we treat the mismatch as a cache miss and replace the stale fact instead of panicking?
There was a problem hiding this comment.
This is just overly defensive code to avoid any weird errors - I don't expect these panics from ever happening. I considered the cache clear that you allude, but it should be impossible for the current code to produce such a scenario. We may want to fail loudly in that case - the contract woudl be bricked, yes, but a wallet would be able to sort it out by clearning the fact manually.
Not ideal if it happens, but if we really think it's impossible then maybe better not to hide it at this early stage where we have such a close relationship with the ecosystem.
Private and utility reads of a PublicImmutable now record the value as a retractable fact at the anchor block, in a public-scope collection per storage slot, and later reads return it without a node roundtrip. A value cached at a block after the anchor is only used once the initialization nullifier is found at the anchor. WithHash exposes the hint check on its own as verify_historical_public_storage_hint, so the private read can pass the cached value as the hint.
Utility and private reads of a cached value are now tested to not call the public storage oracle. The test for reading at an anchor block earlier than the one the value was cached at is renamed to say so.
6345e3a to
e27da24
Compare
* feat(pxe): add simulateAndProveTx to simulate and prove in a single operation (AztecProtocol/aztec-packages#25534) Adds `PXE.simulateAndProveTx`, which simulates a transaction, hands the result to a `prepareProve` callback that returns the request to prove, and then proves it, all as a single PXE operation. No private state sync runs in between, so the simulation and the witness generation see the same notes and tagging indices. `simulateTx` and `proveTx` now share their bodies with the new method through private helpers. There are no tests yet: nothing runs transactions from PXE directly, and doing so needs wallet support whose shape is not settled. * feat!: support public fact scopes (AztecProtocol/aztec-packages#25563) Fact collections used to always belong to an account, because facts were only accessed during private state sync, where the account being synced is known. Collections now belong to a `FactScope`, which is either an account or the new public scope. A collection in the public scope can be accessed whichever accounts are in scope, but still only by the contract that created it. The `aztec::facts` functions and the four fact oracles take a `FactScope` instead of an `AztecAddress`. Public-scope collections use the same database layout as account ones, so no schema migration is needed. Unlike upstream, the fact oracles change in place instead of gaining `V2` names with legacy remappings, so the oracle interface major version moves 32 -> 33. * feat: cache PublicImmutable reads in the fact store (AztecProtocol/aztec-packages#25568) Private and utility reads of a `PublicImmutable` now cache the value in the fact store, in the public scope, so that later reads need no node roundtrip. The fact store retracts the cached value if the block it was read at is reorged out. A value cached from a block after the current anchor is only used once the state variable is confirmed to be initialized at the anchor. * chore: regenerate the standard contracts pinned build for oracle version 33 The pinned standard contracts were compiled against Aztec.nr at oracle interface version 32, which PXE now rejects, so the pinned build, canonical addresses, and class ids are regenerated against the new oracle interface. All four contracts move to new addresses and class ids. * docs: drop the standard contract re-pin from the unreleased migration notes The re-pinned standard contracts have not been deployed, so nobody has seen the intermediate addresses and there is nothing to migrate from. Remove the re-pin note and the standard contract addresses from the v3 contract address domain separator note.
This adds a fact-store based cache to
PublicImmutableso that we don't need to do a node roundtrip every time we access the state variable. The fact-store handles reorgs automatically.There's some sublte details in when and how the init nullifiers are checked depending on anchor blocks, but those are best explained by the code.