Solving the problem with Ethereum cross-client private networks
Tags: ethereum, geth, parity, blockchain
Published: 2017-09-01 13:05:34

---
title: "Solving the problem with Ethereum cross-client private networks"
published: true
description: "I keep talking to people running into this problem again and again: A Geth node wont start talking to a custom Parity network and vice-versa. Here is why and what you can do about it."
cover_image: https://thepracticaldev.s3.amazonaws.com/i/cb2o8l5q3c2vu2suma2h.jpg
tags: ethereum, geth, parity, blockchain
---

This post was initially an answer on [Ethereum Stack Exchange][11], but it was worth more exposure as I keep talking to people running into this problem again and again. And, it's a very time-consuming issue to get a [Geth][12] node talking to a custom [Parity][13] network, and often also vice-versa. 

### Cross-client private networks: The problem

Geth is a client written _for_ [Ethereum][14]. It was one of the first official reference implementations and was never meant to run anything else but Ethereum. If you want to configure Geth for any other chain configuration, you would have to fork the source-code and create your own client implementation based on your desired rule-set. This happened for instance for Expanse ([Gexp][1]) and Ethereum Classic ([Getc][2]).

Parity, however, was created much later than Ethereum itself, by a team that was initially involved with the C++ Ethereum client ([Eth][3]). After they (Gavin Wood, et al.) founded Ethcore (now [Parity Technologies][15]), they created a client with a much broader vision; a client that is not supposed to only run Ethereum. 

Parity allows more abstraction in the core and therefore, all you need to start a new chain is a so called _Chain Specification_ file which describes the whole chain parameters, including consensus rules, validator engines, and so on. The most visible consequence is that Ethereum, Ethereum Classic, and Expanse (just to pick up the examples form above) do not need to maintain their own copy of the Parity source-code in order to support their project and their consensus rules. Parity just works out of the box with the `--chain` parameters `foundation`, `classic`, or `expanse`.

In addition, the `--chain` parameter allows configuring an [entirely custom chain][4] with pluggable consenus, custom transitions, and the validator engine you prefer.

In contrast, Geth only allows to specify a _custom Genesis_ which is only one piece of the puzzle for a complete chain specification. And therefore you will have trouble to connect a Geth node to a custom network of Parity nodes. However, you basically have two options to run a custom cross-client network with both Geth and Parity nodes, explained below.

### Best-practice: "Geth First"

Now, since you have less chain configuration options in Geth than in Parity, I'll call the most obvious idea "Geth First". You chose a network ID and create a [custom Genesis][5], and initialize your new network with:

    geth init geth-genesis.json

You can fire up a miner thread and a couple more Geth nodes at this point to verify the network is doing exactly what you need. 

Now, you can start integrating Parity nodes. There is a tiny rust tool [keorn/parity-spec][6] that converts your custom Geth genesis file into a full Parity chain specification file.

    cargo run -- geth-genesis.json

You can pass the output `parity-spec.json` directly to your Parity node with the `--chain` parameter. 

    parity --chain parity-spec.json

For discovery, you can use [Geth's `admin.addPeer()` commands][7] or [Parity's `--reserved-peers` functionality][8].

However, both Geth and Parity are actively developed code-bases and the converter tool is prone to bugs and often users report generated chain-specification files are still leading to consensus issues. If this happens to you frequently, check out the other option below.

### Best-practice: "Ropsten Revived - Revived"

The probably most stable and most obvious option to run a private network compatible with Geth, Parity, and all the other clients out there, is something I would call "Ropsten Revived - Revived".

Just take a known, working network that is supported by all clients, like the [Ropsten public testnet][9], and slightly modify it. To ease this process, I created presets for both the Geth Genesis and the Parity Chain Specification at [5chdn/crossclient-chainsepc][10]. It contains a `geth.json` and a `parity.json` mimicking a Ropsten revival with different network ID 1337 (`0x539`).

    # Geth

    geth init --datadir ~/.ethereum/crossclient geth.json
    geth --datadir ~/.ethereum/crossclient --networkid 1337 --port 31333 --rpcport 8538

    # Parity

    parity --chain parity.json --port 31337 --jsonrpc-port 8539

The downside of this is probably the unsatisfied desire to add more complex modifications to your custom private development network. However, the predefined genesis and chain-spec offer a good starting point to get you bootstrapped with whatever network you have in mind.


  [1]: https://github.com/expanse-org/go-expanse
  [2]: https://github.com/ethereumproject/go-ethereum
  [3]: https://github.com/ethereum/cpp-ethereum
  [4]: https://github.com/paritytech/parity/wiki/Chain-specification
  [5]: https://github.com/ethereum/go-ethereum/wiki/Private-network#creating-the-genesis-block
  [6]: https://github.com/keorn/parity-spec
  [7]: https://github.com/ethereum/go-ethereum/wiki/Connecting-to-the-network#static-nodes
  [8]: https://ethereum.stackexchange.com/q/12928
  [9]: https://github.com/ethereum/ropsten/blob/master/revival.md
  [10]: https://github.com/5chdn/crossclient-chainspec
  [11]: https://ethereum.stackexchange.com/a/25640
  [12]: https://github.com/ethereum/go-ethereum/wiki/geth
  [13]: https://github.com/paritytech/parity/wiki
  [14]: https://ethereum.org/
  [15]: https://parity.io/