Author: Alexey Vanin, alexey@nspcc.ru

This paper describes a method to test neo-cli nodes with a raw transaction flow. This paper includes step-by-step instruction to prepare test environment with automated tools and run simple test.

Method of testing

Several neo-cli nodes running simultaneously within a consensus group. It is possible to measure the bandwidth of the whole blockchain by sending transactions to the nodes at some high sending rate. A number of transaction in a single block defines blockchain bandwidth. Also, it is possible to measure a number of transactions per second (TPS) — the speed of accepting transactions by the node.

To do those measurements you need:

group of neo-cli nodes

copy of blockchain with a bunch of wallets with assets

prepared transactions to send

Neo-cli nodes

It is relatively simple to prepare a group of neo-cli nodes. There is ready-to-work repositories which allow to build up a group of consensus nodes with different neo-cli version: CityOfZion/neo-local, nspcc-dev/neo-privatenet and so on. But for stress testing, some tweaks must be done to the neo-cli nodes. At first, you might need to do a test with a different block generation time. Default 15s parameter can be changed at protocol.json file inside a neo-cli directory.

More importantly, it is not possible to measure bandwidth with transactions per block limitation. This parameter also can be changed at config.json in a SimplePlugin directory.

Blockchain with wallets and assets

Neo-cli nodes accept a different kind of calls. It may be smart-contract invoke, sending assets from wallet to wallet, etc. But those operations mostly involve users with associated wallets and some assets to spend. Repositories mentioned above, have one “master” wallet with a large number of assets, which is not suitable for the test. There are two ways to resolve this issue:

modify genesis block;

transfer assets from master wallets to other wallets.

The first approach seems more convenient and correct. But it involves block changes directly in the blockchain. This paper describes automated tools to perform the second approach.

Prepared transactions

There are well-known applications to do stress-testing for services: JMeter, Yandex-tank, etc. These tools require a predefined array of HTTP-requests to send. Neo-cli nodes have sendrawtransaction API method. By creating a large number of raw transactions it is possible to create a large amount of HTTP-requests. These requests may be sent to the neo-cli nodes with any available traffic generator.

Preparing environment with automated tools

At first, let’s download neo-bench repository, which is based on neo-local. Then run default prepared environment (neo-cli v2.9.4, 4s/block, 500 txs/block) and generate several wallets with wallet-gen.py script.

Important note: number of wallets must be twice as much as the number of transactions. Creating 20 wallets means that 10 wallets will have some assets (senders) and 10 wallets will be empty (receivers).

These wallets saved in /wallets directory, which is shared with the host. They will not disappear after environment restart.

When wallets are ready, let’s transfer assets from “master” wallet to others with tx-gen.py script. By default, this script sends 10 NEO and 2 GAS. Then script generating raw transactions: transfer of 3 NEO with a fee of 1 GAS. The fee is necessary to overcome the limitations of 21 free transactions per block.

By default file with a raw transaction is saved in the /root directory. Move it into the shared directory for later use.

Don’t forget to change the settings of neo-cli. Let’s connect to the neo-cli-privatenet node and manually change them.

You can automatically change settings of a neo-cli-privatenet node with an automated script from neo-local repository.

When everything will be done commit container changes for further reuse.

The environment is prepared and now it can be repeatedly started along with the test. To do that modify .env file and start only consensus nodes.

From this point, you can set up your traffic-generator and start monitoring TCP-connections on your loopback interface via Wireshark. JMeter and Yandex-tank need formatted HTTP-queries as an input, so you need to prepare them along with the generator specification. Or you can use a simple traffic generator, which is working directly with a list of raw transactions. Generator encapsulates them into JSON RPC 2.0 queries and sends them as fast as it can to the neo-cli node.

Download rpc-raw-generator and put raw.txs file to the raw directory. Start a docker container and run application with your preferences.

For block monitoring, you don’t need to use neo-scan application. Use getblock.py script directly from host to monitor information about blocks: a number of transactions in block and time to generate.