毛寧,李霞,丁明月,李秦偉
(貴州大學計算機科學與技術學院,貴州550025)
區塊鏈技術也即分布式賬本技術,起源于2009年,現在正逐漸發展成為一個去中心化、分布式、去信任的技術方案[1]。利用區塊鏈的共識算法、密碼學、智能合約等技術,以及透明化、可追溯、不可篡改等特性[2],將其應用于電商平臺,能夠解決商品難辨真假、數據透明與隱私保護難以平衡、監管與信息追溯困難、電商平臺、買家用戶、賣家網店之間不能完全信任等諸多實際問題。
就電商平臺而言,因為其實際實施情況和特點,使得區塊鏈技術的使用受到限制,在實際操作中,商家節點總是會出現很多情況,導致完全照搬類似比特幣等區塊鏈技術是行不通的。所以需要一種折中的方案,既能使用區塊鏈技術也能提高交易效率并促進電商平臺模式創新[3]。
本文以聯盟鏈作為應用場景,應用于節點數量較少的小型電商平臺,針對鏈狀態不一致的問題,設計一種隊列同步方案(Queue Synchronization,QS)使得塊數據落后的節點能在不影響共識的情況下恢復丟失的信息。
在以聯盟鏈為應用場景,應用在節點數目較少的小型電商系統中,鏈狀態不一致問題更為突出。一是因為系統中的節點數量較少,對系統的影響大,二是因為系統中節點狀態變化很快。這些實際情況就會讓各節點區塊鏈狀態的一致性變得非常脆弱,很大可能會導致某些節點區塊鏈的塊數據落后于其他節點的塊數據,從而破壞系統的安全性與可用性。如何使塊數據落后的節點與正常節點鏈狀態達到一致,正是需要研究的一個問題。
將區塊鏈技術引入到這樣一種小型平臺下,因為實際應用場景的限制,而存在著一些與理想情況不相適應的問題。智能合約的完全去中心化也無法完全避免技術上的操作風險[4]。在該小型電商平臺中,分布式環境并不太穩定,這樣可能會使得狀態滯后的節點與某些一直在線節點的鏈狀態不一致。不僅如此,電商系統中,新加入的商家節點數量更新很快,新節點需要同步歷史區塊。綜上,以下兩種情況最有可能導致鏈狀態不一致問題:
(1)節點離線后恢復,離線原因可能是故障或者關機,在離線期間因未參與共識建塊,從而導致該節點區塊數據落后,出現鏈狀態不一致。
(2)新節點的加入,新節點加入后是沒有歷史區塊數據的,這樣新節點鏈狀態肯定和其余節點的鏈狀態不一致。
以上兩種情況都是電商平臺中經常出現的,恰恰就是這些“正常”情況,會導致節點出現鏈狀態不一致問題。
由上面所描述的實際情況,可以看出在這樣一個電商平臺系統背景下,鏈狀態不一致是一個很容易出現的情況,并且這種情況很難規避。所以重點就落在了如何高效的解決這個問題。針對區塊同步問題,以太坊給出了三種模式的解決方案:
(1)fast:直接通過網絡同步狀態數據,在同步到當前塊之前不進行任何事務的處理,只對區塊里的數據進行校驗。節省了時間,但該模式可能對歷史數據有部分丟失,不過不影響今后使用。
(2)full:全節點同步,需要下載所有的區塊數據信息,該模式最安全但相當費時,能得到所有的歷史數據。
(3)light:只同步區塊頭數據,可以完成基本的命令操作,速度快,適用于較低配置的設備中。
因為本文所描述的應用場景與以太坊或比特幣等應用場景有很大的區別,所以它們的區塊同步方案的實施會收到很大的限制。本文所設計的方案應用于節點數目較少的小型電商平臺中,旨在不影響系統性能與共識的基礎上解決鏈狀態不一致問題。
為了解決上述電商平臺下的節點鏈狀態不一致問題,設計出了一種隊列同步方案,在該方案中,每個節點都有一個缺失隊列(Defective Queue)和隊列掃描器(Queue Scanner),缺失隊列存儲節點所缺失的區塊信息,隊列掃描器定時掃描缺失隊列中是否存有數據。方案設計兩個部分:狀態檢測模塊和狀態同步模塊。
QS能實現的前提是系統滿足拜占庭算法[5]。在聯盟鏈和私有鏈中,大多使用了經典的實用拜占庭容錯算法(PBFT)。在惡意結點數目不超過限制時,該算法的正確性可被嚴格證明[6]。假設系統中惡意節點、離線節點、鏈狀態待同步節點的總數為f,那么系統中節點總數至少應該為3f+1。或者換句話說,當系統中非正常節點數量為f時,只要節點總數超過3f,QS就能實現對數據丟失節點鏈狀態的同步。
將本文所用到的符號進行說明:
(1)m:節點廣播的交易哈希值
(2)t:時間戳
(3)σi:節點i用MAC技術對信息進行簽名
(4)flag:標記,即區塊在區塊鏈中的位置
(5)flagi:節點i中最新區塊的標記
(6)F:標準標記,系統中正常節點的最新區塊的標記
(7)DQ:缺失隊列
(8)Scanner:隊列掃描器
(9)DF:缺失隊列中位于隊首位置的區塊標記
(10)Ni:節點i的節點編號
(11)block:區塊
(12)data:交易數據
●狀態監測模塊:
在系統中,因為每個節點都會接收交易并全網廣播交易哈希值,所以當每個節點廣播交易的哈希值的時候就是觸發狀態檢測模塊的時候。假設節點NodeA準備廣播交易哈希值,則它廣播的消息如{m,{STATUS_CHECK,Ni,t}σi},其他節點收到消息后回復如下消息 {STATUS_REPLY,Nj,flagj,t}σj。因為系統滿足拜占庭算法,所以NodeA會收到超過2/3個節點發來的flagj是相等的,并且是最大值,將這個值記為標準標記F。之后節點對比自己鏈中最新區塊的標記和F的大小,如果小于F,則該節點需要進行鏈狀態同步,就將自己所缺失區塊的標記按照順序存入缺失隊列,并且將最新區塊的標記強制更新為F,使得該節點能夠和正常節點一樣,參與標記F之后的區塊的共識建塊。假設NodeA最新區塊的標記為H,H<F,則需要將H+1,H+2,…,F等標記按照順序存入缺失隊列隊尾,并將H的值更新為F。如果H=F則不需要將標記存入隊列中,到此,狀態檢測模塊結束。

圖1 缺失隊列功能示意圖
該模塊的作用是檢測節點是否需要進行鏈狀態的同步,如果需要就將節點所缺失區塊的標記存入缺失隊列,為狀態同步模塊做準備。并且將節點最新區塊的標記更新后,使得該節點能夠繼續參與后續共識,避免了節點在同步歷史區塊的同時,新區塊不能及時上鏈。模塊執行過程中系統的運行與共識不受到影響。算法過程如下,其中Message表示節點廣播的交易哈希值時廣播的消息。
Begin
1:if某一節點廣播Messagethen
2:if Message中含有STATUS_CHECK請求then
3: F←Max(flaga,flagb,flagc...)
4: if H <Fthen
5: for temp←H+1 to F
6: DQ.push(temp)
7: H←F
End

圖2 狀態檢測模塊流程圖
●狀態同步模塊:
隊列掃描器按照事先設定的時間間隔定時對缺失隊列進行掃描。如果發現缺失隊列不為空,就將在隊首位置的標記(DF)出隊,然后將DF封裝成一個索要區塊的請求消息{BLOCK_SYN_REQUEST,Ni,DF,t}σi,然后將該消息進行廣播,其余節點收到請求消息后,就在自己的鏈中查找標記為DF的區塊,如果找到了,就向編號為Ni的節點回復如下消息{BLOCK_SYN_REPLY,Nj,DF,block,data,t}σj。節點統計收到的塊(block)和交易數據(data)。如果發現超過2/3個節點發來的消息中塊和交易數據是一致的,就可以將該區塊補充上鏈。如果小于2/3,則再將該區塊的標記重新存入缺失隊列的隊尾,等待下一輪處理。因為其他節點回復的消息中有對應區塊的標記,所以節點在進行消息匯總統計時,不會引起混淆。一旦隊列掃描器掃描到缺失隊列中有數據時,就會觸發狀態同步模塊完成對丟失區塊的補充。
整個QS在執行的過程中,是完全沒有影響到系統的共識過程的。通過狀態檢測中對最新標記的更新使得系統中的所有節點均在參與共識,使得丟失區塊的節點能夠對后續區塊進行共識建塊,同時狀態同步模塊也在對丟失區塊進行補充。整體達到了系統的共識與鏈狀態同步互不干擾的目的,在保證了系統性能與可用性的基礎上解決了鏈狀態不一致的問題。算法過程如下:
鏈狀態待同步節點,Scanner定時掃描DQ,封裝并發送區塊索取請求消息。
Begin:
1:Scanner掃描 DQ
2:if DQ不為空then
3: DF←DQ.pop()
楊嬈:在北方,冬天說降溫就降溫,哪怕昨天還是晴朗天,也不影響第二天大風呼嘯,氣溫驟降。在整個冬天,我就反反復復地感冒,沒幾天舒服的時候。懷孕感冒了,不敢隨便亂吃藥,只能硬挺著。我也很奇怪,為什么冬天孕媽媽這么容易感冒呢?
4: 封裝并發送{BLOCK_SYN_REQUEST,Ni,DF,t}σi
5: 統計收到的{BLOCK_SYN_REPLY,Nj,DF,block,data,t}σj中的block與data
6: if超過2/3數據相同then
7: 存儲block與data
8:else
9: DQ.push(DF)
10:goto1
12:goto 1
End
其余節點,接收區塊索取請求消息,若查詢到相同區塊則進行消息回復。
Begin
1:if收到 {BLOCK_SYN_REQUEST,Ni,DF,t}σithen
2:if查詢到相同的區塊then
3: 回復{BLOCK_SYN_REPLY,Nj,DF,block,data,t}σjEnd

圖3 狀態同步模塊流程圖
在以聯盟鏈為應用場景,應用在節點數目較少的小型電商系統中,傳統的區塊鏈技術在這樣的環境下會受到很多限制。首先在小型電商平臺中,做到完全去中心化是不太實際的,其次,商家節點狀態變化快、新商家節點加入頻繁。這些原因都使得電商平臺系統中的節點鏈狀態極大可能出現不一致,導致某些節點鏈中塊數據丟失。本文針對這一問題提出隊列同步方案,通過狀態檢測和狀態同步兩個模塊完成鏈狀態的同步,并且整個過程不會影響系統的共識建塊過程,是在保證了系統性能與可用性的前提下完成鏈狀態同步的方案。