-
Notifications
You must be signed in to change notification settings - Fork 211
Convert add-chain.sh into a go package #204
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
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
70abccf
Convert add-chain.sh into a go package
bitwiseguy 0b4d631
Create go module
bitwiseguy 4de3faa
Fixes to produce correct output files from addchain module
bitwiseguy 22b4748
Rename go module addchain to add-chain
bitwiseguy 1b1acea
Remove duplicate invocation of registry-data go program
bitwiseguy 9afdef3
Add conditional when searching for contract addrs from file
bitwiseguy 4969abd
Add e2e test for add-chain go module
bitwiseguy 9c04805
Finish removing add-chain go test dep on monorepo
bitwiseguy 175f5ae
Rename add-chain test files to expected.[json|yam]l
bitwiseguy af89ef1
Merge branch 'main' into ss/addchain-go
bitwiseguy 7205dbe
Retrieve L1 url from superchain package instead of hardcoding
bitwiseguy 1b2967a
Use consistent go 1.21 version in all go.mod files
bitwiseguy 61ea05f
Read contract addresses from .deploy file within add-chain
bitwiseguy cb6864a
Move add-chain/.env.test into testdata dir
bitwiseguy 9b4f82e
Merge branch 'main' into ss/addchain-go
bitwiseguy 2fd6532
Refactor 'cast call' commands to reduce duplicate code
bitwiseguy ccd2fdd
Fix call to OptimismPortalProxy.guardian() - instead of calling GUARD…
bitwiseguy c331023
Removed unused genesis.json file from add-chain/testdata dir
bitwiseguy 7013cd3
Use custom yaml encoder to add whitespace
bitwiseguy bcdfb7c
Compare config raw bytes instead of structs in e2e test
bitwiseguy c5c6afe
Add human readable timestamp as comments in yaml file
bitwiseguy dda8220
Remove hardfork timestamp overrides if they match superchain defaults
bitwiseguy 9446436
Move enhanceYAML to a method of RollupConfig
bitwiseguy 354b976
Add godoc comments to a few functions
bitwiseguy 80fad15
improve cast call error handling (#215)
geoknee 7f55ffa
Merge branch 'main' into ss/addchain-go
bitwiseguy 50b1c85
Address PR comments
bitwiseguy bb991a1
Run gofumpt and golangci-lint
bitwiseguy ef4fb1d
Install foundry in Circle CI for cast call in tests
bitwiseguy 1a26e4c
Fix timestamp to use consistent UTC+0 timezone
bitwiseguy 6b8483f
Set Circle CI shell type to bash
bitwiseguy 019fe31
Move shell type to job level in Circle CI
bitwiseguy 5f09d55
Merge branch 'main' into ss/addchain-go
bitwiseguy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ docs/ | |
| .env | ||
| .env* | ||
| !.env.example | ||
| !.env.test | ||
| *.log | ||
|
|
||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # test output artifacts | ||
| testdata/**/awesomechain* | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "encoding/json" | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
| "time" | ||
|
|
||
| "github.com/ethereum-optimism/superchain-registry/superchain" | ||
| "gopkg.in/yaml.v3" | ||
| ) | ||
|
|
||
| // constructRollupConfig creates and populates a ChainConfig struct by reading from an input file and | ||
| // explicitly setting some additional fields to input argument values | ||
| func constructRollupConfig(inputFilePath, chainName, publicRPC, sequencerRPC, explorer string, superchainLevel superchain.SuperchainLevel) (superchain.ChainConfig, error) { | ||
| fmt.Printf("Attempting to read from %s\n", inputFilePath) | ||
| file, err := os.ReadFile(inputFilePath) | ||
| if err != nil { | ||
| return superchain.ChainConfig{}, fmt.Errorf("error reading file: %w", err) | ||
| } | ||
| var config superchain.ChainConfig | ||
| if err = json.Unmarshal(file, &config); err != nil { | ||
| return superchain.ChainConfig{}, fmt.Errorf("error unmarshaling json: %w", err) | ||
| } | ||
|
|
||
| config.Name = chainName | ||
| config.PublicRPC = publicRPC | ||
| config.SequencerRPC = sequencerRPC | ||
| config.SuperchainLevel = superchainLevel | ||
| config.Explorer = explorer | ||
|
|
||
| fmt.Printf("Rollup config successfully constructed\n") | ||
| return config, nil | ||
| } | ||
|
|
||
| // writeChainConfig accepts a rollupConfig, formats it, and writes some output files based on the given | ||
| // target directories | ||
| func writeChainConfig( | ||
| rollupConfig superchain.ChainConfig, | ||
| targetDirectory string, | ||
| superchainRepoPath string, | ||
| superchainTarget string, | ||
| ) error { | ||
| // Create genesis-system-config data | ||
| // (this is deprecated, users should load this from L1, when available via SystemConfig) | ||
| dirPath := filepath.Join(superchainRepoPath, "superchain", "extra", "genesis-system-configs", superchainTarget) | ||
|
|
||
| if err := os.MkdirAll(dirPath, 0o755); err != nil { | ||
| return fmt.Errorf("failed to create directory: %w", err) | ||
| } | ||
|
|
||
| systemConfigJSON, err := json.MarshalIndent(rollupConfig.Genesis.SystemConfig, "", " ") | ||
| if err != nil { | ||
| return fmt.Errorf("failed to marshal genesis system config json: %w", err) | ||
| } | ||
|
|
||
| // Write the genesis system config JSON to a new file | ||
| filePath := filepath.Join(dirPath, rollupConfig.Name+".json") | ||
| if err := os.WriteFile(filePath, systemConfigJSON, 0o644); err != nil { | ||
| return fmt.Errorf("failed to write genesis system config json: %w", err) | ||
| } | ||
| fmt.Printf("Genesis system config written to: %s\n", filePath) | ||
|
|
||
| rollupConfig.Genesis.SystemConfig = superchain.SystemConfig{} // remove SystemConfig so its omitted from yaml | ||
|
|
||
| // Remove hardfork timestamp override fields if they match superchain defaults | ||
| defaults := superchain.Superchains[superchainTarget] | ||
| rollupConfig.SetDefaultHardforkTimestampsToNil(&defaults.Config) | ||
|
|
||
| yamlData, err := yaml.Marshal(rollupConfig) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to marshal yaml: %w", err) | ||
| } | ||
|
|
||
| // Unmarshal bytes into a yaml.Node for custom manipulation | ||
| var rootNode yaml.Node | ||
| if err = yaml.Unmarshal(yamlData, &rootNode); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
| defer cancel() | ||
| if err = rollupConfig.EnhanceYAML(ctx, &rootNode); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Write the rollup config to a yaml file | ||
| filename := filepath.Join(targetDirectory) | ||
| file, err := os.Create(filename) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| defer file.Close() | ||
|
|
||
| encoder := yaml.NewEncoder(file) | ||
| defer encoder.Close() | ||
|
|
||
| encoder.SetIndent(2) | ||
| if err := encoder.Encode(&rootNode); err != nil { | ||
| return fmt.Errorf("failed to write yaml file: %w", err) | ||
| } | ||
|
|
||
| fmt.Printf("Rollup config written to: %s\n", filename) | ||
| return nil | ||
| } | ||
|
|
||
| func getL1RpcUrl(superchainTarget string) (string, error) { | ||
| superChain, ok := superchain.Superchains[superchainTarget] | ||
| if !ok { | ||
| return "", fmt.Errorf("unknown superchain target provided: %s", superchainTarget) | ||
| } | ||
|
|
||
| if superChain.Config.L1.PublicRPC == "" { | ||
| return "", fmt.Errorf("missing L1 public rpc endpoint in superchain config") | ||
| } | ||
|
|
||
| fmt.Printf("Setting L1 public rpc endpoint to %s\n", superChain.Config.L1.PublicRPC) | ||
| return superChain.Config.L1.PublicRPC, nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
|
|
||
| "github.com/ethereum-optimism/superchain-registry/superchain" | ||
| ) | ||
|
|
||
| type AddressData struct { | ||
| Address string `json:"address"` | ||
| } | ||
|
|
||
| var ( | ||
| // Addresses to retrieve from JSON | ||
|
bitwiseguy marked this conversation as resolved.
|
||
| AddressManager = "AddressManager" | ||
| L1CrossDomainMessengerProxy = "L1CrossDomainMessengerProxy" | ||
| L1ERC721BridgeProxy = "L1ERC721BridgeProxy" | ||
| L1StandardBridgeProxy = "L1StandardBridgeProxy" | ||
| L2OutputOracleProxy = "L2OutputOracleProxy" | ||
| OptimismMintableERC20FactoryProxy = "OptimismMintableERC20FactoryProxy" | ||
| SystemConfigProxy = "SystemConfigProxy" | ||
| OptimismPortalProxy = "OptimismPortalProxy" | ||
| ProxyAdmin = "ProxyAdmin" | ||
|
|
||
| // Addresses to retrieve from chain | ||
| SuperchainConfig = "SuperchainConfig" | ||
| Guardian = "Guardian" | ||
| Challenger = "Challenger" | ||
| ProxyAdminOwner = "ProxyAdminOwner" | ||
| SystemConfigOwner = "SystemConfigOwner" | ||
| ) | ||
|
|
||
| func readAddressesFromChain(contractAddresses map[string]string, l1RpcUrl string) error { | ||
| // SuperchainConfig | ||
| address, err := castCall(contractAddresses[OptimismPortalProxy], "superchainConfig()(address)", l1RpcUrl) | ||
| if err != nil { | ||
| contractAddresses[SuperchainConfig] = "" | ||
| } else { | ||
| contractAddresses[SuperchainConfig] = address | ||
| } | ||
|
|
||
| // Guardian | ||
| address, err = castCall(contractAddresses[SuperchainConfig], "guardian()(address)", l1RpcUrl) | ||
| if err != nil { | ||
| address, err = castCall(contractAddresses[OptimismPortalProxy], "guardian()(address)", l1RpcUrl) | ||
|
bitwiseguy marked this conversation as resolved.
|
||
| if err != nil { | ||
| return fmt.Errorf("could not retrieve address for Guardian %w", err) | ||
| } | ||
| } | ||
| contractAddresses[Guardian] = address | ||
|
|
||
| // Challenger | ||
| address, err = castCall(contractAddresses[L2OutputOracleProxy], "challenger()(address)", l1RpcUrl) | ||
| if err != nil { | ||
| return fmt.Errorf("could not retrieve address for Guardian") | ||
| } | ||
| contractAddresses[Challenger] = address | ||
|
|
||
| // ProxyAdminOwner | ||
| address, err = castCall(contractAddresses[ProxyAdmin], "owner()(address)", l1RpcUrl) | ||
| if err != nil { | ||
| return fmt.Errorf("could not retrieve address for ProxyAdminOwner") | ||
| } | ||
| contractAddresses[ProxyAdminOwner] = address | ||
|
|
||
| // SystemConfigOwner | ||
| address, err = castCall(contractAddresses[SystemConfigProxy], "owner()(address)", l1RpcUrl) | ||
| if err != nil { | ||
| return fmt.Errorf("could not retrieve address for ProxyAdminOwner") | ||
| } | ||
| contractAddresses[SystemConfigOwner] = address | ||
|
|
||
| fmt.Printf("Contract addresses read from on-chain contracts\n") | ||
| return nil | ||
| } | ||
|
|
||
| func readAddressesFromJSON(contractAddresses map[string]string, deploymentsDir string) error { | ||
| contractsFromJSON := []string{ | ||
| AddressManager, | ||
| L1CrossDomainMessengerProxy, | ||
| L1ERC721BridgeProxy, | ||
| L1StandardBridgeProxy, | ||
| L2OutputOracleProxy, | ||
| OptimismMintableERC20FactoryProxy, | ||
| SystemConfigProxy, | ||
| OptimismPortalProxy, | ||
| ProxyAdmin, | ||
| } | ||
|
|
||
| deployFilePath := filepath.Join(deploymentsDir, ".deploy") | ||
| _, err := os.Stat(deployFilePath) | ||
|
|
||
| if err != nil { | ||
| // Use legacy deployment artifact schema | ||
| for _, name := range contractsFromJSON { | ||
| path := filepath.Join(deploymentsDir, name+".json") | ||
| file, err := os.ReadFile(path) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to read file: %w", err) | ||
| } | ||
| var data AddressData | ||
| if err = json.Unmarshal(file, &data); err != nil { | ||
| return fmt.Errorf("failed to unmarshal json: %w", err) | ||
| } | ||
| contractAddresses[name] = data.Address | ||
| } | ||
| } else { | ||
| var addressList superchain.AddressList | ||
| rawData, err := os.ReadFile(deployFilePath) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to read file: %w", err) | ||
| } | ||
|
|
||
| if err = json.Unmarshal(rawData, &addressList); err != nil { | ||
| return fmt.Errorf("failed to unmarshal json: %w", err) | ||
| } | ||
|
|
||
| for _, name := range contractsFromJSON { | ||
| address, err := addressList.AddressFor(name) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to retrieve %s address from list: %w", name, err) | ||
| } | ||
| contractAddresses[name] = address.String() | ||
| } | ||
| } | ||
|
|
||
| fmt.Printf("Contract addresses read from deployments directory: %s\n", deploymentsDir) | ||
| return nil | ||
| } | ||
|
|
||
| func writeAddressesToJSON(contractsAddresses map[string]string, superchainRepoPath, target, chainName string) error { | ||
| dirPath := filepath.Join(superchainRepoPath, "superchain", "extra", "addresses", target) | ||
| if err := os.MkdirAll(dirPath, 0o755); err != nil { | ||
| return fmt.Errorf("failed to create directory: %w", err) | ||
| } | ||
|
|
||
| filePath := filepath.Join(dirPath, chainName+".json") | ||
| file, err := os.Create(filePath) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to create file: %w", err) | ||
| } | ||
| defer file.Close() | ||
|
|
||
| // Marshal the map to JSON | ||
| jsonData, err := json.MarshalIndent(contractsAddresses, "", " ") | ||
| if err != nil { | ||
| return fmt.Errorf("failed to marshal json: %w", err) | ||
| } | ||
|
|
||
| // Write the JSON data to the file | ||
| if _, err := file.Write(jsonData); err != nil { | ||
| return fmt.Errorf("failed to write json to file: %w", err) | ||
| } | ||
| fmt.Printf("Contract addresses written to: %s\n", filePath) | ||
|
|
||
| return nil | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.