Add a stack to run an Ethereum node #1
@ -0,0 +1,5 @@
|
|||||||
|
# eth-stack
|
||||||
|
|
||||||
|
Stack to run a Ethereum node (geth + lighthouse beacon node)
|
||||||
|
|
||||||
|
* [Stack documentation](./stack-orchestrator/stacks/eth/README.md)
|
59
stack-orchestrator/compose/docker-compose-eth.yml
Normal file
59
stack-orchestrator/compose/docker-compose-eth.yml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
services:
|
||||||
|
eth-geth:
|
||||||
|
restart: on-failure
|
||||||
|
hostname: eth-geth
|
||||||
|
image: ethereum/client-go:alltools-v1.14.8
|
||||||
|
environment:
|
||||||
|
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
|
||||||
|
ETH_DATADIR: "/root/.ethereum"
|
||||||
|
CERC_NETWORK: ${CERC_NETWORK:-sepolia}
|
||||||
|
CERC_ALLOW_UNPROTECTED_TXS: ${CERC_ALLOW_UNPROTECTED_TXS:-false}
|
||||||
|
CERC_SYNCMODE: ${CERC_SYNCMODE:-full}
|
||||||
|
CERC_GCMODE: ${CERC_GCMODE:-archive}
|
||||||
|
CERC_GETH_VERBOSITY: ${CERC_GETH_VERBOSITY:-3}
|
||||||
|
entrypoint: ["sh", "-c"]
|
||||||
|
command: |
|
||||||
|
"/root/scripts/run-el.sh"
|
||||||
|
volumes:
|
||||||
|
- eth_geth_data:/root/.ethereum
|
||||||
|
- eth_secrets:/root/secrets
|
||||||
|
- ../config/eth/run-el.sh:/root/scripts/run-el.sh
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "nc", "-v", "localhost", "8545"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
|
start_period: 3s
|
||||||
|
ports:
|
||||||
|
- "8545"
|
||||||
|
- "8546"
|
||||||
|
- "6060"
|
||||||
|
- "30303/tcp"
|
||||||
|
- "30303/udp"
|
||||||
|
|
||||||
|
eth-lighthouse:
|
||||||
|
restart: on-failure
|
||||||
|
hostname: eth-lighthouse
|
||||||
|
image: sigp/lighthouse:v5.3.0
|
||||||
|
environment:
|
||||||
|
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
|
||||||
|
ETH_ENDPOINT: "http://eth-geth:8545"
|
||||||
|
EXECUTION_ENDPOINT: "http://eth-geth:8551"
|
||||||
|
LIGHTHOUSE_DATADIR: "/root/.lighthouse"
|
||||||
|
CERC_NETWORK: ${CERC_NETWORK:-sepolia}
|
||||||
|
CERC_CHECKPOINT_SYNC_URL: ${CERC_CHECKPOINT_SYNC_URL}
|
||||||
|
CERC_DEBUG_LEVEL: ${CERC_DEBUG_LEVEL:-info}
|
||||||
|
command: bash /root/scripts/run-cl.sh
|
||||||
|
volumes:
|
||||||
|
- eth_lighthouse_data:/root/.lighthouse
|
||||||
|
- eth_secrets:/root/secrets
|
||||||
|
- ../config/eth/run-cl.sh:/root/scripts/run-cl.sh
|
||||||
|
ports:
|
||||||
|
- "8001"
|
||||||
|
- "9000/tcp"
|
||||||
|
- "9000/udp"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
eth_geth_data:
|
||||||
|
eth_lighthouse_data:
|
||||||
|
eth_secrets:
|
49
stack-orchestrator/config/eth/run-cl.sh
Normal file
49
stack-orchestrator/config/eth/run-cl.sh
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -o pipefail
|
||||||
|
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using the following env:"
|
||||||
|
echo "CERC_NETWORK: ${CERC_NETWORK}"
|
||||||
|
echo "CERC_CHECKPOINT_SYNC_URL: ${CERC_CHECKPOINT_SYNC_URL}"
|
||||||
|
echo "CERC_DEBUG_LEVEL: ${CERC_DEBUG_LEVEL}"
|
||||||
|
echo "LIGHTHOUSE_DATADIR: ${LIGHTHOUSE_DATADIR}"
|
||||||
|
echo "ETH_ENDPOINT: ${ETH_ENDPOINT}"
|
||||||
|
echo "EXECUTION_ENDPOINT: ${EXECUTION_ENDPOINT}"
|
||||||
|
|
||||||
|
# See https://linuxconfig.org/how-to-propagate-a-signal-to-child-processes-from-a-bash-script
|
||||||
|
cleanup() {
|
||||||
|
echo "Signal received, cleaning up..."
|
||||||
|
kill $(jobs -p)
|
||||||
|
|
||||||
|
wait
|
||||||
|
echo "Done"
|
||||||
|
}
|
||||||
|
trap 'cleanup' SIGINT SIGTERM
|
||||||
|
|
||||||
|
# Create a JWT secret at shared path if not found
|
||||||
|
jwtsecret_file_path=/root/secrets/jwtsecret
|
||||||
|
if [ ! -f "$jwtsecret_file_path" ]; then
|
||||||
|
openssl rand -hex 32 | tr -d "\n" > $jwtsecret_file_path
|
||||||
|
echo "Generated JWT secret at $jwtsecret_file_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
http_port=8001
|
||||||
|
lighthouse bn \
|
||||||
|
--network $CERC_NETWORK \
|
||||||
|
--datadir $LIGHTHOUSE_DATADIR/$CERC_NETWORK \
|
||||||
|
--execution-endpoint $EXECUTION_ENDPOINT \
|
||||||
|
--execution-jwt $jwtsecret_file_path \
|
||||||
|
--checkpoint-sync-url $CERC_CHECKPOINT_SYNC_URL \
|
||||||
|
--disable-deposit-contract-sync \
|
||||||
|
--debug-level $CERC_DEBUG_LEVEL \
|
||||||
|
--http \
|
||||||
|
--http-address 0.0.0.0 \
|
||||||
|
--http-port $http_port \
|
||||||
|
2>&1 | tee /var/log/lighthouse_bn.log &
|
||||||
|
|
||||||
|
beacon_pid=$!
|
||||||
|
wait $beacon_pid
|
78
stack-orchestrator/config/eth/run-el.sh
Executable file
78
stack-orchestrator/config/eth/run-el.sh
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using the following env:"
|
||||||
|
echo "CERC_NETWORK: ${CERC_NETWORK}"
|
||||||
|
echo "CERC_ALLOW_UNPROTECTED_TXS: ${CERC_ALLOW_UNPROTECTED_TXS}"
|
||||||
|
echo "CERC_SYNCMODE: ${CERC_SYNCMODE}"
|
||||||
|
echo "CERC_GCMODE: ${CERC_GCMODE}"
|
||||||
|
echo "CERC_GETH_VERBOSITY: ${CERC_GETH_VERBOSITY}"
|
||||||
|
echo "ETH_DATADIR: ${ETH_DATADIR}"
|
||||||
|
|
||||||
|
# See https://linuxconfig.org/how-to-propagate-a-signal-to-child-processes-from-a-bash-script
|
||||||
|
cleanup() {
|
||||||
|
echo "Signal received, cleaning up..."
|
||||||
|
|
||||||
|
# Kill the child process first (CERC_REMOTE_DEBUG=true uses dlv which starts geth as a child process)
|
||||||
|
pkill -P ${geth_pid}
|
||||||
|
sleep 2
|
||||||
|
kill $(jobs -p)
|
||||||
|
|
||||||
|
wait
|
||||||
|
echo "Done"
|
||||||
|
}
|
||||||
|
trap 'cleanup' SIGINT SIGTERM
|
||||||
|
|
||||||
|
# Wait for the JWT secret to be generated
|
||||||
|
jwtsecret_file_path=/root/secrets/jwtsecret
|
||||||
|
retry_interval=3
|
||||||
|
while [ ! -f "$jwtsecret_file_path" ]; do
|
||||||
|
echo "JWT secret not found, retrying after ${retry_interval}s..."
|
||||||
|
sleep $retry_interval
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "JWT secret found at $jwtsecret_file_path"
|
||||||
|
|
||||||
|
NETWORK_OPT=""
|
||||||
|
if [ "$CERC_NETWORK" = "sepolia" ] || [ "$CERC_NETWORK" = "holesky" ] || [ "$CERC_NETWORK" = "mainnet" ]; then
|
||||||
|
NETWORK_OPT="--${CERC_NETWORK}"
|
||||||
|
else
|
||||||
|
NETWORK_OPT="--networkid ${CERC_NETWORK}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
OTHER_OPTS=""
|
||||||
|
if [ "$CERC_ALLOW_UNPROTECTED_TXS" == "true" ]; then
|
||||||
|
# Allow for unprotected (non EIP155) txs to be submitted via RPC
|
||||||
|
OTHER_OPTS="--rpc.allow-unprotected-txs"
|
||||||
|
fi
|
||||||
|
|
||||||
|
geth \
|
||||||
|
${NETWORK_OPT} \
|
||||||
|
--datadir="${ETH_DATADIR}" \
|
||||||
|
--authrpc.addr="0.0.0.0" \
|
||||||
|
--authrpc.vhosts="*" \
|
||||||
|
--authrpc.jwtsecret="$jwtsecret_file_path" \
|
||||||
|
--http \
|
||||||
|
--http.addr="0.0.0.0" \
|
||||||
|
--http.vhosts="*" \
|
||||||
|
--http.api="eth,web3,net,admin,personal,debug" \
|
||||||
|
--http.corsdomain="*" \
|
||||||
|
--ws \
|
||||||
|
--ws.addr="0.0.0.0" \
|
||||||
|
--ws.origins="*" \
|
||||||
|
--ws.api="eth,web3,net,admin,personal,debug" \
|
||||||
|
--state.scheme hash \
|
||||||
|
--gcmode $CERC_GCMODE \
|
||||||
|
--syncmode=$CERC_SYNCMODE \
|
||||||
|
--metrics \
|
||||||
|
--metrics.addr="0.0.0.0" \
|
||||||
|
--verbosity=${CERC_GETH_VERBOSITY} \
|
||||||
|
${OTHER_OPTS} \
|
||||||
|
&
|
||||||
|
|
||||||
|
geth_pid=$!
|
||||||
|
wait $geth_pid
|
124
stack-orchestrator/stacks/eth/README.md
Normal file
124
stack-orchestrator/stacks/eth/README.md
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# eth
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
* Clone the stack repo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
laconic-so fetch-stack git.vdb.to/cerc-io/eth-stack
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create a deployment
|
||||||
|
|
||||||
|
* Create a spec file for the deployment, which will map the stack's ports and volumes to the host:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
laconic-so --stack ~/cerc/eth-stack/stack-orchestrator/stacks/eth deploy init --output eth-spec.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
* Edit `network` in the spec file to map container ports to host ports as required:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
...
|
||||||
|
network:
|
||||||
|
ports:
|
||||||
|
eth-geth:
|
||||||
|
- '8545:8545'
|
||||||
|
- '8546:8546'
|
||||||
|
- '6060:6060'
|
||||||
|
- '30303:30303/tcp'
|
||||||
|
- '30303:30303/udp'
|
||||||
|
eth-lighthouse:
|
||||||
|
- '8001:8001'
|
||||||
|
- '9000:9000/tcp'
|
||||||
|
- '9000:9000/udp'
|
||||||
|
```
|
||||||
|
|
||||||
|
* Create a deployment from the spec file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
laconic-so --stack ~/cerc/eth-stack/stack-orchestrator/stacks/eth deploy create --spec-file eth-spec.yml --deployment-dir eth-deployment
|
||||||
|
```
|
||||||
|
|
||||||
|
* Inside the `eth-deployment` deployment directory, open `config.env` file and set following env variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Optional
|
||||||
|
|
||||||
|
# Network to run the ETH node for (default: sepolia)
|
||||||
|
# (one of mainnet, sepolia, holesky)
|
||||||
|
CERC_NETWORK=
|
||||||
|
|
||||||
|
# Geth options (https://geth.ethereum.org/docs/fundamentals/command-line-options)
|
||||||
|
|
||||||
|
# Allow unprotected txs (default: false)
|
||||||
|
CERC_ALLOW_UNPROTECTED_TXS=
|
||||||
|
|
||||||
|
# Blockchain sync mode (default: full)
|
||||||
|
CERC_SYNCMODE=
|
||||||
|
|
||||||
|
# Garbage collection mode (default: archive)
|
||||||
|
CERC_GCMODE=
|
||||||
|
|
||||||
|
# Verbosity level (default: info)
|
||||||
|
CERC_GETH_VERBOSITY=
|
||||||
|
|
||||||
|
# Lighthouse BN options (https://lighthouse-book.sigmaprime.io/help_bn.html)
|
||||||
|
|
||||||
|
# Verbosity level (default: info)
|
||||||
|
CERC_DEBUG_LEVEL=
|
||||||
|
|
||||||
|
# Required
|
||||||
|
|
||||||
|
# Beacon node endpoint to use for checkpoint sync
|
||||||
|
# (https://eth-clients.github.io/checkpoint-sync-endpoints/)
|
||||||
|
CERC_CHECKPOINT_SYNC_URL=
|
||||||
|
```
|
||||||
|
|
||||||
|
## Start
|
||||||
|
|
||||||
|
* Start the deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
laconic-so deployment --dir eth-deployment start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Check status
|
||||||
|
|
||||||
|
* To list down and monitor the running containers:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# With status
|
||||||
|
docker ps -a
|
||||||
|
|
||||||
|
# Follow logs for eth-geth container
|
||||||
|
laconic-so deployment --dir eth-deployment logs eth-geth -f
|
||||||
|
|
||||||
|
# Follow logs for eth-lighthouse container
|
||||||
|
laconic-so deployment --dir eth-deployment logs eth-lighthouse -f
|
||||||
|
```
|
||||||
|
|
||||||
|
* Once the node has caught up to head, make a request to get the latest block number:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -H "Content-Type: application/json" \
|
||||||
|
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
|
||||||
|
http://localhost:8545
|
||||||
|
```
|
||||||
|
|
||||||
|
## Clean up
|
||||||
|
|
||||||
|
* To stop all services running in the background, while preserving chain data:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
laconic-so deployment --dir eth-deployment stop
|
||||||
|
```
|
||||||
|
|
||||||
|
* To stop all services and also delete chain data:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
laconic-so deployment --dir eth-deployment stop --delete-volumes
|
||||||
|
|
||||||
|
# Remove the deployment dir
|
||||||
|
sudo rm -rf eth-deployment
|
||||||
|
```
|
7
stack-orchestrator/stacks/eth/stack.yml
Normal file
7
stack-orchestrator/stacks/eth/stack.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
version: "1.0"
|
||||||
|
name: eth
|
||||||
|
description: "ETH stack"
|
||||||
|
repos:
|
||||||
|
containers:
|
||||||
|
pods:
|
||||||
|
- eth
|
Loading…
Reference in New Issue
Block a user