中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么進行PBFT共識算法分析及Java實現

發布時間:2021-12-18 13:44:26 來源:億速云 閱讀:240 作者:柒染 欄目:互聯網科技

怎么進行PBFT共識算法分析及Java實現,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

PBFT共識算法詳細分析及Java實現

為什么寫這個

最近研究了區塊鏈相關的一些東西,其實就三大塊:

  1. 分布式存儲(去中心)

  2. 共識機制

  3. 安全加密 分布式存儲,就是一個分布式數據庫,每個節點都保存一份副本。通過非對稱秘鑰,hash等技術對操作數據進行簽名,驗證摘要,可追溯,以鏈式結構存儲,互相以hash摘要校驗數據,防篡改。以拜占庭容錯共識算法解決節點間的通信,達成一致協議。

區塊鏈協議簡介

分布式共識算法是分布式系統的核心,常見的有Paxos、pbft、bft、raft、pow等。區塊鏈中常見的是POW、POS、DPOS、pbft等。 其中:

  • POW、POS、DPOS是開放式的共識協議

  • PBFT為半開放式的共識協議

  • Paxos、raft等是封閉式共識協議

區別:

  • 開放式,無法確切的知道節點的多少及連接狀態,每個節點都可能是惡意的,但是大多數是非惡意的

  • 半開放式,可以確定節點的多少及連接狀態,每個節點都可能是惡意的,但是有滿足一定條件的非惡意節點

  • 封閉式,每個節點都是非惡意的,只不過可能斷開連接或crash。

性能: 從上往下越來越高

總結:

  • 私有鏈是封閉生態的存儲系統,采用Paxos、raft最佳

  • 聯盟鏈有半公開半開放特性,因此拜占庭容錯的PBFT算法比較合適

  • 公有鏈來說,POW、POS、DPOS是比較適合的高安全性的協議

那么,下面我們要說的就是聯盟鏈性質的共識協議:PBFT算法協議。 協議誕生已經很久了,網上的文章也不少,然而基本都是翻譯原論文,稍加一些個人的閱讀心得,細致的分析還是比較少,一些關鍵的銜接點沒有說清楚,粗看好像都懂,但是真正要實現起來,還是有比較多坑。于是本人采用demo的方式,以多線程模擬多節點,實現完整的PBFT算法,其中有一些問題,記錄下來,供各位參考,討論。

PBFT算法簡介


PBFT協議簡單步驟:

主要有三個階段:預準備(pre-prepare)、準備(prepare)、和確認(commit)

  1. 從全網節點選舉出一個主節點(Leader),新區塊由主節點負責生成。

  2. 其中一個節點的客戶端向主節點發起請求。

  3. Pre-Prepare:主節點分配一個序列號n給收到的請求(順序的保證!),并向全網廣播<<PRE-PREPARE,v,n,d>,m>

  4. Prepare:每個節點接收到交易請求后,模擬執行這些交易,驗證交易報文的正確性。驗證通過后,存入預備列表,并向全網廣播<PREPARE,v,n,d,i>

  5. Commit:如果一個節點收到的2f(f為可容忍的拜占庭節點數)個其它節點發來的PREPARE消息摘要都和自己相等,就向全網廣播一條commit消息<COMMIT,v,n,D(m),i>

  6. Reply:如果一個節點收到2f+1條commit消息,即可提交新區塊及其交易到本地的區塊鏈和狀態數據庫(操作確認完成)。

問題分析


整個協議理解起來還算比較簡單,但是這里面有好些問題,需要一一的剖析。

  1. 主節點怎么產生?

  2. 主節點失效了怎么辦?

  3. 主節點造假怎么辦?

  4. 數據怎么重傳?

主節點的產生

因為節點的操作都需要通過主節點,所以每個節點啟動后的第一件事,找主節點。 主節點由公式p = v mod |R|計算得到,這里v是視圖編號,p是副本編號,|R|是副本集合的個數。 所以其實找主節點就是初始化視圖view。

  1. 全網廣播獲取視圖協議:

public static final int VIEW = -1;
  1. 超過2f+1的節點回復的view作為初始化的view(q1:如果無法滿足怎么辦?)

if(this.viewOk)return;
long count = vnumAggreCount.incrementAndGet(msg.getVnum());
if(count >= 2*maxf+1){
	vnumAggreCount.clear();
	this.view = msg.getVnum();
	viewOk = true;
	System.out.println("視圖初始化完成["+index+"]:"+ view);
}
主節點失效了(這里失效指應用掛掉、或被他人控制作惡)

誰先發現主節點失效了,當然,這里是不能通過連接斷開來看,因為即使tcp連接正常,也不一定業務處理正常。答案是,超時控制。 當發起請求的節點在超時時間內沒有完成操作確認,則可以懷疑主節點失效,于是:

  1. 客戶端全網廣播超時的請求報文,為什么不用一個專門的包來發起失效提議?主要是防止發起請求的節點作惡,比如循環發起提議。導致不斷產生提議檢驗,導致網絡擁堵

  2. 副本節點檢查,如果處理過(說明可能是網絡問題),重新將處理結果返回即可,如果未處理,則可能主節點宕機,將請求重新轉發給主節點,且增加超時校驗。這時,如果主節點是正常的,那么就會走正常流程,最終會確認操作請求。如果主節點真的有問題,則設置的超時將觸發

  3. 超時后全網廣播主節點切換提議

if(!this.viewOk) return; // 已經開始選舉視圖,不用重復發起
this.viewOk = false;
// 作為副本節點,廣播視圖變更投票
PbftMsg cv = new PbftMsg(CV, this.index);
cv.setVnum(this.view+1);
PbftMain.publish(cv);

當每個節點都收到2f+1個對同一個view的提議后,則切換成新的view。且檢查是否有請求待發送,一切恢復正常邏輯:

long count = vnumAggreCount.incrementAndGet(msg.getVnum());
if(count >= 2*maxf+1){
	vnumAggreCount.clear();
	this.view = msg.getVnum();
	viewOk = true;
	System.out.println("視圖變更完成["+index+"]:"+ view);
	// 可以繼續發請求
	if(curMsg != null){
		curMsg.setVnum(this.view);
		System.out.println("請求重傳["+index+"]:"+ curMsg);
		doSendCurMsg();
	}
}

提議時,如果有惡意節點重復多次發起,需要檢測每個節點只能投票一次。

String vkey = msg.getNode()+"@"+msg.getVnum();
if(votes_vnum.contains(vkey)){
	return;
}
votes_vnum.add(vkey);
清理狀態

當commit通過后,即確認了操作,則可以對該消息相關的狀態進行清理:

// 清理請求相關狀態
	private void remove(String it) {
		votes_pre.remove(it);
		votes_pare.removeIf((vp)->{
			return StringUtils.startsWith(vp, it);
		});
		votes_comm.removeIf((vp)->{
			return StringUtils.startsWith(vp, it);
		});
		aggre_pare.remove(it);
		aggre_comm.remove(it);
		timeOuts.remove(it);
	}
其他關鍵點

PbftMsg消息的DataKey必須是唯一的,可以通過uuid或者其他方式定義

private int type; // 消息類型
	private int node; // 節點
	private int onode; // 發起請求的節點
	private int vnum; // 視圖編號
	private int no; // 序列號
	private long time; // 時間戳
	private String data; // 數據,表示數據的hash,必須唯一

關于怎么進行PBFT共識算法分析及Java實現問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

开封县| 海门市| 精河县| 道真| 渭南市| 社会| 商南县| 民勤县| 彭山县| 霍邱县| 侯马市| 崇州市| 台北市| 永新县| 涪陵区| 大埔区| 阜新市| 天等县| 平昌县| 唐海县| 临江市| 五大连池市| 海丰县| 砚山县| 辰溪县| 南宁市| 泰和县| 云和县| 阿拉善左旗| 信宜市| 新乡县| 东乌珠穆沁旗| 苍山县| 偏关县| 阿勒泰市| 孟连| 城固县| 临湘市| 乌兰察布市| 鹤岗市| 礼泉县|