由于當(dāng)前智能合約多為串行執(zhí)行和串行驗(yàn)證,導(dǎo)致性能一般,無(wú)法滿足業(yè)務(wù)需求。百度超級(jí)鏈提出了一種新的區(qū)塊鏈數(shù)據(jù)模型:XuperModel?;谶@
由于當(dāng)前智能合約多為串行執(zhí)行和串行驗(yàn)證,導(dǎo)致性能一般,無(wú)法滿足業(yè)務(wù)需求。百度超級(jí)鏈提出了一種新的區(qū)塊鏈數(shù)據(jù)模型:XuperModel?;谶@樣的底層數(shù)據(jù)模型,XuperChain可以使用多核計(jì)算能力來同時(shí)執(zhí)行和驗(yàn)證智能合約,大大提升效率。
本期超級(jí)鏈學(xué)院微課堂的主題就是“為你揭開智能合約的高并發(fā)面紗——XuperModel”!明星講師超哥先來為你劃重點(diǎn)啦,本次課程會(huì)講清楚以下幾點(diǎn):
1. 底層的數(shù)據(jù)模型對(duì)于區(qū)塊鏈系統(tǒng)的重要性
2. 超級(jí)鏈獨(dú)創(chuàng)數(shù)據(jù)模型——XuperModel詳解2
3. 智能合約的性能瓶頸問題超級(jí)鏈如何解決
4. XuperModel與其他數(shù)據(jù)模型的異同點(diǎn)
5. XuperModel為開發(fā)者提供了哪些能力
Q1:數(shù)據(jù)模型對(duì)一個(gè)區(qū)塊鏈系統(tǒng)而言重要么?
非常重要。數(shù)據(jù)模型體現(xiàn)了一個(gè)區(qū)塊鏈系統(tǒng)對(duì)數(shù)據(jù)的組織方式,屬于核心設(shè)計(jì),是其區(qū)別于其他系統(tǒng)的重要特征。例如,比特幣的UTXO,以太坊的MPT,HyperLedger Fabric的讀寫集,都是大家所熟知的區(qū)塊鏈數(shù)據(jù)模型。
Q2:超級(jí)鏈的數(shù)據(jù)模型是什么?
超級(jí)鏈的數(shù)據(jù)模型是XuperModel,是基于UTXO模型進(jìn)一步泛化、抽象而來的一種通用數(shù)據(jù)模型。經(jīng)典的UTXO模型只能描述數(shù)字資產(chǎn)的轉(zhuǎn)移,而XuperModel可以描述由智能合約執(zhí)行而引起的數(shù)據(jù)變更, 同時(shí)又沒有犧牲掉UTXO并發(fā)性能好的優(yōu)點(diǎn)。
Q3: XuperModel和UTXO相比,相同點(diǎn)和不同點(diǎn)是什么?
相同點(diǎn)是每筆交易都會(huì)引用和它相關(guān)的之前發(fā)生的交易。只不過,UTXO模型中,交易的引用關(guān)系表明了資金的來源,而XuperModel中存在兩種引用關(guān)系:一種是表述數(shù)字資產(chǎn)的來源,另一種是表述數(shù)據(jù)的版本依賴關(guān)系。兩種引用關(guān)系分別用TxInput和TxInputExt兩個(gè)字段來表示。當(dāng)交易中只存在數(shù)字資產(chǎn)轉(zhuǎn)移時(shí),XuperModel就退化為UTXO模型。
Q4: 如何知道智能合約執(zhí)行依賴的數(shù)據(jù)版本呢?
在超級(jí)鏈中通過預(yù)執(zhí)行來確定智能合約依賴的數(shù)據(jù)版本。在預(yù)執(zhí)行階段,超級(jí)鏈內(nèi)核會(huì)為每個(gè)智能合約的請(qǐng)求構(gòu)造一個(gè)“沙箱”環(huán)境,其發(fā)起的讀取和寫入請(qǐng)求都會(huì)被內(nèi)核捕獲,從而可以記錄到它讀取的數(shù)據(jù)的版本和即將寫入的數(shù)據(jù)內(nèi)容。
Q5: 其他節(jié)點(diǎn)如何驗(yàn)證智能合約的正確性呢?
每個(gè)交易都是自描述的,其他節(jié)點(diǎn)可以根據(jù)交易中的引用信息復(fù)原智能合約的“沙箱”環(huán)境,復(fù)原的過程中需要檢測(cè)其依賴的資產(chǎn)來源和數(shù)據(jù)版本是否仍然有效。如果是過期的版本,或者資產(chǎn)已經(jīng)被其他交易使用,那么復(fù)原沙箱失敗。如果復(fù)原環(huán)境成功,接下來就會(huì)調(diào)用虛擬機(jī)去執(zhí)行這個(gè)合約,執(zhí)行合約的過程是Lock-Free的,因此并發(fā)性能好。最后,在內(nèi)核數(shù)據(jù)生效時(shí),會(huì)Double-Check引用關(guān)系的有效性,最終生效到狀態(tài)機(jī)里面。
Q6: 那么各個(gè)節(jié)點(diǎn)如何最終達(dá)成一致的狀態(tài)呢?
主要是解決判斷沖突的問題。大家應(yīng)該都用過git,當(dāng)我們運(yùn)行g(shù)it pull的時(shí)候,經(jīng)常會(huì)發(fā)生你的本地內(nèi)容和他人沖突,而需要手動(dòng)介入解決沖突。XuperModel的原理很類似,數(shù)據(jù)的唯一標(biāo)識(shí)是Bucket + Key, 其中Bucket對(duì)應(yīng)合約名字,Key對(duì)應(yīng)存取的變量名。如果多個(gè)交易都修改了同一個(gè)數(shù)據(jù),且他們不存在父子引用的話,那么就是互相沖突的。在XuperModel中,區(qū)塊中的交易擁有更高優(yōu)先權(quán),可以回滾掉和它沖突的未確認(rèn)交易。
Q7: 超級(jí)鏈中的數(shù)據(jù)底層是怎么存儲(chǔ)的呢?
底層有兩個(gè)DB,一個(gè)DB記錄了賬本,另一個(gè)DB維護(hù)著狀態(tài)機(jī)。數(shù)據(jù)每個(gè)版本的變更的詳細(xì)內(nèi)容都是記錄在賬本中的,狀態(tài)機(jī)中只是為每個(gè)變量存儲(chǔ)了一個(gè)Hash指針,這個(gè)Hash指針可以定位到賬本中的某個(gè)交易的某項(xiàng)輸出,體現(xiàn)的是這個(gè)變量的最新內(nèi)容。
Q8: 這種模型是支持多版本的么?
是的。默認(rèn)情況下狀態(tài)機(jī)中的變量的Hash指針式指向最新版本的,通過交易的TxInputExt字段,可以往前回溯到更早的版本。這種多版本機(jī)制的優(yōu)勢(shì)是對(duì)迭代查詢、區(qū)間查詢也很友好,可以避免因遍歷無(wú)效版本而產(chǎn)生的IO開銷。同時(shí),超級(jí)鏈節(jié)點(diǎn)也提供了賬本對(duì)齊的功能,類似于“git checkout”, 可以切換到歷史上任意區(qū)塊對(duì)應(yīng)的狀態(tài)。
Q9: XuperModel和Fabric的數(shù)據(jù)模型有什么異同?
首先,F(xiàn)abric的數(shù)據(jù)模型是不內(nèi)置數(shù)字資產(chǎn)轉(zhuǎn)移的描述的, 而XuperModel則是UTXO模型的泛化,天然支持了數(shù)字資產(chǎn)轉(zhuǎn)移的場(chǎng)景。其次,F(xiàn)abric的數(shù)據(jù)模型中,數(shù)據(jù)的版本是綁定到區(qū)塊高度的,因此對(duì)同一個(gè)Key的多次修改不能發(fā)生在一個(gè)區(qū)塊,就導(dǎo)致他不能實(shí)現(xiàn)“Read Your Own Update”的場(chǎng)景。XuperModel中數(shù)據(jù)的版本是直接引用前置交易的,因此可以立即生效,在同一個(gè)區(qū)塊中可以打包相關(guān)聯(lián)的對(duì)同一個(gè)數(shù)據(jù)的一系列修改行為。
Q10: 對(duì)于應(yīng)用開發(fā)者而言,基于XuperModel可以獲得哪些能力?
首先,獲得了天然的數(shù)據(jù)回溯能力。智能合約中的變量會(huì)隨著合約的調(diào)用不斷地發(fā)生變更,由于XuperModel維護(hù)了每次變更的前一個(gè)版本的哈希指針,可以順藤摸瓜得到之前這個(gè)合約變量的所有版本。例如,我們之前曾經(jīng)有篇小短文介紹了如何用200行智能合約代碼實(shí)現(xiàn)一個(gè)可回溯的文件系統(tǒng):
https://mp.weixin.qq.com/s/8CWKX92WRkeG6MMXkPZmVQ。其次, XuperModel 解耦了智能合約的計(jì)算和存儲(chǔ),使得智能合約的執(zhí)行可以利用上CPU多核的算力,提升整體的性能。
分享結(jié)束后,群里也涌現(xiàn)出了一些精彩問題,摘取部分分享給各位。
問:「 請(qǐng)問XuperModel和超級(jí)鏈說的DAG有什么關(guān)系?」
答:DAG是有向無(wú)環(huán)圖,是多個(gè)交易根據(jù)依賴關(guān)系構(gòu)成的。那么,如何構(gòu)建這種依賴關(guān)系呢?就需要借助XuperModel的能力為智能合約執(zhí)行構(gòu)造一個(gè)沙箱,為其捕獲到依賴關(guān)系,最終把這些交易串起來,形成DAG。
問:「XuperModel是每個(gè)節(jié)點(diǎn)一直維持著一張大圖還是每個(gè)交易都需要回溯?如果是前者,那賬本大了之后新節(jié)點(diǎn)加入需要花費(fèi)很大時(shí)間,而且賬本大了這個(gè)表會(huì)很占內(nèi)存,該如何解決?」
答:在超級(jí)鏈里面,要想構(gòu)造交易,需要先“預(yù)執(zhí)行”,預(yù)執(zhí)行就錨定了交易依賴的數(shù)據(jù)版本,開銷相當(dāng)于在DB中的隨機(jī)查(點(diǎn)查)。狀態(tài)機(jī)DB默認(rèn)是leveldb,不需要長(zhǎng)駐內(nèi)存。
問:「那是每個(gè)交易數(shù)據(jù)之中就寫好了前向的交易,需要預(yù)執(zhí)行的時(shí)候進(jìn)行遞歸搜索,還是在leveldb中專門維持了一種聯(lián)系表?」
答:前半句對(duì)。交易的TxInputExt是這樣的:(ref_txid, ref_offset), 根據(jù)ref_txid可以反查到賬本中的這個(gè)被依賴的交易內(nèi)容,通過ref_offset可以拿到這個(gè)交易的TxOutput[ref_offset]這條數(shù)據(jù)內(nèi)容。因此不需要遍歷。
問:「 兩個(gè)DB如何保證事務(wù) 」
答:超級(jí)鏈中,一個(gè)DB是賬本,相當(dāng)于binlog, 一個(gè)DB是狀態(tài)機(jī),里面有個(gè)Hash指針指向最后一次執(zhí)行成功的區(qū)塊。狀態(tài)生效的粒度是區(qū)塊,通過Batch寫保證原子性,只要當(dāng)區(qū)塊中的交易數(shù)據(jù)變更全部成功寫入狀態(tài)機(jī)后,這個(gè)Hash指針才會(huì)往后『滑動(dòng)』。Hash指針本身也存儲(chǔ)在狀態(tài)DB中,隨同一個(gè)Batch刷下去。
問:「 智能交通業(yè)務(wù)中,節(jié)點(diǎn)的數(shù)據(jù)是否可以漂移在各共識(shí)節(jié)點(diǎn)?如果是秒級(jí)業(yè)務(wù)又該如何解決?」
答:數(shù)據(jù)的傳播通路有兩個(gè):交易的廣播和區(qū)塊的廣播。
區(qū)塊的廣播是線性的,交易的廣播是亂序的。因此,可能出現(xiàn)交易對(duì)象構(gòu)造的交易依賴了一個(gè)對(duì)方節(jié)點(diǎn)還沒同步到的版本。但是,每個(gè)節(jié)點(diǎn)都會(huì)有例程廣播自己本地未確認(rèn)的交易。
如果是秒級(jí)業(yè)務(wù)的話,就要看交易依賴的數(shù)據(jù)量有多大了,還有網(wǎng)絡(luò)的帶寬是公網(wǎng)環(huán)節(jié)還是內(nèi)網(wǎng)環(huán)境。在超級(jí)鏈中,首先是交易廣播先行(盡最大努力、立即廣播),然后是區(qū)塊作為定序后的兜底,確保數(shù)據(jù)的最終一致性。
問:「使用UTXO數(shù)據(jù)模型,當(dāng)區(qū)塊數(shù)據(jù)很多的時(shí)候,查找某個(gè)區(qū)塊中的交易ID所對(duì)應(yīng)的時(shí)間消耗就比較大,需要遍歷每個(gè)區(qū)塊,效率低,那么百度超級(jí)鏈,在交易信息查詢方面做了哪些優(yōu)化?」
答:在超級(jí)鏈?zhǔn)沁@樣存儲(chǔ)的:
Block Namespace:
blockid ->. (block header, txid[N])
Tx Namespace:
txid -> (blockid, tx content....)
因此,查一個(gè)交易,不用遍歷區(qū)塊,而是一次『點(diǎn)查』。(超哥)
關(guān)鍵詞: 百度超級(jí)鏈 XuperModel 數(shù)據(jù)模型