public static void Q2P_McBlockHash_Handle(Session session, int opcode, object msg) { Q2P_McBlockHash q2q_McBlockHash = msg as Q2P_McBlockHash; Block mcbkl = BlockChainHelper.GetMcBlock(q2q_McBlockHash.height); var cons = Entity.Root.GetComponent <Consensus>(); if (mcbkl == null && cons.transferHeight + 3 >= q2q_McBlockHash.height) { // 取最新高度 var chain1 = BlockChainHelper.GetBlockChain(cons.transferHeight); while (chain1 != null) { if (q2q_McBlockHash.height == chain1.height) { mcbkl = chain1.GetMcBlock(); break; } chain1 = chain1.GetMcBlockNext(); } } R2P_McBlockHash r2p_McBlockHash = new R2P_McBlockHash() { hash = mcbkl != null ? mcbkl.hash : "" }; if (r2p_McBlockHash.hash == "") { r2p_McBlockHash.hash = ""; } session.Reply(q2q_McBlockHash, r2p_McBlockHash); }
// 获取最新高度MC块 public Block GetLastMcBlock() { var levelDBStore = Entity.Root.GetComponent <LevelDBStore>(); // 取最新高度 long.TryParse(levelDBStore.Get("UndoHeight"), out long transferHeight); var chain1 = BlockChainHelper.GetBlockChain(transferHeight); var chain2 = chain1.GetMcBlockNext(); while (chain2 != null) { chain1 = chain2; if (chain1.height >= transferHeight + 10) { chain2 = null; } else { chain2 = chain1.GetMcBlockNext(); } } if (DelBlockWithHeightTime.IsPassSet()) { blockMgr.DelBlockWithHeight(consensus, chain1.height); } Block blk1 = chain1.GetMcBlock(); // 2F1 double t_2max = consensus.GetRuleCount(blk1.height + 1); List <Block> blks = blockMgr.GetBlock(blk1.height + 1); blks = BlockChainHelper.GetRuleBlk(consensus, blks, chain1.hash); if (blks.Count >= BlockChainHelper.Get2F1(t_2max)) { chain2 = BlockChainHelper.GetMcBlockNextNotBeLink(chain1); if (chain2 != null) { var blk2 = chain2.GetMcBlock(); double t_1max = consensus.GetRuleCount(blk2.height - 1); if (blk2.linksblk.Count >= BlockChainHelper.Get2F1(t_1max)) { return(blk2); } } } // Auxiliary Address var blkAuxiliary = blks.Find((x) => { return(x.Address == consensus.auxiliaryAddress); }); //if (blkAuxiliary != null && blkAuxiliary.Address == consensus.auxiliaryAddress && blks.Count >= Math.Min(2, consensus.GetRuleCount(blk1.height+1)) ) if (blkAuxiliary != null && blkAuxiliary.Address == consensus.auxiliaryAddress && blks.Count >= Math.Max(2, (BlockChainHelper.Get2F1(t_2max) / 2))) { return(blkAuxiliary); } return(blk1); }
// 获取最新高度MC块 public Block GetLastMcBlock() { var levelDBStore = Entity.Root.GetComponent <LevelDBStore>(); // 取最新高度 去TopBlock long.TryParse(levelDBStore.Get("UndoHeight"), out long transferHeight); var chain1 = BlockChainHelper.GetBlockChain(transferHeight); var chain2 = chain1.GetMcBlockNext(); while (chain2 != null) { chain1 = chain2; chain2 = chain2.GetMcBlockNext(); } blockMgr.DelBlockWithWeight(consensus, chain1.hash, chain1.height); Block blk1 = chain1.GetMcBlock(); // 2F1 float timestamp = TimeHelper.NowSeconds(); double t_2max = consensus.GetRuleCount(blk1.height + 1); List <Block> blks = blockMgr.GetBlock(blk1.height + 1); blks = BlockChainHelper.GetRuleBlk(consensus, blks, chain1.hash); if (blks.Count >= BlockChainHelper.Get2F1(t_2max)) { chain2 = BlockChainHelper.GetMcBlockNextNotBeLink(chain1, timestamp, pooltime); if (chain2 != null) { var blk2 = chain2.GetMcBlock(); double t_1max = consensus.GetRuleCount(blk2.height - 1); if (blk2.linksblk.Count >= BlockChainHelper.Get2F1(t_1max)) { return(blk2); } } } // Super Address var blkSuper = blks.Find((x) => { return(x.Address == consensus.superAddress); }); //if (blkSuper != null && blkSuper.Address == consensus.superAddress && blks.Count >= Math.Min(2, consensus.GetRuleCount(blk1.height+1)) ) if (blkSuper != null && blkSuper.Address == consensus.superAddress && blks.Count >= Math.Max(2, (BlockChainHelper.Get2F1(t_2max) / 2))) { return(blkSuper); } return(blk1); }
// 解决分叉链 public BlockChain ApplyBlockChainMost() { long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight); var chain1 = BlockChainHelper.GetBlockChain(transferHeight); var chain2 = BlockChainHelper.FindtChainMost(chain1, blockMgr, this); if (chain2 != null) { List <BlockChain> list = new List <BlockChain>(); var chainStart = chain2; var chainEnd = chain1; while (chainStart.height != chainEnd.height) { list.Insert(0, chainStart); var blk = chainStart.GetMcBlock(); chainStart = new BlockChain() { hash = blk.prehash, height = blk.height - 1 }; } if (list.Count >= 2) { if (ApplyHeight(list[0])) { return(list[0]); } } return(null); } else if (chain1 != null) { // 应用账本到T-1周期 chain1 = chain1.GetMcBlockNext(blockMgr, this); chain2 = chain1 == null ? null : chain1.GetMcBlockNext(blockMgr, this); if (chain1 != null && chain2 != null) { if (ApplyHeight(chain1)) { return(chain1); } } } return(null); }
public void ApplyBlockChainOld() { // 应用账本到T-1周期 long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight); var before = transferHeight; var chain1 = BlockChainHelper.GetBlockChain(transferHeight).GetMcBlockNext(blockMgr, this); var chain2 = chain1 == null ? null : chain1.GetMcBlockNext(blockMgr, this); while (chain1 != null && chain2 != null) { if (!ApplyHeight(chain1)) { break; } //// 可能会造成找不到块的BUG //var mcblk = chain1.GetMcBlock(); //var blks = blockMgr.GetBlock(mcblk.height - 1); //if (blks.Count > mcblk.linksblk.Count) //{ // for (int ii = blks.Count - 1; ii >= 0; ii--) // { // if (mcblk.linksblk.Find((x) => { return x == blks[ii].hash; }) != blks[ii].hash) // { // var temp = BlockChainHelper.GetBlockChain(blks[ii].height-1); // if(temp.hash!= blks[ii].prehash ) { // blockMgr.DelBlock(blks[ii].hash); // } // } // } //} chain1 = chain2; chain2 = chain2.GetMcBlockNext(blockMgr, this); if (before != transferHeight && chain1 != null && chain1.height % 100 == 0) { Log.Debug($"ApplyHeight {chain1.height}"); } } long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight); if (before != transferHeight) { Log.Debug($"ApplyHeight {before} to {transferHeight}"); } }
async Task <bool> SyncHeight(Block otherMcBlk, string ipEndPoint) { if (transferHeight >= otherMcBlk.height) { return(true); } long.TryParse(levelDBStore.Get("Snap___2F1Height"), out long l2F1Height); l2F1Height = Math.Max(1, l2F1Height); string hash2F1 = await QueryMcBlockHash(l2F1Height, ipEndPoint); BlockChain chain2F1 = BlockChainHelper.GetBlockChain(l2F1Height); if (chain2F1 != null && chain2F1.hash != hash2F1) { if (bifurcatedReport == "") { bifurcatedReport = $"find a bifurcated chain. height: {otherMcBlk.height} address: {otherMcBlk.Address} , rules count: {otherMcBlk.linksblk.Count}"; } return(true); } // 接收广播过来的主块 // 检查链是否一致,不一致表示前一高度有数据缺失 // 获取对方此高度主块linksblk列表,对方非主块的linksblk列表忽略不用拉取 // 没有的块逐个拉取,校验数据是否正确,添加到数据库 // 拉取到的块重复此过程 // UndoTransfers到拉去到的块高度 , 有新块添加需要重新判断主块把漏掉的账本应用 // GetMcBlock 重新去主块 , ApplyTransfers 应用账本 long syncHeight = Math.Max(otherMcBlk.height - 1, transferHeight); long currHeight = Math.Min(otherMcBlk.height - 1, transferHeight); for (long jj = currHeight; jj > l2F1Height; jj--) { currHeight = jj; BlockChain chain = BlockChainHelper.GetBlockChain(jj); string hash = await QueryMcBlockHash(jj, ipEndPoint); if (hash != "" && (chain == null || chain.hash != hash)) { continue; } break; } //Log.Info($"SyncHeight: {currHeight} to {syncHeight}"); bool bUndoHeight = false; long ii = currHeight; for ( ; ii < syncHeight + 1 && ii < currHeight + 100; ii++) { Block syncMcBlk = null; if (ii == otherMcBlk.height - 1) // 同步prehash, 先查 { syncMcBlk = blockMgr.GetBlock(otherMcBlk.prehash) ?? await QueryMcBlock(ii, ipEndPoint); } if (ii == otherMcBlk.height) { syncMcBlk = otherMcBlk; } else { string hash = await QueryMcBlockHash(ii, ipEndPoint); syncMcBlk = blockMgr.GetBlock(hash); if (syncMcBlk == null) { syncMcBlk = await QueryMcBlock(ii, ipEndPoint); } } if (syncMcBlk == null) { break; } if (!blockMgr.AddBlock(syncMcBlk)) { break; } for (int jj = 0; jj < syncMcBlk.linksblk.Count; jj++) { Block queryBlock = blockMgr.GetBlock(syncMcBlk.linksblk[jj]) ?? await QueryBlock(syncMcBlk.linksblk[jj], ipEndPoint); // queryBlock 这里要验证签名 by sxh if (queryBlock == null) { break; } if (!blockMgr.AddBlock(queryBlock)) { break; } } var beLinks = await QueryBeLinkHash(syncMcBlk.hash, ipEndPoint); if (beLinks != null) { for (int jj = 0; jj < beLinks.Count; jj++) { Block queryBlock = blockMgr.GetBlock(beLinks[jj]) ?? await QueryBlock(beLinks[jj], ipEndPoint); if (queryBlock == null) { break; } if (!blockMgr.AddBlock(queryBlock)) { break; } } } // 比较链 if (syncMcBlk.height > 2 && !bUndoHeight) { var chain = BlockChainHelper.GetBlockChain(syncMcBlk.height - 3); if (chain != null) { var chainnext = chain.GetMcBlockNext(); if (chainnext != null) { Block blk2 = blockMgr.GetBlock(chainnext.hash); Block blk3 = blockMgr.GetBlock(syncMcBlk.prehash); if (blk2 != null && blk3 != null && blk2.hash != blk3.prehash) { bUndoHeight = true; } } } } } // 回滚到同步块的高度 if (bUndoHeight) { long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight); levelDBStore.UndoTransfers(currHeight); long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight); } if (ii < syncHeight + 1) { return(false); } return(true); }