Inconsistencies in PolygonScan zkEVM Published Data

Blog post image

MigaLabs

Sun Mar 10 2024

Introduction

At MigaLabs, as a Blockchain Observatory, we wanted to extend our reach to Layer 2’s blockchain scalability solutions. Starting with Polygon’s zkEVM. The idea was to start building a dashboard showing the status of the zkEVM. In this report, we detail the different approaches tried, the problems encountered, how we managed to solve them, how we analysed and processed data, and the obtained results.

Problems with the setup

Repository setup

We followed Polygon’s guide in order to set up the zkEVM node. The nominal requirements for the node to run are:

  • 16GB RAM
  • 4-core CPU
  • 20GB of disk (will increase with the chain) (At the time of setup was 20 GB, wow it says 70 GB).

We set up a node and installed the node following the instructions. However, the docker-compose was not working well; there was one variable that was not being used, and the guide specifies the creation of several folders. However, we thought it was easier to create a single folder and to override the variable in the docker-compose file, which makes the setup much easier.

Proposed setup

Run git clone -b fix/docker-deployment [email protected]:migalabs/zkevm-node.git and cd mainnet && mv example.env .env.

Fill the .env file with the instructions from the guide and docker-compose up -d.

First approach

We were aware that the zkEVM node only works with certain types of Intel Processors (they need to support the AVX2 instruction set). We configured a new machine with an Intel CPU, 8GB RAM, and 50GB of disk. This machine was running Ubuntu OS. We deployed the setup, but the prover would not show any logs. We tried running with debug mode, and we also tried executing the binary with the help option, but no log was shown.

Second approach

After our fairy failure, we upgraded the machine with a different CPU and 16GB of RAM. When running the setup, the prover now shows logs! Great, we now have a running node.

After speaking to the internal zkEVM team, we were told the sync process would take around a week or a bit more. Also, the sync process would use more than 500GB of disk, so we had to upgrade the machine again, this time disk-wise.

The zkEVM team kindly provided a snapshot of the database, which could be imported into the zkEVM node database. However, this process would take more than 16GB of RAM, so our node could not handle the restore process. Also, we tried running the node from scratch, but the prover service kept dying as per the memory limit.

Third approach

After understanding that more requirements were needed, we started researching. We found these software requirements for the node, which mention 32GB of RAM. Therefore, we upgraded the machine once again. With the upgraded machine, we could import the snapshot and then run all services as normal; our node is completely synced and functional now.

Issues with RPC

Once we had a node synchronising the network, we had problems interacting with the RPC container. In particular, the eth_syncing method was not working properly, and there were problems enabling debug mode when accessing debug logs on RPC. In addition to this, we found that they should update the docker-compose regularly since they had an outdated version. Finally, we also found that the node stopped working occasionally out of nowhere. We found that the reason was that they periodically release new versions of the zkevm-node container that are not backwards compatible.

Analysis

The analysis of the data is done using Python 3.11.5. The aim of this analysis is to present statistics and metrics of Polygon’s zkEVM Network using our own node. In particular, we plan to investigate and answer a number of research questions that could be raised from this, such as:

  • How many TPS is this rollup able to handle?
  • What is the latency in this rollup?
  • Study the data availability cost and compare it against what it would cost after EIP4844 is deployed.

Among others.

RPC

For the RPC, we have created an RPC class containing the domain and port where the zkevm-rpc container exists, and we implement two basic functionalities:

  • post to make requests.
  • pprint to format the response of the post call.

RPC Utils

RPC Methods used

We have implemented a number of different methods on the RPC.

Set up a class that will make the requests using the RPC specified above.

zkEVM Crawler

The eth_blockNumber and eth_getBlockByNumber methods from the zkEVM's RPC are the most used ones.

3_most_used_methods.png

MigaLabsDB Setup

Since the response from eth_getBlockByNumber is the following:

  • Object - A block object, or null when no block was found:
  • number: QUANTITY - the block number.
  • hash: DATA, 32 Bytes - hash of the block.
  • parentHash: DATA, 32 Bytes - hash of the parent block.
  • nonce: DATA, 8 Bytes - hash of the generated proof-of-work.
  • sha3Uncles: DATA, 32 Bytes - SHA3 of the uncles’ data in the block.
  • logsBloom: DATA, 256 Bytes - the bloom filter for the logs of the block.
  • transactionsRoot: DATA, 32 Bytes - the root of the transaction trie of the block.
  • stateRoot: DATA, 32 Bytes - the root of the final state trie of the block.
  • receiptsRoot: DATA, 32 Bytes - the root of the receipts trie of the block.
  • miner: DATA,20 Bytes - the beneficiary's address to whom the mining rewards are paid.
  • difficulty: QUANTITY - integer of the difficulty for this block.
  • totalDifficulty: QUANTITY - integer of the total difficulty of the chain until this block.
  • extraData: DATA - the “extra data” field of this block.
  • size: QUANTITY - integer the size of this block in bytes.
  • gasLimit: QUANTITY - the maximum gas allowed in this block.
  • gasUsed: QUANTITY - the total used gas by all transactions in this block.
  • timestamp: QUANTITY - the Unix timestamp for when the block was collated.
  • transactions: Array - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter.
  • uncles: Array - Array of uncle hashes.

We set up a PostgreSQL Schema and Table containing these fields, in particular

5_insert_one_block.png

How do we analyse the data?

We first convert and cast the hexadecimal values to ints.

6_casting.png

We obtain data from polygonscan to compare

7_obtain_csv_from_polygon.png

Integrity checks

The integrity checks that we have implemented are over:

  • transactions count
  • Average size
  • Average gaslimit
  • Sum of gasused

We have not found minor inconsistencies for Transactions count, Average size and Average gas limit, corresponding to missing data from their side for the genesis day (2023-03-24), where they report nothing, and the same applies for the current day (2024-02-05) as the time of this writing.

Transaction count

DateComputed Count TransactionsReported Total Tx
2023-03-2427NaN
2024-02-0516.684NaN

Average size

DateComputed Avg SizeReported Avg Size
2023-03-242251.0NaN
2024-02-051023.0NaN

Average gas limit

DateComputed Avg GaslimitReported Avg Gaslimit
2023-03-2428928571.0NaN
2023-03-2630000000.00.0
2024-02-0530000000.0NaN

In this case, they also have reported 0.0 on 2023-03-26.

Problems with gasused

However, then we took a look at the gas used, the table of inconsistencies is considerably larger.

DateComputed Total GasusedReported Total GasusedTotal Gasused Diff
2023-03-2410.111.343NaNNaN
2023-03-2517.204.5722.447.14714.757.425
2023-03-266.024.98306.024.983
2023-03-271.074.793.2781.007.274.00067.519.755
2023-03-281.188.061.525891.388.300296.673.183
2023-03-29670.978.288567.342.400103.635.929
2023-03-30589.929.774529.647.10060.282.701
2023-03-31824.299.939728.500.20095.799.697
2023-04-011.007.672.482888.389.400119.283.086
2023-04-021.021.405.170876.240.600145.164.584
2023-04-03668.641.654587.603.10081.038.583
2023-04-041.124.573.230428.874.200695.699.011
2023-04-05415.954.728393.816.00022.138.737
2023-04-06948.971.181912.685.40036.285.736
2023-04-07884.985.979846.659.10038.326.916
2023-04-08736.308.219706.109.50030.198.767
2023-04-092.550.452.6812.521.383.00029.069.383
2023-04-102.558.412.2762.531.997.00026.415.406
2023-04-11448.479.495426.224.10022.255.361
2023-04-12379.534.166362.321.50017.212.672
2023-04-13297.533.767287.313.80010.220.010
2023-04-14725.095.552712.772.80012.322.749
2023-04-15955.189.823934.784.20020.405.612
2023-04-16634.728.865616.205.50018.523.404
2023-04-17660.773.678643.058.60017.715.046
2023-04-18397.523.621384.924.60012.598.971
2023-04-19245.335.831239.039.6006.296.276
2023-04-20285.603.918275.008.20010.595.748
2023-04-21411.109.200398.482.50012.626.694
2023-04-22482.495.847470.511.90011.983.906
2023-04-23364.666.178355.273.4009.392.791
2023-04-24455.167.687446.989.8008.177.861
2023-04-25427.500.681405.402.90022.097.778
2023-04-26425.815.952405.811.20020.004.794
2023-04-27439.886.580403.400.30036.486.264
2023-04-28437.781.601415.226.10022.555.460
2023-04-29250.244.759243.080.0007.164.739
2023-04-30221.540.994211.120.70010.420.322
2023-05-01173.610.301168.043.0005.567.329
2023-05-02395.887.444395.230.200657.282
2024-02-052.470.912.630NaNNaN

We found that apart from the "typical" inconsistencies on the "genesis day" and "today", there are inconsistencies every day between 2023-03-25 and 2023-05-02.

We have plotted a chart corresponding to the Total Gassued Diff with hopes of better understanding what was happening.

8_graphic.png

But the only conclusion that we could obtain from this chart is that we always have a larger amount compared to their reported amount (since all the points in this plot are above the X-axis).

Taking a look at 2023-03-25

We wanted to make sure that everything was running well from our side> Thus, we manually checked the gas used reported by polygonscan, and we compared those numbers to the numbers obtained from our node for the 25th of March of 2023 (the first day of inconsistencies). Checking from the website, we found that the blocks that have a timestamp on 2023-03-25 are the blocks from numbers 28 to 48 (both inclusive). Double-checking this data with the timestamp provided with our node, we obtain the same block range for this day.

The data obtained from our node is the following:

9_gasused.png

Now, here are the results:

Block numberData from PolygonScanData from our RPCEqual?
Block 2821.03221.032TRUE
Block 2990.57990.579TRUE
Block 301.426.9821.426.982TRUE
Block 311.427.3401.427.340TRUE
Block 321.427.0521.427.052TRUE
Block 33119.957119.957TRUE
Block 3490.17590.175TRUE
Block 351.453.6201.453.620TRUE
Block 3671.26971.269TRUE
Block 3746.92346.923TRUE
Block 38196.597196.597TRUE
Block 3990.55790.557TRUE
Block 40657.706657.706TRUE
Block 411.427.3661.427.366TRUE
Block 421.427.8681.427.868TRUE
Block 431.427.8641.427.846FALSE
Block 441.427.7361.427.736TRUE
Block 451.427.4601.427.460TRUE
Block 461.428.0941.428.094TRUE
Block 471.427.4621.427.462TRUE
Block 4890.95190.951TRUE
SUM17.204.59017.204.572

We can see here that the sum of column Data from our RPC checks out with our reported data for this day in the table above. However, their sum (Data from PolygonScan) does not. Checking, line by line, each row, we found what seems to be a typo error from their side: block 43 has a permutation between tens and digits.

Even knowing that the number reported by PolygonScan is really far from the reported number for that day from their website, 2.447.147 (> 14M gas of difference). So, where can this number come from?

Where does this number come from?

We continued to investigate this matter, and we found out that there exists a partial sum of these numbers (gas used from blocks 28 to 48) that adds up to 2.447.147.

Block numberData from their website
Block 2821.032
Block 2990.579
Block 301.426.982
Block 311.427.340
Block 321.427.052
Block 33119.957
Block 3490.175
Block 351.453.620
Block 3671.269
Block 3746.923
Block 38196.597
Block 3990.557
Block 40657.706
Block 411.427.366
Block 421.427.868
Block 431.427.864
Block 441.427.736
Block 451.427.460
Block 461.428.094
Block 471.427.462
Block 4890.951

The gas used, as reported on the PolygonScan website, when totaled for block 28, block 35, block 36, block 37, block 38, and block 40, equals a combined amount of 2.447.147.

21.032 + 1.453.620 + 71.269 + 46.923 + 196.597 + 657.706 = 2.447.147

This finding indicates that the reported amount is not likely to be a random number but that they (most probably) had an issue with the synchronisation process during these dates, and they ended up with a partial sum. However, what is concerning is the fact that, almost a year after this incident, the team behind PolygonScan seems to be unaware of these data inconsistencies and that this issue is still not fixed.

Conclusions

This report has explored how to analyze the data from the Polygon zkEVM. We found multiple difficulties when deploying the node due to outdated documentation and other issues that we have reported. Once we managed to obtain data from the zkEVM, we analyzed it and compared it with the data provided by PolygonScan. As a result, we found a number of inconsistencies in the data published by PolygonScan. After analysing and double-checking every step of our analysis, we have found some concerning points that could explain the inconsistencies in the PolygonScan data.

MigaLabs is open to discussing this issue with the interested parties and providing our code so that anybody can reproduce our methodology and corroborate the correctness of our computations.

About MigaLabs
MigaLabs logo

We are a research group specialized in next-generation Blockchain technology. Our team works on in-depth studies and solutions for Blockchain Scalability, Security and Sustainability.

Inconsistencies in PolygonScan zkEVM Published Data