예제 #1
0
        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);
        }
예제 #2
0
        // 获取最新高度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);
        }
예제 #3
0
파일: Rule.cs 프로젝트: mangodager/corlas
        // 获取最新高度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);
        }
예제 #4
0
        // 解决分叉链
        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);
        }
예제 #5
0
        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}");
            }
        }
예제 #6
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);
        }