基于XuperChain提出的一種智能合約并行執(zhí)行區(qū)塊鏈結(jié)構(gòu)解析
近年來(lái),區(qū)塊鏈技術(shù)不僅僅在加密貨幣交易,而且在存證和商品溯源等領(lǐng)域發(fā)揮著重要而廣泛的作用。然而,許多現(xiàn)有的區(qū)塊鏈系統(tǒng)在執(zhí)行智能合約方面表現(xiàn)不佳,無(wú)法滿足業(yè)務(wù)需求,因?yàn)橹悄芎霞s是串行執(zhí)行的。XuperChain是一個(gè)新的區(qū)塊鏈系統(tǒng),它能夠支持智能合約在交易粒度并行地執(zhí)行和驗(yàn)證。
引言
2009年中本聰(Satoshi Nakamoto)發(fā)明了比特幣,這是區(qū)塊鏈技術(shù)首次大規(guī)模成功應(yīng)用。2014年,Vitalik Buterin發(fā)明了以太坊。與比特幣相比,以太坊支持智能合約,允許開(kāi)發(fā)者使用基于區(qū)塊鏈的Solidity語(yǔ)言開(kāi)發(fā)應(yīng)用程序。2015,Linux基金會(huì)推出了超級(jí)賬本,它允許開(kāi)發(fā)人員使用流行的語(yǔ)言如GO開(kāi)發(fā)智能合約。這些系統(tǒng)在實(shí)際使用時(shí)性能表現(xiàn)的一般。本質(zhì)上,是由于智能合約是串行執(zhí)行和串行驗(yàn)證的,也就是說(shuō),對(duì)于單個(gè)節(jié)點(diǎn),只能使用一個(gè)CPU核。XuperChain提出了一種新的區(qū)塊鏈數(shù)據(jù)模型:XuperModel?;谶@樣的底層數(shù)據(jù)模型,XuperChain可以使用多核計(jì)算能力來(lái)同時(shí)執(zhí)行和驗(yàn)證智能合約。
智能合約的性能問(wèn)題
在以太坊中,礦工首先從交易池中提取一組有序事務(wù),然后在一系列事務(wù)中執(zhí)行智能合約調(diào)用,最后將它們打包成塊。接收該區(qū)塊的驗(yàn)證節(jié)點(diǎn)還需要根據(jù)區(qū)塊內(nèi)的交易順序逐一執(zhí)行智能合約,這與之前對(duì)礦工進(jìn)行打包的順序相同,驗(yàn)證節(jié)點(diǎn)和礦工執(zhí)行的結(jié)果應(yīng)該相同。
顯然,智能合約的串行執(zhí)行模式限制了區(qū)塊鏈系統(tǒng)的性能提升,因?yàn)榇袌?zhí)行模式不能充分利用多核的計(jì)算能力。
Hyperledger Fabric提出了一種方法,其中智能合約首先在多個(gè)背書(shū)節(jié)點(diǎn)上執(zhí)行,以獲得讀寫(xiě)集和背書(shū)節(jié)點(diǎn)的簽名。然后,排序節(jié)點(diǎn)對(duì)事務(wù)進(jìn)行排序,并將它們打包到鏈上。這種方法的優(yōu)點(diǎn)是,有些事務(wù)執(zhí)行可以完全并行,但也有一些局限性:未確認(rèn)事務(wù)的輸出不立即可見(jiàn),新事務(wù)的讀依賴性只能是BlockChain中的已確認(rèn)事務(wù)。這使得合約從調(diào)用到數(shù)據(jù)變更生效有較大的延時(shí)。
XuperChain讓智能合約執(zhí)行并行化
1 架構(gòu)概述
XuperChain 事務(wù)執(zhí)行架構(gòu)主要由三個(gè)部分組成,分別為VM層、Bridge層和Model層。 VM層主要用于解釋用戶執(zhí)行合同的字節(jié)碼,目前主要支持的有wasm、native。Bridge 層用于隔離用戶態(tài)和內(nèi)核態(tài),為用戶提供系統(tǒng)調(diào)用的接口,如get、put、迭代器等。Model層用于數(shù)據(jù)的提交、回滾和查詢,其內(nèi)置的smart cache機(jī)制能支持事務(wù)的并發(fā)執(zhí)行。
整個(gè)過(guò)程是這樣的。階段1:首先,客戶端觸發(fā)智能合約的預(yù)執(zhí)行,智能合約的字節(jié)碼由虛擬機(jī)解析執(zhí)行,執(zhí)行過(guò)程中的get、put等系統(tǒng)調(diào)用被Bridge層截獲,Bridge層將記錄執(zhí)行過(guò)程中的讀寫(xiě)集,最后返回給客戶端。階段2:客戶端使用讀寫(xiě)集組裝事務(wù),并附加其簽名,然后將其提交到Model層。Model層將驗(yàn)證讀取集的有效性和正確性,最后將其寫(xiě)入數(shù)據(jù)庫(kù)中。
2 XuperModel
為了描述讀寫(xiě)集,XuperChain定義了一個(gè)名為XuperModel的新的事務(wù)模型。該模型是比特幣UTXO模型的一個(gè)演變。在比特幣的UTXO模型中,每個(gè)交易都需要在輸入字段中引用早期交易的輸出,以證明資金來(lái)源。同樣,在XuperModel中,每個(gè)事務(wù)讀取的數(shù)據(jù)需要引用早先的事務(wù)寫(xiě)入的數(shù)據(jù)。在XuperModel中,事務(wù)的輸入表示在執(zhí)行智能合約期間讀取的數(shù)據(jù)源,即數(shù)據(jù)來(lái)自哪些事務(wù)的輸出。事務(wù)的輸出表示事務(wù)寫(xiě)入狀態(tài)數(shù)據(jù)庫(kù)的數(shù)據(jù),而這些數(shù)據(jù)會(huì)被后續(xù)的合約調(diào)用所引用。
為了進(jìn)一步說(shuō)明XuperModel,考慮兩個(gè)事務(wù):tx1和tx2,其中tx1給變量a賦值1,tx2給變量b賦值2。然后還有第三個(gè)事務(wù)tx3,它調(diào)用一個(gè)合約來(lái)交換兩個(gè)變量的值,最后它的輸出是a=2和b=1,交換兩個(gè)變量。因此,在tx3的輸入中,它將引用tx1和tx2,因?yàn)榍懊娴闹凳怯蓆x1和tx2所修改的,如下圖所示:
3 XuperModel 的智能緩存
為了在運(yùn)行時(shí)獲取合約的讀寫(xiě)集,在預(yù)執(zhí)行每個(gè)合約時(shí)為其分配一個(gè)智能緩存。該緩存對(duì)狀態(tài)數(shù)據(jù)庫(kù)是只讀的,它可以為合約的預(yù)執(zhí)行生成讀寫(xiě)集和結(jié)果。同時(shí),也可用于合約的驗(yàn)證。該緩存由四部分組成:一個(gè)寫(xiě)集合實(shí)例、一個(gè)讀集合實(shí)例、一個(gè)Model實(shí)例的引用和一個(gè)穿透的標(biāo)志,標(biāo)記查詢是否可以穿透到Model實(shí)例中。
在合約預(yù)執(zhí)行時(shí),穿透標(biāo)志設(shè)置為T(mén)rue,Bridge為合同獲取該Cache,通過(guò)緩存可以讀取到DB中的數(shù)據(jù),查詢到的數(shù)據(jù)將緩存在Cache的讀集中。此外,合約可以寫(xiě)入數(shù)據(jù),寫(xiě)入數(shù)據(jù)將在Cache的寫(xiě)集中生效。在預(yù)執(zhí)行之后,讀寫(xiě)集可以被提取到并且一起并返回給客戶端。
驗(yàn)證合約時(shí),是否穿透的標(biāo)志為false,驗(yàn)證節(jié)點(diǎn)根據(jù)提交的事務(wù)的讀寫(xiě)集一個(gè)新的Cache實(shí)例,如果事務(wù)中所引用的版本已經(jīng)過(guò)期,則事務(wù)直接失敗。若版本都有效,節(jié)點(diǎn)將再次執(zhí)行合約,但此時(shí)合約只能從讀取集讀取數(shù)據(jù)。同樣,寫(xiě)入數(shù)據(jù)也只會(huì)在寫(xiě)入集中生效。
為了進(jìn)一步說(shuō)明該Cache,考慮一次合約調(diào)用。XuperChain通過(guò)發(fā)起事務(wù)來(lái)調(diào)用合同。在預(yù)執(zhí)行合約時(shí),Cache是一個(gè)三級(jí)的存儲(chǔ)對(duì)象。假設(shè)合約調(diào)用get操作,則Cache將首先從寫(xiě)集讀取最新數(shù)據(jù),如果未找到,則從讀集中讀取,如果未找到,則從DB讀取。在驗(yàn)證合約時(shí),Cache是兩級(jí)存儲(chǔ)對(duì)象。假設(shè)驗(yàn)證get操作,Cache將首先從寫(xiě)集讀取最新數(shù)據(jù),如果找不到,則從讀集合中讀取。
4 事務(wù)沖突處理
前面提到Cache可以提取智能合約預(yù)執(zhí)行生成的讀寫(xiě)集,這是事務(wù)提交時(shí)重要的組成部分。在XuperChain中,讀寫(xiě)集由讀集和寫(xiě)集組成。其中,讀集由元組組成:變量名,數(shù)據(jù)版本,反映了合同運(yùn)行時(shí)讀取的變量狀態(tài),寫(xiě)集為元組:變量名,數(shù)據(jù)值,表示合同執(zhí)行后對(duì)狀態(tài)數(shù)據(jù)庫(kù)的更改。
數(shù)據(jù)版本是一個(gè)元組:{ref_txid,ref_offset},表示修改變量的最后一個(gè)事務(wù)的ID和事務(wù)的輸出偏移量。Hyperledger結(jié)構(gòu)[3]中的數(shù)據(jù)版本也是一個(gè)元組,但其版本由{blockheight、txnumber}組成,因此無(wú)法支持未確認(rèn)事務(wù)輸出的即時(shí)可用性。顯然,XuperChain的設(shè)計(jì)可以支持更低的延遲。
當(dāng)節(jié)點(diǎn)接收到一個(gè)事務(wù)時(shí),會(huì)首先構(gòu)造一個(gè)臨時(shí)Cache,并用事務(wù)攜帶的讀寫(xiě)集填充該緩存,執(zhí)行合約,驗(yàn)證智能合約執(zhí)行的結(jié)果是否正確。通過(guò)此檢查后,將驗(yàn)證讀寫(xiě)集中變量的版本是否與本地狀態(tài)數(shù)據(jù)庫(kù)中記錄的版本一致,如果不一致,則拒絕事務(wù)。值得注意的是,XuperChain要求寫(xiě)入集中存在的所有變量名必須在讀取集中給出相應(yīng)的數(shù)據(jù)版本,如果變量之前沒(méi)有值,則版本字段應(yīng)保留為空。此外,如果本地未確認(rèn)事務(wù)池中的事務(wù)與塊中的已確認(rèn)事務(wù)之間存在讀寫(xiě)集沖突,則將回滾未確認(rèn)事務(wù)。回滾操作是將寫(xiě)集中的變量還原到讀集中聲明的上一個(gè)版本。
5 智能合約的并行預(yù)執(zhí)行
通過(guò)上述所提到Model、智能緩存和數(shù)據(jù)版本。XuperChain可以做到并行地執(zhí)行智能合約。Bridge會(huì)為每一個(gè)合約調(diào)用生成一個(gè)Context,Context里有一個(gè)Cache實(shí)例對(duì)象,并且生命周期僅限于一次預(yù)執(zhí)行調(diào)用。預(yù)執(zhí)行中的讀寫(xiě)操作將在此Cache中生效,因此預(yù)執(zhí)行過(guò)程相互獨(dú)立。由于合約的預(yù)執(zhí)行是一個(gè)互不影響的過(guò)程,所以合約的預(yù)執(zhí)行可以并行進(jìn)行。
上圖說(shuō)明了合約是如何并行預(yù)執(zhí)行的。假設(shè)Contract1、Contract2和Contract3同時(shí)啟動(dòng)。通過(guò)XuperBridge,初始化了三個(gè)Cache實(shí)例。Cache記錄合約執(zhí)行期間的讀寫(xiě)集,并將其返回給用戶。
6 智能合約的并行驗(yàn)證
當(dāng)合約已經(jīng)預(yù)執(zhí)行完畢后。XuperChain返回給用戶一個(gè)讀寫(xiě)集。用戶將在本地組裝整個(gè)事務(wù),并立即將其提交給XuperChain網(wǎng)絡(luò)。然后XuperChain中的其他驗(yàn)證節(jié)點(diǎn)將驗(yàn)證合約。驗(yàn)證過(guò)程如下所述:
合約的驗(yàn)證主要包括3個(gè)步驟:
Step 1: XuperBridge初始化一個(gè)新的Context,并根據(jù)提交的事務(wù)的讀取集在Context中填充Cache。如果找不到讀集中指定版本的數(shù)據(jù),則表示數(shù)據(jù)優(yōu)先被其他合約更改,則Cache初始化失敗,合約調(diào)用失敗。
Step 2: 節(jié)點(diǎn)驗(yàn)證合約以驗(yàn)證寫(xiě)集是否與事務(wù)中提交過(guò)來(lái)的寫(xiě)入集是否相同。
Step 3: 如果讀寫(xiě)集驗(yàn)證相同,交易驗(yàn)證通過(guò),驗(yàn)證通過(guò)后會(huì)更新?tīng)顟B(tài)數(shù)據(jù),否則返回執(zhí)行失敗。
由于每個(gè)合約的驗(yàn)證都在緩存中運(yùn)行,沖突的事務(wù)將在步驟1中失敗。因此,不同合約的驗(yàn)證是相互獨(dú)立的,合約的正確性驗(yàn)證可以在第2步中并行進(jìn)行。在第3步中,我們還會(huì)再次檢查讀集合的版本是否仍然有效。
7 局限性
以上就是XuperChain 中XuperModel支持合約并行執(zhí)行的內(nèi)容。并且所述的并發(fā)粒度是事務(wù)粒度,事務(wù)執(zhí)行完后會(huì)狀態(tài)是unconfirm狀態(tài),但是已經(jīng)寫(xiě)入到DB中,后續(xù)合約調(diào)用可以直接引用該版本。但是XuperModel還有些缺點(diǎn),首先,在合約執(zhí)行期間對(duì)數(shù)據(jù)庫(kù)的每個(gè)訪問(wèn)都將生成一個(gè)讀集記錄。因此,如果用戶在合約調(diào)用期間訪問(wèn)過(guò)多的數(shù)據(jù),那么讀集將太大,甚至無(wú)法傳輸?shù)狡渌?jié)點(diǎn)。此外,該模型的存儲(chǔ)資源占用較大,有待進(jìn)一步優(yōu)化。
總結(jié)
XuperChain提出了一種新的智能合約并行執(zhí)行區(qū)塊鏈結(jié)構(gòu),其特點(diǎn)是將智能合約的執(zhí)行分為兩個(gè)不同的階段:預(yù)執(zhí)行階段和提交階段,并通過(guò)XuperModel數(shù)據(jù)模型解決并行環(huán)境中的交易沖突問(wèn)題。XuperModel模型是從utxo[1]模型發(fā)展而來(lái)的。目前,學(xué)術(shù)界對(duì)如何提高智能合約的性能有很多的研究。其中一些是從底層的存儲(chǔ)引擎[4]開(kāi)始的,其中一些使用STM技術(shù)[5]并行執(zhí)行合約。XuperChain基于讀寫(xiě)集的方法是確定性的,并且易于實(shí)現(xiàn)。在業(yè)界,Hyperledger Fabric[3]也提出了一種基于讀寫(xiě)集的模型。Fabric模型的主要缺點(diǎn)是數(shù)據(jù)版本綁定到塊高度,因此無(wú)法立即使用未確認(rèn)事務(wù)的輸出。綜上所述,我們認(rèn)為XuperChain提出的體系結(jié)構(gòu)對(duì)于業(yè)界探索智能合約的并行化具有重要意義。今后,超級(jí)鏈團(tuán)隊(duì)將繼續(xù)解決這個(gè)模型的一些局限性,提高性能。