Devnet total rounds calculation

51 views Asked by At

One thing I need to do in my smart contract is to calculate the current epoch's round. The reason why I need it is that my smart contract should not do anything in the first 5-10 minutes of an epoch (so the first 50-100 rounds?).

For this I thought that I could use the current block round, divide it by the rounds per epoch and what's over is the current round in the current epoch.

So far so good? BUT that's not working. Take this example from the devnet:

Round: 5017252 Rounds per epoch: 1200 Epoch = 5017252 / 1200 = ~4181.04333 But the actual epoch is: 4150

On mainnet this calculation DOES work. Anyone has a better idea?

2

There are 2 answers

0
Quentin On

Short answer: There are 2400 rounds per epoch on the devnet, not 1200.

Explanations

On the current devnet (which started the 6th September 2024) an epoch lasts 4 hours rather than 24 hours on the mainnet or 2 hours on the previous devnet.

To check how much rounds are in an epoch you can query this: https://devnet-gateway.multiversx.com/network/config

Response:

{
  "data": {
    "config": {
      "erd_adaptivity": "false",
      "erd_chain_id": "D",
      "erd_denomination": 18,
      "erd_extra_gas_limit_guarded_tx": 50000,
      "erd_gas_per_data_byte": 1500,
      "erd_gas_price_modifier": "0.01",
      "erd_hysteresis": "0.200000",
      "erd_latest_tag_software_version": "D1.6.13.2-hf1",
      "erd_max_gas_per_transaction": 600000000,
      "erd_meta_consensus_group_size": 58,
      "erd_min_gas_limit": 50000,
      "erd_min_gas_price": 1000000000,
      "erd_min_transaction_version": 1,
      "erd_num_metachain_nodes": 58,
      "erd_num_nodes_in_shard": 58,
      "erd_num_shards_without_meta": 3,
      "erd_rewards_top_up_gradient_point": "2000000000000000000000000",
      "erd_round_duration": 6000,
      "erd_rounds_per_epoch": 2400,
      "erd_shard_consensus_group_size": 21,
      "erd_start_time": 1694000000,
      "erd_top_up_factor": "0.500000"
    }
  },
  "error": "",
  "code": "successful"
}

You can see there are 2400 rounds per epoch on the devnet.

Now let's do the same on the mainnet by querying https://gateway.multiversx.com/network/config

Response:

{
  "data": {
    "config": {
      "erd_adaptivity": "false",
      "erd_chain_id": "1",
      "erd_denomination": 18,
      "erd_extra_gas_limit_guarded_tx": 50000,
      "erd_gas_per_data_byte": 1500,
      "erd_gas_price_modifier": "0.01",
      "erd_hysteresis": "0.200000",
      "erd_latest_tag_software_version": "v1.6.13.0",
      "erd_max_gas_per_transaction": 600000000,
      "erd_meta_consensus_group_size": 400,
      "erd_min_gas_limit": 50000,
      "erd_min_gas_price": 1000000000,
      "erd_min_transaction_version": 1,
      "erd_num_metachain_nodes": 400,
      "erd_num_nodes_in_shard": 400,
      "erd_num_shards_without_meta": 3,
      "erd_rewards_top_up_gradient_point": "2000000000000000000000000",
      "erd_round_duration": 6000,
      "erd_rounds_per_epoch": 14400,
      "erd_shard_consensus_group_size": 63,
      "erd_start_time": 1596117600,
      "erd_top_up_factor": "0.500000"
    }
  },
  "error": "",
  "code": "successful"
}

You can see there are 14400 rounds per epoch on the mainnet.

Please be aware that the round duration might change in a future network upgrade. So be careful and don't hardcode it in your contract, especially if it isn't upgradeable

0
Brother Jder On

Even though the devnet is 2400 rounds per epoch instead of previous 1200, indeed one would calculate current_round / 2400 and the result should match the current epoch... Until it doesn't, like the devnet in this case.

Long story short, due to the devnet suffering a hardfork recently, this chronology deduction suffered a bit. If you want to sync to a fixed time, you can rely on rounds or actual timestamp. Otherwise, if you want to sync to a blockchain event, go with blocks or epochs. The relation between these two chronology bases is rather flexible and slightly hard to tie right now.

Here's the longer story now:

Rounds and timestamp are basically tied to the real time, with rounds incrementing each round_duration from the genesis event, no matter what happens with the block generation in chain.

Blocks and epochs are tied to the inner chronology of the chain itself. Blocks increment every time a block is generated and validated on the chain, but there are rounds in which blocks are not generated for many reasons (rollbacks, no consensus, etc). Therefore, you see a drift between current block number and current round number.

Now, regarding epochs, the rounds per epoch metric is rather an optimal number of rounds an epoch should last if everything goes well. Epochs generally last ~1 day in the MultiversX chain, but this is not always the norm, theoretically, as similarly to blocks, different reasons can either force an epoch to pass a bit faster or take longer than the specified rounds per epoch metric.

For example, an epoch can be forced to end sooner if consensus cannot be achieved on metachain for longer than a specified time (this forces a reshuffle of the nodes).

What happened on the devnet is that an epoch lasted longer than the usual rounds per epoch. To be more specific, a hardfork event occured on the devnet on epoch 779 and lasted for ~3 days. This means that when the devnet processing resumed after those 3 days, next epoch was 780 and blocks started incrementing again after the last block validated before the hardfork moment, but the current round (since it's tied to actual time) takes those 3 days into consideration, thus making epoch 779 last ~18 times more than the usual rounds per epoch.

Getting back to your specific problem now:

At the moment, I think there's no correlation between epoch and rounds exposed in the VM so that smart contracts can access it, but it might be a good idea to add the erd_round_at_epoch_start indicator from https://devnet-gateway.multiversx.com/network/status/[shard-number] in here as well. This way, you might be able to easily achieve the result you look for, but this would require a protocol upgrade to include this feature.

In the meantime, I would suggest thinking about whether you should redesign your functional chronology considering the info I just presented above. If your contract should do stuff at specific time of day, go with rounds or timestamp (this is the universal unix timestamp), otherwise, if your smart contract must take into account blockchain inner workings or eventual unexpected downtimes, go around blocks or epochs.