示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
 static public void Apply(this BlockChain chain, DbSnapshot dbSnapshot)
 {
     dbSnapshot.BlockChains.Add("" + chain.height, chain);
 }
示例#7
0
        static public Block GetMcBlock(this BlockChain chain)
        {
            var blockMgr = Entity.Root.GetComponent <BlockMgr>();

            return(blockMgr.GetBlock(chain.hash));
        }