public static int CheckChain(BlockChain chain, List <Block> blks2, BlockMgr blockMgr, Consensus consensus) { blks2 = blks2 ?? blockMgr.GetBlock(chain.height + 1); int rel = IsIrreversible(consensus, chain.GetMcBlock(), blks2) ? 2 : 0; var blksRule = BlockChainHelper.GetRuleBlk(consensus, blks2, chain.hash); var blkAuxiliary = blksRule.Find((x) => { return(x.Address == consensus.auxiliaryAddress); }); //if (blkAuxiliary != null && blkAuxiliary.Address == consensus.auxiliaryAddress && blksRule.Count >= Math.Min(2, consensus.GetRuleCount(chain.height + 1))) var t_2max = consensus.GetRuleCount(chain.height + 1); if (blkAuxiliary != null && blkAuxiliary.Address == consensus.auxiliaryAddress && blksRule.Count >= Math.Max(2, (BlockChainHelper.Get2F1(t_2max) / 2))) { rel = rel + 1; } chain.checkWeight = rel; return(rel); }
public static List <BlockChain> FindtChain(BlockChain chainfrist, List <Block> blks, List <Block> blks2, ref List <BlockChain> list, BlockMgr blockMgr, Consensus consensus) { blks = blks ?? blockMgr.GetBlock(chainfrist.height + 1); for (int ii = blks.Count - 1; ii >= 0; ii--) { if (chainfrist.hash == blks[ii].prehash) { var cc = new BlockChain() { hash = blks[ii].hash, height = blks[ii].height }; if (CheckChain(cc, blks2, blockMgr, consensus) > 0) { list.Add(cc); } } } return(list); }
static public BlockChain GetMcBlockNext(this BlockChain chain, BlockMgr bm = null, Consensus cos = null) { var blockMgr = bm ?? Entity.Root.GetComponent <BlockMgr>(); var consensus = cos ?? Entity.Root.GetComponent <Consensus>(); var chinanext = GetMcBlockNext2F1(chain, blockMgr, consensus); if (chinanext != null) { return(chinanext); } List <BlockChain> list1 = new List <BlockChain>(); List <BlockChain> list2 = new List <BlockChain>(); List <Block> blks1 = blockMgr.GetBlock(chain.height + 1); List <Block> blks2 = blockMgr.GetBlock(chain.height + 2); FindtChain(chain, blks1, blks2, ref list1, blockMgr, consensus); if (list1.Count == 1) { if (list1[0].checkWeight >= 1) { return(list1[0]); } } //var t_2max = consensus.GetRuleCount(chain.height + 1); //List<Block> blks = blockMgr.GetBlock(chain.height + 1); //var blksRule = BlockChainHelper.GetRuleBlk(consensus, blks, chain.hash); //var blkAuxiliary = blksRule.Find((x) => { return x.Address == consensus.auxiliaryAddress; }); //if (blkAuxiliary != null && blkAuxiliary.Address == consensus.auxiliaryAddress && blksRule.Count >= Math.Max(2, (BlockChainHelper.Get2F1(t_2max) / 2))) //{ // List<Block> blksTemp = blockMgr.GetBlock(chain.height + 2); // if(blksTemp.Exists( (x) => { return x.prehash == blkAuxiliary.hash; } )) { // return new BlockChain() { hash = blkAuxiliary.hash, height = blkAuxiliary.height }; // } //} return(null); }
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); }
public bool ApplyHeight(BlockChain blockChain) { if (blockChain == null) { return(false); } // 应用高度不是下一高度 long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight); if (blockChain.height - 1 != transferHeight) { return(false); } Block mcblk = blockChain.GetMcBlock(); if (mcblk == null) { return(false); } Block preblk = BlockChainHelper.GetMcBlock(transferHeight); if (mcblk.prehash != preblk.hash) { return(false); } LuaVMEnv luaVMEnv = Entity.Root.GetComponent <LuaVMEnv>(); ruleInfos = luaVMEnv.GetRules(consAddress, transferHeight); // -------------------------------------------------- calculatePower.Insert(mcblk); //Log.Debug($"ApplyHeight={blockChain.height}, {calculatePower.GetPower()}, {mcblk.GetDiff()}"); using (DbSnapshot dbSnapshot = levelDBStore.GetSnapshotUndo(blockChain.height)) { blockChain.Apply(dbSnapshot); ApplyReward(dbSnapshot, mcblk); if (GetRuleCount(mcblk.height - 1, 2) >= 2 && BlockChainHelper.IsIrreversible(this, mcblk)) { dbSnapshot.Add("2F1Height", mcblk.height.ToString()); } // 连接块交易 for (int ii = 0; ii < mcblk.linksblk.Count; ii++) { Block linkblk = blockMgr.GetBlock(mcblk.linksblk[ii]); if (linkblk == null) { return(false); } if (linkblk.height != 1) { for (int jj = 0; jj < linkblk.linkstran.Count; jj++) { if (!ApplyTransfer(dbSnapshot, linkblk.linkstran[jj], linkblk.height)) { return(false); } if (!ApplyContract(dbSnapshot, linkblk.linkstran[jj], linkblk.height)) { return(false); } } } } dbSnapshot.Commit(); } ruleInfos = luaVMEnv.GetRules(consAddress, mcblk.height, true); return(true); }
static public void Apply(this BlockChain chain, DbSnapshot dbSnapshot) { dbSnapshot.BlockChains.Add("" + chain.height, chain); }
static public Block GetMcBlock(this BlockChain chain) { var blockMgr = Entity.Root.GetComponent <BlockMgr>(); return(blockMgr.GetBlock(chain.hash)); }