-
Notifications
You must be signed in to change notification settings - Fork 865
feat: embed genesis for well-known chains #2835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2835 +/- ##
=======================================
Coverage 48.31% 48.32%
=======================================
Files 671 671
Lines 50576 50576
=======================================
+ Hits 24434 24439 +5
+ Misses 24001 23998 -3
+ Partials 2141 2139 -2
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
masih
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two minor blockers and a bunch of suggestions, otherwise LGTM 🚀
- the genesis JSON files use inconsistent formatting; e.g. different indentation, extra spaces at the end, etc. Please format all three once in your IDE to at least have consistent formatting across the three.
- the substitution logic needs to give a higher priority to explicitly present genesis file. See my comment for a deeper context.
Thank you for knocking this one out so quickly! 🙌
| return err | ||
| var genDoc *types.GenesisDoc | ||
| var appState json.RawMessage | ||
| if genesis.IsWellKnown(chainID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want the genesis substitution order to be:
genesis.jsonin config folder, if present.- if not --> is chain ID well known ?
- yes: load from embedded genesis.
- no: error out with genesis missing
Bonus logic (please feel free to do in a separate PR):
- if explicit is present but for a well known chain ID:
- Check that it is right ( note that the format is JSON and we need to sanitise formatting before checking hash, or... load as struct and compare types equality)
- if good: log in debug that "hey I know my networks -- you don't have to have the genesis file"
- if not good: panic out with appropriate messaging. Most likely accidentally edited genesis; invalid for the network in any case.
- Check that it is right ( note that the format is JSON and we need to sanitise formatting before checking hash, or... load as struct and compare types equality)
This would follow the general operational best practice of: "Explicit over implicit", and "Implicit over unspecified".
Does that make sense @mojtaba-esk? WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed comment.
genesis.json in config folder, if present.
This is checked a few lines above so it does not reach to this point when genesis.json exists.
Will apply the 2 as this makes sense.
Let's do the rest (Bonus logic) in a followup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I see what you mean now. Created a followup for it: https://linear.app/seilabs/issue/PLT-116/validate-explicit-genesis-file-for-well-known-chains-in-seid-init
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mojtaba-esk I think we are still missing item No. 1 in my comment right?
We want to check if the genesis is explicitly set first, and only implicitly load for well known chains if it is absent.
| return errors.Wrap(err, "Failed to read genesis doc from file") | ||
| return errors.Wrap(err, "Failed to marshall default genesis state") | ||
| } | ||
| genDoc = &types.GenesisDoc{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move closer to where it is first used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can't move this as it needs to have an empty gendoc in case the file does not exist and after the follwoing if statement, the given ChainID and the default values like appState is assigned to it.
cmd/seid/cmd/init.go
Outdated
| return errors.Wrap(err, "Failed to marshall default genesis state") | ||
| } | ||
| genDoc = &types.GenesisDoc{} | ||
| if _, err := os.Stat(genFile); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also check that genFile is not a directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do that sure.
app/genesis/genesis_test.go
Outdated
| require.Error(t, err) | ||
| require.Contains(t, err.Error(), "unknown chain-id") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| require.Error(t, err) | |
| require.Contains(t, err.Error(), "unknown chain-id") | |
| require.ErrorContains(t, err, "unknown chain-id") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied
app/genesis/genesis_test.go
Outdated
| var expectedGenesisDigests = map[string]string{ | ||
| "arctic-1": "a8b60161e345d8afb0d9b0c524b6541e6135f5eda4092fae287d8496e14554d8", | ||
| "atlantic-2": "3c135db9177a428893353d7889149ca2ed9c075d6846be07af60354022b81318", | ||
| "pacific-1": "4304cf1c7f46d153b79f1195b2d334f7f7cf02f26e02a3bb77c544a4987c1432", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the hashes of the indented JSON, and technically the same JSON values in different order/indentation is still valid.
But then we will/should never edit those JSON files anyway so hardcoding the hashes of pretty JSON is probably fine 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a critical point. I will see if I can hash it without considering whitespaces. Like the gendoc itself. if that works, the indents are fine as on some IDEs it is configured as one or two tabs one some it uses spaces... etc. Also the ordering should be fine as long as the gendoc structure is not touched.
app/genesis/genesis.go
Outdated
|
|
||
| var wellKnownChainIDs = []string{"arctic-1", "atlantic-2", "pacific-1"} | ||
|
|
||
| func WellKnownChainIDs() []string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used for testing only -- I would recommend hardcoding known chain IDs in tests instead and getting rid of this function. Alternatively, in tests you can get the list by lsing the chains/*.json files which has an added benfit that the code does include all json files put in there.
app/genesis/genesis.go
Outdated
| var wellKnownChainIDs = []string{"arctic-1", "atlantic-2", "pacific-1"} | ||
|
|
||
| func WellKnownChainIDs() []string { | ||
| return append([]string(nil), wellKnownChainIDs...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you decide to keep this function, slices.Clone is more idiomatic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the hint
app/genesis/genesis.go
Outdated
| //go:embed chains/*.json | ||
| var embeddedGenesisFS embed.FS | ||
|
|
||
| var wellKnownChainIDs = []string{"arctic-1", "atlantic-2", "pacific-1"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An edge-case can occure here where someone adds the JSON but forgets to update this.
We can avoid it by loading the known IDs via package Init, which would get rid of this struct entirely and makes the JSON files in chains directory the sole source of truth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. will apply it
| "pacific-1": "3a1f5d87df75f4fdb85eaf1b506e080cbcee3a748048e1e80721f68eb2193e43", | ||
| } | ||
|
|
||
| func genesisDocDigest(chainID string) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the limitation is that we do not order the appState to have a canonical value of it as it would have added extra complexity to the code that seems not be required at this stage.
philipsu522
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huge QoL improvement
## Describe your changes and provide context This PR is a followup for #2835 to handle a case where the user already has their own genesis file and does not want to remove them or overwrite them. Here is the slack comment by @masih that suggested this fix: https://sei-network-io.slack.com/archives/C06A3D4FWE5/p1770833867974669?thread_ts=1770803742.497719&cid=C06A3D4FWE5 ## Testing performed to validate your change --------- Co-authored-by: Mojtaba <mojtaba@celestia.org>
Describe your changes and provide context
This PR proposes embedding genesis file for the well-known networks (pacific-1, arctic-1, atlantic-2) so users only need the seid binary.
Running seid init --chain-id pacific-1 (or arctic-1 / atlantic-2) writes the correct genesis from the binary; no separate genesis download. Adds an app/genesis package with go:embed and tests that assert SHA256 digests of the embedded files to avoid accidental changes.
Fixes PLT-63