Ladislaus

Posted on Feb 01, 2023Read on Mirror.xyz

Testing Beacon Chain Withdrawals with Docker

This guide will provide you with a minimal instruction set if you intend to test:

  • Spinning up a zhejiang testnet node using Geth&Lighthouse with Docker(-Compose)

  • Exiting/withdrawing a validator on zhejiang testnet

  • Preparing withdrawal credential changes

Feel free to check out elementary guides on how to run testnet nodes with the help of Docker or Docker-Compose.

Also, if you’re generally keen on running a production (or testnet) Ethereum node with Docker, check out the awesome eth-docker.net project.


Why run on zhejiang?

  • Very fast node initialisation time (i.e. no extended sync periods + takes less than 2GBs of disk space)

  • Easy to obtain testnet ETH

  • It’s a short-lived, public testnet particularly designed for brief operation tests

  • Dry-run prior to more established testnets like Sepolia & Goerli which will follow in February/March ´23

Run a zhejiang testnet node

As an example client pair we’ll use Geth & Lighthouse on an Ubuntu instance & pre-installed docker-compose - feel free to adapt to different client pairs using this documentation.

1.

Navigate in a terminal/CLI to your user’s /home directory. Create a project directory with subfolders

$ mkdir -p zhejiang/{geth,lighthouse-bn,lighthouse-vc,JWT,validator_keys}; cd zhejiang

2.

Retrieve configuration files for the zhejiang genesis from a repository maintained by the Ethereum Foundation

$ git clone https://github.com/ethpandaops/withdrawals-testnet.git

3.

Generate a JasonWebToken (JWT) so that the execution and consensus client can communicate securely

$ openssl rand -hex 32 | tr -d "\n" > "$(pwd)/JWT/jwtsecret"

4.

Provide Geth with the testnet genesis configuration

$ docker run -it -v $(pwd)/geth:/root/.ethereum -v $(pwd)/withdrawals-testnet/zhejiang-testnet/custom_config_data/genesis.json:/genesis.json ethpandaops/geth:master --datadir /root/.ethereum init genesis.json

Depending on your Docker configuration every Docker command should be preceded by sudo

5.

Copy & paste the below attached Docker-Compose code in a newly created file to be named “docker-compose.yaml” located in the project directory /zhejiang 👇

version: "3.4"

services:
    consensus:
        image: sigp/lighthouse:capella
        container_name: beacon
        tty: true
        restart: on-failure
        volumes:
            - ./lighthouse-bn:/root/.lighthouse
            - ./JWT:/JWT
            - ./withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang
        ports:
            - 127.0.0.1:5052:5052 # consensus http
            - 9000:9000/tcp # consensus p2p, open to internet
            - 9000:9000/udp # consensus p2p, open to internet
        command: >
          lighthouse
          --testnet-dir zhejiang
          beacon_node
          --datadir /root/.lighthouse
          --eth1
          --http
          --http-allow-sync-stalled
          --http-address 0.0.0.0
          --enr-udp-port 9000
          --enr-tcp-port 9000
          --discovery-port 9000
          --validator-monitor-auto
          --execution-endpoints http://geth:8551
          --execution-jwt /JWT/jwtsecret
          --boot-nodes="enr:-Iq4QMCTfIMXnow27baRUb35Q8iiFHSIDBJh6hQM5Axohhf4b6Kr_cOCu0htQ5WvVqKvFgY28893DHAg8gnBAXsAVqmGAX53x8JggmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk,enr:-Ly4QOS00hvPDddEcCpwA1cMykWNdJUK50AjbRgbLZ9FLPyBa78i0NwsQZLSV67elpJU71L1Pt9yqVmE1C6XeSI-LV8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhEDhTgGJc2VjcDI1NmsxoQIgMUMFvJGlr8dI1TEQy-K78u2TJE2rWvah9nGqLQCEGohzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA,enr:-MK4QMlRAwM7E8YBo6fqP7M2IWrjFHP35uC4pWIttUioZWOiaTl5zgZF2OwSxswTQwpiVCnj4n56bhy4NJVHSe682VWGAYYDHkp4h2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhJK-7tSJc2VjcDI1NmsxoQLDq7LlsXIXAoJXPt7rqf6CES1Q40xPw2yW0RQ-Ly5S1YhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA,enr:-MS4QCgiQisRxtzXKlBqq_LN1CRUSGIpDKO4e2hLQsffp0BrC3A7-8F6kxHYtATnzcrsVOr8gnwmBnHYTFvE9UmT-0EHh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhKXoVKCJc2VjcDI1NmsxoQK6J-uvOXMf44iIlilx1uPWGRrrTntjLEFR2u-lHcHofIhzeW5jbmV0c4gAAAAAAAAAAIN0Y3CCIyiDdWRwgiMo,enr:-LK4QOQd-elgl_-dcSoUyHDbxBFNgQ687lzcKJiSBtpCyPQ0DinWSd2PKdJ4FHMkVLWD-oOquXPKSMtyoKpI0-Wo_38Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhES3DaqJc2VjcDI1NmsxoQNIf37JZx-Lc8pnfDwURcHUqLbIEZ1RoxjZuBRtEODseYN0Y3CCIyiDdWRwgiMo,enr:-KG4QLNORYXUK76RPDI4rIVAqX__zSkc5AqMcwAketVzN9YNE8FHSu1im3qJTIeuwqI5JN5SPVsiX7L9nWXgWLRUf6sDhGV0aDKQ7ijXswAAAHJGBQAAAAAAAIJpZIJ2NIJpcIShI5NiiXNlY3AyNTZrMaECpA_KefrVAueFWiLLDZKQPPVOxMuxGogPrI474FaS-x2DdGNwgiMog3VkcIIjKA"

    validator:
        image: sigp/lighthouse:capella
        container_name: vc
        tty: true
        restart: on-failure
        volumes:
            - ./lighthouse-vc:/root/.lighthouse
            - ./withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang
        depends_on:
            - consensus
        command: >
          lighthouse
          --testnet-dir zhejiang
          validator
          --beacon-nodes http://beacon:5052
          --suggested-fee-recipient 0x0000000000000000000000000000000000000000

    execution:
        image: ethpandaops/geth:master
        container_name: geth
        tty: true
        restart: on-failure
        volumes:
            - ./geth:/root/.ethereum
            - ./JWT:/JWT
        ports:
            - 127.0.0.1:8551:8551 # engine rpc
            - 30303:30303/tcp # execution p2p, open to internet
            - 30303:30303/udp # execution p2p, open to internet
            - 8545:8545
        command: >
          --datadir /root/.ethereum
          --http
          --http.addr 0.0.0.0
          --http.vhosts *
          --http.corsdomain *
          --http.api engine,eth,web3,net,debug
          --http.port 8545
          --authrpc.jwtsecret /JWT/jwtsecret
          --authrpc.addr 0.0.0.0
          --authrpc.port 8551
          --authrpc.vhosts *
          --networkid 1337803
          --syncmode full
          --bootnodes "enode://691c66d0ce351633b2ef8b4e4ef7db9966915ca0937415bd2b408df22923f274873b4d4438929e029a13a680140223dcf701cabe22df7d8870044321022dfefa@64.225.78.1:30303,enode://89347b9461727ee1849256d78e84d5c86cc3b4c6c5347650093982b726d71f3d08027e280b399b7b6604ceeda863283dcfe1a01e93728b4883114e9f8c7cc8ef@146.190.238.212:30303,enode://c2892072efe247f21ed7ebea6637ade38512a0ae7c5cffa1bf0786d5e3be1e7f40ff71252a21b36aa9de54e49edbcfc6962a98032adadfa29c8524262e484ad3@165.232.84.160:30303,enode://71e862580d3177a99e9837bd9e9c13c83bde63d3dba1d5cea18e89eb2a17786bbd47a8e7ae690e4d29763b55c205af13965efcaf6105d58e118a5a8ed2b0f6d0@68.183.13.170:30303,enode://2f6cf7f774e4507e7c1b70815f9c0ccd6515ee1170c991ce3137002c6ba9c671af38920f5b8ab8a215b62b3b50388030548f1d826cb6c2b30c0f59472804a045@161.35.147.98:30303"

6.

Start the Docker-Compose environment

$ docker-compose up

Eventually, stop the docker-compose environment: $ docker-compose stop

For stopping only the beacon or execution or validator client services use:

$ docker-compose stop execution/consensus/validator

Interlude: Becoming a validator (out of scope)

Steps 1-4 are well-documented elsewhere:

  1. Add network to your local metmask

  2. Receive 33 zETH from a faucet

  3. Generate validator keys (e.g. with Staking-CLI) using 0x00 credentials (for test purposes)

  4. Deposit via zhejiang launchpad

  5. Look out for your validator on a block explorer

  6. Move generated keys into project folder subdirectory /validator_keys

  7. Import validator key(s) to Lighthouse

    👉 based of the project directory /zhejiang prompt:

$ docker run -it -v $(pwd)/lighthouse-vc:/root/.lighthouse -v $(pwd)/validator_keys:/validator_keys -v  $(pwd)/withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang sigp/lighthouse:capella lighthouse --testnet-dir zhejiang account validator import --directory /validator_keys

Testing withdrawing / exiting a validator

Provide the consensus client with the necessary information in order to be released from consensus duties.

While your validator client is running in the background prompt:

$ docker-compose run --rm --no-deps -v $(pwd)/lighthouse-vc:/root/.lighthouse -v $(pwd)/withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang consensus lighthouse --testnet-dir zhejiang account validator exit --beacon-node http://beacon:5052  --keystore /root/.lighthouse/custom/validators/<0x_yourvalidatorkey>/voting-keystore.json

Edit the validator key directory and voting-keystore.json filename accordingly

Note for mainnet: node operators have to keep on running their node until the validator reaches its assigned exit epoch (s. block explorer) - if it is shutdown too early, the validator will incur penalties.


Addendum: Testing withdrawal credential change

…also known as “BLS to Execution” operation. This operation comprises of a message broadcast to the network which will lead to a change from the BLS withdrawal credentials (0x00) to a regular Ethereum address (0x01) of your choice.

Note: currently around ~60% or ~300,000 mainnet validators have BLS credentials and need to make a one-time change to a regular Ethereum address in order to fully or partially withdraw their stake or rewards.

Find out how to identify withdrawal credentials by entering a validator index on beaconcha.in:

staking with centralized custodians means: not your keys, not your crypto


If you want to test changing withdrawal credentials from 0x00 -> 0x01, check out these Docker instructions utilising a programm called ethdo by attestant.io.

The official Staking-Deposit-CLI by the EF will be updated and include similar functionality shortly.

👉 Broadcasting of your BLS-to-execution key change will NOT happen before the (Zhejiang) Shanghai/Capella fork scheduled for the 07th of February 3 p.m. UTC

https://twitter.com/TimBeiko/status/1621210105479061505?s=20

Up until then the generated message is just stored in a local pool. Once Shanghai/Capella is triggered, the BLS-to-execution messages will be automatically broadcasted/gossiped over the network to your peers.

As soon as a node holding your BLS-to-execution message proposes a block, the message will be executed.

Note for mainnet:

  • Be aware that changing withdrawal credentials involves providing withdrawal private keys. Thus,*never trust* instructions from a random stranger writing blogposts on mirror.xyz or elsewhere - instead: follow official announcements from client teams and developers

  • BLS-to-execution messages cannot be broadcasted until after the Shanghai/Capella hard fork

  • beaconcha.in have announced they will provide a web interface for dragging & dropping a signed credential-change.json file and submit it to the network


****

Please keep in mind this is a testnet guide that may contain mistakes and that takes shortcuts which come with trade-offs. It could quickly become outdated as it’s subject to ever evolving network and client changes.

****

featured image CC BY-NC 2.0 by Matthew Warner

********

This post was supported by a grant from a CLR funding round held by EthStaker, mainly matched by the EF.