作為本文的讀者,可能大部分都進(jìn)行過(guò)eos代幣的轉(zhuǎn)賬操作。我們平時(shí)的交易過(guò)程中,能體驗(yàn)到【立馬到賬】的感覺(jué),這也是eos被越來(lái)越多的人認(rèn)可的重要原因。然而在區(qū)塊鏈系統(tǒng)中一筆交易是否完成,有一個(gè)很重要的因素就是該筆交易在鏈上是否是可逆的。今天我們就來(lái)談?wù)勔还P交易在什么情況下才是不可逆的。
在行文之前首先感謝大佬Raymond及荊凱給予的幫助,同時(shí)建議了解下交易的基礎(chǔ)知識(shí),荊凱大佬曾經(jīng)寫(xiě)了一篇文:
【一五一十】EOS轉(zhuǎn)賬背后,發(fā)生了什么: EOS交易的狀態(tài)
在文中提到有個(gè)pending的倒計(jì)時(shí),同時(shí)幣乎的作者阿華區(qū)塊鏈寫(xiě)過(guò)的幾篇文章,特別分析了一下當(dāng)前區(qū)塊高度與不可逆區(qū)塊高度之間的關(guān)系,得到的結(jié)論是,大約不可逆區(qū)塊與當(dāng)前區(qū)塊高度相差在334個(gè)區(qū)塊左右,換算成時(shí)間的話,大致是2.7分鐘左右。那么這個(gè)pending倒計(jì)時(shí)是什么,和區(qū)塊的不可逆之間有什么關(guān)系呢。
我們都知道在eosio中使用了DPoS共識(shí)機(jī)制而非類(lèi)比特幣的Pow共識(shí)機(jī)制。DPoS機(jī)制的基本邏輯是一筆交易打包在區(qū)塊之后,需要21個(gè)超級(jí)節(jié)點(diǎn)中的2/3以上的節(jié)點(diǎn)進(jìn)行簽名確認(rèn),才認(rèn)為是不可逆的。而節(jié)點(diǎn)生產(chǎn)區(qū)塊的
速度為0.5秒一個(gè)區(qū)塊,每個(gè)節(jié)點(diǎn)輪流出塊的過(guò)程中在6秒的時(shí)間內(nèi)生產(chǎn)12個(gè)區(qū)塊。為什么設(shè)置6秒生產(chǎn)12個(gè)區(qū)塊,BM在一些回答中提到:
6 seconds was chosen based upon the "maximum downtime" if a producer
goes off line. This matches Steem & BitShares where a single missed
block creates 6 seconds without any confirmation.
簡(jiǎn)單的翻譯下:之所以選擇6秒鐘是和節(jié)點(diǎn)離線的最大時(shí)長(zhǎng)有關(guān)的。
那么我們來(lái)設(shè)想一筆交易執(zhí)行節(jié)點(diǎn)A將交易信息打包至區(qū)塊中,此時(shí)節(jié)點(diǎn)A已經(jīng)確認(rèn),在執(zhí)行完成之后還需要至少2/3以上的節(jié)點(diǎn)去確認(rèn)。在eosio設(shè)計(jì)之初,節(jié)點(diǎn)確認(rèn)只需要進(jìn)行一輪即可,但在eos主網(wǎng)上線之前V神提出了不同的意見(jiàn)并給出了相關(guān)的建議,針對(duì)原有設(shè)計(jì)的安全性進(jìn)行舉例分析,感興趣的同學(xué)可以關(guān)注下這個(gè)issue:
https://github.com/EOSIO/eos/issues/2718
V神的質(zhì)疑:

BM的回答:

注:本來(lái)標(biāo)題想搞笑一點(diǎn)這樣寫(xiě)的:震驚!V神和BM竟如此互懟。
最終,在eosio中,DPoS的節(jié)點(diǎn)確認(rèn)修改為兩輪,而V神提到的這篇論文,筆者還在研讀,如有感興趣的也可以一起交流。
我們接著來(lái)看。當(dāng)一筆交易完成打包之后,意味著當(dāng)前節(jié)點(diǎn)以確認(rèn),還需要至少21個(gè)超級(jí)節(jié)點(diǎn)中的2/3以上確認(rèn),而加上需要兩輪確認(rèn),因此我們可以做出如下計(jì)算:

此處也基本可驗(yàn)證上面荊凱和阿華提到的當(dāng)前區(qū)塊高度和不可逆區(qū)塊高度之間的差值,最大為336。我們?cè)诓樵冎骶W(wǎng)的信息也可以看到類(lèi)似的情況,兩者之間的差值為335:

而根據(jù)一個(gè)區(qū)塊生產(chǎn)的時(shí)間為0.5秒計(jì)算,從交易執(zhí)行結(jié)束到變?yōu)椴豢赡鏍顟B(tài)所需要的時(shí)間應(yīng)為168s。當(dāng)然由于網(wǎng)絡(luò)的原因,這個(gè)不可逆狀態(tài)或多或少的會(huì)產(chǎn)生一些時(shí)間上的差異,那么我們是否可以從代碼中找到蛛絲馬跡來(lái)判斷何時(shí)是不可逆的么。
在前面的文章我們分析出塊流程的時(shí)候有這個(gè)步驟:當(dāng)前區(qū)塊高度小于最后一個(gè)不可逆區(qū)塊高度的時(shí)候,這個(gè)交易便是不可逆的了,來(lái)看:
1const auto& gpo = db.get<global_property_object>();
2 if( gpo.proposed_schedule_block_num.valid() && // if there is a proposed schedule that was proposed in a block ...
3 ( *gpo.proposed_schedule_block_num <= pending->_pending_block_state->dpos_irreversible_blocknum ) && // ... that has now become irreversible ...
4 pending->_pending_block_state->pending_schedule.producers.size() == 0 && // ... and there is room for a new pending schedule ...
5 !was_pending_promoted // ... and not just because it was promoted to active at the start of this block, then:
6 )
代碼中也對(duì)區(qū)塊的幾種狀態(tài)給出了解釋即:當(dāng)前節(jié)點(diǎn)生產(chǎn)區(qū)塊的高度小于最后一個(gè)不可逆區(qū)塊的高度時(shí)便為不可逆的。
本文從各位大佬已經(jīng)積累的經(jīng)驗(yàn)出發(fā),從代碼及平時(shí)測(cè)試的經(jīng)驗(yàn)來(lái)分析DPoS機(jī)制中一筆交易最后是如何實(shí)現(xiàn)不可逆的過(guò)程。當(dāng)然理解可能 也有偏差,還請(qǐng)各位多多指教。
如果你覺(jué)得我的文章對(duì)你有一定的幫助,請(qǐng)點(diǎn)擊文章末尾的喜歡該作者。
如果你對(duì)eos開(kāi)發(fā)感興趣,歡迎關(guān)注本公眾號(hào),一起學(xué)習(xí)eos開(kāi)發(fā)。

微信公眾號(hào)
有任何疑問(wèn)或者指教請(qǐng)?zhí)砑颖救藗€(gè)人微信,當(dāng)然有對(duì)eos開(kāi)發(fā)感興趣或者金庸粉的也可以添加一起交流,備注eos開(kāi)發(fā)或金庸。

個(gè)人微信號(hào)