交易池包含本地節點已接收並驗證的所有廣播到網絡的交易,瞭解交易池在區塊打包過程中的作用。

原文標題:《交易池|Substrate 文檔》
撰文:Substrate
翻譯:PolkaWorld

交易池包含本地節點已接收並驗證的所有廣播到網絡的交易(已簽名和未簽名的)。

有效性

交易池檢查交易有效性。請注意,交易的有效性不是硬連接到交易池中,而是由 runtime 定義的。有效性檢查的示例是:

  • 檢查交易索引(nonce)是否正確。
  • 檢查帳戶是否有足夠的資金來支付相關費用。
  • 檢查簽名是否有效。

交易池還定期檢查池中現有交易的有效性。如果發現無效或過期的非永久交易,則將從池中刪除該交易。

排序

如果交易有效,則交易隊列將交易分爲兩類:

  • Ready Queue (就緒隊列)—— 包括可以包含在新的未決區塊中的交易。對於使用 FRAME 構建的 runtime,交易必須遵循就緒隊列中的確切順序。
  • Future Queue (將來隊列)—— 包含將來可能變得有效的交易。例如,某筆交易的隨機數可能對於其帳戶而言過高。該交易將在將來隊列中等待,直到之前的交易包含在鏈中爲止。

注意:可以設計自定義 runtime 來刪除嚴格的交易排序要求。這將允許整個節點在交易傳播和區塊包含方面實施不同的策略。

交易依賴

ValidTransaction 結構定義了 require 並提供了用於構建交易依賴關係圖的參數。該依賴關係圖與 priority (下面會討論到)一起,能讓交易池產生有效的交易線性排列。

對於使用 FRAME 構建的 runtime,節點使用基於帳戶的系統對交易進行排序。每個已簽名的交易都需要包含一個隨機數,每進行一次新交易,該隨機數將增加 1。例如,來自新帳戶的第一筆交易的 nonce = 0 ,第二筆交易的 nonce = 1

至少,如果 nonce> 1,則 FRAME 交易具有提供標籤的 encode (發送者++隨機數)和需要 require 編碼的標籤(發送者++(nonce -1)),如果 nonce = 0,則交易不需要任何內容。

至少,FRAME 交易具有一個 encode(sender ++ nonce)provides 標籤,和一個 encode(sender ++ (nonce -1)) if nonce > 1requires 標籤。如果 nonce=0 則交易不需要任何內容。結果是,來自單個發件人的所有交易將形成其被包括的順序。

Substrate 支持多個 providesrequires 標籤,因此自定義 runtime 可以創建備用依賴項(排序)方案。

交易優先級

ValidTransaction 結構中的交易 priority (優先級)確定就緒隊列中交易的順序。如果節點是下一個區塊生成者,則它將在下一個區塊中按從高到低的優先級對交易進行排序,直到達到該區塊的重量(weight)或長度限制爲止。

priority 定義在一個交易解鎖多個相關交易的情況下關係圖的線性順序。例如,如果我們有兩個(或多個)滿足其依賴關係的交易,那麼我們將使用優先級爲它們選擇順序。

對於使用 FRAME 構建的 runtime,priority 定義爲交易要支付的費用。例如:

  • 如果我們收到來自_不同_發件人的 2 筆交易 (with nonce=0),我們將使用 priority 來確定哪個交易更重要,並首先將其包含在該區塊中。
  • 如果我們從_同一_發件人處收到具有相同隨機數的 2 筆交易,則鏈上只能包含一項交易。我們使用 priority 選擇較高 fee(手續費)的交易來存儲在交易池中。

請注意,交易池不知道費用、帳戶或簽名 —— 它僅處理交易的 priorityrequires、和 provides 參數的抽象概念,要求並提供參數。所有其他詳細信息由 runtime 通過 validate_transaction 函數定義。

交易的生命週期

交易可以遵循兩種路徑:

由我們的節點生產的區塊

  1. 我們的節點偵聽網絡上的交易。
  2. 每筆交易都會經過驗證,並將有效交易放置在交易池中。
  3. 交易池負責對交易進行排序,並返回準備好包含在該區塊中的交易。準備隊列中的交易用於構造區塊。
  4. 執行交易並將狀態更改存儲在本地內存中。來自就緒隊列的交易也將通過網絡傳播(即八卦)給對等方。由於隊列前面的交易具有較高的優先級,並且更有可能在下一個區塊中成功執行,因此我們將精確的排序用作未決區塊。
  5. 構造好的區塊將發佈到網絡。網絡上的所有其他節點都接收並執行該區塊。

請注意,在編寫塊時,不會從就緒隊列中刪除交易,而僅在導入區塊時纔將其刪除。這是由於可能新近編寫的區塊可能無法進入規範鏈。

從網絡中接收到的區塊

區塊被執行後,整個區塊要麼成功要麼失敗。

交易有效性

validate_transaction 是從 runtime 中調用的 ,它檢查有效簽名和隨機數(或 UTXO 鏈的輸出)並返回 Resultvalidate_transaction 孤立地檢查交易,因此它不會捕獲錯誤,例如同一輸出被使用了兩次。

儘管有可能,但 validate_transaction 不會檢查對 pallet 的調用是否會成功。它是潛在的 DoS 向量,因爲網絡中的所有交易都將傳遞到 validate_transaction 中。

validate_transaction 函數應專注於爲池提供必要的信息,以對交易進行排序和排優先級,並迅速拒絕所有無效或過時的交易。該函數將被頻繁調用,對於同一交易可能多次調用。validate_transaction 也有可能使依賴交易失敗,如果該交易以正確的順序執行時將通過 execute_block 的話。

瞭解更多

來源鏈接:substrate.dev