Transport Tutorial Part 3: Next steps

1. Make it portable

Currently the packet is not really portable, because it is connected via USB to the computer in order to get power.

To make it portable, all that is needed is a portable power source, like a battery, that provides the Raspberry Pi with enough power to track the packet for at least a few hours.

The second thing that needs to be done is making the tracking script start automatically after the boot process of the Pi.

pm2 provides an easy way to let the script start automatically after boot. On the Raspberry Pi, install pm2 globally:

npm install pm2 -g
pm2 startup

This should print a fitting command in the terminal. Copy it and paste it in the temrinal again to complete the setup of the pm2 startup script.

Start the tracking script with pm2:

Run this inside the light_alarm folder on the Raspberry Pi
pm2 start --name lightAlarm index.js
Add the tracking script to the list of processes, that will be started autmatically when the raspberry pi is started.
pm2 save

Now log out from the Raspberry Pi, disconnect it from the computer, and connect it to a portable energy source, like a power bank. After 1-2 minutes of booting, the tracking script will start running and it will check the light sensor every second.

2. Connect more nodes

During development it is necessary and convenient to have a rather centralized network with only one node connected.

Once the development has reached the point of proof of concept or a usable product, it’s time to add more nodes to the network, and to give other people the opportunity to join the newly created blockchain network.

This is how the setup should look like after finishing Part 2: A simple supply chain tracking system:

One node diagram

We want to add one more node to the network, that communicates between the seed node and the Iot and the client app.

More nodes diagram

To do so:

2.1. A) Set up at least one seed node

Set up one or multiple seed node(s). Every new node will connect to the seed nodes at first, when booting for the first time. Starting from the seed node, a new node will discover the rest of the network by requesting their peer list and then the peer lists of the newly discovered peers and so on.

The seed node is a node that is specified in the config of the node application under modules.network.seedPeers and that should always stay connected to the network.

It’s also convenient to have the genesis delegates actively forging on the seed node, in case the network hasn’t yet enough real delegates who can take the forging spots.

The exposed configDevnet object is a good template for the config of a seed node, as it includes already all 101 genesis delegates credentials and automatically enables forging for all of them.

2.2. B) Create a new config suited for the node application

Exchange the configDevnet object that we passed to our node during development with an own customized version.

It’s recommended to create a config object with all the options that shall be different to the default config options. To check the default config options, go to the configuration page or check it out directly in the code:
lisk-framework/src/modules/MODULE_NAME/defaults/config.js.
Same goes for the components:
lisk-framework/src/components/COMPONENT_NAME/defaults/config.js.

Most of the configurations can stay the same to what is defined in the default config options, but there is one option that should be updated: The seed node(s).

So to add 1.2.3.4 as a seed node, add an object (or several objects) with the 2 properties ip and wsPort to the seedPeers list:

configDevnet.modules.network.seedPeers = [{ ip: '1.2.3.4', wsPort: 5000}]

By default, the forging delegates list is empty.
This is intended, because the genesis delegates are only needed to set up a working dev environment. Later it’s best if the delegates list is empty, so users can fill their own credentials there, in case they want to activate forging on their node.

If it is desired, e.g. for a proof of concept, to provide already activated forging delegates inside the config, use the devnet genesis delegates in configDevnet or create own genesis delegates and add them to the config.

2.3. C) Publish the application

Add the code for the customized node application (including the custom transaction types) to a public code repository on e.g. Github or Gitlab.

This gives everyone the opportunity to download the application and deploy it on a server in order to connect with the network.

The code should include at least the following files:

  • index.js : The code that initializes and starts the node application

  • package.json : A project file that lists all needed dependencies (this should include lisk-sdk as dependency)

  • transactions/ : A folder with all required custom transaction types

  • README : A Readme which describes the most important steps to setup the node

2.4. D) Connect nodes and verify

Let’s now add a second node to the network.

This new node will not have any forging activated. It will be only here to talk via API with the client app, and over the websocket connection to the seed node. The seed node is therefore the only node right now that can forge new blocks, because all genesis delegates are actively forging on it.

How to replace the genesis delegates with real delegates is covered in the next section Replace dummy delegates with real ones.

To set up the node, just install the published application on a new server.

Don’t forget to open the corresponding ports for HTTP and WS communication!
Snippet of client/app.js
// Constants
const API_BASEURL = 'http://134.209.234.204:4000'; (1)
const PORT = 3000;
1 Add here the correct IP and port to the newly added node.
Logs of newly added node

Synching non forging node

In the logs above we can see, the seed node was already 3 blocks ahead when we first started the second node. It first synchronizes the missing blocks up to the current height and then broadcasts the received transactions from the client app to the seed node, where delegates can add the transactions to blocks and forge them.

These new blocks are broadcasted again to the new node, and the client app can display the data based on the API calls that it sends to the new node.

Log of the seed node with the forging genesis delegates

Forging node logs

Broadcast errors can happen

Sometimes there can be errors when broadcasting transactions between nodes. This is no need to worry! The node will start the sync process soon again, and most times it is successful on the next try.

Common sync issue

In the above image the block at height 284 is not accepted because of an invalid block timestamp. As a result, also the following blocks are discarded by the node as well.

Hick ups like this can happen in the network. The node can resolve these issues at most times on its own by starting a new sync process, where it requests the missing blocks from one of its' peer nodes.

Like shown in the logs, the blocks at height 284, 285 and 286 are discarded. Then, the node realizes it is not in sync with the other nodes and starts the sync process, indicated by the logs Starting sync. During the sync process the missing blocks are received from the peers and added to the database of the node.

3. Replace dummy delegates with real ones

During development of the Lisk Transport application we had one node with enabled forging for all 101 genesis delegates.

After releasing a first version the blockchain application, it is needed that real delegates take the forging slots of the genesis delegates. The network will become stable and decentralized for the first time, when at least 51 real delegates are actively forging in the network.

To join the network as a new delegate:

  1. Create an own, private account on the network

  2. Register a delegate

  3. Set up a node: Follow the steps in the README of the app (Or see the Lisk tutorials, as this process is always basically the same)

  4. Enable forging for the newly created delegate on the node

  5. People get convinced to vote for a delegate in the network, e.g. if the delegate is:

    • helpful

    • reachable

    • trustable

    • accountable

    • sharing rewards

    • offering useful services or tools

3 nodes diagram

It depends on the distribution of vote power, who to convince.

If a delegate joins the network on a very early stage, she will probably replace one of the genesis delegates. The genesis delegates are voted in by the genesis account, which holds all the tokens on the initial network start. The genesis account votes with this tokens for the genesis delegates, in order to stabilize the network during the development.

So when replacing a genesis delegate, the new delegate will need to convince the person who controls the genesis account of the network, which will be most likely the app developer.

Later, when the majority of the existing tokens is distributed among the different private accounts, the new delegate needs to gain the trust of the community in order to be voted into a forging position.

4. Write unit tests for custom transactions

How to test undoAsset functions

5. Task: Add more sensors

Connect more sensors to secure the travel of the packet, e.g. implement a TemperatureAlarm or HumidityAlarm analog to the LightAlarm transaction type.

6. Task: Add other improvements like GPS tracking or estimated travel times