refactor: drop artifact field from SimulationOverrides#22957
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
683f4c5 to
da4bd0d
Compare
da4bd0d to
11e420f
Compare
| salt: Fr.random(), | ||
| constructorArgs: stubConstructorArgs, | ||
| }); | ||
| await this.pxe.registerContractClass(stubArtifact); |
There was a problem hiding this comment.
Love the approach, but I think you have to unfortunately reconstruct the instance in this particular case so it's given an address consistent with the new classId. This is failing in the bot test because we're simulating the deployment of the account contract itself, which calls the constructor that performs some checks related to the init_hash for the emission of the private initialization nullifier. Same for all account contract overrides (there's also a new test if you pull the merge-train that should verify we can simulate constructors properly during kernelless simulations)
11e420f to
10e67ec
Compare
| const findFunctionInArtifact = async ( | ||
| artifact: { name: string; functions: { name: string; parameters: any[] }[] }, | ||
| selector: FunctionSelector, | ||
| contractAddress: AztecAddress, | ||
| ) => { | ||
| for (const fn of artifact.functions) { | ||
| const fnSelector = await FunctionSelector.fromNameAndParameters(fn.name, fn.parameters); | ||
| if (fnSelector.equals(selector)) { | ||
| return { ...fn, contractName: artifact.name } as any; | ||
| } | ||
| } | ||
| throw new Error( | ||
| `Function with selector ${selector} not found in stub artifact for overridden contract at ${contractAddress}.`, | ||
| ); | ||
| }; |
There was a problem hiding this comment.
Claude pulled this out into a helper which made me think.... This logic ,which was previously inline in the switch statement below, is nearly identical to a helper in contract_store.ts. We can probably consolidate those implementations into a single helper (in stdlib abi?)
f0cb734 to
c9c7a6c
Compare
c9c7a6c to
eafdf07
Compare
06fafc0 to
a498f65
Compare
| } | ||
| return cached; | ||
| } | ||
|
|
There was a problem hiding this comment.
Identical to cli-wallet's fn.... Could consider pulling into a helper somewhere, but not sure it's worth it.
| const stubConstructorArgs = type === 'schnorr' ? [Fr.ZERO, Fr.ZERO] : [Buffer.alloc(32), Buffer.alloc(32)]; | ||
| const stubInstance = await getContractInstanceFromInstantiationParams(stubArtifact, { | ||
| salt: Fr.random(), | ||
| constructorArgs: stubConstructorArgs, | ||
| }); | ||
|
|
There was a problem hiding this comment.
I know we've discussed twice already, but I need to be convinced that we actually need this....
Before this PR, we would derive the stub's instance+address here, but then we never actually use the stub's derived address anywhere as far as i can tell. In fact, in the proxied contract source, we overwrote it with the "real" address before ever using/returning it.
Same goes for initialization hash. And IIUC, we should be fine to use the real initialization hash anyway because the stub constructor has the same signature as the real one.....
Maybe i'm missing something about testing deployments as I remember discussing that briefly.
There was a problem hiding this comment.
If both the e2e_kernelless_simulation and e2e_bot tests pass, this is indeed not necessary anymore!
cf88b94 to
a72d30a
Compare
a72d30a to
82138d4
Compare
| cached = (async () => { | ||
| const stubArtifact = await this.accountContracts.getStubAccountContractArtifact(type); | ||
| const { id } = await getContractClassFromArtifact(stubArtifact); | ||
| await this.pxe.registerContractClass(stubArtifact); |
There was a problem hiding this comment.
I'd query PXE using getContractArtifact first. In case it's already registered, we can skip an extra round of hashing
Thunkar
left a comment
There was a problem hiding this comment.
LGTM, except the PXE query to avoid the extra hashing. With that, good to go, nice job!
4d7ac18 to
386276c
Compare
dd377eb to
d48dbfe
Compare
`SimulationOverrides.contracts` entries no longer carry a `ContractArtifact`. Simulation resolves the override-instance's `currentContractClassId` through PXE's locally registered classes, so callers register the target artifact via `pxe.registerContractClass(...)` once, then construct an instance with the desired `currentContractClassId` to drive dispatch. Migrates the in-tree account-stub flows (`cli-wallet`, `embedded_wallet`, `test_wallet`) to pre-register the stub class and bump `currentContractClassId` on the override instance. `proxied_contract_data_source` drops its `getFunctionArtifact*` overrides — function lookup falls through to the regular `ContractStore`.
Match the embedded wallet's pattern: cache the stub class id and preimage keyed on AccountType rather than on a 'schnorr' | 'ecdsa' flavor union, and do the schnorr-vs-ecdsa artifact dispatch inline. The two ECDSA AccountType values share a stub artifact, so on first miss for each variant we'll hash and re-register the same artifact — a bounded one-time cost per type that's worth the simpler shape.
Callers only ever consume the `id` field from `getContractClassFromArtifact`, so cache `Map<AccountType, Promise<Fr>>` instead of the full `ContractClassWithId & ContractClassIdPreimage`. Method renamed `#getStubClass` → `#getStubClassId`, map renamed `#stubClasses` → `#stubClassIds`, callers drop the destructure. Drop the verbose Promise-as-value rationale comment — the idiom is established in this codebase (see ContractSyncService) and the PXE precedents document the cache contract briefly without explaining the dedupe pattern.
d48dbfe to
aec497a
Compare
## Summary Addresses comment #22957 (comment) The same artifact-lookup loop was duplicated three times. Puts two helper fns in `stdlib/abi`: - `findFunctionArtifactBySelector(artifact, selector)` — searches `artifact.functions`, returns `FunctionArtifact | undefined`. - `findFunctionAbiBySelector(artifact, selector)` — searches `artifact.functions ∪ nonDispatchPublicFunctions` via `getAllFunctionAbis`, returns `FunctionAbi | undefined`. Both `ContractStore` and `ProxiedContractStoreFactory` now call the same stdlib primitive. The existing throwing `getFunctionArtifact` helper also reuses `findFunctionArtifactBySelector`. ## Test plan - [x] `yarn workspace @aztec/pxe test src/storage/contract_store/contract_store.test.ts` - [x] `yarn workspace @aztec/stdlib test src/abi/abi.test.ts` - [x] `yarn lint pxe`, `yarn lint stdlib`

Drops the
artifactfield fromSimulationOverrides.contractsentries. Simulation now resolves the override-instance'scurrentContractClassIdthrough PXE's locally registered classes — callers register the target artifact viapxe.registerContractClass(...)once, then construct an instance with the desiredcurrentContractClassIdto drive dispatch.In-tree account-stub flows (
cli-wallet,embedded_wallet,test_wallet) migrate to the pre-register pattern: pre-register the stub class and bumpcurrentContractClassIdon the override instance.proxied_contract_data_sourcedrops itsgetFunctionArtifact*overrides — function lookup falls through to the regularContractStore. The proxy now only overridesgetContractInstance.Test plan