Client Performance with Experimental Storage Rent Implementation

Shreemoy Mishra
RootstockLabs: Research & Technology
5 min readJan 4, 2023

Our proposal for Storage Rent in Rootstock (RSKIP240) adds a new field to each node in the RSK Unitrie. The new field, called lastRentPaidTime, is a unix timestamp indicating the last time storage rent was collected for that trie node.

Our current implementation introduces new classes of Java objects — e.g. StorageRentManager, Rented Node. These are used for rent tracking, rent computation, and rent timestamp updates — i.e. actions are triggered by trie access (reads, writes, deletes) methods in the Repository.

Naturally, these changes will have some impact on the performance of RSKj nodes, e.g. block execution time, disk IO access, disk usage etc. So, we conducted some experiments to measure such impact.

What we expected

We expect storage rent to utilize more RAM and consume more disk space — this is because the new timestamp adds 8 bytes to each unitrie node. We also expect the rent implementation to run a bit slower. This is because the node tracking, rent computations, and rent updates should lead to longer block execution time and more disk IO.

What we found

We used simple, two-sided, t-tests (at 5% level) to measure if an observed change in a metric was statistically significant. We found that

Block Execution time increases by around 10%.

  • An increase of 6% can be attributed to node tracking and rent computations.
  • An increase of 4% can be attributed to rent collection and timestamp updates.

Disk space usage (as measured by increase in unitrie LevelDB files) increases by almost 20%. Such a large increase can be understood as follows.

  • A typical node consumes less than 100 bytes. Adding 8 bytes to each node (the rent timestamp) will naturally increase the size of each entry in the key value database.
  • Edited after initial post: IOV Labs Chief Scientist, Sergio Lerner, notes that there may be another reason for this increase. It is possible that some previously embedded nodes may no longer remain embedded after the change. One way to verify this (in a future experiment) is to increase the threshold for embedding nodes by 8 bytes (in the Trie class within RSKj).
  • Rent timestamps are added to every node, including internal nodes. About half the nodes in the unitrie are internal nodes. These nodes typically do not contain any value (some of them do have a value). The impact of adding a timestamp is more pronounced for these small nodes. On the other hand, nodes that contain contract bytecode are large and the impact of adding a timestamp is small. However, relative to accounts and storage cells, there are very few nodes that contain contract code.
  • RSKj does not have garbage collection enabled (not by default). Thus, every time a rent timestamp is updated, the old value is not removed. Thus, in addition to having larger values, the key-value database also ends up with more keys (some with stale information).

RAM usage and Disk IO were unaffected. We expected both of these to increase, but the experimental blockchain was not large enough to have any statistical impact on RAM usage or on disk IO. We suspect that this may remain the case even once storage rent is activated on mainnet. This is because the RSK state is still under 1GB which is not large enough to impact most clients (RAM is typically 8GB or higher). However, as the state of RSK blockchain grows in the future, we should definitely expect to see some performance impact from additional disk IO.

Takeaway

An increase in disk usage is expected. This should not have any major performance impact on the node. What matters for performance is disk IO, which is impacted by the number of trie keys in the latest state snapshot, not historical state. But as mentioned above, disk IO and RAM consumption are not really affected by rent. This may change in the future when RSK state grows by a lot. The main concern from these experiments is the 10% increase in block execution time. At present, RSK blocks are usually not full. But as adoption increases, the performance impacts will be felt more strongly. Therefore, this can be an area of improvement and optimization in the future.

How we evaluated the performance impact

We compared 4 different versions of RSKJ. Two of them, HOP-4.0.0 and HOP-4.1.0, obviously do not include storage rent. The current implementation of storage rent is in between these releases.

We also ran two versions of the storage rent implementation. The first is the actual reference rent implementation for RSKIP240 linked at the start of the document. The RSKJ benchmarking tool can create and replay a blockchain with 100 blocks in just a few minutes. In these benchmarking runs, the time between blocks is too small for any meaningful amount of storage rent to build up. Nevertheless, these runs can help us measure the impact on execution time due to rent tracking and computation.

In the other version, we replaced the rent timestamp (same as block timestamp) with a block number instead. We also increased the parameter used for the price of storage rent (the rental rate) by a large factor. The rental rate was increased by a factor so that each set of 100 blocks — in the experiment — correspond to an entire year’s worth of blocks. This change helped “accumulate” economically meaningful amounts of storage rent, which leads to rent collections and timestamp updates. This helps us measure the impact of storage rent on disk IO, and disk usage, and the additional impact on block execution time.

So we ran 10 iterations for each variation, with about 300 blocks in each run. The storage rent accumulations can therefore be interpreted as those from a simulation of a 3 year run of the blockchain.

To keep the comparisons meaningful, we need to create “similar” blockchains.

  • We set the block fill level “HALF” instead of the default FULL. Setting blocks to full (approximate, but still) can lead to unexpected errors should there be significant rent collections in some test scenario — which could then push transactions to the next block (making comparisons slightly less meaningful).
  • And we increased the gaslimit to account for the possibility of rent collections being triggered.

--

--