Capture genesis creation metadata into the registry
deploy-config.json- monorepo commit hash where genesis command was invoked
- command invocation and parameters for the genesis generation command
So that we can validate the genesis for standard chains.
We may as well store it for all chains, in case they want to become standard in the future.
Proposed changes:
optimism monorepo
The genesis creation script should store a new file genesis-creation-metadata.json (or, could we just a new field to the genesis.json file?)
Inside, it lists:
commitHash: "abcde".invocationCommand: ["go", "run", "cmd/main.go", "genesis l2"](or the forge route like from this doc https://docs.optimism.io/builders/chain-operators/deploy/genesis)- we already have
deploy-config.jsonfile hanging around
superchain-registry
- add a mechanism where we pull in the commitHash and invocation command from above and store it in the chain config
- need to support legacy chains who didn't have the benefit of the changes above. They will need to be able to specify the missing data manually, most likely in the
.envfile.
If we store the monorepo commitHash in the superchain-registry, will it be able to derive all the other information it needs? Just curious how the invocationCommand and deploy-config.json information would help create the compiled bytecode needed for the validation check if they are also stored in the chain's config .toml file.
From the superchain-registry side, this is how I imagine the bytecode recreation would work
- Fetch the monorepo
commitHashthat we will store in superchain-registry (in the chain config .toml?) - Use the
commitHashto checkout that specific version of the monorepo - Run
forge buildat that point in the monorepo - Fetch the contract bytecode from the forge-artifacts json file for each contract
- Compare that bytecode to what is onchain to ensure they match
Where/how does the invocationCommand and deploy-config.json come into play? Does the forge build command not work in some instances (e.g. for very old chains which require an old version of solidity that forge doesn't support?)
Let me try to clarify this a bit. I think there are the following two approaches to genesis validation:
"compile & ignore immutables"
This is exactly as you describe in your steps 1-5. I think you are correct that an invocationCommand is not required for this approach (although, we still ideally would have the necessary commands to install dependencies and compile, in case pnpm install && forge build does not work for older commits). We also do not need the deploy-config.json for this approach.
This is the initial approach we are taking on #475 .
The downsides are: we ignore immutable variables and have to inspect account balances, maintain the list of standard predeploys and storage variables in a more ad hoc fashion too.
regenerate genesis exactly
This is the gold standard approach. To enumerate the steps, it is the same as above with the following modifications:
3. Run forge build followed by the genesis creation tool (i.e. using the invocationCommand, which will consume deploy-config.json)
4/5: Compare the output of the genesis creation tool with what is on chain (or equivalently, stored in the registry).
The downsides of this are we need more input from the user to regenerate the genesis, but the upsides are that we get an exact description of the output that is acceptable.
I think what we ought to do in the short term is enable the first approach and leave the door open to upgrading the second approach in the future. Since we are trying to make this whole genesis validation approach a "first class citizen" by modifying the genesis creation tooling itself, it seems right to shoot for the gold standard (its much cleaner given the fact we can ensure repeatability of the genesis creation).
Perhaps the invocationCommand field can be left null while we are on the first validation approach. Over time we can migrate to requiring it to be non-nil, which would trigger the gold standard validation when that is implemented. WDYT?
We went with the "regenerate genesis exactly" approach, and are now storing the information in the registry as desired.
We can close this ticket when we update the genesis creation tool in the monorepo, such that it stores the information durably (in a gitignored file). The modification could be done around this line https://github.com/ethereum-optimism/optimism/blob/5a1a18d0ceedc40aad99baf4359e06f09fc7b718/packages/contracts-bedrock/scripts/L2Genesis.s.sol#L112
@bitwiseguy what is the status of the monorepo genesis creation tool update? Has that change landed? If not, do you have an ETA?
@bitwiseguy implemented this here https://github.com/ethereum-optimism/optimism/pull/11763 but it has been decided we will take a different approach and make a tag for chain operators to use to generate their L2 genesis https://github.com/ethereum-optimism/optimism/issues/11778 . This should tide us over until we tackle https://github.com/ethereum-optimism/specs/issues/350