diff --git a/.dockerignore b/.dockerignore index 927362b59..034a5c2d3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1 @@ -geth-data/ reth-data/ -nethermind-data/ diff --git a/.env b/.env index f4ea7b66a..060f7b4a6 100644 --- a/.env +++ b/.env @@ -1,3 +1 @@ -CLIENT=${CLIENT:-reth} -HOST_DATA_DIR=./${CLIENT}-data -USE_BASE_CONSENSUS=true +HOST_DATA_DIR=./reth-data diff --git a/.env.mainnet b/.env.mainnet index c5bd040b5..ac9e52b66 100644 --- a/.env.mainnet +++ b/.env.mainnet @@ -1,92 +1,37 @@ # BASE MAINNET NODE CONFIGURATION -# =========================== +# ============================== # NETWORK CONFIGURATION -# -------------------- +# --------------------- RETH_CHAIN=base BASE_NODE_NETWORK=base -OP_NODE_NETWORK=base-mainnet -OP_GETH_OP_NETWORK=base-mainnet # BASE SEQUENCER ENDPOINTS -# ----------------------- +# ------------------------ RETH_SEQUENCER_HTTP=https://mainnet-sequencer.base.org -OP_SEQUENCER_HTTP=https://mainnet-sequencer.base.org -OP_GETH_SEQUENCER_HTTP=https://mainnet-sequencer.base.org -OP_RETH_SEQUENCER_HTTP=https://mainnet-sequencer.base.org - -# SYNC CONFIGURATION (deprecated) -# ----------------- -OP_NODE_SYNCMODE=execution-layer -OP_NODE_VERIFIER_L1_CONFS=4 -OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true # [REQUIRED] L1 CONFIGURATION -# -------------------------- +# --------------------------- # Replace these values with your L1 (Ethereum) node endpoints -OP_NODE_L1_ETH_RPC= -OP_NODE_L1_BEACON= -OP_NODE_L1_BEACON_ARCHIVER= -OP_NODE_L1_BEACON_FETCH_ALL_SIDECARS="true" -OP_NODE_L1_RPC_KIND="debug_geth" -OP_NODE_L1_TRUST_RPC="false" - BASE_NODE_L1_ETH_RPC= BASE_NODE_L1_BEACON= BASE_NODE_L1_TRUST_RPC="false" # ENGINE CONFIGURATION -# ------------------- -OP_NODE_L2_ENGINE_KIND=reth -OP_NODE_L2_ENGINE_RPC=http://execution:8551 - +# -------------------- BASE_NODE_L2_ENGINE_RPC=ws://execution:8551 BASE_NODE_L2_ENGINE_AUTH=/tmp/engine-auth-jwt BASE_NODE_L2_ENGINE_AUTH_RAW=688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a # P2P CONFIGURATION -# --------------- -OP_NODE_P2P_AGENT=base -OP_NODE_P2P_LISTEN_IP=0.0.0.0 -OP_NODE_P2P_LISTEN_TCP_PORT=9222 -OP_NODE_P2P_LISTEN_UDP_PORT=9222 -OP_NODE_INTERNAL_IP="true" -OP_NODE_P2P_BOOTNODES=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG - +# ----------------- BASE_NODE_P2P_LISTEN_IP=0.0.0.0 BASE_NODE_P2P_ADVERTISE_TCP_PORT=9222 BASE_NODE_P2P_ADVERTISE_UDP_PORT=9222 BASE_NODE_P2P_BOOTNODES=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG -# RETH CONFIGURATION -# ---------------- -OP_RETH_DISABLE_DISCOVERY="false" -OP_RETH_DISABLE_TX_POOL_GOSSIP="true" -OP_RETH_OP_NETWORK="base" - -# RPC CONFIGURATION (deprecated) -# --------------- -OP_NODE_RPC_ADDR=0.0.0.0 -OP_NODE_RPC_PORT=8545 - -# GETH CACHE SETTINGS -# ----------------- -GETH_CACHE="20480" # 20GB -GETH_CACHE_DATABASE="20" # 4GB -GETH_CACHE_GC="12" -GETH_CACHE_SNAPSHOT="24" -GETH_CACHE_TRIE="44" -OP_GETH_NET_RESTRICT="10.0.0.0/8" - # LOGGING & MONITORING -# ------------------ -OP_NODE_LOG_LEVEL=info -OP_NODE_LOG_FORMAT="json" -OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log -OP_NODE_METRICS_ENABLED="true" -OP_NODE_METRICS_ADDR=0.0.0.0 -OP_NODE_METRICS_PORT="7300" - +# -------------------- BASE_NODE_LOG_VERBOSITY=3 BASE_NODE_LOG_FORMAT="json" BASE_NODE_METRICS_ENABLED="true" @@ -95,22 +40,10 @@ BASE_NODE_METRICS_PORT="7300" STATSD_ADDRESS="172.17.0.1" # OPTIONAL SETTINGS -# =============== - -# ETHSTATS MONITORING (OPTIONAL - UNCOMMENT TO ENABLE) -# OP_GETH_ETH_STATS=nodename:secret@host:port -# OP_NETHERMIND_ETHSTATS_ENABLED=true -# OP_NETHERMIND_ETHSTATS_NODE_NAME=NethermindNode -# OP_NETHERMIND_ETHSTATS_ENDPOINT=ethstats_endpoint - -# TRUSTED RPC MODE (OPTIONAL - UNCOMMENT TO ENABLE) (deprecated) -# OP_NODE_L1_TRUST_RPC=true +# ================= -# SNAP SYNC (OPTIONAL EXPERIMENTAL FEATURE - UNCOMMENT TO ENABLE) -# NOTE: This feature is experimental and may lead to syncing issues -# OP_GETH_BOOTNODES=enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301,enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301,enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301,enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301,enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301 -# OP_NETHERMIND_BOOTNODES=enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301,enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301,enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301,enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301,enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301 -# OP_GETH_SYNCMODE=snap +# FOLLOW MODE (OPTIONAL - UNCOMMENT TO ENABLE) +# BASE_NODE_SOURCE_L2_RPC= # FLASHBLOCKS (OPTIONAL - UNCOMMENT TO ENABLE) # RETH_FB_WEBSOCKET_URL=wss://mainnet.flashblocks.base.org/ws diff --git a/.env.sepolia b/.env.sepolia index cb9a8b545..e518129fb 100644 --- a/.env.sepolia +++ b/.env.sepolia @@ -1,92 +1,37 @@ # BASE SEPOLIA TESTNET NODE CONFIGURATION -# ================================== +# ====================================== # NETWORK CONFIGURATION -# -------------------- +# --------------------- RETH_CHAIN=base-sepolia -OP_NODE_NETWORK=base-sepolia BASE_NODE_NETWORK=base-sepolia -OP_GETH_OP_NETWORK=base-sepolia # BASE SEQUENCER ENDPOINTS -# ----------------------- +# ------------------------ RETH_SEQUENCER_HTTP=https://sepolia-sequencer.base.org -OP_SEQUENCER_HTTP=https://sepolia-sequencer.base.org -OP_GETH_SEQUENCER_HTTP=https://sepolia-sequencer.base.org -OP_RETH_SEQUENCER_HTTP=https://sepolia-sequencer.base.org - -# SYNC CONFIGURATION (deprecated) -# ----------------- -OP_NODE_SYNCMODE=execution-layer -OP_NODE_VERIFIER_L1_CONFS=4 -OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true # [REQUIRED] L1 CONFIGURATION -# -------------------------- +# --------------------------- # Replace these values with your L1 (Ethereum) node endpoints -OP_NODE_L1_ETH_RPC= -OP_NODE_L1_BEACON= -OP_NODE_L1_BEACON_ARCHIVER= -OP_NODE_L1_BEACON_FETCH_ALL_SIDECARS="true" -OP_NODE_L1_RPC_KIND="debug_geth" -OP_NODE_L1_TRUST_RPC="false" - BASE_NODE_L1_ETH_RPC= BASE_NODE_L1_BEACON= BASE_NODE_L1_TRUST_RPC="false" # ENGINE CONFIGURATION -# ------------------- -OP_NODE_L2_ENGINE_KIND=reth -OP_NODE_L2_ENGINE_RPC=ws://execution:8551 - +# -------------------- BASE_NODE_L2_ENGINE_RPC=http://execution:8551 BASE_NODE_L2_ENGINE_AUTH=/tmp/engine-auth-jwt BASE_NODE_L2_ENGINE_AUTH_RAW=688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a # P2P CONFIGURATION -# --------------- -OP_NODE_P2P_AGENT=base -OP_NODE_P2P_LISTEN_IP=0.0.0.0 -OP_NODE_P2P_LISTEN_TCP_PORT=9222 -OP_NODE_P2P_LISTEN_UDP_PORT=9222 -OP_NODE_INTERNAL_IP="true" -OP_NODE_P2P_BOOTNODES=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG - +# ----------------- BASE_NODE_P2P_LISTEN_IP=0.0.0.0 BASE_NODE_P2P_ADVERTISE_TCP_PORT=9222 BASE_NODE_P2P_ADVERTISE_UDP_PORT=9222 BASE_NODE_P2P_BOOTNODES=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG -# RETH CONFIGURATION -# ---------------- -OP_RETH_DISABLE_DISCOVERY="false" -OP_RETH_DISABLE_TX_POOL_GOSSIP="true" -OP_RETH_OP_NETWORK="base-sepolia" - -# RPC CONFIGURATION (deprecated) -# --------------- -OP_NODE_RPC_ADDR=0.0.0.0 -OP_NODE_RPC_PORT=8545 - -# GETH CACHE SETTINGS -# ----------------- -GETH_CACHE="20480" # 20GB -GETH_CACHE_DATABASE="20" # 4GB -GETH_CACHE_GC="12" -GETH_CACHE_SNAPSHOT="24" -GETH_CACHE_TRIE="44" -OP_GETH_NET_RESTRICT="10.0.0.0/8" - # LOGGING & MONITORING -# ------------------ -OP_NODE_LOG_LEVEL=info -OP_NODE_LOG_FORMAT="json" -OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log -OP_NODE_METRICS_ENABLED="true" -OP_NODE_METRICS_ADDR=0.0.0.0 -OP_NODE_METRICS_PORT="7300" - +# -------------------- BASE_NODE_LOG_VERBOSITY=3 BASE_NODE_LOG_FORMAT="json" BASE_NODE_METRICS_ENABLED="true" @@ -95,22 +40,10 @@ BASE_NODE_METRICS_PORT="7300" STATSD_ADDRESS="172.17.0.1" # OPTIONAL SETTINGS -# =============== - -# ETHSTATS MONITORING (OPTIONAL - UNCOMMENT TO ENABLE) -# OP_GETH_ETH_STATS=nodename:secret@host:port -# OP_NETHERMIND_ETHSTATS_ENABLED=true -# OP_NETHERMIND_ETHSTATS_NODE_NAME=NethermindNode -# OP_NETHERMIND_ETHSTATS_ENDPOINT=ethstats_endpoint - -# TRUSTED RPC MODE (OPTIONAL - UNCOMMENT TO ENABLE) (deprecated) -# OP_NODE_L1_TRUST_RPC=true +# ================= -# SNAP SYNC (OPTIONAL EXPERIMENTAL FEATURE - UNCOMMENT TO ENABLE) -# NOTE: This feature is experimental and may lead to syncing issues -# OP_GETH_BOOTNODES=enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301,enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301,enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301,enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301,enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301 -# OP_NETHERMIND_BOOTNODES=enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301,enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301,enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301,enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301,enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301 -# OP_GETH_SYNCMODE=snap +# FOLLOW MODE (OPTIONAL - UNCOMMENT TO ENABLE) +# BASE_NODE_SOURCE_L2_RPC= # FLASHBLOCKS (OPTIONAL - UNCOMMENT TO ENABLE) # RETH_FB_WEBSOCKET_URL=wss://sepolia.flashblocks.base.org/ws diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..365eeecec --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily + + - package-ecosystem: docker + directory: / + schedule: + interval: daily diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 000000000..9bbf409e6 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,93 @@ +name: Docker + +on: + schedule: + - cron: '40 11 * * *' + push: + branches: [ "main" ] + # Publish semver tags as releases. + tags: [ 'v*.*.*' ] + pull_request: + branches: [ "main" ] + +env: + # Use docker.io for Docker Hub if empty + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Install the cosign tool except on PR + # https://github.com/sigstore/cosign-installer + - name: Install cosign + if: github.event_name != 'pull_request' + uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0 + with: + cosign-release: 'v2.2.4' + + # Set up BuildKit Docker container builder to be able to build + # multi-platform images and export cache + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # Sign the resulting Docker image digest except on PRs. + # This will only write to the public Rekor transparency log when the Docker + # repository is public to avoid leaking data. If you would like to publish + # transparency data even for private images, pass --force to cosign below. + # https://github.com/sigstore/cosign + - name: Sign the published Docker image + if: ${{ github.event_name != 'pull_request' }} + env: + # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable + TAGS: ${{ steps.meta.outputs.tags }} + DIGEST: ${{ steps.build-and-push.outputs.digest }} + # This step uses the identity token to provision an ephemeral certificate + # against the sigstore community Fulcio instance. + run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0c4df219b..7a3d299c1 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -11,81 +11,13 @@ on: env: REGISTRY: ghcr.io NAMESPACE: ghcr.io/base - GETH_DEPRECATED_IMAGE_NAME: node - GETH_IMAGE_NAME: node-geth RETH_IMAGE_NAME: node-reth - NETHERMIND_IMAGE_NAME: node-nethermind permissions: contents: read packages: write jobs: - geth: - strategy: - matrix: - settings: - - arch: linux/amd64 - runs-on: ubuntu-24.04 - - arch: linux/arm64 - runs-on: ubuntu-24.04-arm - runs-on: ${{ matrix.settings.runs-on }} - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 - with: - egress-policy: audit - - - name: Checkout - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - - - name: Log into the Container registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata for the Docker image - id: meta - uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v4.6.0 - with: - images: | - ${{ env.NAMESPACE }}/${{ env.GETH_DEPRECATED_IMAGE_NAME }} - ${{ env.NAMESPACE }}/${{ env.GETH_IMAGE_NAME }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Build and push the Docker image - id: build - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - file: geth/Dockerfile - tags: ${{ env.NAMESPACE }}/${{ env.GETH_DEPRECATED_IMAGE_NAME }},${{ env.NAMESPACE }}/${{ env.GETH_IMAGE_NAME }} - labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ matrix.settings.arch }} - outputs: type=image,push-by-digest=true,name-canonical=true,push=true - - - name: Export digest - run: | - mkdir -p ${{ runner.temp }}/digests - digest="${{ steps.build.outputs.digest }}" - touch "${{ runner.temp }}/digests/${digest#sha256:}" - - - name: Prepare - run: | - platform=${{ matrix.settings.arch }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - - - name: Upload digest - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: digests-geth-${{ env.PLATFORM_PAIR }} - path: ${{ runner.temp }}/digests/* - if-no-files-found: error - retention-days: 1 reth: strategy: matrix: @@ -104,7 +36,7 @@ jobs: egress-policy: audit - name: Checkout - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Log into the Container registry uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 @@ -128,7 +60,7 @@ jobs: uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: . - file: reth/Dockerfile + file: Dockerfile tags: ${{ env.NAMESPACE }}/${{ env.RETH_IMAGE_NAME }} labels: ${{ steps.meta.outputs.labels }} build-args: | @@ -155,123 +87,6 @@ jobs: if-no-files-found: error retention-days: 1 - nethermind: - strategy: - matrix: - settings: - - arch: linux/amd64 - runs-on: ubuntu-24.04 - - arch: linux/arm64 - runs-on: ubuntu-24.04-arm - runs-on: ${{ matrix.settings.runs-on }} - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 - with: - egress-policy: audit - - - name: Checkout - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 - - - name: Log into the Container registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Extract metadata for the Docker image - id: meta - uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v4.6.0 - with: - images: | - ${{ env.NAMESPACE }}/${{ env.NETHERMIND_IMAGE_NAME }} - - - name: Build and push the Docker image - id: build - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - file: nethermind/Dockerfile - tags: ${{ env.NAMESPACE }}/${{ env.NETHERMIND_IMAGE_NAME }} - labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ matrix.settings.arch }} - outputs: type=image,push-by-digest=true,name-canonical=true,push=true - - - name: Export digest - run: | - mkdir -p ${{ runner.temp }}/digests - digest="${{ steps.build.outputs.digest }}" - touch "${{ runner.temp }}/digests/${digest#sha256:}" - - - name: Prepare - run: | - platform=${{ matrix.settings.arch }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - - - name: Upload digest - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: digests-nethermind-${{ env.PLATFORM_PAIR }} - path: ${{ runner.temp }}/digests/* - if-no-files-found: error - retention-days: 1 - - merge-geth: - runs-on: ubuntu-latest - needs: - - geth - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 - with: - egress-policy: audit - - - name: Download digests - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 - with: - path: ${{ runner.temp }}/digests - pattern: digests-geth-* - merge-multiple: true - - - name: Log into the Container registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Extract metadata for the Docker image - id: meta - uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 - with: - images: | - ${{ env.NAMESPACE }}/${{ env.GETH_DEPRECATED_IMAGE_NAME }} - ${{ env.NAMESPACE }}/${{ env.GETH_IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=tag - type=sha,format=long - - - name: Create manifest list and push - working-directory: ${{ runner.temp }}/digests - run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.NAMESPACE }}/${{ env.GETH_DEPRECATED_IMAGE_NAME }}@sha256:%s ' *) - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.NAMESPACE }}/${{ env.GETH_IMAGE_NAME }}@sha256:%s ' *) - - - name: Inspect image - run: | - docker buildx imagetools inspect ${{ env.NAMESPACE }}/${{ env.GETH_DEPRECATED_IMAGE_NAME }}:${{ steps.meta.outputs.version }} - docker buildx imagetools inspect ${{ env.NAMESPACE }}/${{ env.GETH_IMAGE_NAME }}:${{ steps.meta.outputs.version }} - merge-reth: runs-on: ubuntu-latest needs: @@ -319,51 +134,3 @@ jobs: - name: Inspect image run: | docker buildx imagetools inspect ${{ env.NAMESPACE }}/${{ env.RETH_IMAGE_NAME }}:${{ steps.meta.outputs.version }} - - merge-nethermind: - runs-on: ubuntu-latest - needs: - - nethermind - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 - with: - egress-policy: audit - - - name: Download digests - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 - with: - path: ${{ runner.temp }}/digests - pattern: digests-nethermind-* - merge-multiple: true - - - name: Log into the Container registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Extract metadata for the Docker image - id: meta - uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 - with: - images: | - ${{ env.NAMESPACE }}/${{ env.NETHERMIND_IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=tag - type=sha,format=long - - - name: Create manifest list and push - working-directory: ${{ runner.temp }}/digests - run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.NAMESPACE }}/${{ env.NETHERMIND_IMAGE_NAME }}@sha256:%s ' *) - - - name: Inspect image - run: | - docker buildx imagetools inspect ${{ env.NAMESPACE }}/${{ env.NETHERMIND_IMAGE_NAME }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 237faa4c5..8ddfbfc4a 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -8,37 +8,6 @@ permissions: contents: read jobs: - geth: - strategy: - matrix: - settings: - - arch: linux/amd64 - runs-on: ubuntu-24.04 - - arch: linux/arm64 - runs-on: ubuntu-24.04-arm - runs-on: ${{ matrix.settings.runs-on }} - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 - with: - egress-policy: audit - - - name: Checkout - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - with: - ref: ${{ github.event.pull_request.head.sha }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Build the Docker image - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - file: geth/Dockerfile - push: false - platforms: ${{ matrix.settings.arch }} - reth: strategy: matrix: @@ -49,7 +18,7 @@ jobs: - arch: linux/arm64 runs-on: ubuntu-24.04-arm features: jemalloc,optimism - runs-on: ${{ matrix.settings.runs-on}} + runs-on: ${{ matrix.settings.runs-on }} steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 @@ -60,43 +29,16 @@ jobs: uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: ref: ${{ github.event.pull_request.head.sha }} + - name: Set up Docker Buildx uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + - name: Build the Docker image uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: . - file: reth/Dockerfile + file: Dockerfile push: false build-args: | FEATURES=${{ matrix.settings.features }} platforms: ${{ matrix.settings.arch }} - - nethermind: - strategy: - matrix: - settings: - - arch: linux/amd64 - runs-on: ubuntu-24.04 - - arch: linux/arm64 - runs-on: ubuntu-24.04-arm - runs-on: ${{ matrix.settings.runs-on}} - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 - with: - egress-policy: audit - - - name: Checkout - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - with: - ref: ${{ github.event.pull_request.head.sha }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - name: Build the Docker image - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - file: nethermind/Dockerfile - push: false - platforms: ${{ matrix.settings.arch }} diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml deleted file mode 100644 index 3ce14cff3..000000000 --- a/.github/workflows/update-dependencies.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Update Dockerfile Dependencies -on: - schedule: - - cron: '0 13 * * *' - workflow_dispatch: - -permissions: - contents: write - pull-requests: write - -jobs: - update: - name: update - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: build dependency updater - run: cd dependency_updater && go build - - - name: run dependency updater - id: run_dependency_updater - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: cd dependency_updater && ./dependency_updater --repo ../ --github-action true - - - name: create pull request - if: ${{ steps.run_dependency_updater.outputs.TITLE != '' }} - uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 - with: - title: ${{ steps.run_dependency_updater.outputs.TITLE }} - commit-message: ${{ steps.run_dependency_updater.outputs.TITLE }} - body: "${{ steps.run_dependency_updater.outputs.DESC }}" - branch: run-dependency-updater - delete-branch: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7bb8e3f91..1dc513860 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ /.idea/ -/geth-data/ /reth-data/ -/nethermind-data/ /dependency_updater/dependency_updater .DS_Store diff --git a/reth/Dockerfile b/Dockerfile similarity index 76% rename from reth/Dockerfile rename to Dockerfile index 2c9eec55f..46fd2dfa1 100644 --- a/reth/Dockerfile +++ b/Dockerfile @@ -1,20 +1,5 @@ ARG RUST_VERSION=1.93 -FROM golang:1.24 AS op - -RUN curl -sSfL 'https://just.systems/install.sh' | bash -s -- --to /usr/local/bin - -WORKDIR /app - -COPY versions.env /tmp/versions.env - -RUN . /tmp/versions.env && git clone $OP_NODE_REPO --branch $OP_NODE_TAG --single-branch . && \ - git switch -c branch-$OP_NODE_TAG && \ - bash -c '[ "$(git rev-parse HEAD)" = "$OP_NODE_COMMIT" ]' - -RUN . /tmp/versions.env && cd op-node && \ - make VERSION=$OP_NODE_TAG op-node - FROM public.ecr.aws/docker/library/rust:${RUST_VERSION}-trixie AS rust-builder-base WORKDIR /app @@ -57,19 +42,16 @@ RUN cargo build --bin base-reth-node --bin base-consensus --profile maxperf FROM ubuntu:24.04 RUN apt-get update && \ - apt-get install -y jq curl supervisor && \ + apt-get install -y curl supervisor && \ rm -rf /var/lib/apt/lists/* RUN mkdir -p /var/log/supervisor WORKDIR /app -COPY --from=op /app/op-node/bin/op-node ./ COPY --from=reth-base /app/target/maxperf/base-consensus ./ COPY --from=reth-base /app/target/maxperf/base-reth-node ./ COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf -COPY ./reth/reth-entrypoint ./execution-entrypoint -COPY op-node-entrypoint . -COPY base-consensus-entrypoint . +COPY execution-entrypoint . COPY consensus-entrypoint . CMD ["/usr/bin/supervisord"] diff --git a/README.md b/README.md index 1cbaad17d..2e0b62998 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Base Node -Base is a secure, low-cost, developer-friendly Ethereum L2 built on Optimism's [OP Stack](https://docs.optimism.io/). This repository contains Docker builds to run your own node on the Base network. +Base is a secure, low-cost, developer-friendly Ethereum L2 built on Optimism's [OP Stack](https://docs.optimism.io/). This repository contains a Docker build for running a Base node with `base-reth-node` and `base-consensus`. [![Website base.org](https://img.shields.io/website-up-down-green-red/https/base.org.svg)](https://base.org) [![Docs](https://img.shields.io/badge/docs-up-green)](https://docs.base.org/) @@ -12,15 +12,14 @@ Base is a secure, low-cost, developer-friendly Ethereum L2 built on Optimism's [ ## Quick Start -1. Ensure you have an Ethereum L1 full node RPC available +1. Ensure you have an Ethereum L1 full node RPC and beacon endpoint available. 2. Choose your network: - - For mainnet: Use `.env.mainnet` - - For testnet: Use `.env.sepolia` + - For mainnet: use `.env.mainnet` + - For testnet: use `.env.sepolia` 3. Configure your L1 endpoints in the appropriate `.env` file: ```bash - OP_NODE_L1_ETH_RPC= - OP_NODE_L1_BEACON= - OP_NODE_L1_BEACON_ARCHIVER= + BASE_NODE_L1_ETH_RPC= + BASE_NODE_L1_BEACON= ``` 4. Start the node: @@ -30,28 +29,21 @@ Base is a secure, low-cost, developer-friendly Ethereum L2 built on Optimism's [ # For testnet: NETWORK_ENV=.env.sepolia docker compose up --build - - # To use a specific client (optional): - CLIENT=reth docker compose up --build - - # For testnet with a specific client: - NETWORK_ENV=.env.sepolia CLIENT=reth docker compose up --build ``` -### Supported Clients +## Supported Clients -- `reth` (default) -- `geth` -- `nethermind` +- Execution: `base-reth-node` +- Consensus: `base-consensus` ## Requirements ### Minimum Requirements -- Modern Multicore CPU -- 32GB RAM (64GB Recommended) +- Modern multicore CPU +- 32GB RAM (64GB recommended) - NVMe SSD drive -- Storage: (2 \* [current chain size](https://base.org/stats) + [snapshot size](https://basechaindata.vercel.app) + 20% buffer) (to accommodate future growth) +- Storage: (2 * [current chain size](https://base.org/stats) + [snapshot size](https://basechaindata.vercel.app) + 20% buffer) to accommodate future growth - Docker and Docker Compose ### Production Hardware Specifications @@ -64,64 +56,43 @@ The following are the hardware specifications we use in production: - **Storage**: RAID 0 of all local NVMe drives (`/dev/nvme*`) - **Filesystem**: ext4 -#### Geth Full Node - -- **Instance**: AWS i7i.12xlarge -- **Storage**: RAID 0 of all local NVMe drives (`/dev/nvme*`) -- **Filesystem**: ext4 - -> [!NOTE] -To run the node using a supported client, you can use the following command: -`CLIENT=supported_client docker compose up --build` - -Supported clients: - - reth (runs vanilla node by default, Flashblocks mode enabled by providing RETH_FB_WEBSOCKET_URL, see [Reth Node README](./reth/README.md)) - - geth - - nethermind - ## Configuration ### Required Settings -- L1 Configuration: - - `OP_NODE_L1_ETH_RPC`: Your Ethereum L1 node RPC endpoint - - `OP_NODE_L1_BEACON`: Your L1 beacon node endpoint - - `OP_NODE_L1_BEACON_ARCHIVER`: Your L1 beacon archiver endpoint - - `OP_NODE_L1_RPC_KIND`: The type of RPC provider being used (default: "debug_geth"). Supported values: - - `alchemy`: Alchemy RPC provider - - `quicknode`: QuickNode RPC provider - - `infura`: Infura RPC provider - - `parity`: Parity RPC provider - - `nethermind`: Nethermind RPC provider - - `debug_geth`: Debug Geth RPC provider - - `erigon`: Erigon RPC provider - - `basic`: Basic RPC provider (standard receipt fetching only) - - `any`: Any available RPC method - - `standard`: Standard RPC methods including newer optimized methods +- `BASE_NODE_L1_ETH_RPC`: your Ethereum L1 node RPC endpoint +- `BASE_NODE_L1_BEACON`: your L1 beacon node endpoint +- `BASE_NODE_NETWORK`: `base` or `base-sepolia` +- `RETH_CHAIN`: `base` or `base-sepolia` ### Network Settings - Mainnet: - `RETH_CHAIN=base` - - `OP_NODE_NETWORK=base-mainnet` + - `BASE_NODE_NETWORK=base` - Sequencer: `https://mainnet-sequencer.base.org` +- Sepolia: + - `RETH_CHAIN=base-sepolia` + - `BASE_NODE_NETWORK=base-sepolia` + - Sequencer: `https://sepolia-sequencer.base.org` -### Performance Settings +### Optional Features -- Cache Settings: - - `GETH_CACHE="20480"` (20GB) - - `GETH_CACHE_DATABASE="20"` (4GB) - - `GETH_CACHE_GC="12"` - - `GETH_CACHE_SNAPSHOT="24"` - - `GETH_CACHE_TRIE="44"` +- Flashblocks: set `RETH_FB_WEBSOCKET_URL`. When set, the execution client runs in Flashblocks mode; otherwise it runs in vanilla mode. +- Follow mode: set `BASE_NODE_SOURCE_L2_RPC` +- Pruning: set `RETH_PRUNING_ARGS` -### Optional Features +For full configuration options, see `.env.mainnet` or `.env.sepolia`. + +### Testing Flashblocks RPC Methods -- EthStats Monitoring (uncomment to enable) -- Trusted RPC Mode (uncomment to enable) -- Snap Sync (experimental) +When running in Flashblocks mode, you can query a pending block using the Flashblocks RPC: -For full configuration options, see the `.env.mainnet` file. +```bash +curl -X POST \ + --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["pending", false],"id":1}' \ + http://localhost:8545 +``` ## Snapshots @@ -131,12 +102,12 @@ Snapshots are available to help you sync your node more quickly. See [docs.base. | Network | Status | | ------- | ------ | -| Mainnet | ✅ | -| Testnet | ✅ | +| Mainnet | ✅ | +| Testnet | ✅ | ## Troubleshooting -For support please join our [Discord](https://discord.gg/buildonbase) post in `🛠|node-operators`. You can alternatively open a new GitHub issue. +For support please join our [Discord](https://discord.gg/buildonbase) and post in `🛠|node-operators`. You can alternatively open a new GitHub issue. ## Disclaimer diff --git a/base-consensus-entrypoint b/base-consensus-entrypoint deleted file mode 100755 index cd2801fce..000000000 --- a/base-consensus-entrypoint +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -set -eu - -get_public_ip() { - # Define a list of HTTP-based providers - local PROVIDERS=( - "http://ifconfig.me" - "http://api.ipify.org" - "http://ipecho.net/plain" - "http://v4.ident.me" - ) - # Iterate through the providers until an IP is found or the list is exhausted - for provider in "${PROVIDERS[@]}"; do - local IP - IP=$(curl -s --max-time 10 --connect-timeout 5 "$provider") - # Check if IP contains a valid format (simple regex for an IPv4 address) - if [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "$IP" - return 0 - fi - done - return 1 -} - -if [[ -z "${BASE_NODE_NETWORK:-}" ]]; then - echo "expected BASE_NODE_NETWORK to be set" 1>&2 - exit 1 -fi - -# wait until local execution client comes up (authed so will return 401 without token) -until [ "$(curl -s --max-time 10 --connect-timeout 5 -w '%{http_code}' -o /dev/null "${BASE_NODE_L2_ENGINE_RPC/ws/http}")" -eq 401 ]; do - echo "waiting for execution client to be ready" - sleep 5 -done - -# public-facing P2P node, advertise public IP address -if PUBLIC_IP=$(get_public_ip); then - echo "fetched public IP is: $PUBLIC_IP" -else - echo "Could not retrieve public IP." - exit 8 -fi -export BASE_NODE_P2P_ADVERTISE_IP=$PUBLIC_IP - -echo "$BASE_NODE_L2_ENGINE_AUTH_RAW" > "$BASE_NODE_L2_ENGINE_AUTH" - -if [[ -n "${BASE_NODE_SOURCE_L2_RPC:-}" ]]; then - echo "Running base-consensus in follow mode because BASE_NODE_SOURCE_L2_RPC is set" - exec ./base-consensus follow -else - exec ./base-consensus node -fi diff --git a/consensus-entrypoint b/consensus-entrypoint index be95aa3c5..05b89467a 100755 --- a/consensus-entrypoint +++ b/consensus-entrypoint @@ -1,15 +1,64 @@ #!/bin/bash set -eu -if [ "${USE_BASE_CONSENSUS:-false}" = "true" ]; then - if [ -f ./base-consensus-entrypoint ]; then - echo "Using Base Client" - exec ./base-consensus-entrypoint - else - echo "Base client is not supported for this node type" - exit 1 +get_public_ip() { + local PROVIDERS=( + "http://ifconfig.me" + "http://api.ipify.org" + "http://ipecho.net/plain" + "http://v4.ident.me" + ) + + for provider in "${PROVIDERS[@]}"; do + local IP + IP=$(curl -s --max-time 10 --connect-timeout 5 "$provider") + if [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "$IP" + return 0 fi + done + + return 1 +} + +if [[ -z "${BASE_NODE_NETWORK:-}" ]]; then + echo "expected BASE_NODE_NETWORK to be set" 1>&2 + exit 1 +fi + +if [[ -z "${BASE_NODE_L2_ENGINE_RPC:-}" ]]; then + echo "expected BASE_NODE_L2_ENGINE_RPC to be set" 1>&2 + exit 1 +fi + +if [[ -z "${BASE_NODE_L2_ENGINE_AUTH:-}" ]]; then + echo "expected BASE_NODE_L2_ENGINE_AUTH to be set" 1>&2 + exit 1 +fi + +if [[ -z "${BASE_NODE_L2_ENGINE_AUTH_RAW:-}" ]]; then + echo "expected BASE_NODE_L2_ENGINE_AUTH_RAW to be set" 1>&2 + exit 1 +fi + +until [ "$(curl -s --max-time 10 --connect-timeout 5 -w '%{http_code}' -o /dev/null "${BASE_NODE_L2_ENGINE_RPC/ws/http}")" -eq 401 ]; do + echo "waiting for execution client to be ready" + sleep 5 +done + +if PUBLIC_IP=$(get_public_ip); then + echo "fetched public IP is: $PUBLIC_IP" +else + echo "Could not retrieve public IP." + exit 8 +fi +export BASE_NODE_P2P_ADVERTISE_IP=$PUBLIC_IP + +echo "$BASE_NODE_L2_ENGINE_AUTH_RAW" > "$BASE_NODE_L2_ENGINE_AUTH" + +if [[ -n "${BASE_NODE_SOURCE_L2_RPC:-}" ]]; then + echo "Running base-consensus in follow mode because BASE_NODE_SOURCE_L2_RPC is set" + exec ./base-consensus follow else - echo "Using OP Node" - exec ./op-node-entrypoint + exec ./base-consensus node fi diff --git a/dependency_updater/dependency_updater.go b/dependency_updater/dependency_updater.go deleted file mode 100644 index 56204d77a..000000000 --- a/dependency_updater/dependency_updater.go +++ /dev/null @@ -1,411 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "fmt" - "slices" - "time" - - "github.com/ethereum-optimism/optimism/op-service/retry" - "github.com/google/go-github/v72/github" - "github.com/urfave/cli/v3" - - "log" - "os" - "os/exec" - "strings" -) - -type Info struct { - Tag string `json:"tag,omitempty"` - Commit string `json:"commit"` - TagPrefix string `json:"tagPrefix,omitempty"` - Owner string `json:"owner"` - Repo string `json:"repo"` - Branch string `json:"branch,omitempty"` - Tracking string `json:"tracking"` -} - -type VersionUpdateInfo struct { - Repo string - From string - To string - DiffUrl string -} - -type Dependencies = map[string]*Info - -func main() { - cmd := &cli.Command{ - Name: "updater", - Usage: "Updates the dependencies in the geth, nethermind and reth Dockerfiles", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "token", - Usage: "Auth token used to make requests to the Github API must be set using export", - Sources: cli.EnvVars("GITHUB_TOKEN"), - Required: true, - }, - &cli.StringFlag{ - Name: "repo", - Usage: "Specifies repo location to run the version updater on", - Required: true, - }, - &cli.BoolFlag{ - Name: "commit", - Usage: "Stages updater changes and creates commit message", - Required: false, - }, - &cli.BoolFlag{ - Name: "github-action", - Usage: "Specifies whether tool is being used through github action workflow", - Required: false, - }, - }, - Action: func(ctx context.Context, cmd *cli.Command) error { - err := updater(cmd.String("token"), cmd.String("repo"), cmd.Bool("commit"), cmd.Bool("github-action")) - if err != nil { - return fmt.Errorf("failed to run updater: %s", err) - } - return nil - }, - } - - if err := cmd.Run(context.Background(), os.Args); err != nil { - log.Fatal(err) - } -} - -func updater(token string, repoPath string, commit bool, githubAction bool) error { - var err error - var dependencies Dependencies - var updatedDependencies []VersionUpdateInfo - - f, err := os.ReadFile(repoPath + "/versions.json") - if err != nil { - return fmt.Errorf("error reading versions JSON: %s", err) - } - - client := github.NewClient(nil).WithAuthToken(token) - ctx := context.Background() - - err = json.Unmarshal(f, &dependencies) - if err != nil { - return fmt.Errorf("error unmarshalling versions JSON to dependencies: %s", err) - } - - for dependency := range dependencies { - var updatedDependency VersionUpdateInfo - err := retry.Do0(context.Background(), 3, retry.Fixed(1*time.Second), func() error { - updatedDependency, err = getAndUpdateDependency( - ctx, - client, - dependency, - repoPath, - dependencies, - ) - return err - }) - if err != nil { - return fmt.Errorf("error getting and updating version/commit for "+dependency+": %s", err) - } - - if updatedDependency != (VersionUpdateInfo{}) { - updatedDependencies = append(updatedDependencies, updatedDependency) - } - } - - e := createVersionsEnv(repoPath, dependencies) - if e != nil { - return fmt.Errorf("error creating versions.env: %s", e) - } - - if (commit && updatedDependencies != nil) || (githubAction && updatedDependencies != nil) { - err := createCommitMessage(updatedDependencies, repoPath, githubAction) - if err != nil { - return fmt.Errorf("error creating commit message: %s", err) - } - } - - return nil -} - -func createCommitMessage(updatedDependencies []VersionUpdateInfo, repoPath string, githubAction bool) error { - var repos []string - descriptionLines := []string{ - "### Dependency Updates", - } - - commitTitle := "chore: updated " - - for _, dependency := range updatedDependencies { - repo, tag := dependency.Repo, dependency.To - descriptionLines = append(descriptionLines, fmt.Sprintf("**%s** - %s: [diff](%s)", repo, tag, dependency.DiffUrl)) - repos = append(repos, repo) - } - commitDescription := strings.Join(descriptionLines, "\n") - commitTitle += strings.Join(repos, ", ") - - if githubAction { - err := writeToGithubOutput(commitTitle, commitDescription, repoPath) - if err != nil { - return fmt.Errorf("error creating git commit message: %s", err) - } - } else { - cmd := exec.Command("git", "commit", "-am", commitTitle, "-m", commitDescription) - if err := cmd.Run(); err != nil { - return fmt.Errorf("failed to run git commit -m: %s", err) - } - } - return nil -} - -func getAndUpdateDependency(ctx context.Context, client *github.Client, dependencyType string, repoPath string, dependencies Dependencies) (VersionUpdateInfo, error) { - version, commit, updatedDependency, err := getVersionAndCommit(ctx, client, dependencies, dependencyType) - if err != nil { - return VersionUpdateInfo{}, err - } - if updatedDependency != (VersionUpdateInfo{}) { - e := updateVersionTagAndCommit(commit, version, dependencyType, repoPath, dependencies) - if e != nil { - return VersionUpdateInfo{}, fmt.Errorf("error updating version tag and commit: %s", e) - } - } - - return updatedDependency, nil -} - -func getVersionAndCommit(ctx context.Context, client *github.Client, dependencies Dependencies, dependencyType string) (string, string, VersionUpdateInfo, error) { - var selectedTag *github.RepositoryTag - var commit string - var diffUrl string - var updatedDependency VersionUpdateInfo - options := &github.ListOptions{Page: 1} - currentTag := dependencies[dependencyType].Tag - tagPrefix := dependencies[dependencyType].TagPrefix - - if dependencies[dependencyType].Tracking == "tag" || dependencies[dependencyType].Tracking == "release" { - // Collect all valid tags across all pages, then find the max version - var validTags []*github.RepositoryTag - trackingMode := dependencies[dependencyType].Tracking - - for { - tags, resp, err := client.Repositories.ListTags( - ctx, - dependencies[dependencyType].Owner, - dependencies[dependencyType].Repo, - options) - - if err != nil { - return "", "", VersionUpdateInfo{}, fmt.Errorf("error getting tags: %s", err) - } - - for _, tag := range tags { - // Skip if tagPrefix is set and doesn't match - if tagPrefix != "" && !strings.HasPrefix(*tag.Name, tagPrefix) { - continue - } - - // Filter based on tracking mode: - // - "release": only stable releases (no prerelease suffix) - // - "tag": releases and RC versions only (exclude -synctest, -alpha, etc.) - if trackingMode == "release" { - if !IsReleaseVersion(*tag.Name, tagPrefix) { - continue - } - } else if trackingMode == "tag" { - if !IsReleaseOrRCVersion(*tag.Name, tagPrefix) { - continue - } - } - - // Check if this is a valid upgrade (not a downgrade) - if err := ValidateVersionUpgrade(currentTag, *tag.Name, tagPrefix); err != nil { - continue - } - - validTags = append(validTags, tag) - } - - if resp.NextPage == 0 { - break - } - options.Page = resp.NextPage - } - - // Find the maximum version among valid tags - for _, tag := range validTags { - // Skip if this tag can't be parsed - if _, err := ParseVersion(*tag.Name, tagPrefix); err != nil { - log.Printf("Skipping unparseable tag %s: %v", *tag.Name, err) - continue - } - - if selectedTag == nil { - selectedTag = tag - continue - } - - cmp, err := CompareVersions(*tag.Name, *selectedTag.Name, tagPrefix) - if err != nil { - log.Printf("Error comparing versions %s and %s: %v", *tag.Name, *selectedTag.Name, err) - continue - } - if cmp > 0 { - selectedTag = tag - } - } - - // If no valid version found, keep current version - if selectedTag == nil { - log.Printf("No valid upgrade found for %s, keeping %s", dependencyType, currentTag) - return currentTag, dependencies[dependencyType].Commit, VersionUpdateInfo{}, nil - } - - if *selectedTag.Name != currentTag { - diffUrl = generateGithubRepoUrl(dependencies, dependencyType) + "/compare/" + - currentTag + "..." + *selectedTag.Name - } - - // Get commit SHA from the tag - commit = *selectedTag.Commit.SHA - } - - if diffUrl != "" { - updatedDependency = VersionUpdateInfo{ - dependencies[dependencyType].Repo, - dependencies[dependencyType].Tag, - *selectedTag.Name, - diffUrl, - } - } - - if dependencies[dependencyType].Tracking == "branch" { - branchCommit, _, err := client.Repositories.ListCommits( - ctx, - dependencies[dependencyType].Owner, - dependencies[dependencyType].Repo, - &github.CommitsListOptions{ - SHA: dependencies[dependencyType].Branch, - }, - ) - if err != nil { - return "", "", VersionUpdateInfo{}, fmt.Errorf("error listing commits for "+dependencyType+": %s", err) - } - commit = *branchCommit[0].SHA - if dependencies[dependencyType].Commit != commit { - from, to := dependencies[dependencyType].Commit, commit - diffUrl = fmt.Sprintf("%s/compare/%s...%s", generateGithubRepoUrl(dependencies, dependencyType), from, to) - updatedDependency = VersionUpdateInfo{ - dependencies[dependencyType].Repo, - dependencies[dependencyType].Tag, - commit, - diffUrl, - } - } - } - - if selectedTag != nil { - return *selectedTag.Name, commit, updatedDependency, nil - } - - return "", commit, updatedDependency, nil -} - -func updateVersionTagAndCommit( - commit string, - tag string, - dependencyType string, - repoPath string, - dependencies Dependencies) error { - dependencies[dependencyType].Tag = tag - dependencies[dependencyType].Commit = commit - err := writeToVersionsJson(repoPath, dependencies) - if err != nil { - return fmt.Errorf("error writing to versions "+dependencyType+": %s", err) - } - - return nil -} - -func writeToVersionsJson(repoPath string, dependencies Dependencies) error { - // formatting json - updatedJson, err := json.MarshalIndent(dependencies, "", " ") - if err != nil { - return fmt.Errorf("error marshaling dependencies json: %s", err) - } - - e := os.WriteFile(repoPath+"/versions.json", updatedJson, 0644) - if e != nil { - return fmt.Errorf("error writing to versions.json: %s", e) - } - - return nil -} - -func createVersionsEnv(repoPath string, dependencies Dependencies) error { - envLines := []string{} - - for dependency := range dependencies { - repoUrl := generateGithubRepoUrl(dependencies, dependency) + ".git" - - dependencyPrefix := strings.ToUpper(dependency) - - if dependencies[dependency].Tracking == "branch" { - dependencies[dependency].Tag = dependencies[dependency].Branch - } - - envLines = append(envLines, fmt.Sprintf("export %s_%s=%s", - dependencyPrefix, "TAG", dependencies[dependency].Tag)) - - envLines = append(envLines, fmt.Sprintf("export %s_%s=%s", - dependencyPrefix, "COMMIT", dependencies[dependency].Commit)) - - envLines = append(envLines, fmt.Sprintf("export %s_%s=%s", - dependencyPrefix, "REPO", repoUrl)) - } - - slices.Sort(envLines) - - file, err := os.Create(repoPath + "/versions.env") - if err != nil { - return fmt.Errorf("error creating versions.env file: %s", err) - } - defer file.Close() - - _, err = file.WriteString(strings.Join(envLines, "\n")) - if err != nil { - return fmt.Errorf("error writing to versions.env file: %s", err) - } - - return nil -} - -func writeToGithubOutput(title string, description string, repoPath string) error { - file := os.Getenv("GITHUB_OUTPUT") - f, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return fmt.Errorf("failed to open GITHUB_OUTPUT file: %s", err) - } - defer f.Close() - - titleToWrite := fmt.Sprintf("%s=%s\n", "TITLE", title) - _, err = f.WriteString(titleToWrite) - if err != nil { - return fmt.Errorf("failed to write to GITHUB_OUTPUT file: %s", err) - } - - delimiter := "EOF" - descToWrite := fmt.Sprintf("%s<<%s\n%s\n%s\n", "DESC", delimiter, description, delimiter) - _, err = f.WriteString(descToWrite) - if err != nil { - return fmt.Errorf("failed to write to GITHUB_OUTPUT file: %s", err) - } - - return nil -} - -func generateGithubRepoUrl(dependencies Dependencies, dependencyType string) string { - return "https://github.com/" + dependencies[dependencyType].Owner + "/" + dependencies[dependencyType].Repo -} diff --git a/dependency_updater/go.mod b/dependency_updater/go.mod deleted file mode 100644 index 85193c9c0..000000000 --- a/dependency_updater/go.mod +++ /dev/null @@ -1,14 +0,0 @@ -module github.com/base/node/dependency_updater - -go 1.24.3 - -require ( - github.com/ethereum-optimism/optimism v1.13.3 - github.com/google/go-github/v72 v72.0.0 - github.com/urfave/cli/v3 v3.3.8 -) - -require ( - github.com/Masterminds/semver/v3 v3.4.0 // indirect - github.com/google/go-querystring v1.1.0 // indirect -) diff --git a/dependency_updater/go.sum b/dependency_updater/go.sum deleted file mode 100644 index 72b6f03e4..000000000 --- a/dependency_updater/go.sum +++ /dev/null @@ -1,22 +0,0 @@ -github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= -github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/ethereum-optimism/optimism v1.13.3 h1:rfPx7OembMnoEASU1ozA/Foa7Am7UA+h0SB+OUrxn7s= -github.com/ethereum-optimism/optimism v1.13.3/go.mod h1:WrVFtk3cP45tvHs7MARn9KGQu35XIoXo/IOWU6K/rzk= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM= -github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/urfave/cli/v3 v3.3.8 h1:BzolUExliMdet9NlJ/u4m5vHSotJ3PzEqSAZ1oPMa/E= -github.com/urfave/cli/v3 v3.3.8/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/dependency_updater/version.go b/dependency_updater/version.go deleted file mode 100644 index 31a0a56eb..000000000 --- a/dependency_updater/version.go +++ /dev/null @@ -1,136 +0,0 @@ -package main - -import ( - "fmt" - "regexp" - "strings" - - "github.com/Masterminds/semver/v3" -) - -// rcPattern matches various RC formats: -rc1, -rc.1, -rc-1, -RC1, etc. -var rcPattern = regexp.MustCompile(`(?i)-rc[.-]?(\d+)`) - -// rcOnlyPattern is used to check if a version contains ONLY an RC prerelease (not -synctest, -alpha, etc.) -var rcOnlyPattern = regexp.MustCompile(`(?i)^-rc[.-]?\d+$`) - -// ParseVersion extracts and normalizes a semantic version from a tag string. -// It handles tagPrefix stripping, v-prefix normalization, and RC format normalization. -func ParseVersion(tag string, tagPrefix string) (*semver.Version, error) { - versionStr := tag - - // Step 1: Strip tagPrefix if present (e.g., "op-node/v1.16.2" -> "v1.16.2") - if tagPrefix != "" && strings.HasPrefix(tag, tagPrefix) { - versionStr = strings.TrimPrefix(tag, tagPrefix) - versionStr = strings.TrimPrefix(versionStr, "/") - } - - // Step 2: Normalize RC formats to semver-compatible format - // "-rc1" -> "-rc.1", "-rc-1" -> "-rc.1" - versionStr = normalizeRCFormat(versionStr) - - // Step 3: Parse using Masterminds/semver (handles v prefix automatically) - v, err := semver.NewVersion(versionStr) - if err != nil { - return nil, fmt.Errorf("invalid version format %q: %w", tag, err) - } - - return v, nil -} - -// normalizeRCFormat converts various RC formats to semver-compatible format. -// Examples: "-rc1" -> "-rc.1", "-rc-2" -> "-rc.2" -func normalizeRCFormat(version string) string { - return rcPattern.ReplaceAllString(version, "-rc.$1") -} - -// ValidateVersionUpgrade checks if transitioning from currentTag to newTag -// is a valid upgrade (not a downgrade). -// Returns nil if valid, error explaining why if invalid. -func ValidateVersionUpgrade(currentTag, newTag, tagPrefix string) error { - // First-time setup: no current version, any valid version is acceptable - if currentTag == "" { - _, err := ParseVersion(newTag, tagPrefix) - return err - } - - // Parse current version - currentVersion, err := ParseVersion(currentTag, tagPrefix) - if err != nil { - // Current version unparseable - still validate new version is parseable - _, newErr := ParseVersion(newTag, tagPrefix) - return newErr - } - - // Parse new version - newVersion, err := ParseVersion(newTag, tagPrefix) - if err != nil { - return fmt.Errorf("new version %q is not a valid semver: %w", newTag, err) - } - - // Check for downgrade - if newVersion.LessThan(currentVersion) { - return fmt.Errorf( - "version downgrade detected: %s -> %s", - currentTag, newTag, - ) - } - - return nil -} - -// CompareVersions compares two version tags and returns: -// -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2 -// Returns 0 and error if either version cannot be parsed. -func CompareVersions(v1Tag, v2Tag, tagPrefix string) (int, error) { - v1, err := ParseVersion(v1Tag, tagPrefix) - if err != nil { - return 0, err - } - v2, err := ParseVersion(v2Tag, tagPrefix) - if err != nil { - return 0, err - } - return v1.Compare(v2), nil -} - -// IsReleaseVersion returns true if the tag is a stable release (no prerelease suffix). -// Examples: -// - "v1.0.0" -> true -// - "v1.0.0-rc1" -> false -// - "v1.0.0-synctest.0" -> false -func IsReleaseVersion(tag string, tagPrefix string) bool { - v, err := ParseVersion(tag, tagPrefix) - if err != nil { - return false - } - return v.Prerelease() == "" -} - -// IsRCVersion returns true if the tag is a release candidate version. -// This matches versions with -rc, -rc.N, -rc-N, -rcN suffixes. -// Examples: -// - "v1.0.0-rc1" -> true -// - "v1.0.0-rc.2" -> true -// - "v1.0.0" -> false (stable release, not RC) -// - "v1.0.0-synctest.0" -> false (not an RC) -// - "v1.0.0-alpha" -> false (not an RC) -func IsRCVersion(tag string, tagPrefix string) bool { - v, err := ParseVersion(tag, tagPrefix) - if err != nil { - return false - } - prerelease := v.Prerelease() - if prerelease == "" { - return false - } - // Check if the prerelease is ONLY an RC format (e.g., "rc.1", "rc1", "rc-1") - // We need to check the original format before normalization - return rcOnlyPattern.MatchString("-" + prerelease) -} - -// IsReleaseOrRCVersion returns true if the tag is either a stable release or an RC version. -// This excludes other prereleases like -alpha, -beta, -synctest, etc. -func IsReleaseOrRCVersion(tag string, tagPrefix string) bool { - return IsReleaseVersion(tag, tagPrefix) || IsRCVersion(tag, tagPrefix) -} diff --git a/dependency_updater/version_test.go b/dependency_updater/version_test.go deleted file mode 100644 index 3413cb4ae..000000000 --- a/dependency_updater/version_test.go +++ /dev/null @@ -1,305 +0,0 @@ -package main - -import ( - "testing" -) - -func TestNormalizeRCFormat(t *testing.T) { - tests := []struct { - input string - expected string - }{ - {"v0.3.0-rc1", "v0.3.0-rc.1"}, - {"v0.3.0-rc.1", "v0.3.0-rc.1"}, - {"v0.3.0-rc-1", "v0.3.0-rc.1"}, - {"v0.3.0-RC1", "v0.3.0-rc.1"}, - {"v0.3.0-rc12", "v0.3.0-rc.12"}, - {"v0.3.0", "v0.3.0"}, - {"v0.3.0-alpha", "v0.3.0-alpha"}, - {"v0.3.0-beta.1", "v0.3.0-beta.1"}, - } - - for _, tt := range tests { - t.Run(tt.input, func(t *testing.T) { - result := normalizeRCFormat(tt.input) - if result != tt.expected { - t.Errorf("normalizeRCFormat(%q) = %q, want %q", tt.input, result, tt.expected) - } - }) - } -} - -func TestParseVersion(t *testing.T) { - tests := []struct { - tag string - tagPrefix string - wantErr bool - }{ - // Standard versions - {"v0.2.2", "", false}, - {"v0.3.0", "", false}, - {"1.35.3", "", false}, // nethermind style - no v prefix - - // RC versions - {"v0.3.0-rc1", "", false}, - {"v0.3.0-rc.1", "", false}, - {"v0.3.0-rc-1", "", false}, - {"v0.3.0-rc.2", "", false}, - - // With tagPrefix - {"op-node/v1.16.2", "op-node", false}, - {"op-node/v1.16.3-rc1", "op-node", false}, - - // Non-standard but parseable - {"v1.101603.5", "", false}, // op-geth style - - // Invalid - {"not-a-version", "", true}, - {"", "", true}, - } - - for _, tt := range tests { - t.Run(tt.tag, func(t *testing.T) { - _, err := ParseVersion(tt.tag, tt.tagPrefix) - if (err != nil) != tt.wantErr { - t.Errorf("ParseVersion(%q, %q) error = %v, wantErr %v", tt.tag, tt.tagPrefix, err, tt.wantErr) - } - }) - } -} - -func TestValidateVersionUpgrade(t *testing.T) { - tests := []struct { - name string - currentTag string - newTag string - tagPrefix string - wantErr bool - }{ - // Valid upgrades - {"stable to rc", "v0.2.2", "v0.3.0-rc1", "", false}, - {"rc to rc", "v0.3.0-rc1", "v0.3.0-rc2", "", false}, - {"rc to stable", "v0.3.0-rc2", "v0.3.0", "", false}, - {"stable to stable", "v0.2.2", "v0.3.0", "", false}, - {"patch upgrade", "v0.2.2", "v0.2.3", "", false}, - {"minor upgrade", "v0.2.2", "v0.3.0", "", false}, - {"major upgrade", "v0.2.2", "v1.0.0", "", false}, - {"same version", "v0.2.2", "v0.2.2", "", false}, - - // With tagPrefix - {"prefix upgrade", "op-node/v1.16.2", "op-node/v1.16.3", "op-node", false}, - {"prefix rc upgrade", "op-node/v1.16.2", "op-node/v1.17.0-rc1", "op-node", false}, - - // No v prefix (nethermind style) - {"no v prefix upgrade", "1.35.3", "1.35.4", "", false}, - - // Invalid downgrades - {"downgrade major", "v0.3.0", "v0.2.2", "", true}, - {"downgrade minor", "v0.3.0", "v0.2.9", "", true}, - {"downgrade patch", "v0.3.1", "v0.3.0", "", true}, - {"stable to rc same version", "v0.3.0", "v0.3.0-rc2", "", true}, - {"stable to rc older version", "v0.3.0", "v0.2.0-rc1", "", true}, - - // Edge cases - {"empty current - valid new", "", "v0.3.0", "", false}, - {"empty current - invalid new", "", "not-a-version", "", true}, - {"unparseable current allows update", "not-semver", "v0.3.0", "", false}, - - // Unparseable current with unparseable new should fail - {"unparseable current - unparseable new", "rollup-boost/v0.7.11", "websocket-proxy/v0.0.2", "", true}, - {"unparseable current - valid new", "rollup-boost/v0.7.11", "v0.8.0", "", false}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := ValidateVersionUpgrade(tt.currentTag, tt.newTag, tt.tagPrefix) - if (err != nil) != tt.wantErr { - t.Errorf("ValidateVersionUpgrade(%q, %q, %q) error = %v, wantErr %v", - tt.currentTag, tt.newTag, tt.tagPrefix, err, tt.wantErr) - } - }) - } -} - -func TestCompareVersions(t *testing.T) { - tests := []struct { - name string - v1 string - v2 string - tagPrefix string - want int - }{ - {"v1 less than v2", "v0.2.2", "v0.3.0", "", -1}, - {"v1 greater than v2", "v0.3.0", "v0.2.2", "", 1}, - {"equal versions", "v0.3.0", "v0.3.0", "", 0}, - {"rc less than stable", "v0.3.0-rc1", "v0.3.0", "", -1}, - {"rc1 less than rc2", "v0.3.0-rc1", "v0.3.0-rc2", "", -1}, - {"stable greater than rc", "v0.3.0", "v0.3.0-rc2", "", 1}, - {"with prefix", "op-node/v1.16.2", "op-node/v1.16.3", "op-node", -1}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := CompareVersions(tt.v1, tt.v2, tt.tagPrefix) - if err != nil { - t.Errorf("CompareVersions(%q, %q, %q) unexpected error: %v", tt.v1, tt.v2, tt.tagPrefix, err) - return - } - if got != tt.want { - t.Errorf("CompareVersions(%q, %q, %q) = %d, want %d", tt.v1, tt.v2, tt.tagPrefix, got, tt.want) - } - }) - } -} - -func TestIsReleaseVersion(t *testing.T) { - tests := []struct { - tag string - tagPrefix string - want bool - }{ - // Stable releases - {"v1.0.0", "", true}, - {"v0.2.2", "", true}, - {"1.35.3", "", true}, // nethermind style - {"v1.101603.5", "", true}, // op-geth style - - // With prefix - {"op-node/v1.16.2", "op-node", true}, - - // Pre-release versions (should return false) - {"v1.0.0-rc1", "", false}, - {"v1.0.0-rc.1", "", false}, - {"v1.0.0-rc-1", "", false}, - {"v1.0.0-synctest.0", "", false}, - {"v1.0.0-alpha", "", false}, - {"v1.0.0-beta.1", "", false}, - {"op-node/v1.16.6-synctest.0", "op-node", false}, - {"op-node/v1.16.3-rc1", "op-node", false}, - - // Invalid versions (should return false) - {"not-a-version", "", false}, - {"", "", false}, - } - - for _, tt := range tests { - t.Run(tt.tag, func(t *testing.T) { - got := IsReleaseVersion(tt.tag, tt.tagPrefix) - if got != tt.want { - t.Errorf("IsReleaseVersion(%q, %q) = %v, want %v", tt.tag, tt.tagPrefix, got, tt.want) - } - }) - } -} - -func TestIsRCVersion(t *testing.T) { - tests := []struct { - tag string - tagPrefix string - want bool - }{ - // RC versions - {"v1.0.0-rc1", "", true}, - {"v1.0.0-rc.1", "", true}, - {"v1.0.0-rc-1", "", true}, - {"v1.0.0-RC1", "", true}, - {"v1.0.0-rc12", "", true}, - {"op-node/v1.16.3-rc1", "op-node", true}, - {"op-node/v1.16.3-rc.2", "op-node", true}, - - // Stable releases (not RC) - {"v1.0.0", "", false}, - {"v0.2.2", "", false}, - {"op-node/v1.16.2", "op-node", false}, - - // Other pre-release versions (not RC) - {"v1.0.0-synctest.0", "", false}, - {"op-node/v1.16.6-synctest.0", "op-node", false}, - {"v1.0.0-alpha", "", false}, - {"v1.0.0-beta.1", "", false}, - {"v1.0.0-alpha.rc1", "", false}, // rc is part of another prerelease - - // Invalid versions - {"not-a-version", "", false}, - {"", "", false}, - } - - for _, tt := range tests { - t.Run(tt.tag, func(t *testing.T) { - got := IsRCVersion(tt.tag, tt.tagPrefix) - if got != tt.want { - t.Errorf("IsRCVersion(%q, %q) = %v, want %v", tt.tag, tt.tagPrefix, got, tt.want) - } - }) - } -} - -func TestIsReleaseOrRCVersion(t *testing.T) { - tests := []struct { - tag string - tagPrefix string - want bool - }{ - // Stable releases - should pass - {"v1.0.0", "", true}, - {"v0.2.2", "", true}, - {"op-node/v1.16.2", "op-node", true}, - - // RC versions - should pass - {"v1.0.0-rc1", "", true}, - {"v1.0.0-rc.1", "", true}, - {"op-node/v1.16.3-rc1", "op-node", true}, - - // Other pre-release versions - should NOT pass - {"v1.0.0-synctest.0", "", false}, - {"op-node/v1.16.6-synctest.0", "op-node", false}, - {"v1.0.0-alpha", "", false}, - {"v1.0.0-beta.1", "", false}, - - // Invalid versions - {"not-a-version", "", false}, - } - - for _, tt := range tests { - t.Run(tt.tag, func(t *testing.T) { - got := IsReleaseOrRCVersion(tt.tag, tt.tagPrefix) - if got != tt.want { - t.Errorf("IsReleaseOrRCVersion(%q, %q) = %v, want %v", tt.tag, tt.tagPrefix, got, tt.want) - } - }) - } -} - -func TestRCVersionOrdering(t *testing.T) { - // Verify that RC versions are ordered correctly - versions := []string{ - "v0.2.2", - "v0.3.0-rc.1", - "v0.3.0-rc.2", - "v0.3.0", - "v0.3.1", - } - - for i := 0; i < len(versions)-1; i++ { - current := versions[i] - next := versions[i+1] - t.Run(current+" -> "+next, func(t *testing.T) { - err := ValidateVersionUpgrade(current, next, "") - if err != nil { - t.Errorf("Expected %s -> %s to be valid upgrade, got error: %v", current, next, err) - } - }) - } - - // Verify reverse order is invalid - for i := len(versions) - 1; i > 0; i-- { - current := versions[i] - previous := versions[i-1] - t.Run(current+" -> "+previous+" (downgrade)", func(t *testing.T) { - err := ValidateVersionUpgrade(current, previous, "") - if err == nil { - t.Errorf("Expected %s -> %s to be invalid downgrade", current, previous) - } - }) - } -} diff --git a/docker-compose.yml b/docker-compose.yml index 9eda33173..c88064344 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ services: execution: build: context: . - dockerfile: ${CLIENT:-reth}/Dockerfile + dockerfile: Dockerfile restart: unless-stopped ports: - "8545:8545" # RPC @@ -12,15 +12,13 @@ services: - "30303:30303/udp" # P2P UDP command: ["bash", "./execution-entrypoint"] volumes: - - ${HOST_DATA_DIR}:/data - environment: - - USE_BASE_CONSENSUS=${USE_BASE_CONSENSUS:-false} + - ${HOST_DATA_DIR:-./reth-data}:/data env_file: - ${NETWORK_ENV:-.env.mainnet} # Use .env.mainnet by default, override with .env.sepolia for testnet node: build: context: . - dockerfile: ${CLIENT:-reth}/Dockerfile + dockerfile: Dockerfile restart: unless-stopped depends_on: - execution @@ -31,7 +29,5 @@ services: - "7300:7300" # metrics - "6060:6060" # pprof command: ["bash", "./consensus-entrypoint"] - environment: - - USE_BASE_CONSENSUS=${USE_BASE_CONSENSUS:-false} env_file: - ${NETWORK_ENV:-.env.mainnet} # Use .env.mainnet by default, override with .env.sepolia for testnet diff --git a/reth/reth-entrypoint b/execution-entrypoint similarity index 100% rename from reth/reth-entrypoint rename to execution-entrypoint diff --git a/geth/Dockerfile b/geth/Dockerfile deleted file mode 100644 index c32881405..000000000 --- a/geth/Dockerfile +++ /dev/null @@ -1,44 +0,0 @@ -FROM golang:1.24 AS op - -RUN curl -sSfL 'https://just.systems/install.sh' | bash -s -- --to /usr/local/bin - -WORKDIR /app - -COPY versions.env /tmp/versions.env - -RUN . /tmp/versions.env && git clone $OP_NODE_REPO --branch $OP_NODE_TAG --single-branch . && \ - git switch -c branch-$OP_NODE_TAG && \ - bash -c '[ "$(git rev-parse HEAD)" = "$OP_NODE_COMMIT" ]' - -RUN . /tmp/versions.env && cd op-node && \ - make VERSION=$OP_NODE_TAG op-node - -FROM golang:1.24 AS geth - -WORKDIR /app - -COPY versions.env /tmp/versions.env - -RUN . /tmp/versions.env && git clone $OP_GETH_REPO --branch $OP_GETH_TAG --single-branch . && \ - git switch -c branch-$OP_GETH_TAG && \ - bash -c '[ "$(git rev-parse HEAD)" = "$OP_GETH_COMMIT" ]' - -RUN go run build/ci.go install -static ./cmd/geth - -FROM ubuntu:24.04 - -RUN apt-get update && \ - apt-get install -y jq curl supervisor && \ - rm -rf /var/lib/apt/lists -RUN mkdir -p /var/log/supervisor - -WORKDIR /app - -COPY --from=op /app/op-node/bin/op-node ./ -COPY --from=geth /app/build/bin/geth ./ -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf -COPY geth/geth-entrypoint ./execution-entrypoint -COPY op-node-entrypoint . -COPY consensus-entrypoint . - -CMD ["/usr/bin/supervisord"] diff --git a/geth/geth-entrypoint b/geth/geth-entrypoint deleted file mode 100755 index b598cb3f4..000000000 --- a/geth/geth-entrypoint +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash -set -eu - -VERBOSITY=${GETH_VERBOSITY:-3} -GETH_DATA_DIR=${GETH_DATA_DIR:-/data} -RPC_PORT="${RPC_PORT:-8545}" -WS_PORT="${WS_PORT:-8546}" -AUTHRPC_PORT="${AUTHRPC_PORT:-8551}" -METRICS_PORT="${METRICS_PORT:-6060}" -HOST_IP="" # put your external IP address here and open port 30303 to improve peer connectivity -P2P_PORT="${P2P_PORT:-30303}" -DISCOVERY_PORT="${DISCOVERY_PORT:-30303}" -ADDITIONAL_ARGS="" -OP_GETH_GCMODE="${OP_GETH_GCMODE:-full}" -OP_GETH_SYNCMODE="${OP_GETH_SYNCMODE:-full}" - -# Add cache optimizations with defaults -GETH_CACHE="${GETH_CACHE:-20480}" -GETH_CACHE_DATABASE="${GETH_CACHE_DATABASE:-20}" -GETH_CACHE_GC="${GETH_CACHE_GC:-12}" -GETH_CACHE_SNAPSHOT="${GETH_CACHE_SNAPSHOT:-24}" -GETH_CACHE_TRIE="${GETH_CACHE_TRIE:-44}" - -if [[ -z "$OP_NODE_NETWORK" ]]; then - echo "expected OP_NODE_NETWORK to be set" 1>&2 - exit 1 -fi - -mkdir -p $GETH_DATA_DIR - -echo "$BASE_NODE_L2_ENGINE_AUTH_RAW" > "$BASE_NODE_L2_ENGINE_AUTH" - -if [ "${OP_GETH_ETH_STATS+x}" = x ]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --ethstats=$OP_GETH_ETH_STATS" -fi - -if [ "${OP_GETH_ALLOW_UNPROTECTED_TXS+x}" = x ]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --rpc.allow-unprotected-txs=$OP_GETH_ALLOW_UNPROTECTED_TXS" -fi - -if [ "${OP_GETH_STATE_SCHEME+x}" = x ]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --state.scheme=$OP_GETH_STATE_SCHEME" -fi - -if [ "${OP_GETH_BOOTNODES+x}" = x ]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --bootnodes=$OP_GETH_BOOTNODES" -fi - -if [ "${HOST_IP:+x}" = x ]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --nat=extip:$HOST_IP" -fi - -exec ./geth \ - --datadir="$GETH_DATA_DIR" \ - --verbosity="$VERBOSITY" \ - --http \ - --http.corsdomain="*" \ - --http.vhosts="*" \ - --http.addr=0.0.0.0 \ - --http.port="$RPC_PORT" \ - --http.api=web3,debug,eth,net,engine \ - --authrpc.addr=0.0.0.0 \ - --authrpc.port="$AUTHRPC_PORT" \ - --authrpc.vhosts="*" \ - --authrpc.jwtsecret="$BASE_NODE_L2_ENGINE_AUTH" \ - --ws \ - --ws.addr=0.0.0.0 \ - --ws.port="$WS_PORT" \ - --ws.origins="*" \ - --ws.api=debug,eth,net,engine \ - --metrics \ - --metrics.addr=0.0.0.0 \ - --metrics.port="$METRICS_PORT" \ - --syncmode="$OP_GETH_SYNCMODE" \ - --gcmode="$OP_GETH_GCMODE" \ - --maxpeers=100 \ - --rollup.sequencerhttp="$OP_GETH_SEQUENCER_HTTP" \ - --rollup.halt=major \ - --op-network="$OP_NODE_NETWORK" \ - --discovery.port="$DISCOVERY_PORT" \ - --port="$P2P_PORT" \ - --rollup.disabletxpoolgossip=true \ - --cache="$GETH_CACHE" \ - --cache.database="$GETH_CACHE_DATABASE" \ - --cache.gc="$GETH_CACHE_GC" \ - --cache.snapshot="$GETH_CACHE_SNAPSHOT" \ - --cache.trie="$GETH_CACHE_TRIE" \ - $ADDITIONAL_ARGS # intentionally unquoted diff --git a/go.mod b/go.mod deleted file mode 100644 index aa11010d8..000000000 --- a/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module dependency_updater - -go 1.24.3 diff --git a/nethermind/Dockerfile b/nethermind/Dockerfile deleted file mode 100644 index 4c2df2a0e..000000000 --- a/nethermind/Dockerfile +++ /dev/null @@ -1,51 +0,0 @@ -FROM golang:1.24 AS op - -RUN curl -sSfL 'https://just.systems/install.sh' | bash -s -- --to /usr/local/bin - -WORKDIR /app - -COPY versions.env /tmp/versions.env - -RUN . /tmp/versions.env && git clone $OP_NODE_REPO --branch $OP_NODE_TAG --single-branch . && \ - git switch -c branch-$OP_NODE_TAG && \ - bash -c '[ "$(git rev-parse HEAD)" = "$OP_NODE_COMMIT" ]' - -RUN . /tmp/versions.env && cd op-node && \ - just VERSION=$OP_NODE_TAG op-node - -FROM mcr.microsoft.com/dotnet/sdk:10.0-noble AS build - -ARG BUILD_CONFIG=release -ARG TARGETARCH - -WORKDIR /app - -COPY versions.env /tmp/versions.env - -RUN . /tmp/versions.env && git clone $NETHERMIND_REPO --branch $NETHERMIND_TAG --single-branch . && \ - git switch -c $NETHERMIND_TAG && \ - bash -c '[ "$(git rev-parse HEAD)" = "$NETHERMIND_COMMIT" ]' - -RUN TARGETARCH=${TARGETARCH#linux/} && \ - arch=$([ "$TARGETARCH" = "amd64" ] && echo "x64" || echo "$TARGETARCH") && \ - echo "Using architecture: $arch" && \ - dotnet publish src/Nethermind/Nethermind.Runner -c $BUILD_CONFIG -a $arch -o /publish --sc false -p:NuGetAudit=false - -FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble - -RUN apt-get update && \ - apt-get install -y jq curl supervisor && \ - rm -rf /var/lib/apt/lists/* - -RUN mkdir -p /var/log/supervisor - -WORKDIR /app - -COPY --from=build /publish ./ -COPY --from=op /app/op-node/bin/op-node ./ -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf -COPY nethermind/nethermind-entrypoint ./execution-entrypoint -COPY op-node-entrypoint . -COPY consensus-entrypoint . - -CMD ["/usr/bin/supervisord"] diff --git a/nethermind/nethermind-entrypoint b/nethermind/nethermind-entrypoint deleted file mode 100755 index 66367b22c..000000000 --- a/nethermind/nethermind-entrypoint +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -set -eu - -# Default configurations -NETHERMIND_DATA_DIR=${NETHERMIND_DATA_DIR:-/data} -NETHERMIND_LOG_LEVEL=${NETHERMIND_LOG_LEVEL:-Info} - -RPC_PORT="${RPC_PORT:-8545}" -WS_PORT="${WS_PORT:-8546}" -AUTHRPC_PORT="${AUTHRPC_PORT:-8551}" -METRICS_PORT="${METRICS_PORT:-6060}" -DISCOVERY_PORT="${DISCOVERY_PORT:-30303}" -P2P_PORT="${P2P_PORT:-30303}" -ADDITIONAL_ARGS="" - -# Check if required variables are set -if [[ -z "$OP_NODE_NETWORK" ]]; then - echo "Expected OP_NODE_NETWORK to be set" 1>&2 - exit 1 -fi - -# Create necessary directories -mkdir -p "$NETHERMIND_DATA_DIR" - -# Write the JWT secret -if [[ -z "$BASE_NODE_L2_ENGINE_AUTH_RAW" ]]; then - echo "Expected BASE_NODE_L2_ENGINE_AUTH_RAW to be set" 1>&2 - exit 1 -fi -echo "$BASE_NODE_L2_ENGINE_AUTH_RAW" > "$BASE_NODE_L2_ENGINE_AUTH" - -# Additional arguments based on environment variables -if [[ -n "${OP_NETHERMIND_BOOTNODES:-}" ]]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --Network.Bootnodes=$OP_NETHERMIND_BOOTNODES" -fi - -if [[ -n "${OP_NETHERMIND_ETHSTATS_ENABLED:-}" ]]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --EthStats.Enabled=$OP_NETHERMIND_ETHSTATS_ENABLED" -fi - -if [[ -n "${OP_NETHERMIND_ETHSTATS_ENDPOINT:-}" ]]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS --EthStats.NodeName=${OP_NETHERMIND_ETHSTATS_NODE_NAME:-NethermindNode} --EthStats.Endpoint=$OP_NETHERMIND_ETHSTATS_ENDPOINT" -fi - -# Execute Nethermind -exec ./nethermind \ - --config="$OP_NODE_NETWORK" \ - --datadir="$NETHERMIND_DATA_DIR" \ - --Optimism.SequencerUrl=$OP_SEQUENCER_HTTP \ - --log="$NETHERMIND_LOG_LEVEL" \ - --JsonRpc.Enabled=true \ - --JsonRpc.Host=0.0.0.0 \ - --JsonRpc.WebSocketsPort="$WS_PORT" \ - --JsonRpc.Port="$RPC_PORT" \ - --JsonRpc.JwtSecretFile="$BASE_NODE_L2_ENGINE_AUTH" \ - --JsonRpc.EngineHost=0.0.0.0 \ - --JsonRpc.EnginePort="$AUTHRPC_PORT" \ - --HealthChecks.Enabled=true \ - --Metrics.Enabled=true \ - --Metrics.ExposePort="$METRICS_PORT" \ - --Network.P2PPort="$P2P_PORT" \ - --Network.DiscoveryPort="$DISCOVERY_PORT" \ - $ADDITIONAL_ARGS diff --git a/op-node-entrypoint b/op-node-entrypoint deleted file mode 100755 index 893015882..000000000 --- a/op-node-entrypoint +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash -set -eu - -get_public_ip() { - # Define a list of HTTP-based providers - local PROVIDERS=( - "http://ifconfig.me" - "http://api.ipify.org" - "http://ipecho.net/plain" - "http://v4.ident.me" - ) - # Iterate through the providers until an IP is found or the list is exhausted - for provider in "${PROVIDERS[@]}"; do - local IP - IP=$(curl -s --max-time 10 --connect-timeout 5 "$provider") - # Check if IP contains a valid format (simple regex for an IPv4 address) - if [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "$IP" - return 0 - fi - done - return 1 -} - -if [[ -z "$OP_NODE_NETWORK" && -z "$OP_NODE_ROLLUP_CONFIG" ]]; then - echo "expected OP_NODE_NETWORK to be set" 1>&2 - exit 1 -fi - -# wait until local execution client comes up (authed so will return 401 without token) -until [ "$(curl -s --max-time 10 --connect-timeout 5 -w '%{http_code}' -o /dev/null "${OP_NODE_L2_ENGINE_RPC/ws/http}")" -eq 401 ]; do - echo "waiting for execution client to be ready" - sleep 5 -done - -# public-facing P2P node, advertise public IP address -if PUBLIC_IP=$(get_public_ip); then - echo "fetched public IP is: $PUBLIC_IP" -else - echo "Could not retrieve public IP." - exit 8 -fi -export OP_NODE_P2P_ADVERTISE_IP=$PUBLIC_IP - - -echo "$BASE_NODE_L2_ENGINE_AUTH_RAW" > "$BASE_NODE_L2_ENGINE_AUTH" -export OP_NODE_L2_ENGINE_AUTH=$BASE_NODE_L2_ENGINE_AUTH - -exec ./op-node diff --git a/reth/README.md b/reth/README.md deleted file mode 100644 index 485a0458a..000000000 --- a/reth/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Running a Reth Node - -This is an implementation of the Reth node setup that supports Flashblocks mode based on configuration. - -## Setup - -- See hardware requirements mentioned in the master README -- For Flashblocks mode: Access to a Flashblocks websocket endpoint (for `RETH_FB_WEBSOCKET_URL`) - - We provide public websocket endpoints for mainnet and devnet, included in `.env.mainnet` and `.env.sepolia` - -## Node Type Selection - -The node determines its mode based on the presence of the `RETH_FB_WEBSOCKET_URL` environment variable: - -- **Vanilla Mode** (default): When no `RETH_FB_WEBSOCKET_URL` is provided. -- **Flashblocks Mode**: When `RETH_FB_WEBSOCKET_URL` is provided. - -## Running the Node - -The node follows the standard `docker compose` workflow in the master README. - -```bash -# To run Reth node with Flashblocks support, set RETH_FB_WEBSOCKET_URL in your .env file -CLIENT=reth docker compose up -``` - -## Testing Flashblocks RPC Methods - -When running in Flashblocks mode (with `RETH_FB_WEBSOCKET_URL` configured), you can query a pending block using the Flashblocks RPC: - -```bash -curl -X POST \ - --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["pending", false],"id":1}' \ - http://localhost:8545 -``` - -## Additional RPC Methods - -For a complete list of supported RPC methods, refer to: - -- [Standard Ethereum JSON-RPC](https://ethereum.org/en/developers/docs/apis/json-rpc/) -- [Flashblocks RPC Methods](https://docs.base.org/chain/flashblocks#rpc-api) (Flashblocks mode only) diff --git a/supervisord.conf b/supervisord.conf index aa634ed35..77d11a461 100644 --- a/supervisord.conf +++ b/supervisord.conf @@ -10,7 +10,7 @@ stdout_logfile_maxbytes=0 redirect_stderr=true stopwaitsecs=300 -[program:op-execution] +[program:execution] command=/app/execution-entrypoint stdout_logfile=/dev/fd/1 stdout_logfile_maxbytes=0 diff --git a/versions.env b/versions.env index 0a4b06314..34dc3158d 100644 --- a/versions.env +++ b/versions.env @@ -1,12 +1,3 @@ -export BASE_RETH_NODE_COMMIT=3049ce2e3a5132f2ef74b4ba14a1a952ea6abdfb +export BASE_RETH_NODE_COMMIT=00e656223f5d2af1b2100351462272b26499f12f export BASE_RETH_NODE_REPO=https://github.com/base/base.git -export BASE_RETH_NODE_TAG=v0.8.0 -export NETHERMIND_COMMIT=f5507dec1c9c7f5e31dadae445c08622be166054 -export NETHERMIND_REPO=https://github.com/NethermindEth/nethermind.git -export NETHERMIND_TAG=1.36.2 -export OP_GETH_COMMIT=d0734fd5f44234cde3b0a7c4beb1256fc6feedef -export OP_GETH_REPO=https://github.com/ethereum-optimism/op-geth.git -export OP_GETH_TAG=v1.101702.0 -export OP_NODE_COMMIT=cba7aba0c98aae22720b21c3a023990a486cb6e0 -export OP_NODE_REPO=https://github.com/ethereum-optimism/optimism.git -export OP_NODE_TAG=op-node/v1.16.11 +export BASE_RETH_NODE_TAG=v0.9.1 diff --git a/versions.json b/versions.json deleted file mode 100644 index 3ff19367a..000000000 --- a/versions.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "base_reth_node": { - "tag": "v0.8.0", - "commit": "3049ce2e3a5132f2ef74b4ba14a1a952ea6abdfb", - "owner": "base", - "repo": "base", - "tracking": "release" - }, - "nethermind": { - "tag": "1.36.2", - "commit": "f5507dec1c9c7f5e31dadae445c08622be166054", - "owner": "NethermindEth", - "repo": "nethermind", - "tracking": "release" - }, - "op_geth": { - "tag": "v1.101702.0", - "commit": "d0734fd5f44234cde3b0a7c4beb1256fc6feedef", - "owner": "ethereum-optimism", - "repo": "op-geth", - "tracking": "release" - }, - "op_node": { - "tag": "op-node/v1.16.11", - "commit": "cba7aba0c98aae22720b21c3a023990a486cb6e0", - "tagPrefix": "op-node", - "owner": "ethereum-optimism", - "repo": "optimism", - "tracking": "release" - } -}