Read-Write set semantics(讀寫集)函數
本文討論了關於讀寫集當前實現的細節。區塊鏈
Transaction simulation and read-write set(事務模擬和讀寫集)spa
客戶端提交事務到peer,peer會執行背書驗證並模擬該事務的請求結果,爲該事務的請求準備一個讀寫集。讀集包含了該事務在讀取本地帳本時的一列事務版本信息及該信息對應的的一列惟一鍵,寫集包含了一個惟一鍵(可能也容許與讀集中的鍵重複)列表和事務寫入的最新值。若是事務的執行是刪除操做,那麼將爲這一列惟一鍵設置一個delete標記(在新值的位置)。設計
此外,若是事務爲鍵屢次寫入一個值,則只保留最後一個寫入值。另外,即便在事務讀取結果發出以前更新了鍵值,也會返回事務讀取已提交狀態的值。換句話說,必須保證讀寫一致性。版本控制
正如上面提到的,鍵的版本只在讀取集中記錄,而寫集僅包含由事務設置的一列唯一鍵和它們的最新值。code
能夠有各類各樣的執行版本的方案。版本控制方案的最低要求是爲給定的鍵生成不重複的標識符。例如,使用單調遞增的版本能夠採用一個這樣的方案。在當前的實現中,咱們使用一個基於區塊鏈頂點的版本控制方案,在這個方案中,提交事務的頂點被用做事務修改後的全部鍵的最新版本,事務的頂點由一個元組表示(txNumber是該塊內事務的頂點)。該方案與增量編號方案相比有許多優勢—主要是它支持其餘組件,如statedb、事務模擬和驗證,以實現有效的設計選擇。blog
下面是模擬假想事務的一個示例讀寫集的例子。爲了簡單起見,咱們使用增量數字表示版本。排序
<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>
此外,若是事務在模擬期間執行範圍查詢,那麼範圍查詢及其結果將被添加到讀寫集做爲查詢信息。事務
提交者使用讀-寫集的讀集部分來檢查事務的有效性,並使用讀寫集的寫集部分更新受影響的鍵的版本和值。it
在驗證階段,若是在事務讀集中每個key的版本都可以與world state(假定以前全部的事務都是有效的,包括以前在同一區塊中的已經被提交的事務)中的key版本一致,那麼該條事務則被認爲是有效的。若是讀寫集還包含一個或多個查詢信息,則須要執行額外的驗證。
這些額外的驗證須要確保在本次事務查詢信息返回結果的範圍內的key沒有被插入/刪除/更新過,換句話說,若是咱們在對提交狀態的驗證過程當中從新執行任何一個範圍查詢(在模擬期間執行的事務),那麼它應該會產生與在模擬時所觀察到的結果相同的結果。此檢查確保若是事務在提交期間觀察到虛項,則該事務應被標記爲無效。注意,這個虛項保護僅限於範圍查詢(例如:在chaincode中的GetStateByRange函數)而且尚未爲其餘查詢(例如:在chaincode中的GetQueryResult函數)實現。其餘查詢有可能出現虛項,所以只能在沒有提交到排序的只讀事務中使用,除非應用程序可以保證模擬和驗證/提交時間之間的結果集的穩定性。
若是一個事務經過了有效性檢查,提交者將使用寫集來更新世界狀態。在更新階段,對於寫集中的每一個鍵,相同鍵的值都設置爲在寫集中指定的值,進一步地,這個世界狀態的鍵的版本會被改變,以反映最新的版本。
Example simulation and validation(模擬和驗證案例)
本節經過一個示例場景幫助理解語義。對於本例的目的,在世界狀態中,鍵k的存在是由元組(k、ver、val)表示的,其中,ver是鍵k的最新版本,它的值由val表示。
如今,考慮一組5個事務,T一、T二、T三、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(能夠包含在一個區塊或不一樣的區塊中)
注意:目前還不支持具備多個讀寫集的事務。