Setting up a three node E-Chord network on a single computer
In this tutorial, we will set up an E-Chord network consisting of three nodes. The entire network, including the seed server, will run on a single computer, only using the local network for communication.
To do this, we'll need both the repository for the seed server and for the node. Start by cloning both of these repositories at a location of your choosing. For more information on how to do this, refer to the setting up guide.
Starting the seed server
As always, the first step is to start the seed server. Open a terminal at the seed server's location and use the python3 server.py command. The output should look something like this:
MainThread-INFO: Loaded params
MainThread-INFO: Starting node on 192.168.1.12:8000
If instead, you get a Permission denied error, it most likely means the port is already in use. In that case, edit the port number in params.json and try again.
You have now started the seed server! The server will wait for new nodes to contact it, so the next step is adding some nodes to the network.
Adding a node
Go to the location where you cloned the main repository. A tree view of the repository should look like this:
.
├── client.py
├── config
│ └── params.json
├── LICENSE
├── README.md
├── scripts
│ ├── mass_data.py
│ ├── mass_node_join.py
│ ├── mass_node_leave.py
│ └── visualizer.py
├── src
│ ├── ConnectionPool.py
│ ├── Finger.py
│ ├── Node.py
│ ├── rpc_handlers.py
│ ├── Storage.py
│ └── utils.py
└── start_node.py
3 directories, 15 files
If this looks like a lot, don't worry! We won't be using most of these for our purposes. In fact, there is only one step we need to perform before adding our first node to the network: setting up the seed server parameters. This is essentially equivalent to telling our nodes how to contact the seed server we just opened.
To do this, open the config/params.json file. Find the "seed_server" section and replace the default IP (192.168.1.15) with the seed server's IP, as well as the default port (8000) with the seed server's port. Make sure to save these changes.
Once you've done this, return to the terminal at the repository's location and run the start_node.py file using the python3 start_node.py 9150 command. If you get the permission denied error again, you'll need to run using a different port number. Simply change the last argument of the command. For instance, if you want to run using port number 9200, run the command python3 start_node.py 9200.
If all goes well, you should see output similar to the following:
MainThread:15626-INFO: No other nodes in the network
MainThread:15626-INFO: Initialized predecessor and sucessor list to self
MainThread:15626-INFO: Starting node on :9150
This means our node has joined the network successfully! Since this is the first node to join, we get the No other nodes in the network message.
You might also notice that as time goes on, more and more messages fill the output. This is normal! The Chord protocol contains various periodic routines, so these messages simply inform us every time one of those completes.
Interactions with the seed server
If you return to the terminal window where the seed server is running, you'll notice there is new output there as well. When we initially started our node, we got output such as this:
Thread-3 (handle_connection)-INFO: Got request for seed, sending None
MainThread-INFO: Added ('192.168.1.12', 9150, 11932)
This tells us the node we started contacted the seed server and asked for a seed, but got nothing (because there are no nodes in the network yet)! The node was then added to the seed server's list. Afterwards, you'll notice the seed server periodically outputting messages like these:
Poll-INFO: Polling node: ('192.168.1.12', 9150)
Poll-INFO: Node is alive
This means our seed server is periodically contacting our node, asking it if it is still there. The node responds and so the server determines it is alive, therefore keeping it in its list.
Adding a second node
Let's now add a second node. Just like before, open a new terminal window at the location of the node repository and execute the command python3 start_node.py 9951. You don't necessarily have to use the same port number, but make sure it is different to the ones used by the seed server and your first node.
Since you're executing this in the same repository, you've already made the necessary changes to the parameters, so you don't need to worry about making those changes again.
You should now notice that the initial messages we get as output are different to those of the first node.
MainThread:2503-INFO: Got seed from seed server
MainThread:2503-INFO: Asking seed for successor
MainThread:2503-INFO: Got successor
MainThread:2503-INFO: Asking successor for this node's successor list
MainThread:2503-INFO: Initialized successor list
MainThread:2503-INFO: Starting node on :9151
These tell us that the second node recognizes that there's another node in the network and contacts it. We can see the start of this exchange in the seed server's output as well.
Thread-172 (handle_connection)-INFO: Got request for seed, sending ('192.168.1.12', 9150, 11932)
MainThread-INFO: Added ('', 9151, 2503)
The second node asked the seed server for a seed. This time, since the first node was already in the network, the seed server provided the second node with the information necessary to connect to it.
Between the stabilization messages of the first node, you'll find the below output as well:
MainThread:11932-INFO: Got new successor
This tells us that the first node is now also aware of the second node's existence.
The network should now contain both of the nodes we added. Finally, let's add a third node and observe the output we get. Just like before, open a new terminal and start another node, with a different port to those already used.
The result should be the same as when we added the second node. Both existing nodes connect to the new node. The seed server will initially send information about one of the two existing nodes randomly. If you repeat this experiment multiple times, you'll find that sometimes, the third node initially gets information about the first node, whereas other times it gets information about the second one.
Finally, we can use one of the provided scripts to get a better view of the current network. Open a new terminal at the repository's location. Use cd scripts to enter the scripts directory and execute the python3 visualizer.py command.
You'll notice output similar to this:
╔═══════════════╦═══════════════╦══════════╗
║ Successors ║ Predecessors ║ Keys ║
╠═══════════════╬═══════════════╬══════════╣
║ 2503 -> 8230 ║ 15626 <- 8230 ║ 2503: 0 ║
╠═══════════════╬═══════════════╬══════════╣
║ 8230 -> 15626 ║ 8230 <- 2503 ║ 8230: 0 ║
╠═══════════════╬═══════════════╬══════════╣
║ 15626 -> 2503 ║ 2503 <- 15626 ║ 15626: 0 ║
╚═══════════════╩═══════════════╩══════════╝
Total keys: 0
Stability: 100.00%
If the nodes aren't visible, make sure you're using ports in the visualizer's range. By default, this range is 9150 to 9250.
You are now able to confirm that everything is indeed stable. Each node should have the next one as its successor, increasing in ID, until the last one, which connects to the first one again. The predecessors, of course, go in the opposite direction.
Conclusion
If this is the case, then you have successfully created an E-Chord network on your computer! Note that even though this network runs in the exact same way as a regular network, it all happens locally on a single machine. For more information on the differences between this and an actual network, refer to the E-Chord discussion.