I am currently trying to perform heavy load testing on a ERC20 token. My plan is to use truffle to test stuff like how long it would take for 500 transfer transactions to be deployed (on a private blockchain), maximum number of transactions per second and ideally some tests on scalability by including transactions from multiple nodes. Below is my code for running 500 transactions

const EnergyToken = artifacts.require("EnergyToken");
const assert = require('assert');
const truffleAssert = require('truffle-assertions');
const { performance } = require('perf_hooks');

const numberOfTransactions = 200;
contract("Energy Token Test3 ", async accounts => {

     it("send $numberOfTransactions transactions from account 0 to account 1", async () => {

       let contract = await EnergyToken.at("0x5BbD383bD43aC3896B86207eFe88cf0628ad06F0");

        for (let i = 1; i < 1 + numberOfTransactions; i++) {
           let t0 =performance.now();  

             contract.transfer.sendTransaction(accounts[1],1,{from: accounts[0]});

            let t1 = performance.now();
            console.log("Transaction " + i + " ***** From:" + accounts[0] + " ***** To: " + accounts[1] + "took " + (t1-t0) + " ms" );



The problem is that right now I am measuring the time it takes to submit those transactions, rather than how fast they are deployed. I tried using await before contract.transfer but then transactions are processed 1 by 1 (1 tx per block) and it also takes an enormous amount of time. My question is if there is a better way of measuring the time?


My question is if there is a better way of measuring the time?

I suspect there is a conceptual disconnect. It's not a synchronous operation and the time is dependent on more factors than are accounted for here. Also, the rapid-fire transactions would probably lead to trouble in production if done this way.

Network Throughput

Yes, you are measuring the time for your process to iterate and submit the transactions. The network time to process the transaction depends on other factors:

  • The gasPrice (not specified, but it could be with {gasPrice: bid})
  • Network congestion
  • Network block gasLimit (block carrying capacity)

At best, you can measure transaction confirmation time at a given point in time. It is uncoupled from your loop - more or less the same, given a gasPrice, at a certain time (network conditions) unless the network becomes saturated, possibly because of your aggressive submissions. Also, you will find it is more appropriately measured on a curve.

enter image description here

Source: https://www.ethgasstation.info/index.php (scroll down)

Scaling Suggestions

These suggestions are adjacent to your question, for the benefit of others who come across this post.

  • Address the missing/failure case. Success is not assured - mispricing gas, for example. A missing/failed transaction can jam up the whole queue because transactions from a given account are guaranteed to mine in nonce order. Resubmit or cancel so life can go on.
  • Consider Rate Limiting. Your own transactions can be a source of network congestion that may lead to increasing gasPrices in future blocks, and that can lead to mispricing gas. Keep in mind there is a finite block gasLimit and it is possible to fill it up if you're really serious but it will be very expensive to sustain it.

Have a look over here: Concurrency patterns for account nonce

It is very possible to get very misleading information from a testnet where the transactions are essentially free and network utilization is much less than mainnet.

Hope it helps.

  • Thanks for the answer. It is true that I am kind of confused as to how to test those things because I am working on a private testnet as you mentioned and I am not sure what I can test accurately in such conditions. As for the gas price, correct me if I am wrong but I would still have to send a lot of transactions for if I want the gas price to affect transactions process time (since miners will prioritise the transactions with higher price). Otherwise if I just send them 1 by 1 they will be processed no matter the gas price Jan 30 '20 at 20:59

You can measure the transaction time spent between creation until it appears on the blockchain.

Once you create the transaction you record the time with the hash in a database. When a transaction is mined you record the block timestamp.

There are other time you can measure also like the first time a transaction appears in the pending pool.

As said by Rob there are many parameters that will affect the results. Like block gas limit, network usage, server capacity, mining time (for PoW it is a random process).

  • Hi @Ismael, thanks for your answer. This makes sense but I am unsure about how I can get the hash of the transacation before I receive the receipt? Is there a way of calculating it before I send the transaction? Jan 31 '20 at 18:03
  • @AleksiDaskalov With web3 you have "transactionHash" event that will be fired before the transaction is mined web3js.readthedocs.io/en/v1.2.5/…. You can always sign it by yourself and obtain the transaction hash before sending it.
    – Ismael
    Jan 31 '20 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.