DEV Community

Cover image for How to merge an Ethereum network right from the genesis block
Afri
Afri

Posted on

How to merge an Ethereum network right from the genesis block

The merge is arguably the most significant milestone of the Ethereum research and development roadmap. By attaching a proof-of-stake consensus beacon chain to an already established proof-of-work execution chain, it is possible to swap out the consensus engine on a hot network. However, this is a very tedious task. Wouldn't it be nice to be able to launch an Ethereum network right from the proof-of-stake stage? Here's how!

The following sections outline how to configure an execution-layer client and a consensus-layer client so that they have everything in place to execute the entire merge already in the genesis block. Here, we'll use Geth and Lodestar.

Execution-Layer Configuration

Creating a new genesis for Geth is as simple as running geth dumpgenesis and subsequently modifying fields as needed for the testnet, i.e., for a new devnet or local testnet, we'll run:

geth --sepolia dumpgenesis
Enter fullscreen mode Exit fullscreen mode

This uses the latest Sepolia testnet genesis.

Now, we have to adjust the genesis configuration:

  1. Set a new chainID for replay protection.
  2. Set all protocol upgrades to block 0, including mergeForkBlock and mergeNetsplitBlock.
  3. Set merge total terminal difficulty (TTD) to 0 and the TTD-passed flag to true (terminalTotalDifficulty, terminalTotalDifficultyPassed).

    "config":{
      "chainId":39677693,
      "homesteadBlock":0, 
      "eip150Block":0,
      "eip155Block":0,
      "eip158Block":0,
      "byzantiumBlock":0,
      "constantinopleBlock":0,
      "petersburgBlock":0,
      "istanbulBlock":0,
      "muirGlacierBlock":0,
      "berlinBlock":0,
      "londonBlock":0,
      "mergeForkBlock":0,
      "mergeNetsplitBlock":0,
      "terminalTotalDifficulty":0,
      "terminalTotalDifficultyPassed":true
    },
    
  4. Remove the ethash parameters altogether. We don't need any additional pre-merge consensus engine.

  5. Remove the existing alloc and create a custom allocation per our needs.

  6. Adjust the genesis parameters as desired, mainly timestamp, extraData, and nonce, to ensure they do not match an existing genesis. Note that all fields need to be hexadecimal for the Geth genesis file.

      "nonce":"0x44144",
      "timestamp":"0x63A1E047",
      "extraData":"0x887b30d1e617484474521f31a37376760299fa7f15eb4214fce4157744b896c2",
      "gasLimit":"0x1c9c380",
      "difficulty":"0x20000",
      "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
      "coinbase":"0x0000000000000000000000000000000000000000",
      "number":"0x0",
      "gasUsed":"0x0",
      "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
    

That's it. Now all that is left is the deposit contract. Since we merge from genesis, this has to be part of the genesis state.

For that, we have to take the vanilla deposit contract from the consensus specs: deposit_contract.sol, get the Solidity compiler version 0.6.11, compile the binary of the runtime part and create an empty deposit tree.

Fortunately, the contract's runtime code and initial state remain always the same (see protolambda's notes), so we can copy and paste this into our genesis file.

  "alloc":{
    "0x0420420420420420420420420420420420420420":{
      "balance":"0x0",
      "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033",
      "storage": {
        "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b",
        "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71",
        "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c",
        "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c",
        "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30",
        "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1",
        "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c",
        "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193",
        "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1",
        "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b",
        "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220",
        "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f",
        "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e",
        "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784",
        "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb",
        "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb",
        "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab",
        "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4",
        "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f",
        "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa",
        "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c",
        "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167",
        "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7",
        "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0",
        "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544",
        "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765",
        "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4",
        "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1",
        "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636",
        "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c",
        "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7"
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

So, we add the binary and storage tuples to the allocation of the genesis file.

Once set, we initialize as many execution clients as desired, using geth init. Let's start with two:

geth init \
  --datadir "./data/execution/0" \
  ./execution/genesis.json

geth init \
  --datadir "./data/execution/1" \
  ./execution/genesis.json
Enter fullscreen mode Exit fullscreen mode

Lastly, we get the genesis hash to be used as a reference for the consensus client setup later. For that, we run an execution node and get the genesis from it, e.g., attach to it and query eth.getBlockByNumber(0).

geth \
  --networkid 39677693 \
  --datadir "./data/execution/0" \
  console
Enter fullscreen mode Exit fullscreen mode

Note down the genesis hash for the consensus-layer configuration later and also get the node's enode address to connect other execution-layer clients. Let's connect another one right away.

geth \
  --networkid 39677693 \
  --datadir "./data/execution/1" \
  --authrpc.port 8651 \
  --port 31303 \
  --bootnodes "enode://39dc4161c55076d1245c7c8383996606e1d1d4a9006e58454bd8e2c139970269fa682560bfed2087bf1d1f5d5fc0d40f143b46398a8eaee343b43136f373f091@127.0.0.1:30303"
Enter fullscreen mode Exit fullscreen mode

Persist the bootnodes in a text file for later use, e.g., bootnodes.txt.

That's our execution-layer configuration. It currently runs two nodes locally that do nothing except wait for a consensus client to provide blocks.

Consensus-Layer Configuration

To create a new consensus-layer configuration, get the latest mainnet.yaml config from the consensus specs.

  1. Come up with a unique CONFIG_NAME, i.e., the name of our testnet, here: mergednet.
  2. Set the TTD to 0 and the terminal hash to the genesis hash we previously extracted from the execution-layer client.
  3. Set the minimum genesis time to the genesis time of the execution layer or any desired time greater than that. Also, create a sensible genesis delay, e.g., two hours. We don't want to wait seven days!
  4. Set the fork versions to something custom to not conflict with mainnet, e.g., 0x00677693 for genesis, 0x01677693 for Altair, etc. Also, consider setting all upgrades to activate on genesis epoch 0.
  5. Set the deposit chain and network ID to the previously created execution-layer network and match the deposit contract address to the one in the genesis, here: 39677693, 0x0420420420420420420420420420420420420420.

In addition to the config.yaml for the consensus layer, we also create auxiliary files for the deposit contract:

  1. deploy_block.txt containing the block number 0
  2. deposit_contract_block.txt containing the execution genesis hash
  3. deposit_contract.txt containing the deposit-contract address from the genesis allocation, here: 0x0420420420420420420420420420420420420420

Lastly, before generating the genesis, we need to create validators that kick off the chain right from the start.

  1. We'll generate BIP-39 mnemonics for everyone who is going to run genesis validators and store them in a mnemonics.yaml file. Take a look at protolambda's notes for mnemonic-yaml formatting: protolambda/eth2-testnet-genesis#mnemonics.
  2. Update the MIN_GENESIS_ACTIVE_VALIDATOR_COUNT to something sensible; we don't need 16k validators for our network yet. If you plan to run eight validators, set it to 8.
  3. Lastly, use the eth2 testnet genesis tool to generate the genesis.ssz state for a merge configuration:
eth2-testnet-genesis merge \
  --config "./consensus/config.yaml" \
  --eth1-config "./execution/genesis.json" \
  --mnemonics "./consensus/mnemonic.yaml" \
  --state-output "./consensus/genesis.ssz" \
  --tranches-dir "./consensus/tranches"
Enter fullscreen mode Exit fullscreen mode

The genesis state will contain the initial genesis validators, and there is no need to conduct actual deposits. To add more validators later, use the deposit contract at any time.

That's all for the configuration. We can run beacon nodes now and allow them to network and discover peers before genesis. Note that the network needs at least two peered beacon nodes; otherwise, the nodes will act as if they are offline and refuse to author blocks!

lodestar beacon \
  --suggestedFeeRecipient "0xCaA29806044A08E533963b2e573C1230A2cd9a2d" \
  --execution.urls "http://127.0.0.1:8551" \
  --jwt-secret "./data/execution/0/geth/jwtsecret" \
  --dataDir "./data/consensus/0" \
  --paramsFile "./consensus/config.yaml" \
  --genesisStateFile "./consensus/genesis.ssz" \
  --enr.ip 127.0.0.1
Enter fullscreen mode Exit fullscreen mode

Note we are setting the ENR IP to whatever we need (here: localhost) so that we can use the ENR as the initial bootnode record. Get it from the identity endpoint:

curl http://localhost:9596/eth/v1/node/identity
Enter fullscreen mode Exit fullscreen mode

All ENRs can be persisted in a file such as bootnodes.txt that we can pass to the beacon-chain clients later to bootstrap the networking.

lodestar beacon \
  --suggestedFeeRecipient "0xCaA29806044A08E533963b2e573C1230A2cd9a2d" \
  --execution.urls "http://127.0.0.1:8651" \
  --jwt-secret "./data/execution/1/geth/jwtsecret" \
  --dataDir "./data/consensus/1" \
  --paramsFile "./consensus/config.yaml" \
  --genesisStateFile "./consensus/genesis.ssz" \
  --enr.ip 127.0.0.1 \
  --rest.port 9696 \
  --port 9100 \
  --network.connectToDiscv5Bootnodes true \
  --bootnodes "enr:-Ku4QFqWLadqfhKv7669IBdUwAilxPt9khrHqXVTqZjYdYtyNGTs4qeZslPf5Jx61QrKnMZ6-AcSgvu4zEcmSnnUrIIFh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDYGrlYAmd2k___________gmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQIK5OOTyDgyoNl6TIqkWyap7VTqnIzlq40kE4N-250mV4N0Y3CCIyg"
Enter fullscreen mode Exit fullscreen mode

We do this for as many beacon nodes as we want. Note that we need to enable discv5 bootnodes for our local network; otherwise, our clients will not peer.

That's it for our consensus-layer configuration. We have two Geth execution nodes running with two Lodestar beacon nodes connected with each other. Now, we have to launch the network.

Launch the Network

We have both execution-layer and consensus-layer clients running already. We can easily make sure they are running correctly by reading the logs. If they fail to authenticate or connect, there will be errors.

However, to kick off the network, we must ensure the validators are loaded and connected before genesis. If we fail to generate a chain within the first 32 slots, the clients will remain forever in a syncing state, potentially preventing long-range attacks. Therefore, if your beacon node is already past the 32nd slot, bump the genesis delay and redo the consensus-layer configuration.

We can use the deposit CLI to generate validator keypairs. Run ./deposit existing-mnemonic and follow the instructions.

This generates deposit data and the actual keypairs. The deposit data can be discarded as we don't need to conduct any deposits. The keys can be imported to our validator client. Make sure also to provide a password.

lodestar validator \
  --dataDir "./data/consensus/0" \
  --suggestedFeeRecipient "0xCaA29806044A08E533963b2e573C1230A2cd9a2d" \
  --graffiti "YOLO MERGEDNET GETH LODESTAR" \
  --paramsFile "./consensus/config.yaml" \
  --importKeystores "./consensus/validator_keys" \
  --importKeystoresPassword "./consensus/validator_keys/password.txt"
Enter fullscreen mode Exit fullscreen mode

Once the keys and passwords are imported, the validator client will wait to take on its duties. Once the minimum genesis time and genesis delay is passed, it will propose blocks and attestations.

Terminal Screenshot showing Geth execution blocks matching the Lodestar consensus payload

That's it. That's our new Ethereum network, merged right from genesis.

Additional Resources

Credit goes to Gajinder, Parithosh, and Protolamda for the valuable pointers, tools, and documentation. Thank you so much for your contributions!

Now that you scrolled to the end of this article, I will reward you with the entire configuration used in this tutorial: github.com/q9f/mergednet - I pedantically created one commit for each step.

Thanks for reading!

Top comments (12)

Collapse
 
johnrisk profile image
John Risk • Edited

Thanks @q9 for this elaborate article with the github commits. It would help us a lot.
It was very easy to follow up and understand things along the way.

I got an error in the beacon and the validator when it publishes its first block at slot 0:
Error on submitPoolSyncCommitteeSignatures [0] slot=1, validatorIndex=0 PublishError.InsufficientPeers
but it looks like a normal error in lodestar that is waiting for a fix and not affecting the process.

I had another issue where the nodes stopped syncing after reproducing a couple of blocks, and it was fixed by your suggestion to put --syncmode full

Collapse
 
nietpham profile image
Niet

I got the same issue. How can I fix this?

Collapse
 
seanconneryadigium profile image
Sean Connery

Hi Afri,

First of all, thanks for this awesome tutorial and repository. It helped me understand a lot of things about the merge configurations.

I was trying to follow along with the article and I'm stuck at the point where the network won't kick off - I'm using Geth/Prysm (running two geth nodes connected to two beacon nodes, with the 8 validators connected to the first beacon node)

I'm using pretty much the same execution/beacon configurations in the article.
The only change I made was the GENESIS_DELAY: 3600

Here's a screenshot of the beacon logs:
ibb.co/DCrQTNX

All the commands, and configs that I'm using are in this repo:
github.com/oone-world/merge-from-g...

Could you please help me with this?

Collapse
 
seanconneryadigium profile image
Sean Connery

Turns out the issue was that the timestamp (in genesis.json) + GENESIS_DELAY (in config.yaml) is in the past!

This just torpedoes the whole thing!

Collapse
 
mxmar profile image
Matt • Edited

For the timestamp in genesis.json have you used MIN_GENESIS_TIME or sum of MIN_GENESIS_TIME+GENESIS_DELAY?

Thread Thread
 
q9 profile image
Afri

The timestamp in genesis.json is not important, you could also set it to January 1st, 1970. Important is MIN_GENESIS_TIME and GENESIS_DELAY.

Collapse
 
avenbreaks profile image
Cici Sabrina

how to setup genesis delay and timestap in your genesis? im trying to change genesis delay 3200 and timestap the day now but its not synced.

Collapse
 
avenbreaks profile image
Cici Sabrina

eth. getBlockByNumber(0)

i took from the hash: "0x56c9b4417bafc42766888bae53959de8f0e5ac898eec6b30880c340f45d6ede9", and put this hash in deposit_contract_block.txt

then I tried to execute everything and run as you provide but I get a notification like this:
Node is syncing - Service Unavailable: Node is syncing - waiting for peers - Failed to obtain attester duty.

in the beacon node they get peer :
info: Searching peers - peers: 1 - slot: 3264964 (skipped 3264964) - head: 0 0 0x9e15…5549 - execution: valid(0x56c9…ede9) - finalized: 0x0000…0000:0

in geth I get something like this:
Beacon client online, but never received consensus updates. Please ensure your beacon client is operational to follow the chain!

Collapse
 
q9 profile image
Afri

slot: 3264964 (skipped 3264964) indicates that something is wrong with your genesis timestamp. it should be less than 32 ideally.

Collapse
 
avenbreaks profile image
Cici Sabrina

sorry, sir, what do you mean, can I just change my timestamp to number 32?

Thread Thread
 
nflaig profile image
Nico Flaig

Genesis time should not be more than 32 slots behind current time. For example if your SECONDS_PER_SLOT value is 12, then genesis time must not be more than 384 seconds in the past when starting the network.

There is a known issue (github.com/ChainSafe/lodestar/issu...) were Lodestar won't be able to sync due to a genesis time to far in the past and no peers to range sync historical data from.

Collapse
 
aakash4dev profile image
Aakash Singh Rajput

sir, can you also tell how to make rollups for blockchains ?