Skip to content

Setting up a private network

zilm13 edited this page Dec 2, 2016 · 17 revisions

If you consider setting up Ethereum private network with Harmony as nodes, this part of documentation will guide you through it. We'll overview 2 configurations: simple one, with only one support node, call it "Minimal configuration", and "Recommended configuration" with 2 seed nodes, 2 miners and any number of regular nodes. Most steps are common for any setup but there are few differences if you want to run network for simple experiments with small resources or require better stability and scalability. Just follow instructions step-by-step:

  1. Installation
  2. Genesis for private network
  3. Common node configuration
  4. Network-specific configuration
  1. Running your network
  2. Integration with Geth
  3. Securing your network

Installation

Install Ethereum Harmony on all nodes.

Ethereum Harmony uses EterheumJ library and requires Java 8. To get latest version of the tool, git clone it

 git clone [email protected]:ether-camp/ethereum-harmony.git
 cd ethereum-harmony

For more information about Harmony installation check README.

We'll start configuration from genesis. Genesis is the first block in your future network and it should be the same on all nodes.

Genesis for private network

Typical genesis file looks like this

{
  "nonce": "0x00006d6f7264656e",
  "difficulty": "0x000002",
  "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x",
  "gasLimit": "0x2FEFD8",
  "alloc": {
    "cd2a3d9f938e13cd947ec05abc7fe734df8dd826": { "balance": "10000000000000000" }
  }
}

You could find it in distribution: frontier-private.json
Most values are in hexadecimal format, except balance. Balance values are in WEI, smallest Ethereum coin, stored in decimal units. What you should notice or change in genesis:

  • difficulty - keep this number low enough, so you'll not spend a lot of machine power on new blocks. Default value is good for it.
  • alloc - it's a part of genesis block, where you could predefine addresses with some ether balance just from the beginning of network run. Note, that you need private key or seed phrase to execute transactions from addresses you add there.

Example allocates some funds to address with private key "cow". You could add it later on any node with "Import Address" dialog in "Wallet" section of Harmony and transfer money from it using this key. If you want to restrict access to ether, you could use "New mnemonic address" feature while running Harmony on any network, add one address, copy it to alloc section and use such genesis in your future private network.

Once your nodes get first block after genesis, you will not be able to change it without removing DB on these nodes and removing old blockchain. And all your nodes should use the same genesis. So make sure you have the same file on all nodes.

Common node configuration

Node configuration depends on node role in network but most parts are common for all roles in one private network.
You could find private network example configuration in repository: private.conf. When Harmony starts, configuration file is merged with EterheumJ configuration, so if you want to know all configuration options and their default values, take a look at ethereumj.conf

You should have following options in your config:

# Network id
peer.networkId = 365

Network Id. Use any number greater than 2, same for all nodes. 1 and 2 are already used in Live and Morden networks.

peer.discovery.enabled = true

Enable peer discovery for p2p exchange between all your nodes

peer.listen.port = 30303

Incoming connections listening port. You could later override it from command line.

database.reset = false

If you want to keep your blockchain after peer restart, turn database reset off.

# Key value data source values: [leveldb/redis/mapdb]
keyvalue.datasource=leveldb

LevelDB is generally more stable than MapDB. Use Redis for high-load applications.

blockchain.config.name = null
blockchain.config.class = "org.ethereum.config.blockchain.FrontierConfig"

Use either "org.ethereum.config.blockchain.FrontierConfig" or "org.ethereum.config.blockchain.HomesteadConfig". For private network you could use either, but it should be the same on all nodes.
All improvements in Homestead are described in official Ethereum documentation. These changes are made for public network and affects mostly gas spendings and fixes potential vulnerabilities. So if you don't care about gas expense and your network is private, you will not see much difference.

Other options you may need to change depends on your network structure and node roles.

Network-specific configuration

Choose either minimal or recommended configuration. Minimal requires one base network node but Recommended is close by configuration and stability to real networks.

Minimal configuration

Minimal configuration

Pros: 1 base node and any number of regular nodes
Cons: If base node is down, private network is down too

Seed / Miner node configuration

sync.enabled = false
mine.start = true
cache.flush.blocks = 1

You have 1 mine node in network, so nobody could create blocks in network excluding this node. To keep its DB up-to-date, flush it on every block. But if you later add another mining node in network, keeping the same configuration, your mining nodes could start to produce wrong blocks. So it's safer to turn sync on

sync.enabled = true

This change in configuration requires manual start of mining from Harmony Terminal after start and each restart using miner_start command:

node> miner_start 
true

Please note: with default settings on first run miner builds Mining DataSet which may take up to 10 minutes, so don't expect new blocks immediately after mining start.

Regular node configuration

sync.enabled = true

You need to enable sync on your regular node, so its DB will be up-to-date.

Then you need to get Seed/Miner node info and fill it in active peer section of all regular nodes like this:

peer.active = [
    {
          ip = 207.12.89.101
          port = 30303
          nodeId = e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c
          nodeName = "my poc-9-peer-1"
    },
]

To get nodeId of your seed node, start it, open Harmony Terminal and type admin_nodeInfo command:

node> admin_nodeInfo 
{
  "enode": "enode://70c0c9a5c4d6ae4c7a6e4b8d2acd07f747827e7ea55ac47a7b4b7de561d3bdcae00596dabc0defd842d27b
[email protected]:10101",
  "listenAddr": "192.168.1.40:10101",
  "ip": "192.168.1.40",
  "name": "EthereumJ/v1.3.6/Mac OS X/Java1.7/RELEASE-0e76829",
  "id": "70c0c9a5c4d6ae4c7a6e4b8d2acd07f747827e7ea55ac47a7b4b7de561d3bdcae00596dabc0defd842d27b48097214b64
1db3e0f55ffa3f46b2e7ae265a6931b",
  "ports": {
    "discovery": 10101,
    "listener": 10101
  },
  "protocols": {
    "eth": {
      "network": 365,
      "difficulty": "0xa7310ae",
      "genesis": "0x27862782907a78d975cc5f139d888c746b01acc2270c8be149a7154e55ea9f65",
      "head": "0x6c9ea6dd7a3f9f789f049392948eef479991c934b36e1cdf69d1086576f07c4b"
    }
  }
}

id parameter is what you need. If you delete DB on seed node, it will be generated again. If you restart node it will not be changed assuming DB reset option is off in configuration. Also you could hardcode private key in seed config, so even after DB removing node will have same nodeId:

# Private key of the peer
# The key is generated by default on the first run and stored in the database folder
# If you have your own peer ID, specify its private key here
peer.privateKey = f67c4032a7ff79bbfa7a780331b235c4eb681d51a0704cb1562064fb6c4bced4

Where privateKey is 64 characters hex.

Recommended configuration

Recommended configuration

Pros: Stable and scalable, when one seed or one miner is down, private network keeps running
Cons: Requires more resources than Minimal Configuration

Seed configuration

sync.enabled = true

All you need is just make sure you have sync enabled.

Miner configuration

sync.enabled = true
mine.start = true

You have several miners now and you are required to keep synchronization between them. You should start mining process by running command miner_start in Harmony Terminal. Other miners will automatically break in. If you restart any miner, but not the all miners simultaneously, you are not required to manually start mining process.

Please note: with default settings on first run miner builds Mining DataSet which may take up to 10 minutes, so don't expect new blocks immediately after mining start.

Regular nodes configuration

Enable sync in config:

sync.enabled = true

And add seed nodes as active peers in config, the same way you do with Minimal Configuration, but for 2 seed nodes. Please refer to Regular node configuration in Minimal Configuration part.

With Recommended Configuration you can restart or swap any node without downtime for whole network. You can add new seed nodes and new miners. This configuration is very similar to the real network, just a bit smaller.

Running your network

Now you have several nodes, same genesis file for all of them, their role-specific configuration, so you could start all nodes.

Launch Harmony with following command:

./gradlew bootRun -Dethereumj.conf.file=ABS_PATH_TO/private-configuration.conf -DgenesisFile=ABS_PATH_TO/private-genesis.json

Start with seed and miner nodes and after that you could add regular nodes to your network. When mining starts (takes up to 10 minutes on first run, much faster after miner restart), you could create contracts, invoke them and send funds like in real network.

By default, Harmony will keep database at user home location at ~/ethereumj/database. To change that location you need to run with:

-Ddatabase.dir="~/ethereumj/PATH_TO_DATABASE"

Default ports are:

  • 30303 for peer. Use -Dpeer.listen.port=33333 to change it
  • 8080 for web interface and JSON RPC. Use -Dserver.port=8888 to change it

Integration with Geth

You could use Geth or other Ethereum clients for seed or miner nodes, moreover some of your seed nodes could be Harmony, others - Geth.

  1. Initialize Geth DB with your genesis, same genesis, you use for Harmony:
$ geth --datadir /ABS_PATH_TO/DB_FOLDER --networkid 365 --nodiscover --verbosity 6 --port 30309 init /ABS_PATH_TO/YOUR_PRIVATE_NET_GENESIS.json
  1. Run Geth seed node:
$ geth --datadir /ABS_PATH_TO/DB_FOLDER --networkid 365 --nodiscover --verbosity 6 --port 30309 console
  1. Check your Geth seed enode to add it to your Harmony active peers:
> admin.nodeInfo
{
  enode: "enode://24990ae825aae59af337c98cac0f5948d9de7da70c0a0c99b4a50dd1b7d797eb5fa681f3727f8306351c175363c3a346941d5342fba1f844e7ec18cb1c347e84@[::]:30309?discport=0",
  id: "24990ae825aae59af337c98cac0f5948d9de7da70c0a0c99b4a50dd1b7d797eb5fa681f3727f8306351c175363c3a346941d5342fba1f844e7ec18cb1c347e84",
  ip: "::",
  listenAddr: "[::]:30309",
  name: "Geth/v1.5.1-stable/darwin/go1.7.1",
  ports: {
    discovery: 0,
    listener: 30309
  },
  protocols: {
    eth: {
      difficulty: 2,
      genesis: "0x05b2dc41ade973d26db921052bcdaf54e2e01b308c9e90723b514823a0923592",
      head: "0x05b2dc41ade973d26db921052bcdaf54e2e01b308c9e90723b514823a0923592",
      network: 365
    }
  }
}

Securing your network

If all nodes of your private network runs inside intranet and their incoming connection ports are not forwarded to whole Internet, you should not have any issues with security. But if you want your network to be accessed from Internet but restricted to certain persons, you need to take some security measures.

In case you need to be partially accessed from Internet, make special "gateway" node for it.
Configure it like usual seed node with some changes in config:

peer.trusted = [ { ip = "*"} ]
peer.discovery.enabled = false
peer.active = [
# your seed nodes here
]

This way only node that knows your gateway nodeId will be able to connect to your network. All other nodes even if they know host and port will be rejected. Also you may need to protect your Harmony web part and JSON RPC with HTTP Auth or Firewall.

Another, more protected way is to manually add all nodes, connection from which is allowed, to peer.trusted list with their nodeIds, instead of { ip = "*"}. It's more secure but you need to keep this list up-to-date and restart peer on update.

NOTE: You should disable peer discovery for any node accessible from Internet:

peer.discovery = false

Also, consider setting up HTTPS for Harmony: Enabling access via HTTPS