1. 程式人生 > >Hyperledger Fabric 交易背書的基本工作流程詳解

Hyperledger Fabric 交易背書的基本工作流程詳解

本文內容精選自華章鮮讀專欄《Hyperledger-Fabric-原始碼分析與深入解讀》一書第二章“架構分析”。

 

《Hyperledger-Fabric-原始碼分析與深入解讀》紙書預計出版時間:2018年9月

華章鮮讀上線:2018年7月(按章更新,紙書出版前更完本書全部內容)

Hyperledger Fabric原始碼分析與深入解讀

我們概述一個交易的請求流程。如圖2-5所示。

Hyperledger Fabric原始碼分析與深入解讀

圖2-5 交易的請求流程

 

 

圖字翻譯:

 

Peers 同級節點

Orderers 訂單方

Endorse(TX) 發起交易TX

Respond(TX) 響應交易TX

Broadcast(EndorsedTX) 廣播已發起的交易TX

Blocks 寫入區塊

 

(1)客戶端建立交易和傳送給它選擇的背書peer節點

 

 

呼叫交易,客戶端傳送一個PROPOSE訊息到它選擇的一組背書peer節點。給定chaincodeID的背書peer節點的設定由客戶端通過peer節點實現,從背書策略知道背書peer節點的設定。例如,交易能被髮送給所有給定chaincodeID背書者,也就是說,一些背書者能夠離線,其它人可能反對和選擇不為交易背書。提交客戶端嘗試滿足背書者可用的背書策略表達。

接下來,將描述PROPOSE訊息格式,討論在提交客戶端和背書者之間可能的互動模式。

PROPOSE訊息格式

一個PROPOSE訊息的格式是,其中tx是強制的,anchor可選引數在下面列出。

 

clientID是提交客戶端的身份,chaincodeID引用交易相關的鏈碼,txPayload是提交交易自身的載體,timestamp是由客戶端維護的一個單獨遞增整型值,clientSig是tx的其它域客戶端簽名.

txPayload的細節會在呼叫交易和部署交易之間有所不同。

對於呼叫交易,txPayload會包含兩個域

  • ● operation表示鏈碼操作函式和引數
  • ● metadata表示呼叫相關的屬性.

對於部署交易,txPayload會包含三個域

  • ● source表示鏈碼的原始碼
  • ● metadata表示鏈碼和應用的相關屬性
  • ● policies包含所有peer節點可訪問的鏈碼的相關策略,例如背書策略。注意背書策略在部署交易中不支援txPayload,但部署的txPayload包含背書策略ID和它的引數。
  • ● anchor包含讀版本依賴,或更具體地說,鍵-版本對(即,anchor是KxN的一個子集),它捆綁或“錨”PROPOSE請求到指定KVS中key的版本。如果客戶端指定anchor引數,背書者背書交易的情況是,只基於讀它本地KVS匹配anchor中的相應KEY的版本號。

tx加密雜湊被所有node節點用作唯一的交易標識tid(即,tid=HASH(tx))。客戶端儲存tid在記憶體中,等待背書peer節點的響應。

 

客戶端決定與背書者互動的順序。例如,客戶端通常會發送(即,沒有anchor引數)到一個單獨的背書者,背書者隨後產生版本依賴(anchor),客戶端可以在晚些時候使用這個版本依賴(anchor)作為它的PROPOSE訊息引數,傳送給其它背書者。另外的例子,客戶端能直接傳送(沒有anchor)到它選擇的所有背書者。不同的通訊模式都有可能,客戶端在這方面是自由的。

 

(2)背書peer節點模擬交易和產生背書籤名

 

 

在從客戶端接收訊息時,背書peer節點epID首先校驗客戶端簽名clientSig,然後模擬一個交易。如果客戶端指定了anchor,那麼背書peer節點模擬交易只基於在它本地KVS匹配的由anchor指定的版本號對應的key讀版本號(即下面定義的readset)。

模擬一個交易涉及背書節點嘗試執行一個交易(txPayload),通過呼叫鏈碼到交易引用(chaincodeID)和背書peer節點本地持有的狀態拷貝。

作為執行的結果,背書peer節點計算讀版本依賴(readset)和狀態更新(writeset),也在DB語言中稱為MVCC+postimage info。

回顧狀態包含鍵/值對。所有鍵/值對實體都是版本化的,那就是說,每個實體包含排序版本資訊,它是在每次鍵的值更新時增加的。解釋交易的peer節點記錄了所有的被鏈碼訪問的鍵/值對,不管讀或是寫,peer節點不會更新它的狀態。更具體地說:

  • ● 在背書節點執行一個交易前給定狀態s,被交易讀取的每個鍵k,鍵/值對(k,s(k).version)被新增到readset。
  • ● 此外,對於每一個被交易編輯的鍵k到值v’,鍵/值對(k,v’)被新增到writeset。或者,v’能成為新值與前值(s(k).value)的增量。

如果客戶端在PROPOSE訊息中指定了anchor,那麼客戶端指定的anchor在模擬交易時必須等於背書peer節點產生的readset.

 

然後,peer節點內部提交交易提案到它的邏輯部分來背書交易,稱為背書邏輯。預設時,一個peer節點的背書邏輯接受交易提案並簡單簽署。無論如何,背書邏輯可以執行任意功能。

如果背書邏輯決定背書一個交易,它傳送訊息到提交客戶端,其中:

  • ● 交易提案:=tran-proposal:=(epID,tid,chaincodeID,txContentBlob,readset,writeset),其中txContentBlob是鏈碼/交易專用資訊。目的是讓txContentBlob用作tx的一些陳述(例如,txContentBlob=tx.txPayload).
  • ● epSig是背書peer節點的交易提案簽名。

否則,如果背書邏輯拒絕背書交易,背書者可以傳送訊息(TRANSACTION-INVALID,tid,REJECTED)到提交客戶端。

 

注意背書者在這一步不能改變它的狀態,在背書沒有影響狀態的情況下交易模擬產生狀態更新。

 

(3)提交客戶端收集交易背書並通過排序服務廣播它

 

 

提交客戶端一直等待直到它在(TRANSACTION-ENDORSED,tid,,)上收集到“足夠”的訊息和簽名來推斷出交易提案已背書。

“足夠”的準確數字取決於鏈碼背書策略。如果背書策略是安全的,交易已經背書;注意它還沒提交。經過背書節點簽過名的TRANSACTION-ENDORSED訊息的集合包含了被背書過的交易。

如果提交客戶端沒有設法為交易提案收集背書,則放棄這個交易,稍後再試。

對於一個具有有效背書的交易,我們現在開始使用排序服務。提交客戶端使用broadcast(blob)呼叫排序服務,其中blob=endorsement.如果客戶端沒有能力直接呼叫排序服務,它可以通過它選擇的peer節點代理廣播。這樣的peer節點必須被客戶端信任不會從背書移除任何訊息或其它可能被無效的交易。注意一點,無論如何,代理peer節點不可能製造有效背書。

 

(4)排序服務向peer節點提交交易

 

 

當一個事件(seqno,prevhash,blob)發生並且一個peer節點已為所有序列號低於seqno的blosbs更新狀態,peer節點執行如下流程,圖2-6所示。

  • ● 它檢查blob.endorsement是有效的,根據的是它引用的鏈碼(blob.tran-proposal.chaincodeID)。
  • ● 在典型情況下,它也驗證了依賴(blob.endorsement.tran-proposal.readset)在期間沒有被違反。在更復雜的用例中,背書中的交易提案域可能不同,在這種情況下,背書策略指定狀態如何形成。

依賴的驗證能以不同的方式實現,根據一致性屬性或為狀態更新選擇的“孤立保證”。Serializability是一個預設的孤立保證,除非鏈碼背書策略指定一個不同的。Serializability能夠通過在readset中的每個key關聯的版本被提供,相當於key在狀態中的版本,並拒絕不滿足這個要求的交易。

  • ● 如果所有這些檢查通過,交易被視為有效或承諾。在這種情況下,peer節點在PeerLedger用1標記交易,適用於blob.endorsement.tran-proposal.writeset區塊鏈狀態(如果交易提案是相同的,其它背書策略邏輯定義了函式處理blob.endorsement)。
  • ● 如果blob.endorsement背書策略驗證失敗,交易無效,並且peer節點在PeerLedger的位掩碼用0標記交易。重要的是要注意無效交易不會改變狀態。

Hyperledger Fabric原始碼分析與深入解讀

圖2-6 提交交易

 

 

Hyperledger Fabric原始碼分析與深入解讀