Hyperledger Fabric 交易過程中讀寫集語義

Hyperledger Fabric 交易過程中讀寫集語義

https://hyperledger-fabric.readthedocs.io/zh_CN/latest/readwrite.html

交易模擬和讀寫集

背書節點 在模擬交易期間,會爲交易準備一個讀寫集。讀集 包含了模擬期間交易讀取的鍵和鍵的版本的列表。寫集 包含了交易寫入鍵(可以與讀取集中的鍵重疊)的新值。如果交易是刪除一個鍵,該鍵就會被增加一個刪除標識(在新值的位置)。

如果交易多次向同一個鍵寫入數據,只有最後寫入的數據會記錄下來。同樣,如果交易讀取一個鍵的值,就會返回這個鍵的已提交狀態的值,即使讀取之前在同一個交易中更新了鍵值。換句話說,不支持“讀你所寫”的語義。

就像前面所說的,鍵的版本只記錄在讀集中;寫集只包含鍵和交易設置的鍵的最新值。

版本的實現有很多種。版本設計的基本需求是,鍵不能有重複的版本號。例如單調遞增的數字。**在目前的實現中,我們使用交易所在的區塊高度來作爲交易中所有修改的鍵的版本號。**這樣區塊中交易的高度通過一個元組來表示(txNumber 是區塊中交易的高度)。這種方式比遞增的數字有更多好處,主要有,它可以讓其他組件比如狀態數據庫、交易模擬和驗證有更多的設計選擇。

下邊是爲模擬一個交易所準備的讀寫集示例。爲了簡化說明,我們使用了一個遞增的數字來表示版本。

<TxReadWriteSet>
  <NsReadWriteSet name="chaincode1">
    <read-set>
      <read key="K1", version="1">
      <read key="K2", version="1">
    </read-set>
    <write-set>
      <write key="K1", value="V1">
      <write key="K3", value="V2">
      <write key="K4", isDelete="true">
    </write-set>
  </NsReadWriteSet>
<TxReadWriteSet>

另外,如果交易在模擬中執行的是一個範圍查詢,範圍查詢和它的結果都會被記錄在讀寫集的 查詢信息(query-info) 中。


交易驗證和使用讀寫集更新世界狀態

提交節點 使用讀寫集中的讀集來驗證交易,使用寫集來更新受影響的鍵的版本和值。

在驗證階段,如果讀集中鍵的版本和世界狀態中鍵的版本一致就認爲該交易是 有效的 ,這裏我們假設所有之前 有效 的交易(同一個區塊中該交易之前的交易)都會被提交(提交狀態)。當讀寫集中包含一個或多個查詢信息(query-info)時,需要執行額外的驗證。

這種額外的驗證需要確保在根據查詢信息獲得的結果的超集(多個範圍的合併)中沒有插入、刪除或者更新鍵。 換句話說,如果我們在模擬執行交易期間重新執行任何一個範圍,我們應該得到相同的結果。這個檢查保證瞭如果交易在提交期間出了虛項,該交易就會被標記爲無效的。這種檢查只存在於範圍查詢中(例如鏈碼中的 GetStateByRange 方法)其他查詢中沒有實現(例如鏈碼中的 GetQueryResult 方法)。其他查詢仍會存在出現虛項的風險,我們應該只在不向排序服務提交的只讀交易中使用查詢,除非應用程序能保證模擬的結果和驗證/提交時的結果一致。

如果交易通過了有效性驗證,提交節點就會根據寫集更新世界狀態。在更新階段,會根據寫集更新世界狀態中對應的鍵的值。然後,世界狀態中鍵的版本會更新到最新的版本。


模擬和驗證示例

本章節通過示例場景幫助你理解讀寫集語義。在本例中,k 表示鍵,在世界狀態中表示一個元組 (k,ver,val)ver 是鍵 k 的版本, val 是值。

現在假設有五個交易 T1,T2,T3,T4 和 T5 ,所有的交易模擬都基於同一個世界狀態的快照。下邊的步驟展示了世界狀態和模擬這些交易時的讀寫活動。

World state: (k1,1,v1), (k2,1,v2), (k3,1,v3), (k4,1,v4), (k5,1,v5)
T1 -> Write(k1, v1'), Write(k2, v2')
T2 -> Read(k1), Write(k3, v3')
T3 -> Write(k2, v2'')
T4 -> Write(k2, v2'''), read(k2)
T5 -> Write(k6, v6'), read(k5)

現在,假設這些交易的順序是從 T1 到 T5(他們可以在同一個區塊,也可以在不同區塊)

  1. T1 通過了驗證,因爲它沒有執行任何讀操作。然後世界狀態中的鍵 k1k2 被更新爲 (k1,2,v1'), (k2,2,v2')

  2. T2 沒有通過驗證,因爲它讀了鍵 k1,但是交易 T1 改變了 k1

  3. T3 通過了驗證,因爲它沒有執行任何讀操作。然後世界狀態中的鍵 k2 被更新爲 (k2,3,v2'')

  4. T4 沒有通過驗證,因爲它讀了鍵 k2,但是交易 T1 改變了 k2

  5. T5 通過了驗證,因爲它讀了鍵 k5,但是 k5 沒有被其他任何交易改變

注意:不支持有多個讀寫集的交易。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章