Beispiel #1
0
        private void OnLatest_block(HttpMessage httpMessage)
        {
            var consensus = Entity.Root.GetComponent <Consensus>();
            var showCount = 10;

            var height = consensus.transferHeight;

            if (!GetParam(httpMessage, "Index", "index", out string index))
            {
                index = "0";
            }

            List <Block> BlockList = new List <Block>();

            for (long ii = height - showCount * int.Parse(index); ii > height - showCount * (int.Parse(index) + 1) && ii > 0; ii--)
            {
                Block myblk = BlockChainHelper.GetMcBlock(ii);

                if (myblk != null)
                {
                    BlockList.Add(myblk);
                }
            }
            httpMessage.result = JsonHelper.ToJson(BlockList);
        }
Beispiel #2
0
        public void MinerReward()
        {
            if (httpPool != null)
            {
                Dictionary <string, MinerTask> miners = httpPool.GetMinerReward(out long miningHeight);
                if (miners != null && miningHeight + 3 < height)
                {
                    string ownerAddress = Wallet.GetWallet().GetCurWallet().ToAddress();

                    var mcblk = BlockChainHelper.GetMcBlock(miningHeight);
                    if (mcblk != null && mcblk.Address == ownerAddress)
                    {
                        var       miner     = miners.Values.First(c => c.random == mcblk.random);
                        WalletKey walletKey = Wallet.GetWallet().GetCurWallet();

                        // 出块奖励
                        if (miner != null)
                        {
                            Transfer transfer = new Transfer();
                            transfer.addressIn  = ownerAddress;
                            transfer.addressOut = miner.address;
                            transfer.amount     = Consensus.GetReward(miningHeight).ToString();
                            transfer.nonce      = TimeHelper.NowSeconds();
                            transfer.type       = "tranfer";
                            transfer.hash       = transfer.ToHash();
                            transfer.sign       = transfer.ToSign(walletKey);
                            minerTransfer.Add(mcblk.hash, transfer);
                        }

                        // 参与奖励
                    }
                    httpPool.DelMiner(miningHeight);
                }
            }
        }
        public static void OnGetMcBlock(HttpMessage httpMessage)
        {
            Dictionary <string, string> map = new Dictionary <string, string>();
            // 版本检查
            string version = httpMessage.map["version"];

            if (version != Miner.version)
            {
                map.Remove("report");
                map.Add("report", "error");
                map.Add("tips", $"Miner.version: {Miner.version}");
                return;
            }

            // 矿池登记检查
            if (Pool.registerPool && poolIpAddress.IndexOf(httpMessage.request.RemoteEndPoint.Address.ToString()) == -1)
            {
                map.Add("tips", "need register Pool");
                return;
            }

            long ___height = long.Parse(httpMessage.map["height"]);

            var mcblk = BlockChainHelper.GetMcBlock(___height);

            if (mcblk != null)
            {
                var poolBlock = new PoolBlock();
                poolBlock.hash     = mcblk.hash;
                poolBlock.Address  = mcblk.Address;
                poolBlock.random   = mcblk.random;
                httpMessage.result = JsonHelper.ToJson(poolBlock);
            }
        }
Beispiel #4
0
        public void DelBlockWithWeight(Consensus consensus, string prehash, long perheight)
        {
            using (DbSnapshot snapshot = levelDBStore.GetSnapshot())
            {
                List <Block> blks = GetBlock(perheight + 1);
                blks = BlockChainHelper.GetRuleBlk(consensus, blks, prehash);

                List <string> list = snapshot.Heights.Get((perheight + 1).ToString());
                if (list != null)
                {
                    for (int ii = list.Count - 1; ii >= 0; ii--)
                    {
                        if (blks.Find(x => x.hash == list[ii]) == null)
                        {
                            snapshot.Blocks.Delete(list[ii]);
                            cacheDict.Remove(list[ii]);
                            cacheList.Remove(list[ii]);
                            list.RemoveAt(ii);
                        }
                    }
                    snapshot.Heights.Add((perheight + 1).ToString(), list);
                    snapshot.Commit();
                }
            }
        }
Beispiel #5
0
        public Dictionary <string, BlockSub> MinerReward_SOLO()
        {
            if (httpPool != null)
            {
                Dictionary <string, BlockSub>  minerTransfer = new Dictionary <string, BlockSub>();
                Dictionary <string, MinerTask> miners        = httpPool.GetMinerReward(out long miningHeight);
                if (miners != null && miningHeight + 5 < httpPool.height)
                {
                    string ownerAddress = Wallet.GetWallet().GetCurWallet().ToAddress();

                    var mcblk = BlockChainHelper.GetMcBlock(miningHeight);
                    if (mcblk != null && mcblk.Address == ownerAddress)
                    {
                        var miner = miners.Values.FirstOrDefault(c => c.random == mcblk.random);
                        if (miner != null)
                        {
                            var transfer = new BlockSub();
                            transfer.addressIn  = ownerAddress;
                            transfer.addressOut = miner.address;
                            transfer.type       = "transfer";
                            transfer.amount     = Consensus.GetReward(miningHeight).ToString();
                            transfer.data       = CryptoHelper.Sha256($"{mcblk.hash}_{ownerAddress}_{miner.address}_{transfer.amount}_Reward_SOLO");
                            minerTransfer.Add(transfer.addressOut, transfer);

                            transferProcess.AddTransferHandle(ownerAddress, miner.address, transfer.amount, transfer.data);
                            transferProcess.SaveTransferToDB();
                        }
                    }
                    httpPool.DelMiner(miningHeight);
                    return(minerTransfer);
                }
            }
            return(null);
        }
Beispiel #6
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);
        }
Beispiel #7
0
        public Block CreateBlock(Block preblk)
        {
            if (preblk == null)
            {
                return(null);
            }

            Block myblk = new Block();

            myblk.Address   = Wallet.GetWallet().GetCurWallet().ToAddress();
            myblk.prehash   = preblk != null ? preblk.hash : "";
            myblk.timestamp = nodeManager.GetNodeTime();
            myblk.height    = preblk != null ? preblk.height + 1 : 1;
            myblk.random    = System.Guid.NewGuid().ToString("N").Substring(0, 16);

            //引用上一周期的连接块
            List <Block> blks = blockMgr.GetBlock(preblk.height);

            blks = BlockChainHelper.GetRuleBlk(consensus, blks, preblk.prehash);
            for (int ii = 0; ii < blks.Count; ii++)
            {
                myblk.AddBlock(ii, blks[ii]);
            }
            RefTransfer(myblk);
            myblk.prehashmkl = myblk.ToHashMerkle(blockMgr);

            return(myblk);
        }
Beispiel #8
0
        private void OnInfo(HttpMessage httpMessage)
        {
            //Infomsg infomsg = new Infomsg();
            Dictionary <string, object> infomsg = new Dictionary <string, object>();

            infomsg.Add("success", true);
            infomsg.Add("message", "successful operation");
            Dictionary <string, object> result = new Dictionary <string, object>();

            var   consensus = Entity.Root.GetComponent <Consensus>();
            var   height    = consensus.transferHeight;
            Block myblk     = BlockChainHelper.GetMcBlock(height);

            result.Add("network ", "testnet");
            string[] capabilities = { "SMARTX", "FAST_SYNC" };
            result.Add("capabilities", capabilities);
            result.Add("clientId", "Smartx/v1.0.0-Windows/amd64");
            result.Add("coinbase", "0xcc1ca38eda5dd60d243633e95b893a14c44b8df8");
            result.Add("activePeers", 2);
            result.Add("pendingTransactions", 10);
            result.Add("latestBlockNumber", height.ToString());
            result.Add("latestBlockHash", myblk.hash);
            infomsg.Add("result", result);
            httpMessage.result = JsonHelper.ToJson(infomsg);
        }
Beispiel #9
0
        private void OnBlocktranHash(HttpMessage httpMessage)
        {
            if (!GetParam(httpMessage, "1", "hash", out string hash))
            {
                httpMessage.result = "please input hash";
                return;
            }
            using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0))
            {
                var transfer = dbSnapshot.Transfers.Get(hash);
                if (transfer != null)
                {
                    Block myblk = BlockChainHelper.GetMcBlock(transfer.height);
                    if (transfer.addressIn == "" && transfer.addressOut == "" || transfer.addressIn == null && transfer.addressOut == null)
                    {
                        transfer.addressIn  = "00000000000000000000000000000000";
                        transfer.addressOut = myblk.Address;
                    }
                    if (transfer.timestamp == 0)
                    {
                        transfer.timestamp = myblk.timestamp;
                    }
                }

                if (transfer == null || transfer.timestamp == 0)
                {
                    httpMessage.result = "false";
                }
                else
                {
                    httpMessage.result = JsonHelper.ToJson(transfer);
                }
            }
        }
Beispiel #10
0
        public void GetNearBlock(HttpMessage httpMessage)
        {
            if (!GetParam(httpMessage, "1", "browserIndex", out string browserIndexStr))
            {
                httpMessage.result = "command error! \nexample: GetNearBlock browserIndex";
                return;
            }
            long.TryParse(browserIndexStr, out long browserIndex);

            List <Block> list = new List <Block>();
            // 高度差太大的块直接忽略
            var consensus = Entity.Root.GetComponent <Consensus>();
            var blockMgr  = Entity.Root.GetComponent <BlockMgr>();
            var rule      = Entity.Root.GetComponent <Rule>();
            var showCount = 19;

            var height = browserIndex != 0 ? browserIndex : consensus.transferHeight;

            for (long ii = height; ii > height - showCount && ii > 0; ii--)
            {
                Block myblk = BlockChainHelper.GetMcBlock(ii);
                if (myblk != null)
                {
                    list.Add(myblk);
                }
            }

            if (consensus.transferHeight <= height && rule.state != 0)
            {
                var last = rule.GetLastMcBlock();
                if (last != null)
                {
                    var pre = blockMgr.GetBlock(last.prehash);
                    if (pre.height != consensus.transferHeight)
                    {
                        list.Insert(0, pre);
                        if (list.Count > showCount)
                        {
                            list.RemoveAt(list.Count - 1);
                        }
                    }
                    list.Insert(0, last);
                    if (list.Count > showCount)
                    {
                        list.RemoveAt(list.Count - 1);
                    }
                }
            }

            List <Block> list2 = new List <Block>();

            for (int ii = 0; ii < list.Count; ii++)
            {
                Block blk = list[ii].GetHeader();
                list2.Add(blk);
            }

            httpMessage.result = JsonHelper.ToJson(list2);
        }
Beispiel #11
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);
        }
Beispiel #12
0
        public Block GetMcBlock(long rewardheight)
        {
            var httpPoolRelay = Entity.Root.GetComponent <HttpPoolRelay>();

            if (httpPoolRelay != null)
            {
                return(httpPoolRelay.GetMcBlock(rewardheight));
            }
            return(BlockChainHelper.GetMcBlock(rewardheight));
        }
Beispiel #13
0
        public static void Q2P_Prehashmkl_Handle(Session session, int opcode, object msg)
        {
            Q2P_Prehashmkl q2p_Prehashmkl = msg as Q2P_Prehashmkl;
            Block          mcbkl          = BlockChainHelper.GetMcBlock(q2p_Prehashmkl.height);
            R2P_Prehashmkl r2p_Prehashmkl = new R2P_Prehashmkl()
            {
                prehashmkl = mcbkl != null ? mcbkl.prehashmkl : ""
            };

            session.Reply(q2p_Prehashmkl, r2p_Prehashmkl);
        }
Beispiel #14
0
        public static void Q2P_McBlock_Handle(Session session, int opcode, object msg)
        {
            Q2P_McBlock q2p_McBlock = msg as Q2P_McBlock;
            Block       mcbkl       = BlockChainHelper.GetMcBlock(q2p_McBlock.height);
            R2P_McBlock r2p_McBlock = null;

            r2p_McBlock = new R2P_McBlock()
            {
                block = mcbkl != null?JsonHelper.ToJson(mcbkl) : ""
            };
            session.Reply(q2p_McBlock, r2p_McBlock);
        }
Beispiel #15
0
        private void OnBlocktranHash(HttpMessage httpMessage)
        {
            if (!GetParam(httpMessage, "1", "hash", out string hash))
            {
                httpMessage.result = "please input hash";
                return;
            }
            using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0))
            {
                var transfer = dbSnapshot.Transfers.Get(hash);
                if (transfer != null)
                {
                    Block myblk = BlockChainHelper.GetMcBlock(transfer.height);
                    if (transfer.addressIn == "" && transfer.addressOut == "" || transfer.addressIn == null && transfer.addressOut == null)
                    {
                        transfer.addressIn  = "00000000000000000000000000000000";
                        transfer.addressOut = "00000000000000000000000000000000";
                    }

                    if (transfer.type == "contract")
                    {
                        string[] arr = transfer.data.Replace("\"", "").Replace("\\", "").Replace("transfer(", "").Replace(")", "").Split(",");
                        transfer.amount = arr[arr.Length - 1];
                        if (transfer.data.Contains("transfer("))
                        {
                            httpMessage.map.Clear();
                            httpMessage.map.Add("address", transfer.addressIn);
                            OnProperty(httpMessage);
                            var res = JsonHelper.FromJson <Dictionary <string, string> >(httpMessage.result);
                            foreach (KeyValuePair <string, string> kv in res)
                            {
                                if (kv.Value.Contains(transfer.addressOut))
                                {
                                    transfer.temp = new List <string>();
                                    transfer.temp.Add(kv.Value.Split(":")[0]);
                                    break;
                                }
                            }
                        }
                    }
                }

                if (transfer == null || transfer.timestamp == 0)
                {
                    httpMessage.result = "false";
                }
                else
                {
                    httpMessage.result = JsonHelper.ToJson(transfer);
                }
            }
        }
Beispiel #16
0
        public void OnGlobal_info(HttpMessage httpMessage)
        {
            long.TryParse(Entity.Root.GetComponent <LevelDBStore>().Get("UndoHeight"), out long UndoHeight);
            var blk = BlockChainHelper.GetMcBlock(UndoHeight);

            Dictionary <string, object> globalInfo = new Dictionary <string, object>();

            globalInfo.Add("success", true);
            globalInfo.Add("message", "successful operation");
            globalInfo.Add("currentBlockHeight", UndoHeight.ToString());
            globalInfo.Add("globalDifficulty", blk.GetDiff().ToString());
            globalInfo.Add("globalHashRate", Entity.Root.GetComponent <Consensus>().calculatePower.GetPower());
            httpMessage.result = JsonHelper.ToJson(globalInfo);
        }
Beispiel #17
0
        // 获取最新高度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);
        }
Beispiel #18
0
        private void OnTransactions(HttpMessage httpMessage)
        {
            if (!GetParam(httpMessage, "Index", "index", out string index))
            {
                index = "0";
            }
            int             Index           = int.Parse(index);
            List <BlockSub> transactionList = new List <BlockSub>();

            using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0))
            {
                if (!GetParam(httpMessage, "1", "address", out string address))
                {
                    httpMessage.result = "please input address";
                }
                var account = dbSnapshot.Accounts.Get(address);

                if (account != null)
                {
                    int TFA_Count = dbSnapshot.List.GetCount($"TFA__{address}");
                    Index = TFA_Count - Index * 12;

                    for (int ii = Index; ii > Index - 12 && ii > 0; ii--)
                    {
                        string hasht = dbSnapshot.List.Get($"TFA__{address}", ii - 1);
                        if (hasht != null)
                        {
                            var transfer = dbSnapshot.Transfers.Get(hasht);
                            if (transfer != null)
                            {
                                if (transfer.addressIn == "" && transfer.addressOut == "" || transfer.addressIn == null && transfer.addressOut == null)
                                {
                                    transfer.addressIn  = "00000000000000000000000000000000";
                                    transfer.addressOut = address;
                                }
                                Block myblk = BlockChainHelper.GetMcBlock(transfer.height);
                                if (transfer.timestamp == 0)
                                {
                                    transfer.timestamp = myblk.timestamp;
                                }
                                transactionList.Add(transfer);
                            }
                        }
                    }
                }
                httpMessage.result = JsonHelper.ToJson(transactionList);
            }
        }
Beispiel #19
0
        static public BlockChain GetMcBlockNext2F1(this BlockChain chain, BlockMgr bm = null, Consensus cos = null)
        {
            var          blockMgr  = bm ?? Entity.Root.GetComponent <BlockMgr>();
            var          consensus = cos ?? Entity.Root.GetComponent <Consensus>();
            List <Block> blks      = blockMgr.GetBlock(chain.height + 1);
            List <Block> blks2     = blockMgr.GetBlock(chain.height + 2);

            for (int ii = blks.Count - 1; ii >= 0; ii--)
            {
                if (chain.hash != blks[ii].prehash || !BlockChainHelper.IsIrreversible(consensus, blks[ii], blks2))
                {
                    blks.RemoveAt(ii);
                }
            }

            if (blks.Count == 0)
            {
                return(null);
            }

            Block  mcBlk    = blks[0];
            double mcWeight = GetBlockWeight(consensus, mcBlk, blks2);

            for (int ii = 1; ii < blks.Count; ii++)
            {
                Block  blk    = blks[ii];
                double weight = GetBlockWeight(consensus, blk, blks2);
                if (weight > mcWeight)
                {
                    mcBlk    = blk;
                    mcWeight = weight;
                }
                else
                if (weight == mcWeight)
                {
                    if (blk.hash.CompareTo(mcBlk.hash) > 0)
                    {
                        mcBlk    = blk;
                        mcWeight = weight;
                    }
                }
            }

            return(new BlockChain()
            {
                hash = mcBlk.hash, height = mcBlk.height
            });
        }
Beispiel #20
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);
        }
Beispiel #21
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}");
            }
        }
Beispiel #22
0
        public Block CreateBlock(Block preblk, ref bool bBlkMining)
        {
            if (preblk == null)
            {
                return(null);
            }
            string address = Wallet.GetWallet().GetCurWallet().ToAddress();

            Block myblk = new Block();

            myblk.Address   = Wallet.GetWallet().GetCurWallet().ToAddress();
            myblk.prehash   = preblk != null ? preblk.hash : "";
            myblk.timestamp = nodeManager.GetNodeTime();
            myblk.height    = preblk != null ? preblk.height + 1 : 1;
            myblk.random    = System.Guid.NewGuid().ToString("N").Substring(0, 16);

            //引用上一周期的连接块
            var blks1 = blockMgr.GetBlock(preblk.height);
            var blks2 = BlockChainHelper.GetRuleBlk(consensus, blks1, preblk.prehash);

            for (int ii = 0; ii < blks2.Count; ii++)
            {
                myblk.AddBlock(ii, blks2[ii]);
            }

            // 比较相同高度的出块
            var blks3   = blockMgr.GetBlock(myblk.height);
            var blklast = blks3.Find(x => (x.Address == address && x.prehash == myblk.prehash && x.linksblk.Count >= myblk.linksblk.Count));

            if (blklast != null)
            {
                bBlkMining = false;
                return(blklast);
            }

            CalculatePower.SetDT(myblk, preblk, httpRule);

            RefTransfer(myblk);
            myblk.prehashmkl = myblk.ToHashMerkle(blockMgr);

            bBlkMining = true;

            //Log.Debug($"Rule.CreateBlock {myblk.height} linksblk:{myblk.linksblk.Count} linkstran:{myblk.linkstran.Count} blks1:{blks1.Count} blks3:{blks3.Count}");

            return(myblk);
        }
Beispiel #23
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);
        }
Beispiel #24
0
        private void OnBlocktranHash(HttpMessage httpMessage)
        {
            if (!GetParam(httpMessage, "1", "hash", out string hash))
            {
                httpMessage.result = "please input hash";
                return;
            }
            using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0))
            {
                var transfer = dbSnapshot.Transfers.Get(hash);
                if (transfer != null)
                {
                    Block myblk = BlockChainHelper.GetMcBlock(transfer.height);
                    if (transfer.addressIn == "" && transfer.addressOut == "" || transfer.addressIn == null && transfer.addressOut == null)
                    {
                        transfer.addressIn  = "00000000000000000000000000000000";
                        transfer.addressOut = "00000000000000000000000000000000";
                    }

                    if (transfer.type == "contract")
                    {
                        string[] arr = transfer.data.Replace("\"", "").Replace("\\", "").Replace("transfer(", "").Replace(")", "").Split(",");
                        transfer.amount = arr[arr.Length - 1];
                        if (transfer.data.Contains("transfer("))
                        {
                            var symbol = LuaContract.GetSymbol(transfer.addressOut);
                            transfer.temp = new List <string>();
                            transfer.temp.Add(symbol);
                        }
                    }
                }

                if (transfer == null)
                {
                    httpMessage.result = "false";
                }
                else
                {
                    httpMessage.result = JsonHelper.ToJson(transfer);
                }
            }
        }
Beispiel #25
0
        public static void Q2P_BeLinkHash_Handle(Session session, int opcode, object msg)
        {
            Q2P_BeLinkHash q2q_McBlockHash = msg as Q2P_BeLinkHash;
            R2P_BeLinkHash r2p_McBlockHash = new R2P_BeLinkHash();

            var consensus = Entity.Root.GetComponent <Consensus>();
            var blockMgr  = Entity.Root.GetComponent <BlockMgr>();

            Block        mcbkl  = blockMgr.GetBlock(q2q_McBlockHash.hash);
            double       t_1max = consensus.GetRuleCount(mcbkl.height + 1);
            List <Block> blks   = blockMgr.GetBlock(mcbkl.height + 1);

            blks = BlockChainHelper.GetRuleBlk(consensus, blks, mcbkl.hash);


            string[] hashs = blks.Select(a => a.hash).ToArray();
            r2p_McBlockHash.hashs = JsonHelper.ToJson(hashs);

            session.Reply(q2q_McBlockHash, r2p_McBlockHash);
        }
Beispiel #26
0
        static public bool IsRuleOnline(long height, string address)
        {
            var mcblk = BlockChainHelper.GetMcBlock(height - 1);

            if (mcblk != null)
            {
                var blockMgr = Entity.Root.GetComponent <BlockMgr>();
                for (int i = 0; i < mcblk.linksblk.Count; i++)
                {
                    Block blk = blockMgr.GetBlock(mcblk.linksblk[i]);
                    if (blk != null)
                    {
                        if (blk.Address == address)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Beispiel #27
0
 static public Block GetMcBlock(long height)
 {
     return(BlockChainHelper.GetMcBlock(height));
 }
Beispiel #28
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);
        }
Beispiel #29
0
        public async void Run()
        {
            await Task.Delay(2000);

            long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight);

            Log.Debug($"Consensus.Run at height {transferHeight}");

            // 恢复到停机前的高度
            ApplyBlockChain();

            // 算力统计
            calculatePower.Clear();
            for (long ii = Math.Max(1, transferHeight - calculatePower.statistic); ii <= transferHeight; ii++)
            {
                calculatePower.Insert(BlockChainHelper.GetMcBlock(ii));
            }

            int blockIndex = 0;

            while (true)
            {
                try
                {
                    if (newBlocks.Count > 0)
                    {
                        for (blockIndex = blockIndex % newBlocks.Count; blockIndex < newBlocks.Count; blockIndex++)
                        {
                            if (newBlocks[blockIndex] == null)
                            {
                                continue;
                            }
                            var   ipEndPoint = newBlocks[blockIndex].ipEndPoint;
                            Block otherMcBlk = JsonHelper.FromJson <Block>(newBlocks[blockIndex].block);
                            if (Check(otherMcBlk))
                            {
                                if (await SyncHeight(otherMcBlk, newBlocks[blockIndex].ipEndPoint))
                                {
                                    newBlocks.RemoveAll((x) => { return(x.ipEndPoint == ipEndPoint); });
                                    break;
                                }
                                //if (await SyncHeight(otherMcBlk, newBlocks[ii].ipEndPoint))
                                ApplyBlockChain();
                            }
                            //break;
                        }
                    }

                    ApplyBlockChain();

                    lock (this)
                    {
                        runAction?.Invoke();
                        runAction = null;
                    }

                    if (bifurcatedReportTime.IsPassOnce() && bifurcatedReport != "")
                    {
                        Log.Info(bifurcatedReport);
                        bifurcatedReport = "";
                    }

                    await Task.Delay(1000);
                }
                catch (Exception e)
                {
                    newBlocks.Clear();
                    Log.Error(e);
                    await Task.Delay(1000);
                }
            }
        }
Beispiel #30
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);
        }