通過訂閱“newHeads”確保正確的塊順序
我在通過本地節點上的 WebSocket 連接處理新塊時遇到問題。有時我會收到多個具有相同
blockNumber
但不同blockHash
es 的事件。我從一些 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
等於hash
’7665192
sparentHash
,我會將其作為規範塊。然而,這只是引入了更多的問題:
如果我連續多次收到重複的 blockNumbers 怎麼辦?
- 例如
7665191, 7665191, 7665192, 7665192, 7665193, 7665193 ...
如果 parentHash 不是以前的副本之一怎麼辦?
- 例如
parentHash
7665192 不等於任何雜湊值7665191
重申我的問題:什麼是推薦的方法來確保我只儲存你可以在 bscscan 上找到的塊中的真實交易。
基本上,您想要的是確認給定的塊已包含在規範鏈中。我假設您不需要非常高的安全性,因為根據您的範例,僅確認一個塊就足以滿足您的需要。
我認為擴展您的第二個選項可能是一個解決方案。
備選方案 1 - 使用父雜湊驗證雙塊
假設您收到了兩個編號為 1000 的塊。
- 等到您收到一個編號為 +1 的區塊,而不是您要確認的區塊(區塊編號 1001)。
- 檢查塊 1001 的 parentHash 並查看它是否與任何編號為 1000 的塊的雜湊匹配。如果匹配,則知道這是要包含的塊。
- 如果您根本沒有匹配項(不確定是否可以執行完整節點),那麼您應該呼叫以獲取雜湊值等於塊 1001 的 parentHash 的塊。使用 web3js,您將使用
web3.eth.getBlock(parentHashOfBlock1001)
. 然後,您將擁有正確的塊號 1000。備選方案 2 - 僅在確認時包含
另一種解決方案是在包含前一個塊的交易之前總是等待一個塊。
- 當你收到一個區塊頭時,不要在你的數據庫中包含它的交易。相反,獲取與 parentHash 對應的塊
web3.eth.getBlock(parentHashOfCurrentBlock)
。- 檢查您是否已在數據庫中包含該父塊。當您兩次收到相同的塊號時,可能會發生這種情況(即使其中一個無效,兩個塊也應具有相同的父級)。如果不包括:
- 在您的數據庫中包含該父塊的事務。
你總是會遲到一個街區,但它應該能在大多數情況下解決你的問題。
備選方案 3 - 等待…然後按編號獲取塊
您的節點應負責刪除無效塊。如果您等待一定數量的塊,然後按編號獲取過去的塊,您應該只收到有效的塊。