node icon indicating copy to clipboard operation
node copied to clipboard

introducing "safe" block number on Ethereum/Goerli instead of a fixed block confirmation

Open brewmaster012 opened this issue 1 year ago • 2 comments

The Ethereum 2.0 replaces the PoW consensus with PoS, which changes finality rules. As a result, the fixed block confirmation number is no longer the most appropriate.

brewmaster012 avatar Jan 14 '24 15:01 brewmaster012

Can you provide more details on the idea of "safe" block number?

lumtis avatar Jan 16 '24 20:01 lumtis

This is referring to the idea of a Checkpoint in Eth, @brewmaster012 or are you talking about something else?

CharlieMc0 avatar Aug 12 '24 15:08 CharlieMc0

Here is an Alchemy doc that explained all the tags : https://docs.alchemy.com/reference/ethereum-developer-guide-to-the-merge#what-are-safe-and-finalized

ws4charlie avatar Nov 07 '24 17:11 ws4charlie

Collected some test results from an Alchemy endpoint. The patterns I found were:

  1. latest block == safe block + gap1 (22 <= gap1 <= 54, probably based on Epoch)
  2. safe block == finalized block + gap2 (gap2 == 32 or 64)

Basically, we need to

  1. Fetch the safeBlockNumber from endpoint as 1st step.
  2. If a transaction's inclusionBlockNumber <= safeBlockNumber, zetaclients can post inbound/outbound votes.
[2024-11-06 22:51:09] latest: 21133499, safe: 21133470, finalized: 21133406 ===========> gap1: 29, gap2: 64
[2024-11-06 22:51:20] latest: 21133500, safe: 21133470, finalized: 21133406 ===========> gap1: 30, gap2: 64
[2024-11-06 22:51:31] latest: 21133501, safe: 21133470, finalized: 21133406 ===========> gap1: 31, gap2: 64
[2024-11-06 22:51:42] latest: 21133502, safe: 21133470, finalized: 21133438 ===========> gap1: 32, gap2: 32
[2024-11-06 22:51:53] latest: 21133503, safe: 21133470, finalized: 21133438 ===========> gap1: 33, gap2: 32
[2024-11-06 22:52:04] latest: 21133504, safe: 21133470, finalized: 21133438 ===========> gap1: 34, gap2: 32
[2024-11-06 22:52:15] latest: 21133505, safe: 21133470, finalized: 21133438 ===========> gap1: 35, gap2: 32
[2024-11-06 22:52:25] latest: 21133506, safe: 21133470, finalized: 21133438 ===========> gap1: 36, gap2: 32
[2024-11-06 22:52:36] latest: 21133506, safe: 21133470, finalized: 21133438 ===========> gap1: 36, gap2: 32
[2024-11-06 22:52:47] latest: 21133507, safe: 21133470, finalized: 21133438 ===========> gap1: 37, gap2: 32
[2024-11-06 22:52:58] latest: 21133508, safe: 21133470, finalized: 21133438 ===========> gap1: 38, gap2: 32
[2024-11-06 22:53:09] latest: 21133509, safe: 21133470, finalized: 21133438 ===========> gap1: 39, gap2: 32
[2024-11-06 22:53:19] latest: 21133510, safe: 21133470, finalized: 21133438 ===========> gap1: 40, gap2: 32
[2024-11-06 22:53:30] latest: 21133511, safe: 21133470, finalized: 21133438 ===========> gap1: 41, gap2: 32
[2024-11-06 22:53:41] latest: 21133512, safe: 21133470, finalized: 21133438 ===========> gap1: 42, gap2: 32
[2024-11-06 22:53:52] latest: 21133513, safe: 21133470, finalized: 21133438 ===========> gap1: 43, gap2: 32
[2024-11-06 22:54:03] latest: 21133514, safe: 21133470, finalized: 21133438 ===========> gap1: 44, gap2: 32
[2024-11-06 22:54:14] latest: 21133515, safe: 21133470, finalized: 21133438 ===========> gap1: 45, gap2: 32
[2024-11-06 22:54:25] latest: 21133516, safe: 21133470, finalized: 21133438 ===========> gap1: 46, gap2: 32
[2024-11-06 22:54:35] latest: 21133516, safe: 21133470, finalized: 21133438 ===========> gap1: 46, gap2: 32
[2024-11-06 22:54:46] latest: 21133517, safe: 21133470, finalized: 21133438 ===========> gap1: 47, gap2: 32
[2024-11-06 22:54:57] latest: 21133518, safe: 21133470, finalized: 21133438 ===========> gap1: 48, gap2: 32
[2024-11-06 22:55:08] latest: 21133519, safe: 21133470, finalized: 21133438 ===========> gap1: 49, gap2: 32
[2024-11-06 22:55:19] latest: 21133520, safe: 21133470, finalized: 21133438 ===========> gap1: 50, gap2: 32
[2024-11-06 22:55:30] latest: 21133521, safe: 21133470, finalized: 21133438 ===========> gap1: 51, gap2: 32
[2024-11-06 22:55:41] latest: 21133522, safe: 21133470, finalized: 21133438 ===========> gap1: 52, gap2: 32
[2024-11-06 22:55:52] latest: 21133523, safe: 21133470, finalized: 21133438 ===========> gap1: 53, gap2: 32
[2024-11-06 22:56:02] latest: 21133524, safe: 21133502, finalized: 21133438 ===========> gap1: 22, gap2: 64
[2024-11-06 22:56:13] latest: 21133525, safe: 21133502, finalized: 21133438 ===========> gap1: 23, gap2: 64
[2024-11-06 22:56:24] latest: 21133525, safe: 21133502, finalized: 21133438 ===========> gap1: 23, gap2: 64
[2024-11-06 22:56:35] latest: 21133526, safe: 21133502, finalized: 21133438 ===========> gap1: 24, gap2: 64
[2024-11-06 22:56:46] latest: 21133527, safe: 21133502, finalized: 21133438 ===========> gap1: 25, gap2: 64
[2024-11-06 22:56:56] latest: 21133528, safe: 21133502, finalized: 21133438 ===========> gap1: 26, gap2: 64
[2024-11-06 22:57:07] latest: 21133529, safe: 21133502, finalized: 21133438 ===========> gap1: 27, gap2: 64
[2024-11-06 22:57:18] latest: 21133530, safe: 21133502, finalized: 21133438 ===========> gap1: 28, gap2: 64
[2024-11-06 22:57:29] latest: 21133531, safe: 21133502, finalized: 21133438 ===========> gap1: 29, gap2: 64
[2024-11-06 22:57:40] latest: 21133532, safe: 21133502, finalized: 21133438 ===========> gap1: 30, gap2: 64
[2024-11-06 22:57:51] latest: 21133533, safe: 21133502, finalized: 21133438 ===========> gap1: 31, gap2: 64
[2024-11-06 22:58:02] latest: 21133534, safe: 21133502, finalized: 21133438 ===========> gap1: 32, gap2: 64
[2024-11-06 22:58:12] latest: 21133534, safe: 21133502, finalized: 21133470 ===========> gap1: 32, gap2: 32
[2024-11-06 22:58:23] latest: 21133535, safe: 21133502, finalized: 21133470 ===========> gap1: 33, gap2: 32
[2024-11-06 22:58:34] latest: 21133536, safe: 21133502, finalized: 21133470 ===========> gap1: 34, gap2: 32
[2024-11-06 22:58:44] latest: 21133537, safe: 21133502, finalized: 21133470 ===========> gap1: 35, gap2: 32
[2024-11-06 22:58:55] latest: 21133538, safe: 21133502, finalized: 21133470 ===========> gap1: 36, gap2: 32
[2024-11-06 22:59:06] latest: 21133539, safe: 21133502, finalized: 21133470 ===========> gap1: 37, gap2: 32
[2024-11-06 22:59:17] latest: 21133540, safe: 21133502, finalized: 21133470 ===========> gap1: 38, gap2: 32
[2024-11-06 22:59:27] latest: 21133541, safe: 21133502, finalized: 21133470 ===========> gap1: 39, gap2: 32
[2024-11-06 22:59:38] latest: 21133542, safe: 21133502, finalized: 21133470 ===========> gap1: 40, gap2: 32
[2024-11-06 22:59:49] latest: 21133542, safe: 21133502, finalized: 21133470 ===========> gap1: 40, gap2: 32
[2024-11-06 23:00:00] latest: 21133543, safe: 21133502, finalized: 21133470 ===========> gap1: 41, gap2: 32
[2024-11-06 23:00:10] latest: 21133544, safe: 21133502, finalized: 21133470 ===========> gap1: 42, gap2: 32
[2024-11-06 23:00:21] latest: 21133545, safe: 21133502, finalized: 21133470 ===========> gap1: 43, gap2: 32
[2024-11-06 23:00:32] latest: 21133546, safe: 21133502, finalized: 21133470 ===========> gap1: 44, gap2: 32
[2024-11-06 23:00:42] latest: 21133547, safe: 21133502, finalized: 21133470 ===========> gap1: 45, gap2: 32
[2024-11-06 23:00:53] latest: 21133548, safe: 21133502, finalized: 21133470 ===========> gap1: 46, gap2: 32
[2024-11-06 23:01:04] latest: 21133549, safe: 21133502, finalized: 21133470 ===========> gap1: 47, gap2: 32

ws4charlie avatar Nov 07 '24 17:11 ws4charlie

To get a sense of how deterministic/consistent the safe block number is, some tests had been performed on four different node providers: Alchemy(ACMY), QuickNode(QUIK), Ankr(ANKR), AllThatNode(ATND).

The test result file:

result_four_node_providers.md

The test query: image

What was found:

  1. The Alchemy and QuickNode endpoints fetch safe block number without issue, while the Ankr and AllThatNode(this node is now being used in mainnet) endpoints could NOT fetch safe block number very well. It looks to me that the Ethereum's safe tag is not widely adopted across node providers ATM.

  2. The safe block number returned by the Alchemy and QuickNode sometimes diverged. For example, when Alchemy says the safe block is 96 and QuickNode says 64, the zetaclient working with a QuickNode might post its vote 32 blocks later than the zetaclient working with an Alchemy node.

[ACMY][2024-11-07 11:04:57] latest: 21137144, safe: 21137094, finalized: 21137062 ===========> gap1: 50, gap2: 32 [QUIK][2024-11-07 11:04:57] latest: 21137144, safe: 21137094, finalized: 21137062 ===========> gap1: 50, gap2: 32 [ANKR][2024-11-07 11:04:58] latest: 21137144, safe: 21137144, finalized: 21137062 ===========> gap1: 0, gap2: 82 [ATND][2024-11-07 11:04:59] latest: 21137144, safe: 21137144, finalized: 21137062 ===========> gap1: 0, gap2: 82

[ACMY][2024-11-07 11:05:10] latest: 21137145, safe: 21137094, finalized: 21137062 ===========> gap1: 51, gap2: 32 [QUIK][2024-11-07 11:05:10] latest: 21137145, safe: 21137094, finalized: 21137062 ===========> gap1: 51, gap2: 32 [ANKR][2024-11-07 11:05:11] latest: 21137145, safe: 21137145, finalized: 21137062 ===========> gap1: 0, gap2: 83 [ATND][2024-11-07 11:05:12] latest: 21137145, safe: 21137145, finalized: 21137062 ===========> gap1: 0, gap2: 83

[ACMY][2024-11-07 11:05:23] latest: 21137146, safe: 21137094, finalized: 21137062 ===========> gap1: 52, gap2: 32 [QUIK][2024-11-07 11:05:23] latest: 21137146, safe: 21137094, finalized: 21137062 ===========> gap1: 52, gap2: 32 [ANKR][2024-11-07 11:05:24] latest: 21137146, safe: 21137146, finalized: 21137062 ===========> gap1: 0, gap2: 84 [ATND][2024-11-07 11:05:25] latest: 21137147, safe: 21137146, finalized: 21137062 ===========> gap1: 1, gap2: 84

[ACMY][2024-11-07 11:05:36] latest: 21137147, safe: 21137094, finalized: 21137062 ===========> gap1: 53, gap2: 32 [QUIK][2024-11-07 11:05:36] latest: 21137147, safe: 21137094, finalized: 21137062 ===========> gap1: 53, gap2: 32 [ANKR][2024-11-07 11:05:37] latest: 21137147, safe: 21137147, finalized: 21137062 ===========> gap1: 0, gap2: 85 [ATND][2024-11-07 11:05:38] latest: 21137148, safe: 21137148, finalized: 21137062 ===========> gap1: 0, gap2: 86

[ACMY][2024-11-07 11:05:49] latest: 21137149, safe: 21137126, finalized: 21137062 ===========> gap1: 23, gap2: 64 [QUIK][2024-11-07 11:05:49] latest: 21137148, safe: 21137094, finalized: 21137062 ===========> gap1: 54, gap2: 32 [ANKR][2024-11-07 11:05:50] latest: 21137148, safe: 21137148, finalized: 21137062 ===========> gap1: 0, gap2: 86 [ATND][2024-11-07 11:05:51] latest: 21137149, safe: 21137149, finalized: 21137062 ===========> gap1: 0, gap2: 87

[ACMY][2024-11-07 11:06:02] latest: 21137150, safe: 21137126, finalized: 21137062 ===========> gap1: 24, gap2: 64 [QUIK][2024-11-07 11:06:02] latest: 21137150, safe: 21137094, finalized: 21137062 ===========> gap1: 56, gap2: 32 [ANKR][2024-11-07 11:06:04] latest: 21137149, safe: 21137150, finalized: 21137062 ===========> gap1: 18446744073709551615, gap2: 88 [ATND][2024-11-07 11:06:05] latest: 21137150, safe: 21137150, finalized: 21137062 ===========> gap1: 0, gap2: 88

[ACMY][2024-11-07 11:06:15] latest: 21137151, safe: 21137126, finalized: 21137062 ===========> gap1: 25, gap2: 64 [QUIK][2024-11-07 11:06:16] latest: 21137151, safe: 21137094, finalized: 21137062 ===========> gap1: 57, gap2: 32 [ANKR][2024-11-07 11:06:18] latest: 21137150, safe: 21137094, finalized: 21137062 ===========> gap1: 56, gap2: 32 [ATND][2024-11-07 11:06:19] latest: 21137151, safe: 21137151, finalized: 21137062 ===========> gap1: 0, gap2: 89

[ACMY][2024-11-07 11:06:30] latest: 21137152, safe: 21137126, finalized: 21137062 ===========> gap1: 26, gap2: 64 [QUIK][2024-11-07 11:06:30] latest: 21137152, safe: 21137094, finalized: 21137062 ===========> gap1: 58, gap2: 32 [ANKR][2024-11-07 11:06:32] latest: 21137152, safe: 21137094, finalized: 21137062 ===========> gap1: 58, gap2: 32 [ATND][2024-11-07 11:06:33] latest: 21137152, safe: 21137152, finalized: 21137062 ===========> gap1: 0, gap2: 90

[ACMY][2024-11-07 11:06:44] latest: 21137153, safe: 21137126, finalized: 21137062 ===========> gap1: 27, gap2: 64 [QUIK][2024-11-07 11:06:44] latest: 21137153, safe: 21137094, finalized: 21137062 ===========> gap1: 59, gap2: 32 [ANKR][2024-11-07 11:06:45] latest: 21137153, safe: 21137153, finalized: 21137062 ===========> gap1: 0, gap2: 91 [ATND][2024-11-07 11:06:46] latest: 21137153, safe: 21137153, finalized: 21137062 ===========> gap1: 0, gap2: 91

[ACMY][2024-11-07 11:06:57] latest: 21137154, safe: 21137126, finalized: 21137062 ===========> gap1: 28, gap2: 64 [QUIK][2024-11-07 11:06:57] latest: 21137154, safe: 21137094, finalized: 21137062 ===========> gap1: 60, gap2: 32 [ANKR][2024-11-07 11:06:58] latest: 21137154, safe: 21137154, finalized: 21137062 ===========> gap1: 0, gap2: 92 [ATND][2024-11-07 11:06:59] latest: 21137154, safe: 21137154, finalized: 21137062 ===========> gap1: 0, gap2: 92

[ACMY][2024-11-07 11:07:10] latest: 21137155, safe: 21137126, finalized: 21137062 ===========> gap1: 29, gap2: 64 [QUIK][2024-11-07 11:07:10] latest: 21137155, safe: 21137094, finalized: 21137062 ===========> gap1: 61, gap2: 32 [ANKR][2024-11-07 11:07:11] latest: 21137155, safe: 21137155, finalized: 21137062 ===========> gap1: 0, gap2: 93 [ATND][2024-11-07 11:07:12] latest: 21137155, safe: 21137155, finalized: 21137062 ===========> gap1: 0, gap2: 93

[ACMY][2024-11-07 11:07:23] latest: 21137156, safe: 21137126, finalized: 21137062 ===========> gap1: 30, gap2: 64 [QUIK][2024-11-07 11:07:23] latest: 21137156, safe: 21137094, finalized: 21137062 ===========> gap1: 62, gap2: 32 [ANKR][2024-11-07 11:07:25] latest: 21137155, safe: 21137156, finalized: 21137062 ===========> gap1: 18446744073709551615, gap2: 94 [ATND][2024-11-07 11:07:26] latest: 21137157, safe: 21137157, finalized: 21137062 ===========> gap1: 0, gap2: 95

[ACMY][2024-11-07 11:07:36] latest: 21137157, safe: 21137126, finalized: 21137062 ===========> gap1: 31, gap2: 64 [QUIK][2024-11-07 11:07:36] latest: 21137157, safe: 21137126, finalized: 21137094 ===========> gap1: 31, gap2: 32 [ANKR][2024-11-07 11:07:38] latest: 21137157, safe: 21137157, finalized: 21137062 ===========> gap1: 0, gap2: 95 [ATND][2024-11-07 11:07:39] latest: 21137157, safe: 21137157, finalized: 21137062 ===========> gap1: 0, gap2: 95

[ACMY][2024-11-07 11:07:49] latest: 21137159, safe: 21137126, finalized: 21137094 ===========> gap1: 33, gap2: 32 [QUIK][2024-11-07 11:07:50] latest: 21137159, safe: 21137126, finalized: 21137094 ===========> gap1: 33, gap2: 32 [ANKR][2024-11-07 11:07:51] latest: 21137158, safe: 21137158, finalized: 21137094 ===========> gap1: 0, gap2: 64 [ATND][2024-11-07 11:07:52] latest: 21137159, safe: 21137159, finalized: 21137094 ===========> gap1: 0, gap2: 65

[ACMY][2024-11-07 11:08:03] latest: 21137160, safe: 21137126, finalized: 21137094 ===========> gap1: 34, gap2: 32 [QUIK][2024-11-07 11:08:03] latest: 21137160, safe: 21137126, finalized: 21137094 ===========> gap1: 34, gap2: 32 [ANKR][2024-11-07 11:08:04] latest: 21137159, safe: 21137160, finalized: 21137094 ===========> gap1: 18446744073709551615, gap2: 66 [ATND][2024-11-07 11:08:05] latest: 21137160, safe: 21137160, finalized: 21137094 ===========> gap1: 0, gap2: 66

[ACMY][2024-11-07 11:08:16] latest: 21137161, safe: 21137126, finalized: 21137094 ===========> gap1: 35, gap2: 32 [QUIK][2024-11-07 11:08:16] latest: 21137161, safe: 21137126, finalized: 21137094 ===========> gap1: 35, gap2: 32 [ANKR][2024-11-07 11:08:18] latest: 21137161, safe: 21137160, finalized: 21137094 ===========> gap1: 1, gap2: 66 [ATND][2024-11-07 11:08:19] latest: 21137161, safe: 21137161, finalized: 21137094 ===========> gap1: 0, gap2: 67

[ACMY][2024-11-07 11:08:30] latest: 21137162, safe: 21137126, finalized: 21137094 ===========> gap1: 36, gap2: 32 [QUIK][2024-11-07 11:08:30] latest: 21137162, safe: 21137126, finalized: 21137094 ===========> gap1: 36, gap2: 32 [ANKR][2024-11-07 11:08:32] latest: 21137162, safe: 21137162, finalized: 21137094 ===========> gap1: 0, gap2: 68 [ATND][2024-11-07 11:08:33] latest: 21137162, safe: 21137162, finalized: 21137094 ===========> gap1: 0, gap2: 68

ws4charlie avatar Nov 07 '24 18:11 ws4charlie

It looks to me that the Ethereum's safe tag is not widely adopted across node providers ATM.

We can enforce people use RPCs where safe is supported but would need some type of self-test at startup so any zetaclient attempting to use an RPC that doesn't support all required methods gets a clear error message at launch.

For the gap values and based on the examples above are you saying at best the wait time would be 32 blocks but at worst we'd have to wait for 93 blocks?

CharlieMc0 avatar Nov 07 '24 20:11 CharlieMc0

For the gap values and based on the examples above are you saying at best the wait time would be 32 blocks but at worst we'd have to wait for 93 blocks?

The wait time (in blocks) is the value of gap1 which approximately ranges from 22 to 54 (observed on Alchemy node)

ws4charlie avatar Nov 12 '24 18:11 ws4charlie

We'll put this task on hold for the time being.

ws4charlie avatar Nov 18 '24 15:11 ws4charlie