Summary
- Check that there is network connectivity between the two Docker containers and reconfigure if necessary. Check there is sufficient memory allocated to each container.
In each Docker container
- Install the go-ethereum
geth program
- Create two accounts (Ethereum addresses)
- Run
geth with the exact same custom genesis.json file, same --networkid, --datadir set to your preferred directory and with the parameter for geth to start mining.
- Test that
geth is working
- Connect the
geth instances.
Short Answer To Your Questions
Q: How the connectivity between the two can be enabled?
- A: First set up connectivity between the Docker containers. Some references provided, but don't use
127.0.0.1 as this is normally confined to be used within your operating system / Docker container.
Q: Is it that the wrong IP address is being used? In general, is it possible to utilize a specific IP address from the host by forwarding the IP Address appropriately.
- A: There should be a non-
127.0.0.1 IP address available from within the Docker container. Instructions below to find this address.
Q: Should the console not be exited in Step 2 above?
- A: Test your setup first using
geth ... console. Don't exit the geth command prompt while you are testing.
Q: In either of the above cases, how do we connect to an existing geth instance? I tried using geth attach "http://127.0.0.1:3001", but it gave me an error saying, connection refused. Any suggestions as to how we can attach to an existing geth instance?
- A: I've listed some tests below to check your Docker container networking connectivity. Once connectivity is resolved, use your
--rpc* parameters and your should be able to connect using geth attach ... with the non-127.0.0.1 address and port.
EDIT 23/04/2016 - OP solved the connectivity issue using 192.*.*.* instead of 127.0.0.1 for the IP addresses as shown in the following Docker commands:
docker run -it -p 192.XXX.XXX.XXX:30303:30303 --name e1 <eth image>
and
docker run -it -p 192.XXX.XXX.XXX:30304:30304 --name e2 --link e1:e1 <eth image>
EDIT 24/04/2016 - OP has the data directories to be created in the root (/) directory. This will require superuser (root) permission. It is better to store the data directory within your home directory. Use $HOME/tempdatadir1 instead of /tempdatadir1. By default, geth will create your data directory in $HOME/.ethereum.
Details Below
Docker Container Connectivity And Requirements
Memory
geth will require more than 512 Mb so you may want to test with 1 Gb and increase it if necessary.
Docker Networking
Aim
You will need to set up your Docker containers so that geth in Container #1 can connect to geth in Container #2 and vice versa.
In your question, you have mapped 127.0.0.1:30303 to be accessed externally through port 30303. The 127.0.0.1 IP address is a localhost addresses that normally does not allow communication from outside the operating system. Please check for the non-127.0.0.1 IP address by using ifconfig -a within your Docker containers to determine what your non-localhost IP addresses are. Try using these IP addresses to communicate across the Docker containers.
References
Check Connectivity
Get the IP address from within Container #1 using ifconfig -a:
ifconfig -a
lo ...
inet addr:127.0.0.1 ...
...
docker0 ...
inet addr:192.168.0.1
Run geth on port 30303 in Container #1 as shown in the next section (or as you documented in your Question).
From Container #2 or the host, you should be able to run the following command - you will have to hit Control-C to teminate the connection:
user@Kumquat:~$ telnet 192.168.0.1 30303
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.
If your IP address is not set up to receive your connection attempt, your results should look like:
user@Kumquat:~$ telnet 192.168.0.1 30303
Trying 192.168.0.1...
telnet: Unable to connect to remote host: No route to host
If your IP address is correct, but your port is not mapped correctly, you should see:
user@Kumquat:~$ telnet 192.168.0.1 30303
Trying 192.168.0.1...
telnet: Unable to connect to remote host: Connection refused
Configure geth
Configure geth with the basic parameters so we can verify that it is working as expected, without the P2P connection between the Docker containers. You will firstly need to configure two accounts to test your mining.
New Accounts
In Container #1, run the following command twice to create two new accounts:
user@Kumquat:~$ geth --datadir "$HOME/tempdatadir1" account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat Passphrase:
Address: {a6847de2447db964ef89644752921c204bf563ab}
Data related to your account (in encrypted format) is stored in your --datadir directory under the subdirectory keystore. Make sure that you back these files up (and remember your password) if you are using this account in the main Ethereum network.
user@Kumquat:~$ ls -al $HOME/tempdatadir1/keystore
total 12
drwx------ 2 user user 4096 Apr 24 16:11 .
drwx------ 3 user user 4096 Apr 24 16:11 ..
-rw------- 1 user user 491 Apr 24 16:11 UTC--2016-04-24T06-11-04.534736154Z--a6847de2447db964ef89644752921c204bf563ab
And the same in Container #2, using the --datadir for Container #2.
Run geth Miner
Run the following command in Container #1, and you should see messages like the ones listed below:
geth --datadir "/tempdatadir1" --port "30303" \
--genesis genesis.json --networkid 6161 \
--mine --minerthreads 1 console
Same for Container #2:
geth --datadir "/tempdatadir2" --port "30304" \
--genesis genesis.json --networkid 6161 \
--mine --minerthreads 1 console
The messages you should be seeing follow:
I0422 23:24:07.347255 8218 worker.go:348] Mined block (#6248 / 11175b1e). Wait 5 blocks for confirmation
I0422 23:24:07.347868 8218 worker.go:569] commit new work on block 6249 with 0 txs & 0 uncles. Took 521.208µs
I0422 23:24:07.348356 8218 worker.go:569] commit new work on block 6249 with 0 txs & 0 uncles. Took 378.62µs
I0422 23:24:18.248751 8218 worker.go:348] Mined block (#6249 / 50cdfdeb). Wait 5 blocks for confirmation
I0422 23:24:18.249306 8218 worker.go:569] commit new work on block 6250 with 0 txs & 0 uncles. Took 470.831µs
Sending An Ether From Account #1 to Account #2
In each container, run the sendTransaction command in the geth console. You mining operation should be adding ethers to eth.accounts[0] (first account, also called coinbase). This command will send an ether from eth.accounts[0] to eth.accounts[1]:
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, "ether")})
"0xde465790a8ae4ce1aad3179d071ac49ed447c09199de26ce02327e8790e63e4b"
Wait for the transaction to be mined. Then run the getTransaction command to check the transaction has been mined into a block:
> eth.getTransaction("0xde465790a8ae4ce1aad3179d071ac49ed447c09199de26ce02327e8790e63e4b")
{
...
blockNumber: 6266,
...
}
Check the account balance of eth.accounts[1]:
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
1
Connect The geth Instances
You will need to find the enode information for each geth instance. I've shortened the long node public key from "d9d93b749257a1d4eaec18ab1c1ad39dc9220e449cfe248aceafc586193ead0ac14a088be5afb8455bd8f14bab7428162b8fbeda399ec748f5df0369789730d9" to "d9d9...30d9" for ease of reading - use the full version in your configuration.
In Container #1, run the following command in the geth ... console:
> admin.nodeInfo
{
enode: "enode://d9d9...30d9@[::]:30303?discport=0",
...
}
Get the same information from geth in Container #2.
In the Peer Discovery section below, replace [::] in your enode with the externally accessible IP address of your Docker container, and remove the ?discport=0 text.
Peer Discovery
You have 3 methods to get geth in your Docker containers to connect to each other:
Bootnodes
In Container #1, add the --bootnodes parameter to your geth command line like, where "d9d9...30d9" needs to be replaced by the appropriate public key for geth in Container #2:
geth --bootnodes "enode://1234...5678@192.168.0.2:30304" ...
In Container #2, you can add the similar parameters:
geth --bootnodes "enode://d9d9...30d9@192.168.0.1:30303" ...
This will connect your geth nodes for the initial peer discovery where they should discover each other an maintain a P2P connection.
static-nodes.json
Add the following text, replaced with your node information, in your --datadir directory in a file named static-nodes.json:
[
"enode://1234...5678@192.168.0.2:30304",
"enode://d9d9...30d9@192.168.0.1:30303"
]
trusted-nodes.json
Same as static-nodes.json above, but the node connections here do not count towards the --maxpeers parameter if specified.
Try the different configuration styles until I find one that is stable for at least a few days.
Peer Discovery References
How To Run geth In The Background
To run geth as a background process, remove the console parameter from your geth command and append the & symbol that will start the process in the background. As you may want to inspect the messages from geth, you should pipe (send) the output from geth into a log file.
This is how I do it:
Make a subdirectory logs in your $HOME directory:
mkdir $HOME/logs
Set up a script file with your geth command line option. I call mine runGeth and save it in $HOME/bin . Ths full filename is $HOME/bin/runGeth, and this file contains:
#!/bin/sh
# Kill any running geth instances gracefully
killall -q --signal SIGINT geth
# Wait for 10 seconds
sleep 10
# Make sure that geth is really killed. Try hard killing again
killall -q geth
# Run geth in the background,
# piping the output messages to a log file
geth --rpc [other parameters] --verbosity 3 2>> $HOME/logs/geth.log &
You will have to run the following command to make this script executable:
user@Kumquat:~$ chmod 700 $HOME/bin/runGeth
You can now start geth running the script from your command line:
user@Kumquat:~$ runGeth
If this does not work, use the full pathname:
user@Kumquat:~$ $HOME/bin/runGeth
To attach to your geth instance running in the background, use the command:
geth attach
This will use the IPC protocol to connect to the geth instance running in the background.
If you want to connect to the geth instance from your other Docker container, or from outside your Docker container, use the following command with the correct IP and port numbers:
geth attach rpc:http://192.XXX.XXX.XXX:8545
Note that the port 8545 is the default RPC port that can be set using the --rpcport {port} command line parameter.
You can exit from these geth attach processes without affecting the geth instance running in the background.
And as I don't like typing out long command line parameters, I create the file $HOME/bin/attachGeth with the following contents:
#!/bin/sh
geth attach rpc:http://192.XXX.XXX.XXX:8545
And chmod 700 $HOME/bin/attachGeth so I can attach to the background running geth using the command attachGeth or $HOME/bin/attachGeth.
To view the log files from the geth instance running in the background:
tail -F $HOME/logs/geth.log
Hit Control-C to terminate this process.
Any suggestions as to how to get around this?
– skarred14 Apr 24 '16 at 05:53--datadir $HOME/tempdatadir1. – BokkyPooBah Apr 24 '16 at 06:07gethin the background to the bottom of my answer. – BokkyPooBah Apr 24 '16 at 08:56- If the genesis files are different, would it affect the connectivity between nodes?
- What would be suggested to allocate funds to accounts created at the nodes and transact from one node to another?
– skarred14 Apr 26 '16 at 16:37