📜 ⬆️ ⬇️

The million question

Perhaps many of you wondered: how will the behavior of a smart contract change, if its data weighs hundreds of megabytes and stores hundreds of thousands or millions of records? Will transactions go up? How will this affect the network as a whole? Will some types of variables in solidity cope with this task better than others? We decided to personally find out the answers to these questions and conduct an experiment in our private Ethereum network, simulating the situations described. What came out of this, read further in the article.


Test description


We wanted to find out how the load will affect one smart contract of one million transactions and a large amount of data.

Measured such parameters:
')

Blockchain parameters

We had a private PoA blockchain with two authorized writing nodes and one “passive” from which transactions were sent.

All three nodes were running on identical servers:


Smart Contract Description

It was created two smart contract. One had mapping bytes32 as the field, => bytes32, the other had a one-dimensional bytes32 array. Each of the contracts contained a function that takes as a parameter the value of bytes32 and saves this value as an element of the corresponding mapping or array (in fact, the value was stored in the blockchain's storage).

Brief description of the mapping contract

contract TesterMapping { mapping (bytes32 => bytes32) StoragedData; function Storing(bytes32 data) { if(StoragedData[data]!= "Y") StoragedData[data] = "Y"; } } 

Brief description of the contract with the array

 Con tract TesterArray { bytes32[] StoragedArray; function Storing(bytes32 data) { for(uint256 i = 0; i < StoragedArray.length; i++) { if(StoragedArray[i] == data) return; } StoragedArray.push(data); } } 

Test progress and results


First, a smart contract with a field-mapping was tested. Once a second, a transaction with a random 32-byte value was sent to it. Due to technical problems, testing took a little longer than planned, and the million transaction was sent three weeks after sending the first one. Then a smart contract with an array was tested.

Mapping — contract

Throughout the experiment, neither the transaction value nor the block size fluctuated by any meaningful amount. Each transaction was processed almost instantly, both the first and the millionth. The duration of the block creation periodically varied from 1 to 9 seconds, but always a value of 5 seconds symmetrically set in the genesis block (if one second passed between creating the block n and n + 1, then the block n + 2 appeared after 9 seconds), that is the average block creation time remained equal to 5 seconds. However, some patterns in the occurrence of these fluctuations were not noticed and, perhaps, this was due to the operation of our network or supporting server software (antiviruses, etc.).

Array contract

In this variant, due to the presence of an array looping cycle (for searching for matching values), the cost of one transaction increased from 40 thousand KGas to more than 2 million KGas in the first two thousand transactions. In this case, the duration of processing a single transaction in the first few hundred transactions has already become longer than the creation time of one block. Because of this, the size of one block for approximately 500 transactions fell to its minimum and did not increase any more, since one transaction began to fall at best into one block. The processing time very quickly became so long that after sending only three thousand transactions, “raking” the resulting queue took about four hours, while the network would be paralyzed (of course, if the sender in the “combat” network had enough money to pay for expensive transactions).

findings




Unfortunately, we did not find a way to determine how much data in the storage is occupied by the data of a specific smart contract when using the mapping array. Perhaps someone from the readers will be able to tell your version.

Source: https://habr.com/ru/post/354122/


All Articles