fabric1.0分析(版本迭代中)

fabric1.0與0.6相比改動較大,解決了不少痛點問題。第一:動態增加節點功能 第二:分鏈結構,容易實現spv 第三:策略管理(過濾器)機制,增加權限控制。 第四:提高高可用性HA(此詞來自于殷舒~若使用不當和我沒關系~~)增加kafka集群。第五:支持合約升級,有利于后期維護。第六:將ca功能拆分,ca證書分發的過程可以單獨處理。第七:模塊分割,結構清晰,各模塊分工明確。

fabric1.0整體流程是客戶端通過grpc連接peer的endorser server,endorser server仿真智能合約,仿真結果簽名后返回客戶端,客戶端通過Broadcast將返回結果發送至orderer,orderer處理數據將結果交給kafka集群,orderer切割kafka交易成塊,orderer將切割的block信息通過Deliver發送給commiter peer,committer peer之間通過gossip來實現一致性,commit peer 存儲到db中。

fabric1.0管理不是以chaincode為處理單元,而是以chainID分割,也就是說以鏈為單位進行處理。fabric1.0以channel為載體,peer節點與orderer通信前提是搭建channel,而且每個channel只能承載一條鏈chainid,每個chainid 可以承載多個智能合約。(多個智能合約用一條鏈,ledger數據也是在一起?)這種思想有利于動態增加節點,peer節點關心的chainid可以直接向orderer進行訂閱(join channel)。

fabric0.6處理交易信息都是由peer節點進行處理,而在1.0里交易由endorser server接收后,都是要交給system chaincode處理。目前一共由五個系統級chaincode,他們分別是:

cscc:負責joinchannel/config update等
escc:負責對傳入數據進行簽名(msp管理)
lccc:負責deploy invoke
vscc:負責簽名驗證/策略驗證(這里如何進行策略驗證?)
qscc:負責ledger查詢

這五個系統級應用綁定在chainID:test_id 上,這五個又分成chainlessCC chainCC,例如cscc用于joinchannel沒有數據需要單獨存儲所以是ChainlessCC,escc執行合約產生的數據需要保存所以是ChainCC,形象說endorser peer節點搭建合約仿真環境的時候,需要考慮是否要給其流出存儲接口,合約產生的數據都提交到這個接口,合約結束后統計數據內容。

Peer節點Ledger:
類型:state存儲/block存儲/ledgerProvider/index
statedb:用于存儲世界狀態可選:leveldb couchdb
blockdb:存儲block信息,leveldb
indexdb:存儲塊號索引 txid,leveldb
ledgerProviderdb:屬于管理db,記錄整個peer一共由多少chainID ledger
/**************************************************

Ledger工程描述(可跳過):
init期間創建“openedLedgers”的map表,key:chainID,value:PeerLedger實例對象。PeerLedger數據結構由三個重要成員變量:statedb操作句柄/blockdb+indexed操作句柄/ledgerProviderdb操作句柄。所以每個chainID在創建的時候都要創建chainID-PeerLedger操作句柄。在初始化期間創建ledgerProvider對象,該對象是各Ledgerdb的總句柄,chainID—PeerLedger的分配就是由ledgerProvider管理。
***************************************************/
Orderer節點ledger:
類型:block存儲db
可選file ram兩種方式
/**************************************************
Ledger工程描述(可跳過):
Orderer是以chainID為單位進行ledger存儲,其方式與Peer 節點非常相似,map中key為chainID,value:能夠對block進行操作的ReadWrite對象/以及便于查找的鏈表指針(ram方式是采用的鏈表方式存儲)為什么不采用數組而采用鏈表呢?這里是因為其要維護一個動態的臨時block組,當block數量過多的時候要從低塊號刪除block,數組刪除后不好填補空間。
**************************************************/

通信方式:
客戶端通過endorser grpc訪問endorser peer
客戶端通過Broadcast訪問orderer
orderer通過Deliver訪問commuter peer

ordererManager:多鏈管理員

所有由客戶端發起創建的chainID,ordererManager負責管理所有有關chainID的操作。GetChain(),newChain(),以及生成該chain的策略方案,Chain相應的數據庫操作等
PS:ProposeChain的函數配置創建前先提交了kafka,這里思考可能是因為其他命令都是先交給kafka后直接存儲,而配置文件的提交orderer必須在本地操作,先要生成對象,這里目的性還不清晰。
/****************************************************
ordererManager工程描述(可跳過):
ordererManager數據結構{
chains map key:chainID value:chainSupport
ledger:數據庫訪問句柄
consenter:solo/kafka 操作句柄

ledger consenter 好理解,chainSupport主要是生成策略方案/配置管理/過濾器管理/kafka通信/簽名及認證/數據庫操作(policyManager/sharedconfigManager/ledgerManager)
****************************************************/
過濾器Filter:
過濾器在orderer模塊創建chainID時配置的Filter,過濾器包括判斷batch大小是否在規定范圍內/policy檢測/config檢測是否通過等。過濾器都在什么地方使用?solo是在生成block前進行檢測,例如如果該tx是配置,則在進行config檢測時發現沒有該配置,也就是說這是一條創建ChainID的操作,則調用ordererManager來創建chainID

創建channel流程:
由于合約要依附chainID,chainID要依附channel,創建channel是首先要做的。
1)客戶端發起create channel操作,客戶端封裝自己的Item,例如:本地證書/策略項。個人看的版本還沒有支持外接參數導入(以后可能會支持自定義配置),消息封裝簽名。
2)將消息通過broadcast發送給orderer節點,本地創建Deliver client連接到orderer
3)orderer節點消息解析出chainID,ordererManager檢測是否存在該chainID發現不存在后,檢測提交的是否是chainID配置項,檢測配置項是否滿足規則,交給kafka。
4)kafka消費者將該tx信息使用過濾器進行過濾,過濾器發現這是chainID配置項,則交給ordererManager進行創建配置操作,然后將信息存儲到orderer本地塊里
5)塊存儲過程中利用通道將block信息通過Deliver發送給客戶端

 所以chainID的第一個塊一定是配置塊,但最終配置塊不一定是第一塊,當發起config更新時第一塊不再具有意義。

join channel流程:
客戶端建立channel后,其他peer節點如果對該chainID關心,則可以訂閱該channel
假設peer0對某chainID關心
1)客戶端封裝報文結構,包括:需要訪問的chaincodeName:cscc 訪問的方法:JoinChaincode chainID配置塊內容:first block
2)客戶端創建endorser client 鏈接peer0 endorser服務
3)peer0檢測消息真實性以及判斷訪問的chaincodeID是否是系統chaincode
4)將報文數據傳遞給cscc,cscc在本地創建first block保存chainID配置塊,同時與orderer建立Deliver通信。
5)peer0返回status信息
6)客戶端檢測status

這里peer0的作用是希望做commit peer,結果其還是需要endorser的功能,這種情況下沒有做到節點分開。
(kafka集群是否與orderer節點分離,目前看還是在一起的)

deploy流程:
1)客戶端封裝報文結構,包括:需要訪問的chaincodeName:lccc 訪問的方法:deploy 簽名:xxx
2)客戶端創建endorser client 鏈接peer0 endorser服務
3)peer0檢測消息真實性后發送lccc,執行部署操作,返回數據
4)peer0將lccc返回數據,送入escc進行簽名,將簽名結果返回客戶端
5)客戶端驗證返回數據真實性后,簽名通過broadcast發送給orderer。

策略機制分類:
orderer接受消息的策略機制
orderer建立chainID的策略機制
chaincode執行的策略機制
chaincode部署的策略機制

這幾個策略機制個人理解實現還不完全,目前情況是只支持Sign一中策略,也就是通過簽名個數來執行策略,而且一直在改動,個人分析的版本還不支持-p 來指定chaincode策略,fabric也在持續更新,下面是未來得及整理的某一個版本的策略部分,選看:

chain的創建 join 以及后續的應用部署/調用/查詢,都是在這個chain上,chain所應用的策略很重要。

明確:這些管理都是在orderer上做的

1.configManager如何管理配置?
configManager時policyManager sharedManager的匯總,負責對policyManager sharedManager的消息錄入/分析/整理。有個policyProviderMap的key value key是各種策略類型(簽名策略/配置策略/order item策略),value是一個PolicyProvider對象,例如簽名策略的value是具有getPolicy與驗證是否符合policy的能力的對象。
2.policyManager如何管理?
multiledger創建policyManager結構體:

policyManagerImpl{
providers 負責newPolicy
policies 負責記錄各種策略,并提供驗證策略的方法(Evaluate)

創建configHandlerMap的map,key:configuration_policy value:policyManagerImpl

調用policyManagerImpl的beginHandlers方法 processConfig方法 commitHandlers方法

實際程序處理的時候是對configManager整體解析config,內部調用各自configtype的beginHandlers等interface方法,這里為了清晰,單獨提取policyManager。

首先檢測配置編號是否正確,檢測新的策略是否滿足舊的策略限制,滿足舊的策略就更新

舉例:chain:test_id

mini——config:

Item1:
        {
            type: configItem_orderer
            key: consensusType
            value:solo
        }

Item2:
        {
            type:configItem_orderer
            key: batchSizeKey
            Value: {maxMessagecount, AbsoluteMaxBytes, PreferredMaxBytes}
        }

Item3:
        {
            type:configItem_orderer
            key:BatchTimeoutKey
            value:{timeout}
        }

Item4:
        {
            type:configItem_orderer
            key:IngressPolicyNamesKey
            value:AcceptAllPolicyKey
        }

Item5:
        {
            type:configItem_orderer
            key:EgressPolicyNamesKey
            value:AccessAllPolicyKey    
        }

Item6:
        {
            type:configItem_Policy
            key:NewConfigurationItemPolicyKey    
            value:Policy{
                                    type:Policy_signature
                                    Policy:RejectAllPolicy{
                                                                                version:0
                                                                                Identities:nil
                                                                                Policy{
                                                                                                    SignturePolicy{
                                                                                                                                    Noutof(N=1,SignPolicy{nil})
                                                                                                                            }
                                                                                            }
                                                                        }
                                }
        }
Item6代表從nil個policy條件中滿足1個,則驗證通過,由于sign policy=nil,所以一定是拒絕的,RejectAllPolicy

Item7:
     {
            type:configItem_Policy
            key: AcceptAllPolicyKey
            Policy:同上,剛好相反N=0
        }

System-config:

Item1:
       {
                type:config_orderer
                key:chainCreationPolicyNamesKey
                Value:DefaultChainCreationPolicyNames
         }

Item2:
        {
            type:config_orderer
            key:KafkaBrokerkey
            value:一個代理的IP地址Brokers
        }

上述創建了一個配置,該配置是block0,應用到chainid=test_id上

根據配置創建該chainID的policyManager sharedConfigManager

policyProviderMap[Policy_signature] = NewPolicyProvider
policyProviderMap[config_policy] = policyManager
policyProviderMap[config_orderer] = sharedConfigManager

調用interface Handler BeginConfig() RollbackConfig() CommitConfig() ProposeConfig()將配置項解析

解析是否存在oldconfig,如果存在檢查ModificationPolicy,調用其Evaluate判斷可否update策略,這個ModificationPolicy如果未定義,則采用key:NewConfigurationItemPolicyKey,如果注意發現,該配置一旦解析完成存儲,下次則不可以更改這個配置,因為我們配置的是Policy:RejectAllPolicy

其中NewPolicy函數返回的是一個函數,evaluation函數。

分析evaluation這個函數指針:
SignaturePolicy分成from/signed by,兩部分。from負責統計滿足多少policy可以算通過,signed by是用來計算簽名的,可以指定簽名人來驗證數據。其結構可以遞歸

from signby
signby
signby
from signby
singby
singly

目前應該只支持簽名策略。

策略管理在何處使用?
更新config的時候
invoke/query的時候

sharedconfig:所有itemtype=orderer配置內容在這

問題:這種多少人簽名通過的Policy外界如何配置

創建一個新的chain,以上內容策略是如何定義的??????????

peer節點
Item1:

type:“ConfigurationItemMSP”
key: mapKey
value: 各種證書

Item2:
{
type:ConfigurationItem_peer
key:AnchorPeerConfItemKey
value:ip:port
}
Item3:
{
type:configuration_orderer
Key:creationPolicyKey
value:{
AcceptAllPolicy
Hash(allItem)
}
}

廣播到orderer后,交給multimanager管理調用ProposeChain(),orderer檢測了Key:creationPolicyKey是否是系統中已經配置的支持的創建chain方式,目前只是支持AcceptAllPolicy,在orderer處理創建channel的時候都是找sqschain來處理的。那幾個manager例如:policyManager sharedConfigManager,這里policyManager未執行策略

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容