<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      BFT共識協議Java簡單實現

      關于拜占庭容錯

      拜占庭容錯指的是若干節點之間要達成信息一致,但是其中節點可能會作惡,比如發送不一致的假消息,這一點與Raft等以前熟知的非拜占庭容錯協議不一樣,非拜占庭容錯場景里的節點可能會故障,但不會故意作惡。
      BFT協議里要求有3N+1個節點,那么如果誠實節點達到2N+1,則整個節點網絡可以達到共識。
      分為3個階段:PRE-PREPARE, PREPARE, COMMIT

      代碼

      public class Message {
          enum Type {PRE_PREPARE, PREPARE, COMMIT};
          Type type; //消息類型
          int viewNumber; //任期,主節點不換任期不變
          int seqNumber; //消息在某任期下的序列號
          String digest; //消息摘要
          int senderId; //發送者ID,消息是誰發的
      
          public Message(Type type, int viewNumber, int seqNumber, String digest, int senderId){
              this.type  = type;
              this.viewNumber = viewNumber;
              this.seqNumber = seqNumber;
              this.digest = digest;
              this.senderId = senderId;
          }
      
      import com.alibaba.fastjson2.JSON;
      
      import java.util.HashMap;
      import java.util.Queue;
      import java.util.concurrent.LinkedBlockingQueue;
      
      /**
       * 模擬節點
       * */
      public class Node implements Runnable{
          int id;
          public boolean primary;
          //List<Node> allNodes; // 模擬廣播
          Queue<Message> preQueue = new LinkedBlockingQueue<Message>();
          Queue<Message> prepareQueue = new LinkedBlockingQueue<Message>();
          Queue<Message> commitQueue = new LinkedBlockingQueue<Message>();
      
          HashMap<String, Integer> msgMap = new HashMap<>(); //key viewnumber+seqNubmer+type+digest  value count
          HashMap<String, Boolean> msgBroadMap = new HashMap<>(); //key viewnumber+seqNubmer+type+digest  value bool
      
      
          public Node (int id, boolean primary){
              this.id = id;
              this.primary = primary;
          }
      
          //接收消息
          void receive(Message message) {
              try {
                  Thread.sleep(200);
              } catch (InterruptedException e) {
                  throw new RuntimeException(e);
              }
              String key =  getMessageKey(message);
              if(null==msgMap.get(key)){
                      msgMap.put(key, 1);
                  }else {
                      msgMap.put(key, msgMap.get(key)+1);
                  }
              msgBroadMap.put(key, false);
      
              //System.out.println(msgMap);
              //System.out.println(msgBroadMap);
      
              switch (message.type){
                  case PRE_PREPARE: preQueue.add(message); break;
                  case PREPARE: prepareQueue.add(message); break;
                  case COMMIT: commitQueue.add(message); break;
              }
          }
      
          private boolean isMessageTrue(Message msg){
              String key = getMessageKey(msg);
              if(null!=msgMap.get(key)){
                  if(msgMap.get(key) >= 3) return true;
              }
              return false;
          }
      
          // 節點收PRE_PREPARE消息,到網絡中廣播 prepare消息
          void handlePrePrepare(Message msg) {
              System.out.println(this.id + "節點收到PRE-PREPARE消息" + JSON.toJSONString(msg));
              NetwokContext.broadcast(msg, Message.Type.PREPARE, this.id);
              String key = getMessageKey(msg);
              msgBroadMap.put(key, true);
          }
      
          // 節點收到prepare消息,判斷一致的消息數量是否達到2n+1,是則廣播commit消息
          void handlePrepare(Message msg) {
              String key = getMessageKey(msg);
              if(isMessageTrue(msg) && !msgBroadMap.get(key)){
                  System.out.println(this.id + "節點收到PREPARE消息" + JSON.toJSONString(msg) + "后,已收到滿足數量的一致消息,廣播COMMIT消息");
                  NetwokContext.broadcast(msg, Message.Type.COMMIT, this.id);
                  msgBroadMap.put(key, true);
              }
          }
      
          //節點收到commit消息,判斷一致的消息數量是否達到2n+1,是則最終提交
          void handleCommit(Message msg){
              String key = getMessageKey(msg);
              if(isMessageTrue(msg) && !msgBroadMap.get(key)) {
                  System.out.println(this.id + "節點收到COMMIT消息" + JSON.toJSONString(msg) + "后,已收到滿足數量的一致消息,進行本地提交執行");
                  msgBroadMap.put(key, true);
              }
          }
      
      
          @Override
          public void run() {
              while (true){
                  if(!preQueue.isEmpty()) handlePrePrepare(preQueue.poll());
                  if(!prepareQueue.isEmpty()) handlePrepare(prepareQueue.poll());
                  if(!commitQueue.isEmpty()) handleCommit(commitQueue.poll());
                  try {
                      Thread.sleep(10);
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }
              }
          }
      
          private String getMessageKey(Message msg){
              return msg.viewNumber+""+ msg.seqNumber + "" + msg.type + msg.digest;
          }
      }
      

      上面是消息類和節點類,接下來是這個4節點網絡環境的模擬上下文,以及測試程序。

      /**
       * 模擬節點中保存的網絡上下文
       * */
      public class NetwokContext {
          public static List<Node> allNodes = new ArrayList<>(); // 模擬廣播
      
          public static void broadcast(Message msg, Message.Type type,int senderId){
              for(Node node : allNodes){
                  Message amsg = new Message(type, msg.viewNumber, msg.seqNumber, msg.digest, senderId);
                  node.receive(amsg);
              }
          }
      }
      
      public class PBFTdemo {
          public static void main(String[] args) throws Exception{
              // 模擬 4 個節點,其中 Node0 是主節點
              Node node0 = new Node(0, true);
              Node node1 = new Node(1, false);
              Node node2 = new Node(2, false);
              Node node3 = new Node(3, false);
              NetwokContext.allNodes.add(node0);
              NetwokContext.allNodes.add(node1);
              NetwokContext.allNodes.add(node2);
              NetwokContext.allNodes.add(node3);
              Thread thread0 = new Thread(node0);
              Thread thread1 = new Thread(node1);
              Thread thread2 = new Thread(node2);
              Thread thread3 = new Thread(node3);
              thread0.setDaemon(true);
              thread1.setDaemon(true);
              thread2.setDaemon(true);
              thread3.setDaemon(true);
              thread0.start();
              thread1.start();
              thread2.start();
              thread3.start();
      
              case1();
              //case2();
      
              TimeUnit.SECONDS.sleep(10);
          }
          //正常情況
          private static void case1(){
              String digest = "提刀上洛"; // 簡化
              Message prePrepare = new Message(Message.Type.PRE_PREPARE, 0, 1, digest, 0);
              for (Node node : NetwokContext.allNodes) {
                  node.receive(prePrepare);
              }
          }
          //主節點作惡
          private static void case2(){
              NetwokContext.allNodes.get(0).receive(new Message(Message.Type.PRE_PREPARE, 0, 1, "提刀上洛", 0));
              NetwokContext.allNodes.get(1).receive(new Message(Message.Type.PRE_PREPARE, 0, 1, "提刀上洛", 0));
              NetwokContext.allNodes.get(2).receive(new Message(Message.Type.PRE_PREPARE, 0, 1, "跑路", 0));
              NetwokContext.allNodes.get(3).receive(new Message(Message.Type.PRE_PREPARE, 0, 1, "跑路", 0));
          }
      }
      

      case1運行結果:

      1節點收到PRE-PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      0節點收到PRE-PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      2節點收到PRE-PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      3節點收到PRE-PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      0節點收到PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PREPARE","viewNumber":0}后,已收到滿足數量的一致消息,廣播COMMIT消息
      1節點收到PREPARE消息{"digest":"提刀上洛","senderId":1,"seqNumber":1,"type":"PREPARE","viewNumber":0}后,已收到滿足數量的一致消息,廣播COMMIT消息
      2節點收到PREPARE消息{"digest":"提刀上洛","senderId":1,"seqNumber":1,"type":"PREPARE","viewNumber":0}后,已收到滿足數量的一致消息,廣播COMMIT消息
      3節點收到PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PREPARE","viewNumber":0}后,已收到滿足數量的一致消息,廣播COMMIT消息
      0節點收到COMMIT消息{"digest":"提刀上洛","senderId":1,"seqNumber":1,"type":"COMMIT","viewNumber":0}后,已收到滿足數量的一致消息,進行本地提交執行
      1節點收到COMMIT消息{"digest":"提刀上洛","senderId":1,"seqNumber":1,"type":"COMMIT","viewNumber":0}后,已收到滿足數量的一致消息,進行本地提交執行
      2節點收到COMMIT消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"COMMIT","viewNumber":0}后,已收到滿足數量的一致消息,進行本地提交執行
      3節點收到COMMIT消息{"digest":"提刀上洛","senderId":1,"seqNumber":1,"type":"COMMIT","viewNumber":0}后,已收到滿足數量的一致消息,進行本地提交執行
      

      case2運行結果:

      0節點收到PRE-PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      1節點收到PRE-PREPARE消息{"digest":"提刀上洛","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      2節點收到PRE-PREPARE消息{"digest":"跑路","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      3節點收到PRE-PREPARE消息{"digest":"跑路","senderId":0,"seqNumber":1,"type":"PRE_PREPARE","viewNumber":0}
      

      posted on 2025-07-25 15:09  肥兔子愛豆畜子  閱讀(12)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 婷婷六月色| 亚洲av成人一区二区三区| 亚洲偷自拍国综合| 国产日韩久久免费影院| 蜜芽亚洲AV无码精品国产午夜 | 无码一级视频在线| 亚洲精品乱码久久久久久| 亚洲一区二区三区色视频| 国产精品成人久久电影| 国产一区在线播放av| 亚洲色欲在线播放一区| 久久99久国产精品66| 国产精品国产三级在线专区| 久久婷婷成人综合色综合| 免费可以在线看a∨网站| 中国女人大白屁股ass| 国产精品综合av一区二区| 国产午夜福利视频在线| 2020国产激情视频在线观看| 中文字幕一区二区三区精华液| 精品偷拍被偷拍在线观看| 久久香蕉欧美精品| 绥阳县| 亚洲国产色一区二区三区| 四虎亚洲国产成人久久精品| 国产精品午夜福利合集| 国产不卡一区不卡二区| 九九热免费精品视频在线| 西西444www高清大胆| 日韩精品中文女同在线播放| 中文字幕第一页国产| 四虎永久在线高清免费看| 又爽又大又黄a级毛片在线视频| 国产免费性感美女被插视频| 国产大学生粉嫩无套流白浆 | 日韩精品一区二区三区中文无码| 日本一卡2卡3卡4卡无卡免费| 黑人大战中国av女叫惨了| 国产精品一区在线免费看| 夜夜添无码试看一区二区三区| 亚洲欧洲中文日韩久久av乱码 |