按這五個標準索引記憶體池的目的是什麼?
在txmempool.h的比特幣原始碼中,一條評論說未確認的交易由五個標準索引:
* mapTx is a boost::multi_index that sorts the mempool on 5 criteria: * - transaction hash (txid) * - witness-transaction hash (wtxid) * - descendant feerate [we use max(feerate of tx, feerate of tx with all descendants)] * - time in mempool * - ancestor feerate [we use min(feerate of tx, feerate of tx with all unconfirmed ancestors)]
我可以理解為什麼我們需要在交易進入記憶體池時對其進行索引。但我無法理解需要根據 txid 和 wtxid 對它們進行排序(雖然它們是雜湊輸出,所以它們就像隨機數,為什麼還要麻煩索引它們?)。而且我也不明白
descendant feerate
and的意思ancestor feerate
。我可以推斷出一個簡單的概念是礦工願意將具有更高費用率的交易放在他們的區塊中,所以簡單地排序fee rate
對我來說是有意義的,但為什麼要基於交易的父母和孩子進行排序呢?
mempool 是全節點的短期記憶體。我們使用其內容,例如:
- 與同行交換資訊
- 建構塊模板
- 估計費率
- 跟踪我們錢包的待付款
索引允許我們根據索引的每個鍵查找完整的事務對象。
txid
/wtxid
例如,
txid
andwtxid
出現在事務中繼的上下文中,作為完整事務對象的速記標識符。我們告訴對等點我們有一個僅使用 txid 的新 tx 列表,他們通過列出相應的txid
/來請求其中的一個子集來響應wtxid
。我們使用這個鍵來查找對象並滿足他們的請求。txid
在每個“緊湊塊中繼”獲得一個新塊後,我們還使用來重新組裝塊。txid
同樣,當新交易花費未確認的輸入時,我們可以根據該新交易輸入中引用的內容查找父交易。通常,我們會在txid
任何時候引用單個交易。
time in mempool
當我們建立新的交易時,我們需要估計在預期的時間範圍內能夠讓我們得到確認的費率。我們的估計基於跟踪交易在我們的記憶體池中被包含在一個塊中之前的時間長度。雖然未經確認的交易無限期地保持有效(或直到輸入被花費在另一筆交易中),但我們希望允許使用者輕鬆取代不成功的交易嘗試。完整節點在其記憶體池中停留 14 天后會丟棄交易。此外,政策只保留一組衝突事務中的第一個,除非第一個事務發出可替換性信號並且後續事務滿足替換前一個事務的要求。無論哪種方式,我們有時都希望根據交易在記憶體池中的時間來查找交易,
ancestor feerate
祖先集由事務及其所有祖先組成。祖先是觀察到的交易在拓撲上所依賴的交易:一個交易在其所有父代都被包含之前不能包含在一個塊中。如果 tx_C 花費了 tx_B 的輸出,而 tx_B 花費了 tx_A 的輸出,則 tx_A 和 tx_B 是 tx_C 的祖先,並且 tx_C 的祖先集是 {tx_A, tx_B, tx_C}。交易的祖先費率是指
Σ(fees)/Σ(vsize)
它的祖先集。當我們建構區塊模板時,我們將所有交易按其祖先費率排序,並選擇具有最高祖先費率的祖先集到塊模板。選擇一個祖先集後,每個相關交易的祖先集都會更新,我們選擇新的最高的。重複直到塊已滿或沒有任何東西可供選擇。
這種方法確保了交易在區塊中以拓撲順序出現,正確地優先考慮孩子支付父母的情況,並貪婪地最大化區塊模板中收取的交易費用。如果我們只看交易的費率,我們可能會錯過交易依賴於沉重的低費用交易,或者交易被高費率的孩子撞到。
descendant feerate
後代ferate是祖先ferate的對應物。它是
Σ(fees)/Σ(size)
給定事務及其所有後代的。例如,tx_A 有兩個子交易 tx_B 和 tx_C。如果 tx_B 的費用率低於 tx_A,但 tx_C 的費用率高於 tx_A,則 tx_C 的後代費用率最高,tx_B 的費用率最低,tx_A 介於兩者之間。記憶體池大小是有限的。有時,當有大量區塊空間需求時,送出到網路的交易數量超過了節點記憶體池的容量。屆時,記憶體池將丟棄最不可能包含在區塊中的交易。雖然祖先的ferate告訴我們什麼是最有價值的,但後代的ferate告訴我們哪些事務發出最低優先級的信號。我們首先丟棄具有最低後代費率的交易。如果我們只看交易本身的費率,我們可能會錯過低費率交易是 CPFP 情況下的父交易。在上面的例子中,我們將首先丟棄 tx_B,因為它的ferate 最低,然後丟棄 tx_A(其後代的ferate 高於它自己的ferate,但低於 tx_C 的)。驅逐 tx_A 也會驅逐 tx_C,因為它不能包含在一個塊中,它的父級創建它花費的輸出。