Setup

For tests we set up 10 EC2 instances on a private network, we used genesis as bellow:

{
  "difficulty": "0x400",
  "extraData": "0x00",
  "gasLimit": "0x2fefd8",
  "nonce": "0x0000000000000042",
  "ommersHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  "timestamp": "0x00",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "alloc": {
    "d7a681378321f472adffb9fdded2712f677e0ba9": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}
  }
}

for mining we used ethminer from https://github.com/Genoil/cpp-ethereum.git from branch 108 which supports CPU mining

we were testing on ubuntu 16.04, to compile ethminer you need to instal some packages:

sudo apt-get -y install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install git cmake libcryptopp-dev libleveldb-dev libjsoncpp-dev libboost-all-dev libgmp-dev libreadline-dev libcurl4-gnutls-dev ocl-icd-libopencl1 opencl-headers mesa-common-dev libmicrohttpd-dev build-essential -y
sudo apt-get install libjsonrpccpp-dev -y

We started ethminer with ethminer -C -F 127.0.0.1:8546 and ours client with sbt -Dconfig.file=/home/ubuntu/node.conf run

Testing

Firstly we run nodes not connected to each other, this way nodes got their own versions of blockchain after chains were ~60 blocks long we connected them together and let them mine and resolve conflicting branches at the same time.

We let them run for 3 days and after checking did not notice any error in logs, nodes are roughly on the same block and they are mining without any issue.

We also checked that we produced blocks with correct ommer.

After that we connected geth classic node and it was able to join network and sync chain from genesis to current block (it was configured for same private network) and it continues ti accepting new blocks after sync was finished

Issue with geth

Also while testing we found out that if geth node is connected only to one node it will not sync if best blocks are too far away in terms of height

eth/fetcher/fetcher.go:631] Peer 010d7622a3242a48: discarded block #16598 [3861d9e4…], distance 3043

what fixed the issue was adding more connections, you can do this with geth console

admin.addPeer("node_address")

etc-client configuration

node.conf file should contains

etc-client {

  client-id = "etc-client"

  client-version = "etc-client/v0.1"

  datadir = "/home/ubuntu/chain_data"

  //File format of the keys (in plain text): publicKey ++ CR/LF ++ privateKey
  keys-file = ${etc-client.datadir}"nodeId.keys"

  keystore-dir = ${etc-client.datadir}"keystore"

  // time the system will wait to shutdown the ActorSystem.
  shutdown-timeout = "15.seconds"

  network {

    protocol-version = "1"

    server-address {
      interface = "public_ip"
      port = 9076
    }

    discovery {
      bootstrap-nodes = [
        //list of nodes in network
      ]

      bootstrap-nodes-scan-interval = 2 minutes
    }

    peer {
      connect-retry-delay = 20 seconds
      connect-max-retries = 30
      disconnect-poison-pill-timeout = 5 seconds
      wait-for-hello-timeout = 3 seconds
      wait-for-status-timeout = 30 seconds
      wait-for-chain-check-timeout = 15 seconds

      max-blocks-headers-per-message = 200
      max-blocks-bodies-per-message = 200
      max-receipts-per-message = 200
      max-mpt-components-per-message = 400

      max-peers = 200
      network-id = 1
    }

    rpc {
      enabled = true
      interface = "127.0.0.1"
      port = 8546
      apis = "eth,web3,net"
    }
  }

  mining {
    tx-pool-size = 1000
    ommers-pool-size = 30
    block-cashe-size = 30
    coinbase = "aa758c0b47afcafb9751a516e56a7c3332571933"
    pooling-services-timeout = 5.seconds
  }

  blockchain {
    frontier-block-number = "0"
    homestead-block-number = "1150000"
    eip150-block-number = "2500000"
    eip160-block-number = "3000000"
    difficulty-bomb-pause-block-number = "3000000"
    difficulty-bomb-continue-block-number = "5000000"

    // Doc: https://blog.ethereum.org/2016/07/20/hard-fork-completed/
    dao-fork-block-number = "1920000"
    dao-fork-block-total-difficulty = "39490964433395682584"
    dao-fork-block-hash = "94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f"

    chain-id = "3d"

    custom-genesis-file = "/home/ubuntu/custom-genesis.json"

    // YP eq 150
    block-reward = "5000000000000000000"
  }

  fast-sync {
    do-fast-sync = false
    peers-scan-interval = 3.seconds
    blacklist-duration = 30.seconds
    start-retry-interval = 5.seconds
    sync-retry-interval = 5.seconds
    peer-response-timeout = 10.seconds
    print-status-interval = 2.seconds
    persist-state-snapshot-interval = 1.minute

    max-concurrent-requests = 50
    block-headers-per-request = 2048
    block-bodies-per-request = 128
    receipts-per-request = 60
    nodes-per-request = 1000
    min-peers-to-choose-target-block = 2
    target-block-offset = 500

    check-for-new-block-interval = 1.seconds
    block-resolving-depth = 20
  }

  db {
    iodb {
      path = ${etc-client.datadir}"iodb/"
    }
    leveldb {
      path = ${etc-client.datadir}"leveldb/"
      create-if-missing = true
      paranoid-checks = true // raise an error as soon as it detects an internal corruption
      verify-checksums = true // force checksum verification of all data that is read from the file system on behalf of a particular read
      cache-size = 0
    }
  }

  filter {
    filter-timeout = 10.minutes
    filter-manager-query-timeout = 3.seconds
    pending-transactions-manager-query-timeout = 5.seconds
  }

}

akka {
  loggers = ["akka.event.slf4j.Slf4jLogger"]
  loglevel = "DEBUG"
  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
  logger-startup-timeout = 30s
}

geth classic configuration

chain.json

{
    "id": "custom",
    "name": "Morden Testnet",
    "genesis": {
        "nonce": "0x0000000000000042",
        "timestamp": "0x00",
        "parentHash": "",
        "extraData": "0x00",
        "gasLimit": "0x2fefd8",
        "difficulty": "0x0400",
        "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "coinbase": "0x0000000000000000000000000000000000000000",
        "alloc": {
            "d7a681378321f472adffb9fdded2712f677e0ba9": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}
        }
    },
    "chainConfig": {
        "forks": [
            {
                "name": "Homestead",
                "block": 494000,
                "requiredHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
                "features": [
                    {
                        "id": "difficulty",
                        "options": {
                            "type": "homestead"
                        }
                    },
                    {
                        "id": "gastable",
                        "options": {
                            "type": "homestead"
                        }
                    }
                ]
            },
            {
                "name": "GasReprice",
                "block": 1783000,
                "requiredHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
                "features": [
                    {
                        "id": "gastable",
                        "options": {
                            "type": "eip150"
                        }
                    }
                ]
            },
            {
                "name": "The DAO Hard Fork",
                "block": 1885000,
                "requiredHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
                "features": []
            },
            {
                "name": "Diehard",
                "block": 1915000,
                "requiredHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
                "features": [
                    {
                        "id": "eip155",
                        "options": {
                            "chainID": 62
                        }
                    },
                    {
                        "id": "gastable",
                        "options": {
                            "type": "eip160"
                        }
                    },
                    {
                        "id": "difficulty",
                        "options": {
                            "length": 2000000,
                            "type": "ecip1010"
                        }
                    }
                ]
            }
        ],
        "badHashes": [
        ]
    },
    "bootstrap": [
        //nodes to connect
    ]
}