Skip to content

Commit 2ab24fe

Browse files
cakevmmattsse
andauthored
feat(optimism): Add support for all Superchain configs and enable their usage (#14562)
Co-authored-by: Matthias Seitz <[email protected]>
1 parent f3715e8 commit 2ab24fe

23 files changed

+903
-31
lines changed

Cargo.lock

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,8 @@ url = { version = "2.3", default-features = false }
553553
zstd = "0.13"
554554
byteorder = "1"
555555
mini-moka = "0.10"
556+
tar-no-std = { version = "0.3.2", default-features = false }
557+
miniz_oxide = { version = "0.8.4", default-features = false }
556558

557559
# metrics
558560
metrics = "0.24.0"

crates/chainspec/res/genesis/base.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/chainspec/res/genesis/optimism.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/chainspec/res/genesis/sepolia_base.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/chainspec/res/genesis/sepolia_op.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/net/peers/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ pub enum AnyNode {
125125

126126
impl AnyNode {
127127
/// Returns the peer id of the node.
128+
#[allow(clippy::missing_const_for_fn)]
128129
pub fn peer_id(&self) -> PeerId {
129130
match self {
130131
Self::NodeRecord(record) => record.id,
@@ -135,6 +136,7 @@ impl AnyNode {
135136
}
136137

137138
/// Returns the full node record if available.
139+
#[allow(clippy::missing_const_for_fn)]
138140
pub fn node_record(&self) -> Option<NodeRecord> {
139141
match self {
140142
Self::NodeRecord(record) => Some(*record),

crates/optimism/chainspec/Cargo.toml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,17 @@ alloy-hardforks.workspace = true
3333
# op
3434
op-alloy-rpc-types.workspace = true
3535

36-
# io
36+
serde = { workspace = true, optional = true }
3737
serde_json.workspace = true
3838

39+
# io
40+
tar-no-std = { workspace = true, optional = true }
41+
miniz_oxide = { workspace = true, features = ["with-alloc"], optional = true }
42+
3943
# misc
4044
derive_more.workspace = true
45+
paste = { workspace = true, optional = true }
46+
thiserror = { workspace = true, optional = true }
4147

4248
[dev-dependencies]
4349
reth-chainspec = { workspace = true, features = ["test-utils"] }
@@ -46,6 +52,7 @@ op-alloy-rpc-types.workspace = true
4652

4753
[features]
4854
default = ["std"]
55+
superchain-configs = ["miniz_oxide", "paste", "tar-no-std", "thiserror", "thiserror", "dep:serde"]
4956
std = [
5057
"alloy-chains/std",
5158
"alloy-genesis/std",
@@ -61,4 +68,20 @@ std = [
6168
"derive_more/std",
6269
"reth-network-peers/std",
6370
"serde_json/std",
71+
"serde?/std",
72+
"miniz_oxide?/std",
73+
"thiserror?/std",
74+
]
75+
serde = [
76+
"alloy-chains/serde",
77+
"alloy-consensus/serde",
78+
"alloy-eips/serde",
79+
"alloy-hardforks/serde",
80+
"alloy-primitives/serde",
81+
"miniz_oxide?/serde",
82+
"op-alloy-rpc-types/serde",
83+
"reth-ethereum-forks/serde",
84+
"reth-optimism-forks/serde",
85+
"reth-optimism-primitives/serde",
86+
"reth-primitives-traits/serde",
6487
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"arena-z","environment":"mainnet"},{"name":"arena-z-testnet","environment":"sepolia"},{"name":"automata","environment":"mainnet"},{"name":"base-devnet-0","environment":"sepolia-dev-0"},{"name":"bob","environment":"mainnet"},{"name":"boba","environment":"sepolia"},{"name":"creator-chain-testnet","environment":"sepolia"},{"name":"cyber","environment":"mainnet"},{"name":"cyber","environment":"sepolia"},{"name":"ethernity","environment":"mainnet"},{"name":"ethernity","environment":"sepolia"},{"name":"funki","environment":"mainnet"},{"name":"funki","environment":"sepolia"},{"name":"hashkeychain","environment":"mainnet"},{"name":"ink","environment":"mainnet"},{"name":"ink","environment":"sepolia"},{"name":"lisk","environment":"mainnet"},{"name":"lisk","environment":"sepolia"},{"name":"lyra","environment":"mainnet"},{"name":"metal","environment":"mainnet"},{"name":"metal","environment":"sepolia"},{"name":"mint","environment":"mainnet"},{"name":"mode","environment":"mainnet"},{"name":"mode","environment":"sepolia"},{"name":"oplabs-devnet-0","environment":"sepolia-dev-0"},{"name":"orderly","environment":"mainnet"},{"name":"pivotal","environment":"sepolia"},{"name":"polynomial","environment":"mainnet"},{"name":"race","environment":"mainnet"},{"name":"race","environment":"sepolia"},{"name":"redstone","environment":"mainnet"},{"name":"settlus-mainnet","environment":"mainnet"},{"name":"settlus-sepolia","environment":"sepolia"},{"name":"shape","environment":"mainnet"},{"name":"shape","environment":"sepolia"},{"name":"snax","environment":"mainnet"},{"name":"soneium","environment":"mainnet"},{"name":"soneium-minato","environment":"sepolia"},{"name":"sseed","environment":"mainnet"},{"name":"swan","environment":"mainnet"},{"name":"swell","environment":"mainnet"},{"name":"tbn","environment":"mainnet"},{"name":"tbn","environment":"sepolia"},{"name":"unichain","environment":"mainnet"},{"name":"unichain","environment":"sepolia"},{"name":"worldchain","environment":"mainnet"},{"name":"worldchain","environment":"sepolia"},{"name":"xterio-eth","environment":"mainnet"},{"name":"zora","environment":"mainnet"},{"name":"zora","environment":"sepolia"}]
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env bash
2+
3+
# Usage: ./fetch_superchain_config.sh
4+
# Switch to the same directory as the script and run it.
5+
# This will checkout the latest superchain registry commit and create three files.
6+
# - superchain-configs.tar: A tar archive containing all superchain configs
7+
# - available-chains.json: A JSON file containing all available chains
8+
# - ../src/superchain/chain_specs.rs: A Rust file containing all chain specs
9+
10+
# Requires:
11+
# - MacOS: brew install qpdf zstd yq
12+
13+
SCRIPT_DIR=$(pwd)
14+
TEMP_DIR=$(mktemp -d)
15+
16+
# Clone the repository and go to the directory
17+
git clone --depth 1 https://github.com/ethereum-optimism/superchain-registry.git "$TEMP_DIR"
18+
# shellcheck disable=SC2164
19+
cd "$TEMP_DIR"
20+
21+
22+
DICT_FILE="$TEMP_DIR/superchain/extra/dictionary"
23+
TARGET_PATH="$TEMP_DIR/result"
24+
GENESIS_TARGET_PATH="$TARGET_PATH/genesis"
25+
CONFIGS_TARGET_PATH="$TARGET_PATH/configs"
26+
27+
GENESIS_SRC_DIR="$TEMP_DIR/superchain/extra/genesis"
28+
CONFIGS_SRC_DIR="$TEMP_DIR/superchain/configs"
29+
mkdir -p "$GENESIS_TARGET_PATH"
30+
mkdir -p "$CONFIGS_TARGET_PATH"
31+
32+
echo "Convert TOML files to JSON..."
33+
# JSON makes the handling in no-std environments easier
34+
find "$CONFIGS_SRC_DIR" -type f -name "*.toml" | while read -r file; do
35+
36+
# Compute destination file path
37+
REL_PATH="${file#"$CONFIGS_SRC_DIR"/}"
38+
DEST_PATH="$CONFIGS_TARGET_PATH/${REL_PATH%.toml}"
39+
40+
# Ensure destination directory exists
41+
mkdir -p "$(dirname "$DEST_PATH")"
42+
43+
# Convert the toml file to json
44+
yq -p toml -o json "$file" > "$DEST_PATH.json"
45+
done
46+
47+
echo "Extract and compress the genesis files..."
48+
# We compress the genesis files with zlib-flate to save space and to a compression
49+
# format that makes it easier to handle them in no-std environments
50+
find "$GENESIS_SRC_DIR" -type f -name "*.json.zst" | while read -r file; do
51+
52+
# Compute destination file path
53+
REL_PATH="${file#"$GENESIS_SRC_DIR"/}"
54+
DEST_PATH="$GENESIS_TARGET_PATH/${REL_PATH%.zst}"
55+
56+
# Ensure destination directory exists
57+
mkdir -p "$(dirname "$DEST_PATH")"
58+
59+
# Extract the file
60+
zstd -q -d -D="$DICT_FILE" "$file" -o "$DEST_PATH"
61+
62+
# Remove "config" field from genesis files, because it is not consistent populated.
63+
# We will add it back in from the chain config file during runtime.
64+
# See: https://github.com/ethereum-optimism/superchain-registry/issues/901
65+
jq -c 'del(.config)' "$DEST_PATH" > "$DEST_PATH.tmp"
66+
mv "$DEST_PATH.tmp" "$DEST_PATH"
67+
68+
# Compress with zlib-flate and remove the original file
69+
zlib-flate -compress < "$DEST_PATH" > "$DEST_PATH.zz"
70+
rm "$DEST_PATH"
71+
72+
done
73+
74+
# Save revision
75+
git rev-parse HEAD > "$TARGET_PATH/superchain_registry_commit"
76+
git rev-parse HEAD > "$SCRIPT_DIR/superchain_registry_commit"
77+
78+
# Copy the LICENSE file
79+
cp "$TEMP_DIR/LICENSE" "$TARGET_PATH/LICENSE"
80+
81+
# Set the modification time of all files to 1980-01-01 to ensure the archive is deterministic
82+
find "$TARGET_PATH" -exec touch -t 198001010000.00 {} +
83+
84+
# shellcheck disable=SC2164
85+
cd "$TARGET_PATH"
86+
# Create a tar archive excluding files that are not relevant superchain directory
87+
# shellcheck disable=SC2035
88+
COPYFILE_DISABLE=1 tar --no-acls --no-xattrs -cf superchain-configs.tar --exclude "._COMMIT" *
89+
90+
# Move result to the script directory
91+
mv superchain-configs.tar "$SCRIPT_DIR"
92+
93+
echo "Create available-chains.json..."
94+
# Create available-chains.json from chainList.json
95+
# shellcheck disable=SC2002
96+
JSON_DATA=$(cat "$TEMP_DIR/chainList.json" | jq -r 'sort_by(.parent.chain, .identifier | split("/")[1])')
97+
98+
# Extract network and chain names
99+
PARENT_CHAINS=$(echo "$JSON_DATA" | jq -r '.[].parent.chain')
100+
IDENTIFIERS=$(echo "$JSON_DATA" | jq -r '.[].identifier | split("/")[1]')
101+
# shellcheck disable=SC2206
102+
PARENT_CHAINS_ARRAY=($PARENT_CHAINS)
103+
# shellcheck disable=SC2206
104+
IDENTIFIERS_ARRAY=($IDENTIFIERS)
105+
106+
RESULTS=()
107+
RESULT_RS="// Generated by fetch_superchain_config.sh\nuse crate::create_chain_spec;\n\n"
108+
109+
echo "Generate available-chains.json and chain_specs.rs..."
110+
for i in "${!PARENT_CHAINS_ARRAY[@]}"; do
111+
NAME="${IDENTIFIERS_ARRAY[$i]}"
112+
ENVIRONMENT="${PARENT_CHAINS_ARRAY[$i]}"
113+
# Skip Optimism and Base here because it is implemented separately
114+
if [ "$NAME" == "op" ] || [ "$NAME" == "base" ]; then
115+
continue
116+
fi
117+
118+
# Validate file existence in our target path <environment>/<name>.json.zst
119+
FILE_PATH="$GENESIS_TARGET_PATH/${PARENT_CHAINS_ARRAY[$i]}/${IDENTIFIERS_ARRAY[$i]}.json.zz"
120+
if [ -f "$FILE_PATH" ]; then
121+
RESULTS+=("{\"name\": \"$NAME\", \"environment\": \"$ENVIRONMENT\"}")
122+
RESULT_RS+="create_chain_spec!(\"$NAME\", \"$ENVIRONMENT\");\n"
123+
else
124+
echo "Error: File not found: $FILE_PATH" >&2
125+
fi
126+
done
127+
128+
# Write available-chains.json
129+
# shellcheck disable=SC2005
130+
echo "$(printf '%s\n' "${RESULTS[@]}" | jq -c -s 'sort_by(.name, .environment)')" > "$SCRIPT_DIR/available-chains.json"
131+
132+
# Write chain_specs.rs
133+
echo -e "$RESULT_RS" | sed '${/^$/d;}' > "$SCRIPT_DIR/../src/superchain/chain_specs.rs"
134+
135+
# Clean up
136+
# shellcheck disable=SC2164
137+
cd "$TEMP_DIR/../"
138+
rm -rf "$TEMP_DIR"
139+
140+
echo "Done."

0 commit comments

Comments
 (0)