Transactions

通過訂閱“newHeads”確保正確的塊順序

  • May 27, 2021

我在通過本地節點上的 WebSocket 連接處理新塊時遇到問題。有時我會收到多個具有相同blockNumber但不同blockHashes 的事件。

我從一些 StackExchange 執行緒中了解到,其中一個塊不是規範鏈的一部分。但是,我的問題是:如何確定其中哪一個在規範鏈上?"newHeads"當我打開 WebSocket 連接並在訂閱後接收新塊以確保該塊是規範的時,我需要採取的確切步驟是什麼?

例子

這是一個應用程序的縮短日誌,它將來自最新塊的一些事務儲存到 SQL 數據庫中。

Added block #7665190 | hash 0x9ba66766f3835d5be9191e0ad7c79b741707e78dcf1f2a8898b7a7c2141d357c
Added block #7665191 | hash 0xe550f98974b4b02fff709842f670e682fc90403ead36d6258927b38cd45a56bc
Added block #7665191 | hash 0x068f5648b0509303640a1aa9c10764c89f33482148fde4ef94ce0ab4f21c25d1
Added block #7665192 | hash 0x36c2f7e9a4542a2311c91e8cd1560994ca14841086be86d0f6dbb1be9eae9d46
Added block #7665193 | hash 0x0cd7d6e0dac1c3288e574b454d7e4dee9123c4e1e94b6e87307aae32e812f1f1

getBlockByNumber在接收到足以確定這確實是我想在我的數據庫中儲存事務的“正確”塊後,是否使用RPC 呼叫?

我不這麼認為,因為如果我getBlockByNumber第一次使用,7665191我仍然會收到該塊中的交易。然後在後續使用它之後,7665191我會收到另一組交易,其中可能包括一堆以前的交易。因此在我的 SQL 數據庫中的規範事務雜湊/地址之間引入了冗餘和可能的不匹配。

我能想到的第二種選擇是等到我收到一個 blockNumber 之後(例如7665192在這種情況下),然後檢查它的parentHash. 如果 ’s 之一7665191等於hash7665192s parentHash,我會將其作為規範塊。然而,這只是引入了更多的問題:

  • 如果我連續多次收到重複的 blockNumbers 怎麼辦?

    • 例如7665191, 7665191, 7665192, 7665192, 7665193, 7665193 ...
  • 如果 parentHash 不是以前的副本之一怎麼辦?

    • 例如parentHash7665192 不等於任何雜湊值7665191

重申我的問題:什麼是推薦的方法來確保我只儲存你可以在 bscscan 上找到的塊中的真實交易。

基本上,您想要的是確認給定的塊已包含在規範鏈中。我假設您不需要非常高的安全性,因為根據您的範例,僅確認一個塊就足以滿足您的需要。

我認為擴展您的第二個選項可能是一個解決方案。

備選方案 1 - 使用父雜湊驗證雙塊

假設您收到了兩個編號為 1000 的塊。

  1. 等到您收到一個編號為 +1 的區塊,而不是您要確認的區塊(區塊編號 1001)。
  2. 檢查塊 1001 的 parentHash 並查看它是否與任何編號為 1000 的塊的雜湊匹配。如果匹配,則知道這是要包含的塊。
  3. 如果您根本沒有匹配項(不確定是否可以執行完整節點),那麼您應該呼叫以獲取雜湊值等於塊 1001 的 parentHash 的塊。使用 web3js,您將使用web3.eth.getBlock(parentHashOfBlock1001). 然後,您將擁有正確的塊號 1000。

備選方案 2 - 僅在確認時包含

另一種解決方案是在包含前一個塊的交易之前總是等待一個塊。

  1. 當你收到一個區塊頭時,不要在你的數據庫中包含它的交易。相反,獲取與 parentHash 對應的塊web3.eth.getBlock(parentHashOfCurrentBlock)
  2. 檢查您是否已在數據庫中包含該父塊。當您兩次收到相同的塊號時,可能會發生這種情況(即使其中一個無效,兩個塊也應具有相同的父級)。如果不包括:
  3. 在您的數據庫中包含該父塊的事務。

你總是會遲到一個街區,但它應該能在大多數情況下解決你的問題。

備選方案 3 - 等待…然後按編號獲取塊

您的節點應負責刪除無效塊。如果您等待一定數量的塊,然後按編號獲取過去的塊,您應該只收到有效的塊。

引用自:https://ethereum.stackexchange.com/questions/99514