比特幣源碼解讀十八(挖礦)

? ? ?本篇我們就看挖礦成功后對區(qū)塊的有效性進行檢測的代碼。也就是CheckWork所做的事情。檢驗之時,線程的優(yōu)先級必須為THREAD_PRIORITY_NORMAL。現(xiàn)在我們就直接看下CheckWork()函數(shù)的代碼邏輯。

CheckWork檢測

通過代碼我們看到在進行ProcessBlock()正式檢測之前要對難度值和父區(qū)塊進行檢測。如果這兩項檢測通過后,再正式調(diào)用ProcessBlock()進行新挖區(qū)塊的檢測。需要說明的是這個ProcessBlock()區(qū)塊檢測和從其他節(jié)點發(fā)送過來的區(qū)塊信息("block")檢測過程是一樣的。都是調(diào)用這個ProcessBlock()進行檢測。

? ? 我們現(xiàn)在就進入ProcessBlock()函數(shù)進行源碼解讀,由于這個函數(shù)很大,檢測項目很多,我們也向往常一樣分段來分析解讀:

對塊的基本信息和擴展信息檢測

上在的代碼對是否是舊塊(重復(fù)添加),基本信息(checkBlock()),和擴展信息進行了檢測,塊的基本信息檢測包括:1。塊的大小,2。(工作量證明)CheckProofOfWork 3。時間戳(區(qū)塊時間戳早于驗證時刻未來兩個小時)4。塊的第?一個交易信息必須是coinbase和有且有一個coinBase交易5。交易信息(CheckTransaction)6。檢測多重支付(有2個或以上的同樣的交易信息)7。簽名的有效性8。MerkleRoot(默克樹根)的有效性。

現(xiàn)在我們就看下checkBlock()的源碼,就是按照這樣一個檢測列表進行檢測的:

基本信息檢測

上面對基本信息和擴展信息進行了檢測,我們接著往下看:

檢測孤塊和存儲區(qū)塊數(shù)據(jù)到磁盤中

我們說一下孤塊的概念和形成原因

如果節(jié)點收到了一個有效的區(qū)塊,而在現(xiàn)有的區(qū)塊鏈中卻未找到它的父區(qū)塊,那么這個區(qū)塊被認為是“孤塊”。孤塊會被保存在孤塊池中,直到它們的父區(qū)塊被節(jié)點收到。一旦收到了父區(qū)塊并且將其連接到現(xiàn)有區(qū)塊鏈上,節(jié)點就會將孤塊從孤塊池中取出,并且連接到它的父區(qū)塊,讓它作為區(qū)塊鏈的一部分。當兩個區(qū)塊在很短的時間間隔內(nèi)被挖出來,節(jié)點有可能會以相反的順序接收到它們,這個時候孤塊現(xiàn)象就會出現(xiàn)。

現(xiàn)在我們看AcceptBlock是如何將新區(qū)塊存儲到磁盤中的,在寫入磁盤之前還要進行精確的POW校驗。我們就直接通過源碼來看下這個校驗列表,這個函數(shù)很長,我分兩部分截圖來看:

一。區(qū)塊普通檢測

寫入?yún)^(qū)塊校驗1

二。區(qū)塊版本檢測

區(qū)塊版本校驗

通過區(qū)塊版本檢測可以看到這里是用于區(qū)分比特幣分叉之后的處理,這里用的方案就是平常說的大數(shù)投票方案(IsSuperMajority)簡稱ISM,這個方案的規(guī)是這樣的,大家可以對著代碼了解:

1.在對比特幣協(xié)議進行升級時,是用區(qū)塊的nVersion進行+1區(qū)分的。

2.升級開始后,如果在過去1000個區(qū)塊(6~7天)內(nèi),有750個區(qū)塊的nVersion為新版本號(也就是說75%的算力已升級),那么新功能會被激活。所有新版本軟件產(chǎn)生的區(qū)塊會按照新規(guī)則進行驗證,未驗證通過會被拒絕。而舊版本軟件產(chǎn)生的區(qū)塊依然按照舊規(guī)則進行驗證,只要合格同樣可被網(wǎng)絡(luò)接受。

3.在版本號大于等于2的區(qū)塊中,達到在過去1000個區(qū)塊內(nèi)有950個區(qū)塊的nVersion為新版本號,那么所有由舊版本軟件產(chǎn)生的舊版本號區(qū)塊會被拒絕,這樣軟分叉激活就完成了。

我把IsSuperMajority函數(shù)截出來,大家可以更深刻的理解下。

IsSuperMajority函數(shù)

對版本檢測完成后,下面就開始真正的寫入磁盤了。

存儲和廣播區(qū)塊

到這里基本上一個區(qū)塊挖出來后就已經(jīng)被記錄下來了,但我們還有一個沒有處理,那就是孤鏈池,就是如果有此區(qū)塊的子區(qū)塊,則可以被鏈記錄了。所以ProcessBlock()最后的部分就是處理孤鏈池。

循環(huán)處理孤鏈池

這個函數(shù)循環(huán)孤鏈池mapOrphanBlocksByPrev,通過區(qū)塊hash值不斷循環(huán)查找。然后調(diào)用AsseptBlock()處理所有依賴此區(qū)塊的孤塊。

到這里基本上一個挖礦的過程就完了,我們基本上了解挖礦的過程,和挖礦成功后是如何處理最新的交易和區(qū)塊的。最后又是如何進行全網(wǎng)廣播的,大家可以在源碼中了解更詳細的處理。

我們?nèi)绻欣斫獠粚Φ牡胤?,歡迎大家指正。



作者:區(qū)塊鏈研習(xí)社比特幣源碼研讀班,black

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容