麻豆国内精品欧美在线-麻豆国内精品久久久久久-麻豆国产在线观看一区二区-麻豆国产在线观看免费-麻豆国产原创-麻豆国产一区二区在线观看

性能趕超EOS?一文帶你深挖并發(fā)執(zhí)行模型區(qū)塊鏈

區(qū)塊鏈大本營 2018-08-19 19:41
分享到:
導(dǎo)讀

本文將帶你去偽存真,從多維度認(rèn)知主流公鏈。

公鏈性能一直是行業(yè)關(guān)注的重點,如DAG的強一致性,sharding的技術(shù)可行性,超級節(jié)點的中心化問題等等。對于這些問題的解決方案都在試圖通過改變區(qū)塊鏈共識結(jié)構(gòu)的方式提升性能,適用性不高,安全性也有待證明。

8月11日,星云鏈?zhǔn)紫邪l(fā)&星云鏈技術(shù)白皮書主編尚書為我們分享了一個性能提升方向的探索成果——并發(fā)執(zhí)行模型,有效地在8核16G的機器上實現(xiàn)了2000TPS的最大并發(fā),且還可以根據(jù)需求做橫向擴展。

作為開發(fā)者或者投資者,你對公鏈真正了解多少?本文將帶你去偽存真,從多維度認(rèn)知主流公鏈。

以下內(nèi)容為尚書現(xiàn)場分享實錄,由區(qū)塊鏈大本營整理發(fā)布。

正文:

我們今天的主題是關(guān)于公鏈性能的提升。接下來我將會講并發(fā)執(zhí)行模型。

一、如何評估公鏈性能

TPS(Transaction per Second),指的是每秒交易數(shù)量。一般來說,一個區(qū)塊鏈每秒鐘能打包的交易數(shù)量就是TPS,但這樣評估并不完全準(zhǔn)確。因為在區(qū)塊鏈的結(jié)構(gòu)里面,是一個區(qū)塊一個區(qū)塊產(chǎn)生的,每個區(qū)塊從產(chǎn)生到傳播到公網(wǎng)之間,存在網(wǎng)絡(luò)延遲,下一個人拿到這一區(qū)塊的時候,才能生成下一個區(qū)塊。

所以中間除了打包這個過程外,還有一些其他的操作。打包的時間并不等同于TPS,而是比如說有1萬個交易發(fā)送上鏈,直到最后一個交易上鏈,這中間有個時間窗口。用N除以這個時間窗口,得到的TPS才是準(zhǔn)確的。

?

?

再嚴(yán)格一點說,我們在錢包里面做交易的時候,會出現(xiàn)什么場景?

這里我們首先要知道一個概念:51%攻擊。它指的是有人掌握了全網(wǎng)50%以上算力之后,用這些算力來重新計算已經(jīng)確認(rèn)過的區(qū)塊,使其產(chǎn)生分叉并且獲得利益的行為。

比如說我們有一條10個區(qū)塊的主鏈,但有另一個算力更強的人,他悄悄在世界上一個隱秘的地方挖了20個區(qū)塊出來。這時,大家在公網(wǎng)上面看到的只有10個區(qū)塊,這10個區(qū)塊交易完之后,你的賬戶應(yīng)當(dāng)有10塊錢,但是在它挖的20個區(qū)塊的公鏈上面,你可能只有5塊錢。又因為最長的鏈?zhǔn)侵麈湥坏┧?0個區(qū)塊釋放到公網(wǎng)上,這條長鏈就變成了主鏈。實際上在公鏈上的10個區(qū)塊里面,記錄的所有的數(shù)據(jù)都被回滾掉了。

你在以太上面做完交易,imToken會告訴你需要等12個區(qū)塊的確認(rèn)。這個確認(rèn)是什么意思呢?當(dāng)一個區(qū)塊產(chǎn)生了之后,并沒有人可以保證這個區(qū)塊會永遠(yuǎn)被寫在整個區(qū)塊鏈的主鏈上面,它有可能變成一條側(cè)鏈。

這里存在著巨大的風(fēng)險,比如說在交易所里像OTC這種業(yè)務(wù),你給交易所10萬塊錢,拿到了1萬個Token。但可能過一段時間,交易所之前驗證的那個區(qū)塊被回滾了,這個時候?qū)嶋H上你手上并沒有那些Token。這樣也就導(dǎo)致你原來花的10萬塊錢買的Token消失了,沒有任何人能幫你找的回來。

因此,所有的交易所錢包都需要一個確認(rèn)的過程。交易完成后,一定要等到多少個區(qū)塊確認(rèn)之后,交易所和錢包認(rèn)為你這個交易所在的那個主鏈,很難被回滾了——當(dāng)然只是說很難被回滾,并不是說不可能被回滾,比如說它有90%的概率不可能被回滾了,交易所也同意承擔(dān)這10%的風(fēng)險,通知你轉(zhuǎn)賬成功。這里就存在一個確認(rèn)的時間。

從更嚴(yán)格的角度來講,我們發(fā)了一萬個交易到鏈上去,理論上只有這一萬個交易全部確認(rèn)之后,我們才說這一萬個交易真正上鏈了,這個TPS才是我們最真實的TPS。那么,我們要怎樣來衡量這個確認(rèn)的概念呢?

?

?

1.PoW

2年前我們的公鏈有比特幣,有以太坊。這兩條公鏈所采用的共識算法叫做PoW。這就相當(dāng)于大家一起來解一個智力游戲,比如說猜數(shù)字,誰最先猜出來了,誰擁有記賬的權(quán)力。大家都在拼算力,隨著整個網(wǎng)絡(luò)算力的提升,題目的難度也在不斷加大。

比特幣設(shè)計了一個算法,保證平均每10分鐘出一個區(qū)塊。隨著網(wǎng)絡(luò)算力提升,它也會不斷調(diào)整游戲的難度,以保證每10分鐘出一個區(qū)塊。通過對安全性做計算,它認(rèn)為每10分鐘出現(xiàn)一個區(qū)塊,并且,當(dāng)有6個區(qū)塊出現(xiàn)時,在將近一個小時的時間窗口里面,不可能再有另外一個挖出了7個區(qū)塊的大礦場,能夠把這6個區(qū)塊一次性全部給回滾掉。

所以說,我們所謂的確認(rèn)狀態(tài),不是100%的確認(rèn),只是一個大概率確認(rèn)狀態(tài)。

雖然比特幣說它是6個區(qū)塊確認(rèn),但是可能在交易所里面你需要等到12個確認(rèn),或者20個確認(rèn),才把那個賬目真正打到你的賬戶里面去,因為交易所也怕風(fēng)險。

以太的方案在比特幣之上做了一個擴展。因為比特幣10分鐘才有一筆交易,這對于所有的交易場景來說,基本是不可用的,除非是非常大額的交易,愿意等這10分鐘。比特幣的策略是上一個區(qū)塊出完之后,緊跟著出來下一個區(qū)塊,這是一個比拼算力的過程。

以太引入了一個新的概念。在同一個高度上,比如說上一個區(qū)塊鏈已經(jīng)出完了,接下來該出高度為11的區(qū)塊了,這時可能在整個網(wǎng)絡(luò)里面,有100個人在一個很短的時間窗口里同時挖出了第11個區(qū)塊。但只有一個最終能夠鏈到我們主鏈上來,所以有10個是作廢的。

這10個被作廢掉的區(qū)塊當(dāng)然是有價值的,因為它也消耗了算力。以太的方案是把這10個區(qū)塊的算力,也加入到整個主鏈狀態(tài)評估過程中,就可以在一個更短的時間內(nèi)確認(rèn)。因為在那個很短的時間窗口里,全網(wǎng)貢獻(xiàn)的算力跟比特幣在一個區(qū)塊上貢獻(xiàn)的算力差不多,通過這種方式它也能夠達(dá)到跟比特幣相當(dāng)?shù)囊粋€安全指標(biāo)。以太這樣做的轉(zhuǎn)賬速度差不多在15-20秒一個區(qū)塊,它需要等12個區(qū)塊。

而在火幣上面,大約要等到28個區(qū)塊才會確認(rèn)。因為火幣也怕承擔(dān)風(fēng)險。到了12個區(qū)塊也并不能說100%能夠確認(rèn),它還有概率會被回滾掉。一旦回滾,火幣平臺就需要擔(dān)負(fù)極大的資產(chǎn)損失責(zé)任,所以它在這個地方會等得更久。

這就是在最早一代的公鏈項目里,我們確認(rèn)狀態(tài)的現(xiàn)狀。它是一個概率,不是100%。

2. DPoS

到了下一代,我們現(xiàn)在看的EOS,包括我們星云1.0所用的共識,就是DPoS。

DPoS的方案是怎樣的呢?比如說我們有21個人在參與挖礦,一起編制了一條主鏈。在這條主鏈里我挖了一個礦之后,剩下的人在輪流挖礦的過程中,如果有14個不一樣的人在我挖的這個區(qū)塊后面出了區(qū)塊,就證明他認(rèn)可我這個區(qū)塊,可以認(rèn)為他給我投了一票。一個區(qū)塊如果拿到了2/3 1的票,也就是21個人里面15個人的票,包括我自己,那么這個區(qū)塊就能夠得到確認(rèn)。這其中有一個巨大的假設(shè)條件——整個網(wǎng)絡(luò)里面,這21個人里面,不會超過7個人及以上是壞人,所以我們能干這個事情。

但是這個里面依舊會存在一個場景:這21個人里頭,如果有7個作惡節(jié)點,他有可能在這邊挖了一個區(qū)塊,在另外一條隱藏的側(cè)鏈上面也挖一個區(qū)塊,然后再賄賂另外的8個人,也就是一共搞到15個人,在另外一條側(cè)鏈上挖出一個更長的區(qū)塊。等到哪天符合他的利益,比如說他在主鏈上已經(jīng)花了1個億,但是在側(cè)鏈上那1個億還在的時候,他們把隱藏的那條側(cè)鏈公開給全網(wǎng),全網(wǎng)在舊鏈上的所有數(shù)據(jù)全部被擦除掉,他們手上就重新得到了1個億。也就是說,這少部分的15個人剝奪了所有人的利益。這樣理論上來講,也是不安全的。

當(dāng)然現(xiàn)在大家對這個事情沒有那么關(guān)注,大家還是相信那21個人,那21個人也是公開自己身份的。如果他們真的干了這個事情,可能會被人追殺,但是你也不知道他們會不會干。如果他能掙100億美金,他也是有可能會干的,對吧?

這個就是第二階段,大家對如何確認(rèn)的一個看法。

3. PoS變種

到了第三個階段,就是現(xiàn)在以太在提的Casper,然后我們提了一個Proof of Devotion。在我們這里,要保證的是做到100%確認(rèn)。也就是如果公鏈告訴你,這個區(qū)塊被確認(rèn)了,那它一定是100%被確認(rèn)了。這里引入了一個新的機制在于,所有要進(jìn)來挖礦的人,需要先交一筆押金,你如果在這里面做了惡,你的押金會被扣。這就有一個可控的變量,你要是作惡到了極限,那就把所有人的押金全部扣完。

我們設(shè)計的方案是,即使所有人的押金全部扣完,你也沒有辦法把我們之前確認(rèn)過的區(qū)塊給回滾掉。從而保證我們一旦確認(rèn),就是100%的確認(rèn),因為在我們的體制下面,你已經(jīng)沒有足夠的資金去回滾區(qū)塊。這個就是第三代Casper和我們提的Proof of Devotion要做的事情,也就是確認(rèn)的狀態(tài)。這兩個算法都設(shè)計出來了,但還是在驗證階段。

這就是在一個公鏈上面交易確認(rèn)狀態(tài)的三個發(fā)展方向。

二、前提條件

公鏈畢竟是公鏈,我們有一個不可能的三角,就像我們原來分布式的Cap一樣,在公鏈里也有一個不可能的三角——安全性、去中心化、性能。在現(xiàn)有的條件下,三者只能選二,然后等到整個大環(huán)境,包括硬件條件、軟件條件、網(wǎng)絡(luò)環(huán)境等全部上來之后,剩下的那一個指標(biāo),才能隨著大環(huán)境而提升。而安全性和去中心化,在這里面扮演的是很重要的角色。所以,在提升公鏈性能的時候是有一些假設(shè)、一些條件在前面的,這些條件從理論上來講是不應(yīng)該逾越的。

在這里,我們可以操作的事情有哪些呢?共識這里出現(xiàn)了一個新的變種DAG,它不是區(qū)塊鏈,在它的場景里面已經(jīng)沒有區(qū)塊的概念了,而是所有的交易在整個網(wǎng)絡(luò)中織成一張大網(wǎng)來做到一致性。但這個方案現(xiàn)在要想做到強一致,還是存在一些問題的,所以我們現(xiàn)在還只是關(guān)注區(qū)塊鏈項目,是有區(qū)塊概念的。

?

?

在這個大環(huán)境下面,每一個區(qū)塊在挖的過程中,必須要經(jīng)歷三個階段。

第一是打包時間。一個礦工從網(wǎng)絡(luò)中收集到了很多交易,要把這些交易打包成一個區(qū)塊。打包結(jié)束之后,算好最終狀態(tài)變化的情況,就可以把所有的數(shù)據(jù)廣播到全網(wǎng)去。這里面就有一個打包的時間。

除此之外,還有一個網(wǎng)絡(luò)延遲。它不像EOS,公網(wǎng)是所有的礦工網(wǎng)絡(luò)直連的,相當(dāng)于是一個小的局域網(wǎng)。正經(jīng)的說,我們要保證去中心化場景時,我們一定是要在公網(wǎng)環(huán)境的,這就不可避免會存在網(wǎng)絡(luò)延遲。

那么對方(另外一個礦工)收到區(qū)塊之后,他需要去驗證一下你算的所有的數(shù)據(jù)是不是對的,你如果算不對,那我在你的后面出塊的話,相當(dāng)于所有的數(shù)據(jù)都錯了。所以收到的礦工一定還有一個驗證時間。這樣來看,一個區(qū)塊必然有這三個時間,這三個時間里面,又很詭異的有一個現(xiàn)象,就是我們在一個特定的算法里面,驗證時間是可以遠(yuǎn)小于計算時間的。

舉個例子,比如說排序,我們現(xiàn)在來看,最快的排序也是O(NlogN)的,但在特定場景里面,我們要想驗證一個排序?qū)嶋H上是很快的,只需要判斷是從大到小或者從小到大一個排序的過程就可以了,這就是O(N)的時間復(fù)雜度。

在一個特定的算法里面,我們算法執(zhí)行的時間,實際上遠(yuǎn)遠(yuǎn)大于算法驗證的時間。這是一個很好的現(xiàn)象,如果真的可以做到這一點的話,我們的打包時間會遠(yuǎn)遠(yuǎn)大于驗證時間。但我們是一個通用公鏈,并不知道用戶會在我們鏈上寫什么算法。我們不知道他們什么時候會做什么樣的事情,也就不知道該怎么去驗證它算的對不對。

因此,在這樣一個尷尬的場景里面,我們的打包時間跟驗證時間實際上是一樣的,因為我們必須重走一遍它的邏輯。這樣來看,我們只能盡量把這兩個時間都縮小,把網(wǎng)絡(luò)延遲時間縮小。

?

?

根據(jù)網(wǎng)絡(luò)延遲,實際上就是要減少網(wǎng)絡(luò)包的大小。我們可以從兩個方向著手。

一個是序列化。我們能不能找到一個更好的序列化的方案,把我們的數(shù)據(jù)全部變成一個更好的序列化結(jié)構(gòu),變成二進(jìn)制流發(fā)出去?這個里面我們使用了Protocol Buffer,以太用了它自己設(shè)計的一個RLP。

其實RLP的性能會比Protocol Buffer要好,但RLP算法本身的擴展性非常差,我們在設(shè)計整個區(qū)塊鏈的過程中,不能保證未來會發(fā)生什么變化——我們未來的核心協(xié)議網(wǎng)絡(luò)包的結(jié)構(gòu)會不會產(chǎn)生變化,會不會添加一些新的字段,會不會改一些字段,這些都是我們不知道的,所以我們必須保留這個擴展性。從這個角度來說,Protocol Buffer比RLP要靈活的多。因此,我們選擇了一個性能稍微更差一點的Protocol Buffer,但是它的擴展性更好。

第二是數(shù)據(jù)壓縮。我們做完序列化之后,要打包成網(wǎng)絡(luò)包,發(fā)到網(wǎng)絡(luò)里面去。這里我們一定要做一個壓縮,我們現(xiàn)在用的是Google Snappy。這個算法能夠幫助我們完成50%的壓縮率,對整個網(wǎng)絡(luò)延遲的貢獻(xiàn)度實際上是相當(dāng)高的。

三、并發(fā)執(zhí)行模型

接下來我們要考慮的事情就是怎么把打包時間和驗證時間進(jìn)行縮短。這就是我們今天要講的重點。我們首創(chuàng)的并發(fā)執(zhí)行模型是什么樣的,為什么這樣設(shè)計,它為什么可以提升公鏈的性能,又是如何縮短設(shè)計的并行執(zhí)行模型時間的。

我們可以直觀地感受到所有交易被提交到區(qū)塊鏈上時,礦工打包的過程和它驗證的過程可以理解為一個有限狀態(tài)機,區(qū)塊鏈可以理解為一個狀態(tài)的集合。它有很多狀態(tài),所有交易到我們區(qū)塊鏈公網(wǎng)上來之后,實際上我們狀態(tài)的集合會發(fā)生遷移,它從某一個狀態(tài)變到下一個狀態(tài)。它就是一個有限狀態(tài)機。

在傳統(tǒng)的場景下面,這個狀態(tài)機是什么樣的呢?所有的交易被提交到公網(wǎng)上來了之后,他們對狀態(tài)遷移的過程是一個交易執(zhí)行的過程。一個交易執(zhí)行完了之后,它遷移到下一個狀態(tài),我們再基于這個狀態(tài)再接進(jìn)來一個交易,再跳到下一個狀態(tài),所以,就變成了一個串行的確定有限狀態(tài)機。

?

?

那么我們能不能把交易的執(zhí)行過程,這個串行的狀態(tài)機變成一個并行的——你提交上來10個交易,我能不能把這10個交易同時執(zhí)行,最終合并到同一個狀態(tài)集合里面去,這種情況能不能實現(xiàn)??

?

問題重重

我們上來就遇到了這樣三個問題。

?

?

第一個問題:當(dāng)我們把狀態(tài)的遷移過程從串行變成并行之后,會不會每次執(zhí)行的結(jié)果不一樣?這一過程是否為確定有限狀態(tài)機?

第二個問題:假設(shè)我們可以把所有的狀態(tài)做成并行的。那么要將多個交易并行后得到的狀態(tài)集合融合,這一過程中會不會產(chǎn)生沖突?產(chǎn)生沖突了怎么辦?有沒有辦法互不沖突?

第三個問題:在傳統(tǒng)的MySQL里有個讀寫鎖,只要讀寫不沖突就好了。但在我們并行執(zhí)行過程中是否存在一個更強的邏輯?我們是否需要事務(wù)隔離?如果不需要,我們能否讓它變成一個更加并行的狀態(tài)?

在第一個問題里,它變成并行化之后,還是不是確定的狀態(tài)機呢?很不幸它不是。這個問題非常棘手,我們可以通過一個實際例子來說明。比如說我們在初始狀態(tài)下,A和B有兩個賬戶,A有1 NAS,B和C都沒有NAS,那我們現(xiàn)在要挖一個區(qū)塊,這個區(qū)塊里面我們收到了2筆交易。

第一種情況是A到B轉(zhuǎn)賬執(zhí)行完后,B到C再轉(zhuǎn)賬,這個時候的結(jié)果就是A和B都沒有NAS了,C有一個NAS。

第二種情況是B和C可能先執(zhí)行了,A和B再執(zhí)行,但是B到C執(zhí)行的過程中,它們之間轉(zhuǎn)移一個NAS是不成功的,所以這一交易失敗,A向B則會轉(zhuǎn)移成功。最后的結(jié)果是A和C沒有NAS,B有一個NAS。顯然,我們把它并行化之后,如果這個順序被打散了,最終的結(jié)果也就不一致了。

在第二個問題里,我們能不能讓兩個交易并發(fā)執(zhí)行,在最終做狀態(tài)合并的時候互不沖突?這其實也很難做到。我們有一個很直觀的感覺,比如說A到B我們收到了一個區(qū)塊,里面有三個交易,A到B、B到C和D到E。

這樣看來,感覺“A到B”和“B到C”是相互關(guān)聯(lián)的,因為它們共享了一個地址B,而D到E似乎跟這兩個交易沒有太多的關(guān)系,是兩波不一樣的人。

那我們能不能由此把它分成兩個部分,讓A到B,B到C串行執(zhí)行,D到E跟他們并行執(zhí)行呢?這個想象很美好,但是實際上不是這樣子的。比特幣上可以這樣干,但是所有基于以太的、通用的智能合約結(jié)構(gòu),這樣都做不了。

A到B這一筆交易,它有可能不是一個普遍的轉(zhuǎn)賬,并不只是單純的NAS轉(zhuǎn)移。B可能是一個合約——這又是一個致命的問題:A到B轉(zhuǎn)賬可能會調(diào)用某一個合約,在這個合約的邏輯里,可能其中的某一條指令要從合約把一筆錢轉(zhuǎn)到另一個賬戶上去,那個賬戶有可能是D,有可能是E。

我們根本不知道用戶會在他的合約里面存什么樣的地址,結(jié)果我們想當(dāng)然地把AB、BC、DE做分割,但是可能就踩到雷了,A到B實際上是影響D到E的,這些事情在早期其實是沒有辦法預(yù)判的。所以說,我們想做到互不沖突也非常困難。

第三個問題,我們是否需要做事務(wù)隔離?

?

?

顯然,我們不能允許1、2兩個中間,互相操作相同的數(shù)據(jù),如果操作相同數(shù)據(jù)——我舉個例子,比如在2里面它先讀了X=0,在2執(zhí)行的過程中,1執(zhí)行結(jié)束了,它把X設(shè)為了1,那2還在同一個交易里面再去讀X的時候,又變成了1,實際上這個場景是不可能出現(xiàn)的。2在執(zhí)行過程中,要么X全程都是1,要么X全都是0,不可能出現(xiàn)先讀到0,再讀到1。

所以,場景里面一定要做事務(wù)隔離。

解決思路

那么要解決這三個問題,我們能干些什么?

關(guān)于第一個問題,我們從一個確定的狀態(tài)變成一個非確定的,我們需要去關(guān)注交易和交易之間的依賴關(guān)系。存在依賴關(guān)系的交易,是一定存在先后執(zhí)行順序的,比如我們常說的拓?fù)渑判蚪Y(jié)構(gòu)。所以,除了打包過程要記錄它的依賴關(guān)系以外,我們在驗證的時候,還要根據(jù)所記錄的依賴關(guān)系做最終驗證。?

?

這里我們需要做兩個事情。如果我們要記錄依賴關(guān)系的話,相當(dāng)于有兩個交易,第一個交易做完,它所有狀態(tài)修改的集合,我們是需要保存的,不然再做第二個交易的時候,都不知道它改過什么,也沒辦法去判斷依賴關(guān)系。也就是說,我們就需要保存所有的交易執(zhí)行之后的狀態(tài)集合。另外,我們要提供機制,能夠查詢兩個修改后的集合之間的精確依賴關(guān)系,這個存儲其實也是要很大開銷的。

第二個問題,我們能不能做到互不沖突?極難做到,因為我們完全不知道用戶在他的合約里面放了什么數(shù)據(jù),也極難追蹤。我們只能盡量使兩個交易互不沖突,因為我們有一個基礎(chǔ)的預(yù)判,from和to只要互不重疊,沖突的概率就會相對小一點。

我們有一個調(diào)動模型,但最終還要有一個東西來保證它們真的互不沖突。所以兩個修改后的狀態(tài)集合產(chǎn)生了之后,我們要去看這個集合里面都修改過什么?增刪查改4個操作他們都做過什么?對同一個數(shù)據(jù)做的增刪查改,哪種場景下是沖突的,哪種是不沖突的?我們需要定義這個沖突模式。?

?

與此同時,我們也需要保存所有修改后集合的狀態(tài),因為我們最終需要去判斷兩個集合是否相互沖突,和第一個問題一樣,我們需要一大筆存儲的開銷。

到了第三個問題,我們要做事務(wù)隔離。比如交易1執(zhí)行之前的狀態(tài)是0,交易2在執(zhí)行之前狀態(tài)也是0,1和2可能并行執(zhí)行。這一過程中,可能都會對0那個狀態(tài)的數(shù)據(jù)做修改,但他們一旦修改做了重疊之后影響了其他交易的執(zhí)行,這就不是事務(wù)隔離。所以我們還要保證一點:1和2在做執(zhí)行的過程中,他們所依賴的前提的狀態(tài)都是0,相當(dāng)于把0的狀態(tài)拷貝兩份,給他們各自一份作為初始條件。

?

?

除了要把所有交易的修改集合保存以外,我們還要把所有的交易最開始依賴的初始條件保存,這樣看的話,又是一大堆東西要存,而且這個場景是事務(wù)隔離,這個交易可能會失敗,需要讓它回滾。所以算法復(fù)雜度也提高了,我的存儲復(fù)雜度也提高了。

解決方案

?

?

為了解決這幾個問題,我們做了三個事情:

第一,我們把所有的狀態(tài)統(tǒng)一到一起。原來的狀態(tài)是分散的,我們不知道如何判斷不同狀態(tài)之間的沖突關(guān)系和依賴關(guān)系。所以我們在這邊做了一個叫World State的工具,把所有的狀態(tài)都統(tǒng)計、管理起來。你在增刪查改任何東西之前,可以通過它來判斷沖突、查看狀態(tài)。

World State只是一個管理工具,那數(shù)據(jù)存在哪呢?我們還要存所有的交易修改之后的狀態(tài)、和所有交易執(zhí)行前的狀態(tài)。而且在這個過程中,我們還得去判斷它的依賴關(guān)系、沖突關(guān)系,實際上是要把每一份都拷貝一份,這個事情非常好解決。但實際上是不可行的,比如說TPS要上萬,相當(dāng)于是一秒鐘以內(nèi)要復(fù)制1萬份;要上百萬,就要復(fù)制上百萬份…相當(dāng)于是TPS越高,要的存儲就越高,哪幾臺機器能夠扛得住這么大的存儲呢?

所以第二件事是,我們設(shè)計了一個結(jié)構(gòu)來簡化這個存儲,這個名字叫做“支持嵌套事務(wù)的多版本控制并發(fā)數(shù)據(jù)庫(MVCC DB)”,這個結(jié)構(gòu)在我們的代碼里面已經(jīng)開源了,大家如果感興趣可以看一下里面更多的細(xì)節(jié)。

第三個,我們剛剛說它變成一個非確定性狀態(tài)機,要根據(jù)依賴關(guān)系來構(gòu)建結(jié)構(gòu)。它實際上是個拓?fù)鋱D,會隨著網(wǎng)絡(luò)傳播到下一個驗證者那里,那個驗證者會根據(jù)它的拓?fù)渑判蚪Y(jié)構(gòu)做一個調(diào)度,哪些交易可并行執(zhí)行,哪些交易必須等到上一個交易執(zhí)行完之后才能做,這里就要有一個拓?fù)鋱D的執(zhí)行引擎,來保障我們最終完成的一致性。

四、性能評測

這是我們整個模型在公鏈上跑出來的測試數(shù)據(jù)。我們可以看一下這樣的結(jié)構(gòu)給我們的性能帶來了哪些變化。

?

?

我們的機器是i7,四核,純智能合約的交易,在一秒內(nèi)我們嘗試打包,我們可以看到下面分別是一個核、兩個核和四個核的狀態(tài),這個數(shù)據(jù)實際上是線型增長的。

所以如果我們控制了更多的核,這個數(shù)據(jù)還會不斷往上漲,直到哪一天它遇到了IO瓶頸——就像右邊純轉(zhuǎn)賬交易測試數(shù)據(jù)看到的,我們也是一個核、兩個核、四個核在做,但是它達(dá)到一個高度之后,它就遇到了IO瓶頸,我本機的IO撐不住這么多的場景了,這以后它增長的速度就開始放緩了。

我們現(xiàn)在本機是四核的,在線上跑的是八核的。線上8核情況下,合約交易和轉(zhuǎn)賬交易混合的場景下,我們最高測出了2000TPS。EOS單條鏈測的大約是1000-3000TPS,它的機器設(shè)備是128核的配置,網(wǎng)絡(luò)是10GB/s直連,也就是說128核做到了1000-3000。實際上我們通過8核已經(jīng)做到了,而且我們橫向擴展到128核的話,性能還會提升。從這個角度來說,我們的性能是會擴展得比它更好的。

當(dāng)然我們現(xiàn)在只是一個模型結(jié)構(gòu)的優(yōu)化,沒有對IO做任何的優(yōu)化,接下來我們實際上有一套IO的優(yōu)化策略要去執(zhí)行,那部分做完之后,我們的性能實際上會比EOS高的多得多。

這些是我們目前已經(jīng)完成的工作。

五、未來發(fā)展方向

最后,我們來看一下現(xiàn)在的行業(yè)內(nèi)部都在如何優(yōu)化他們各自供應(yīng)鏈的性能。

算法優(yōu)化

首先是一個縱向的優(yōu)化。在所有的結(jié)構(gòu)確定下來之后,你可以把你的算法,把IO速度做優(yōu)化。我們?nèi)ミx取交易做并發(fā)的時候,選取策略也可以做優(yōu)化,包括我們在做網(wǎng)絡(luò)傳輸?shù)倪^程中,每一個交易的from和to實際上是很長的。但這個交易除了廣播到了我以外,也廣播到了所有其他的人。也就是說,其他人手上是有它的from和to地址的,那我在網(wǎng)絡(luò)傳輸過程中,是否可以優(yōu)化策略,就不用傳這些信息了。通過這樣的方式我們可以減少網(wǎng)絡(luò)包大小,把網(wǎng)絡(luò)延遲拉低,也能整體延長我們的TPS。

這是在已有框架內(nèi)的優(yōu)化方向,那么如果你有條件改框架的話,你能做哪些事情呢?

提升CPU核數(shù)以提升性能,這實際上是一個橫向擴展的機制。

所有的挖礦節(jié)點,網(wǎng)絡(luò)直連,就像EOS做的那樣,網(wǎng)絡(luò)延遲速度幾乎可以忽略不計,這樣的話,TPS也高,所以它做到了0.5秒出塊。

以太V神提出的sharding

這個sharding是什么概念呢?以太現(xiàn)在是一條單鏈,他想通過多鏈結(jié)構(gòu)來提升它的性能。在多鏈狀態(tài)里,并不是說你擁有一個錢包,你就可以在多鏈上自由買賣。你在A鏈上有100個ETH,你在B鏈上你沒有這100個ETH,你如果要用B鏈的服務(wù),你首先需要把你的錢從A鏈轉(zhuǎn)到B鏈。

這樣看來,多鏈結(jié)構(gòu)并沒有給大家?guī)砣魏螌嵸|(zhì)便利性,所以他提的sharding,我個人認(rèn)為是一個偽命題。既然是這樣一個sharding模式的話,你為什么要把所有人綁在你的多鏈里面呢?你為什么是一個側(cè)鏈的結(jié)構(gòu),而不是單獨的另外一條鏈,通過跨鏈協(xié)議的方式讓大家交互起來,最終就變成網(wǎng)絡(luò)里面上千萬條鏈,都是以太,但是這些鏈之間可以通過跨鏈協(xié)議彼此互連,數(shù)據(jù)共享。每一條線每天都能提供百萬TPS,對于任何一個單獨的廠商來說,是足夠使用的。所以我們覺得sharding是一個偽命題,跨鏈才是真命題。

最近比較火的Nervos

他們提出一個方案,不要把計算放在公鏈的礦工節(jié)點去做計算,而是放在客戶端去做計算,你算完以后給我就好了。你在算的過程中,要把所有的依賴關(guān)系和沖突都算好,我這邊只做驗證。這個角度上來看的話,它把我們之前并行的結(jié)構(gòu)通過另外一個方案,從一個非確定狀態(tài)機變成了一個確定狀態(tài)機。理論上可行,但是這里面存在一個重大的問題在于,在客戶端完成計算,如何在服務(wù)端進(jìn)行驗證?如何保證兩種運算的一致?

區(qū)塊鏈共識,這是清華的姚期智教授參與做的方案,將區(qū)塊變成一個DAG。

在某一個高度上,你可能挖出了10個區(qū)塊,這10個區(qū)塊并不是只有一個被網(wǎng)絡(luò)接受,而是10個都被網(wǎng)絡(luò)接受,這10個里面包含的交易能夠有一個算法達(dá)成最終一致性。

純DAG模式

實際上,純DAG現(xiàn)在還面臨著眾多問題,每個人在自己的節(jié)點上看到的數(shù)據(jù)都不一樣,那你怎么保證最終的一致性?每個時間窗口的強一致性?這些都是存在的問題。

區(qū)塊 交易 里面 狀態(tài) 網(wǎng)絡(luò)
分享到:

1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉(zhuǎn)載的稿件都會明確標(biāo)注作者和來源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請轉(zhuǎn)載時務(wù)必注明文章作者和"來源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為TMT觀察網(wǎng)或?qū)⒆肪控?zé)任;
3.作者投稿可能會經(jīng)TMT觀察網(wǎng)編輯修改或補充。


專題報道

主站蜘蛛池模板: 国产精品网站在线观看 | 亚洲精品一线二线三线 | 精品午夜久久网成年网 | 国产精品人人视频 | 99视频在线免费观看 | 亚洲激情自拍偷拍 | 国产福利一区二区三区四区 | 亚洲AV永久无码精品澳门 | 色淫阁小说 | 亚洲色欲色欲综合网站 | 国产亚洲综合久久 | 亚洲欧美专区精品伊人久久 | 免费人成在线观看视频播放 | 欧美亚洲国产一区二区三区 | 极品丝袜乱系列在线阅读 | 暖暖中国免费观看高清完整版 | 国产福利不卡一区二区三区 | 国产一级特黄在线播放 | 色姑娘久久 | 九哥草逼网 | 网站视频免费 | 希岛爱理作品在线观看 | 91动漫在线观看 | 日本在线视频播放 | 侵犯小男生免费视频网站 | 奇米7777第四色 | 99精品免费在线 | 欠操h| 亚洲香蕉伊在人在线观婷婷 | 欧洲美女人牲交一级毛片 | 放荡护士玩3p口述 | 国产小视频网站 | 草莓视频看污 | 校园春色自拍偷拍 | 久久这里只有精品视频9 | 99在线视频精品费观看视 | 青青草国产精品久久碰 | 九九国产在线视频 | 日本红怡院亚洲红怡院最新 | 精品午夜寂寞影院在线观看 | 久久精品视频在线看 |