diff --git a/.gitmodules b/.gitmodules index 216f76996..072bce75e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -200,3 +200,7 @@ [submodule "vendor/gnosis-chain-configs"] path = vendor/gnosis-chain-configs url = https://github.com/zah/gnosis-chain-configs.git +[submodule "vendor/capella-testnets"] + path = vendor/capella-testnets + url = https://github.com/ethpandaops/withdrawals-testnet.git + branch = master diff --git a/Makefile b/Makefile index b9493c2a8..180b5e86b 100644 --- a/Makefile +++ b/Makefile @@ -593,6 +593,14 @@ sepolia-dev-deposit: | sepolia-build deposit_contract clean-sepolia: $(call CLEAN_NETWORK,sepolia) +### Capella devnets + +capella-devnet-2: + tmuxinator start -p scripts/tmuxinator-el-cl-pair-in-devnet.yml network="vendor/capella-testnets/withdrawal-devnet-2/custom_config_data" + +clean-capella-devnet-2: + scripts/clean-devnet-dir.sh vendor/capella-testnets/withdrawal-devnet-2/custom_config_data + ### ### Gnosis chain binary ### diff --git a/beacon_chain/eth1/eth1_monitor.nim b/beacon_chain/eth1/eth1_monitor.nim index 318aa81a8..de3cf9870 100644 --- a/beacon_chain/eth1/eth1_monitor.nim +++ b/beacon_chain/eth1/eth1_monitor.nim @@ -1370,14 +1370,14 @@ proc findTerminalBlock(provider: Web3DataProviderRef, return value # Block A follows, B leads. - var - a = awaitWithRetries( - provider.web3.provider.eth_getBlockByNumber("latest", false)) - b = await next(a) + var a = awaitWithRetries( + provider.web3.provider.eth_getBlockByNumber("latest", false)) if a.number.uint64 == 0 and a.totalDifficulty >= ttd: return a + var b = await next(a) + while true: let one = a.totalDifficulty >= ttd let two = b.totalDifficulty >= ttd diff --git a/beacon_chain/networking/network_metadata.nim b/beacon_chain/networking/network_metadata.nim index e931172bb..31a335f09 100644 --- a/beacon_chain/networking/network_metadata.nim +++ b/beacon_chain/networking/network_metadata.nim @@ -156,8 +156,7 @@ proc loadEth2NetworkMetadata*(path: string, eth1Network = none(Eth1Network)): Et depositContractBlockHash = if depositContractBlockHashStr.len > 0: Eth2Digest.strictParse(depositContractBlockHashStr) - elif (not runtimeConfig.DEPOSIT_CONTRACT_ADDRESS.isDefaultValue) and - depositContractBlock != 0: + elif not runtimeConfig.DEPOSIT_CONTRACT_ADDRESS.isDefaultValue: raise newException(ValueError, "A network with deposit contract should specify the " & "deposit contract deployment block hash in a file " & diff --git a/scripts/bash_utils.sh b/scripts/bash_utils.sh new file mode 100644 index 000000000..045581e4f --- /dev/null +++ b/scripts/bash_utils.sh @@ -0,0 +1,17 @@ +if [ -z "${BASH_UTILS_SOURCED:-}" ]; then +BASH_UTILS_SOURCED=1 + +VERBOSE="0" + +log() { + if [[ "${VERBOSE}" -ge "1" ]]; then + echo "${@}" + fi +} + +run() { + echo Launching: $* + $* +} + +fi diff --git a/scripts/clean-devnet-dir.sh b/scripts/clean-devnet-dir.sh new file mode 100755 index 000000000..3dfbf9f8a --- /dev/null +++ b/scripts/clean-devnet-dir.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +if [ -z "$1" ]; then + echo "Usage: run-devnet-el-cl-pair.sh " + exit 1 +fi + +if [ ! -d "$1" ]; then + echo "Please supply a valid network metadata directory" + exit 1 +fi + +set -Eeu + +NETWORK=$(cd "$1"; pwd) + +cd $(dirname "$0") + +source ./repo_paths.sh +rm -rf "$(data_dir_for_network)" diff --git a/scripts/detect_platform.sh b/scripts/detect_platform.sh new file mode 100644 index 000000000..82bd975ba --- /dev/null +++ b/scripts/detect_platform.sh @@ -0,0 +1,15 @@ +if [ -z "${DETECT_PLATFORM_SOURCED:-}" ]; then +DETECT_PLATFORM_SOURCED=1 + +# OS detection +OS="linux" +if uname | grep -qi darwin; then + OS="macos" +elif uname | grep -qiE "mingw|msys"; then + OS="windows" +fi + +# Architecture detection +ARCH="$(uname -m)" + +fi diff --git a/scripts/geth_binaries.sh b/scripts/geth_binaries.sh new file mode 100644 index 000000000..d967672ae --- /dev/null +++ b/scripts/geth_binaries.sh @@ -0,0 +1,110 @@ +if [ -z "${GETH_BINARIES_SOURCED:-}" ]; then +GETH_BINARIES_SOURCED=1 + +SCRIPTS_DIR="$(dirname "${BASH_SOURCE[0]}")" +BUILD_DIR="$(cd "$SCRIPTS_DIR/../build"; pwd)" + +source "${SCRIPTS_DIR}/detect_platform.sh" +source "${SCRIPTS_DIR}/bash_utils.sh" + +: ${CURL_BINARY:="curl"} +: ${STABLE_GETH_BINARY:="${BUILD_DIR}/downloads/geth"} +: ${GETH_CAPELLA_BINARY:="${BUILD_DIR}/downloads/geth_capella"} +: ${GETH_EIP_4844_BINARY:="${BUILD_DIR}/downloads/geth_eip4844"} + +download_geth_stable() { + if [[ ! -e "${STABLE_GETH_BINARY}" ]]; then + GETH_VERSION="1.10.26-e5eb32ac" + GETH_URL="https://gethstore.blob.core.windows.net/builds/" + + case "${OS}-${ARCH}" in + linux-amd64|linux-x86_64) + GETH_TARBALL="geth-linux-amd64-${GETH_VERSION}.tar.gz" + ;; + linux-arm64|linux-aarch64) + GETH_TARBALL="geth-linux-arm64-${GETH_VERSION}.tar.gz" + ;; + macos-amd64|macos-x86_64) + GETH_TARBALL="geth-darwin-amd64-${GETH_VERSION}.tar.gz" + ;; + macos-arm64|macos-aarch64) + # There is no official binary for macOS/ARM at the moment + # The AMD64 binary should work under Rosetta + GETH_TARBALL="geth-darwin-amd64-${GETH_VERSION}.tar.gz" + ;; + windows-amd64|windows-x86_64) + GETH_TARBALL="geth-windows-amd64-${GETH_VERSION}.zip" + ;; + *) + echo "No Geth binaries available for platform: ${OS}-${ARCH}" + exit 1 + ;; + esac + + log "Downloading Geth binary" + + "$CURL_BINARY" -sSLO "$GETH_URL/$GETH_TARBALL" + local tmp_extract_dir + tmp_extract_dir=$(mktemp -d geth-stable-tarball-XXX) + CLEANUP_DIRS+=("$tmp_extract_dir") + tar -xzf "$GETH_TARBALL" -C "$tmp_extract_dir" --strip-components=1 + mkdir -p "$(dirname "$STABLE_GETH_BINARY")" + mv "$tmp_extract_dir/geth" "$STABLE_GETH_BINARY" + chmod +x "$STABLE_GETH_BINARY" + fi +} + +download_status_geth_binary() { + BINARY_NAME="$1" + BINARY_FS_PATH="$2" + + if [[ ! -e "${BINARY_FS_PATH}" ]]; then + case "${OS}-${ARCH}" in + linux-amd64|linux-x86_64) + GETH_PLATFORM=linux-amd64 + ;; + linux-arm64|linux-aarch64) + GETH_PLATFORM=linux-arm64 + ;; + macos-amd64|macos-x86_64) + GETH_PLATFORM=macos-amd64 + ;; + macos-arm64|macos-aarch64) + GETH_PLATFORM=macos-arm64 + ;; + windows-amd64|windows-x86_64) + GETH_PLATFORM=windows-amd64 + ;; + *) + echo "No Status Geth binaries available for platform: ${OS}-${ARCH}" + exit 1 + ;; + esac + + log "Downloading Status geth binary ($1)" + + GETH_TARBALL_NAME="geth-binaries-${GETH_PLATFORM}.tar.gz" + GETH_TARBALL_URL="https://github.com/status-im/nimbus-simulation-binaries/releases/download/latest/${GETH_TARBALL_NAME}" + GETH_BINARY_IN_TARBALL="geth/${BINARY_NAME}/geth" + + "$CURL_BINARY" -o "$GETH_TARBALL_NAME" -sSL "$GETH_TARBALL_URL" + local tmp_extract_dir + tmp_extract_dir=$(mktemp -d geth-status-tarball-XXX) + CLEANUP_DIRS+=("$tmp_extract_dir") + tar -xzf "$GETH_TARBALL_NAME" -C "$tmp_extract_dir" --strip-components 2 \ + "$GETH_BINARY_IN_TARBALL" + mkdir -p "$(dirname "$BINARY_FS_PATH")" + mv "$tmp_extract_dir/geth" "$BINARY_FS_PATH" + chmod +x "$BINARY_FS_PATH" + fi +} + +download_geth_capella() { + download_status_geth_binary withdrawals-timestamp "$GETH_CAPELLA_BINARY" +} + +download_geth_eip_4844() { + download_status_geth_binary eip-4844 "$GETH_EIP_4844_BINARY" +} + +fi diff --git a/scripts/launch_local_testnet.sh b/scripts/launch_local_testnet.sh index 37f33e850..e0e0e70d3 100755 --- a/scripts/launch_local_testnet.sh +++ b/scripts/launch_local_testnet.sh @@ -478,6 +478,7 @@ download_geth() { if [[ ! -e "build/${GETH_BINARY}" ]]; then log "Downloading Geth binary" + mkdir -p "build" pushd "build" >/dev/null "${CURL_BINARY}" -sSLO "${GETH_URL}/${GETH_TARBALL}" local tmp_extract_dir diff --git a/scripts/repo_paths.sh b/scripts/repo_paths.sh new file mode 100644 index 000000000..ccd817de7 --- /dev/null +++ b/scripts/repo_paths.sh @@ -0,0 +1,24 @@ +if [ -z "${REPO_PATHS_SOURCED:-}" ]; then +REPO_PATHS_SOURCED=1 + +SCRIPTS_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) +BUILD_DIR=$(cd "$SCRIPTS_DIR/../build" &> /dev/null && pwd) + +data_dir_for_network() { + NETWORK_ID=$(cat "$NETWORK/genesis.json" | jq '.config.chainId') + echo "$BUILD_DIR/data/$NETWORK_ID" +} + +create_data_dir_for_network() { + NETWORK_DIR=$(data_dir_for_network) + mkdir -p "$NETWORK_DIR" + echo "$NETWORK_DIR" +} + +create_jwt_token() { + if [ ! -f "$1" ]; then + openssl rand -hex 32 | tr -d "\n" > "$1" + fi +} + +fi diff --git a/scripts/run-catalyst.sh b/scripts/run-catalyst.sh deleted file mode 100755 index 0f1b76aab..000000000 --- a/scripts/run-catalyst.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -# set -Eeuo pipefail - -# https://notes.ethereum.org/rmVErCfCRPKGqGkUe89-Kg - -# Genesis block hash: 0xfoobar -# To start miner, run miner.start() -# To increase verbosity: debug.verbosity(4) - -GENESISJSON=$(mktemp) -GETHDATADIR=$(mktemp -d) - -echo \{\ - \"config\": \{\ - \"chainId\":1,\ - \"homesteadBlock\":0,\ - \"eip150Block\":0,\ - \"eip155Block\":0,\ - \"eip158Block\":0,\ - \"byzantiumBlock\":0,\ - \"constantinopleBlock\":0,\ - \"petersburgBlock\":0,\ - \"istanbulBlock\":0,\ - \"muirGlacierBlock\":0,\ - \"berlinBlock\":0,\ - \"londonBlock\":0,\ - \"clique\": \{\ - \"period\": 5,\ - \"epoch\": 30000\ - \},\ - \"terminalTotalDifficulty\":0\ - \},\ - \"nonce\":\"0x42\",\ - \"timestamp\":\"0x0\",\ - \"extraData\":\"0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\ - \"gasLimit\":\"0x1C9C380\",\ - \"difficulty\":\"0x400000000\",\ - \"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\ - \"coinbase\":\"0x0000000000000000000000000000000000000000\",\ - \"alloc\":\{\ - \"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\":\{\"balance\":\"0x6d6172697573766477000000\"\} \ - \},\ - \"number\":\"0x0\",\ - \"gasUsed\":\"0x0\",\ - \"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\ - \"baseFeePerGas\":\"0x7\"\ -\} > "${GENESISJSON}" - -# Initialize the genesis -~/go-ethereum/build/bin/geth --http --ws -http.api "engine" --datadir "${GETHDATADIR}" init "${GENESISJSON}" - -# Import the signing key (press enter twice for empty password) -~/go-ethereum/build/bin/geth --http --ws -http.api "engine" --datadir "${GETHDATADIR}" account import <(echo 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8) - -# Start the node (and press enter once to unlock the account) -~/go-ethereum/build/bin/geth --http --ws --http.api "eth,net,engine" -ws.api "eth,net,engine" --datadir "${GETHDATADIR}" --allow-insecure-unlock --unlock "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" --password "" --nodiscover console diff --git a/scripts/run-geth-el.sh b/scripts/run-geth-el.sh deleted file mode 100755 index dfaf1e83a..000000000 --- a/scripts/run-geth-el.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash -# Via Adrian Sutton - -if [ -z "$1" ]; then - echo "Usage: run-geth-el.sh " - exit 1 -fi - -set -Eeu - -NETWORK=$1 - -NETWORK_ID=$(cat "$NETWORK/genesis.json" | jq '.config.chainId') - -GETH=${HOME}/execution_clients/go-ethereum/build/bin/geth - -# https://github.com/eth2-clients/merge-testnets/tree/main/kintsugi -EXECUTION_BOOTNODES=$(awk '{print $1}' "$NETWORK/el_bootnode.txt" | paste -s -d, -) - -GETHDATADIR=$(mktemp -d) -GENESISJSON="${NETWORK}/genesis.json" - -echo "GETHDATADIR = ${GETHDATADIR}" - -# Initialize the genesis -$GETH --http --ws -http.api "engine" --datadir "${GETHDATADIR}" init "${GENESISJSON}" - -# Import the signing key (press enter twice for empty password) -$GETH --http --ws -http.api "engine" --datadir "${GETHDATADIR}" account import <(echo 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8) - -#--password "execution/geth/passfile.txt" -#--nodekey "execution/signer.key" - -$GETH \ - --http \ - --http.port 8550 \ - --http.api "engine,eth,net,admin,web3" \ - --http.corsdomain="*" \ - --http.vhosts="*" \ - --ws \ - --ws.port 8551 \ - --ws.api "engine,eth,net,admin,web3" \ - --allow-insecure-unlock \ - --datadir "${GETHDATADIR}" \ - --bootnodes "${EXECUTION_BOOTNODES}" \ - --port 30308 \ - --password "" \ - --syncmode full \ - --unlock "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" \ - --mine \ - --networkid $NETWORK_ID \ - console diff --git a/scripts/run-geth-in-devnet.sh b/scripts/run-geth-in-devnet.sh new file mode 100755 index 000000000..afbf5abe5 --- /dev/null +++ b/scripts/run-geth-in-devnet.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Via Adrian Sutton + +if [ -z "$1" ]; then + echo "Usage: run-geth-el.sh " + exit 1 +fi + +if [ ! -d "$1" ]; then + echo "Please supply a valid network metadata directory" + exit 1 +fi + +set -Eeu + +NETWORK=$(cd "$1"; pwd) + +cd $(dirname "$0") + +source geth_binaries.sh +source repo_paths.sh + +download_geth_capella + +: ${GETH_AUTH_RPC_PORT:=18550} +: ${GETH_WS_PORT:=18551} + +DATA_DIR="$(create_data_dir_for_network "$NETWORK")" + +JWT_TOKEN="$DATA_DIR/jwt-token" +create_jwt_token "$JWT_TOKEN" + +NETWORK_ID=$(cat "$NETWORK/genesis.json" | jq '.config.chainId') + +EXECUTION_BOOTNODES="" +if [[ -f "$NETWORK/el_bootnode.txt" ]]; then + EXECUTION_BOOTNODES+=$(awk '{print $1}' "$NETWORK/el_bootnode.txt" "$NETWORK/el_bootnode.txt" | paste -s -d, -) +fi + +if [[ -f "$NETWORK/el_bootnodes.txt" ]]; then + EXECUTION_BOOTNODES+=$(awk '{print $1}' "$NETWORK/el_bootnodes.txt" "$NETWORK/el_bootnode.txt" | paste -s -d, -) +fi + +GETH_DATA_DIR="$DATA_DIR/geth" +EXECUTION_GENESIS_JSON="${NETWORK}/genesis.json" + +set -x + +if [[ ! -d "$GETH_DATA_DIR/geth" ]]; then + # Initialize the genesis + $GETH_CAPELLA_BINARY --http --ws -http.api "engine" --datadir "${GETH_DATA_DIR}" init "${EXECUTION_GENESIS_JSON}" +fi + +$GETH_CAPELLA_BINARY \ + --authrpc.port ${GETH_AUTH_RPC_PORT} \ + --authrpc.jwtsecret "$JWT_TOKEN" \ + --allow-insecure-unlock \ + --datadir "${GETH_DATA_DIR}" \ + --bootnodes "${EXECUTION_BOOTNODES}" \ + --port 30308 \ + --password "" \ + --metrics \ + --syncmode=full \ + --networkid $NETWORK_ID diff --git a/scripts/run-nimbus-eth2-in-withdrawal-testnet.sh b/scripts/run-nimbus-in-devnet.sh similarity index 95% rename from scripts/run-nimbus-eth2-in-withdrawal-testnet.sh rename to scripts/run-nimbus-in-devnet.sh index 589ecea9e..6a86b061e 100755 --- a/scripts/run-nimbus-eth2-in-withdrawal-testnet.sh +++ b/scripts/run-nimbus-in-devnet.sh @@ -30,7 +30,7 @@ create_jwt_token "$JWT_TOKEN" --network="$NETWORK" \ --log-level=DEBUG \ --data-dir="$DATA_DIR/nimbus_bn" \ - --el=http://localhost:18550/ \ + --web3-url=http://localhost:18550/ \ --rest:on \ --rest-port=15052 \ --metrics=on \ diff --git a/scripts/start_geth_nodes.sh b/scripts/start_geth_nodes.sh index 67e4517b6..16fee8115 100755 --- a/scripts/start_geth_nodes.sh +++ b/scripts/start_geth_nodes.sh @@ -26,7 +26,7 @@ for GETH_NUM_NODE in $(seq 0 $(( GETH_NUM_NODES - 1 ))); do GETH_DATA_DIRS+=(${GETHDATADIR}) openssl rand -hex 32 | tr -d "\n" > "${GETHDATADIR}/jwtsecret" ${GETH_BINARY} --http --ws -http.api "engine" --datadir "${GETHDATADIR}" init "${GENESISJSON}" - ${GETH_BINARY} --http --ws --http.corsdomain '*' --http.api "eth,net,engine" -ws.api "eth,net,engine" --datadir "${GETHDATADIR}" ${DISCOVER} --port ${GETH_NET_PORT} --http.port ${GETH_HTTP_PORT} --ws.port ${GETH_WS_PORT} --authrpc.port ${GETH_AUTH_RPC_PORT} --authrpc.jwtsecret "${GETHDATADIR}/jwtsecret" &> "${DATA_DIR}/geth-log${GETH_NUM_NODE}.txt" & + ${GETH_BINARY} --syncmode full --http --ws --http.corsdomain '*' --http.api "eth,net,engine" -ws.api "eth,net,engine" --datadir "${GETHDATADIR}" ${DISCOVER} --port ${GETH_NET_PORT} --http.port ${GETH_HTTP_PORT} --ws.port ${GETH_WS_PORT} --authrpc.port ${GETH_AUTH_RPC_PORT} --authrpc.jwtsecret "${GETHDATADIR}/jwtsecret" &> "${DATA_DIR}/geth-log${GETH_NUM_NODE}.txt" & GETH_RETRY=0 while :; do if [[ -S "${GETHDATADIR}/geth.ipc" ]]; then diff --git a/scripts/tmuxinator-el-cl-pair-in-devnet.yml b/scripts/tmuxinator-el-cl-pair-in-devnet.yml new file mode 100644 index 000000000..a11a711fb --- /dev/null +++ b/scripts/tmuxinator-el-cl-pair-in-devnet.yml @@ -0,0 +1,11 @@ +name: devnet +root: . +windows: + - main: + layout: main-horizontal + # Synchronize all panes of this window, can be enabled before or after the pane commands run. + # 'before' represents legacy functionality and will be deprecated in a future release, in favour of 'after' + # synchronize: after + panes: + CL: ./scripts/run-<%= @settings["cl"] or "nimbus" %>-in-devnet.sh <%= @settings["network"] %> + EL: ./scripts/run-<%= @settings["el"] or "geth" %>-in-devnet.sh <%= @settings["network"] %> diff --git a/vendor/capella-testnets b/vendor/capella-testnets new file mode 160000 index 000000000..9deb7d566 --- /dev/null +++ b/vendor/capella-testnets @@ -0,0 +1 @@ +Subproject commit 9deb7d5663b389243dae6b2d0c902aa221e088f7