예제 #1
0
        public void ClearOutTimeDB()
        {
            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot(0, true))
            {
                string str_Counted = snapshot.Get("Pool_Counted");
                long   counted     = 0;
                long.TryParse(str_Counted, out counted);
                string        str_MR          = snapshot.Get($"Pool_MR_{counted-1}");
                MinerRewardDB minerRewardLast = null;
                if (!string.IsNullOrEmpty(str_MR))
                {
                    minerRewardLast = JsonHelper.FromJson <MinerRewardDB>(str_MR);
                }
                if (minerRewardLast != null)
                {
                    bool bCommit  = false;
                    int  delCount = 5760 * 3;
                    for (long ii = counted - 2; ii > counted - delCount; ii--)
                    {
                        string key = $"Pool_MR_{ii}";
                        if (!string.IsNullOrEmpty(snapshot.Get(key)))
                        {
                            bCommit = true;
                            snapshot.Delete(key);
                        }
                        else
                        {
                            break;
                        }
                    }

                    // Miner
                    for (long ii = minerRewardLast.minHeight; ii > minerRewardLast.minHeight - delCount; ii--)
                    {
                        string key = $"Pool_H2_{ii}";
                        if (!string.IsNullOrEmpty(snapshot.Get(key)))
                        {
                            bCommit = true;
                            snapshot.Delete(key);
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (bCommit)
                    {
                        snapshot.Commit();
                    }
                }
            }
        }
예제 #2
0
        public void MinerSave()
        {
            if (httpPool != null)
            {
                Dictionary <string, MinerTask> miners = httpPool.GetMinerRewardMin(out long miningHeight);
                if (miners != null && miningHeight + 3 < httpPool.height)
                {
                    using (DbSnapshot snapshot = PoolDBStore.GetSnapshot(0, true))
                    {
                        string json         = snapshot.Get("Pool_H_Miner");
                        long   height_miner = -1;
                        if (!string.IsNullOrEmpty(json))
                        {
                            long.TryParse(json, out height_miner);
                        }

                        if (height_miner == -1 || height_miner < miningHeight)
                        {
                            snapshot.Add("Pool_H_Miner", miningHeight.ToString());
                            snapshot.Add("Pool_H2_" + miningHeight, JsonHelper.ToJson(miners));
                            snapshot.Commit();
                            httpPool.DelMiner(miningHeight);
                        }
                    }
                }
            }
        }
예제 #3
0
        public Dictionary <string, BlockSub> GetMinerReward_SOLO(long minHeight, long maxHeight)
        {
            Dictionary <string, BlockSub> minerTransfer = new Dictionary <string, BlockSub>();

            if (httpPool != null)
            {
                string addressIn = Wallet.GetWallet().GetCurWallet().ToAddress();

                for (long rewardheight = minHeight; rewardheight < maxHeight; rewardheight++)
                {
                    Dictionary <string, MinerTask> miners = null;
                    using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
                    {
                        string json = snapshot.Get("Pool_H2_" + rewardheight);
                        if (!string.IsNullOrEmpty(json))
                        {
                            miners = JsonHelper.FromJson <Dictionary <string, MinerTask> >(json);
                        }
                    }

                    if (miners != null)
                    {
                        var mcblk = GetMcBlock(rewardheight);
                        if (mcblk != null && mcblk.Address == ownerAddress)
                        {
                            var miner = miners.Values.FirstOrDefault(c => c.random.IndexOf(mcblk.random) != -1);
                            if (miner != null)
                            {
                                BigFloat reward = new BigFloat(Consensus.GetReward(rewardheight));
                                reward = reward * (1.0f - GetServiceFee());

                                var transfer = new BlockSub();
                                transfer.addressIn  = addressIn;
                                transfer.addressOut = miner.address;
                                string pay = BigHelper.Round8(reward.ToString());

                                if (minerTransfer.TryGetValue(miner.address, out transfer))
                                {
                                    transfer.amount = BigHelper.Add(transfer.amount, pay);
                                }
                                else
                                {
                                    transfer            = new BlockSub();
                                    transfer.addressIn  = addressIn;
                                    transfer.addressOut = miner.address;
                                    transfer.amount     = BigHelper.Sub(pay, "0.002"); // 扣除交易手续费
                                    transfer.type       = "100%";                      // 有效提交百分比
                                    transfer.data       = CryptoHelper.Sha256($"{mcblk.hash}_{maxHeight}_{ownerAddress}_{miner.address}_Reward_SOLO");
                                    minerTransfer.Add(transfer.addressOut, transfer);
                                }
                            }
                        }
                    }
                }
            }
            return(minerTransfer);
        }
예제 #4
0
        public void ClearOutTimeDB()
        {
            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
            {
                // Miner
                string json         = snapshot.Get("Pool_H_Miner");
                long   height_miner = -1;
                if (!string.IsNullOrEmpty(json))
                {
                    long.TryParse(json, out height_miner);
                }

                for (long ii = OutTimeDBMiner; ii < OutTimeDBMiner * 3; ii++)
                {
                    string key = "Pool_H_" + (height_miner - ii);
                    if (!string.IsNullOrEmpty(snapshot.Get(key)))
                    {
                        snapshot.Delete("Pool_H_" + (height_miner - ii));
                    }
                    else
                    {
                        break;
                    }
                }

                long   counted     = 0;
                string str_Counted = snapshot.Get("Pool_Counted");
                long.TryParse(str_Counted, out counted);
                for (long ii = OutTimeDBCounted; ii < OutTimeDBCounted * 3; ii++)
                {
                    long index = counted - ii;
                    if (!string.IsNullOrEmpty(snapshot.Get($"Pool_MR_{index}")))
                    {
                        snapshot.Delete($"Pool_MR_{index}");
                        snapshot.Delete($"Pool_MT_{index}");
                    }
                    else
                    {
                        break;
                    }
                }
                snapshot.Commit();
            }
        }
예제 #5
0
        public Block GetMcBlock(long ___height)
        {
            if (___height <= 1)
            {
                return(null);
            }

            try
            {
                PoolBlock poolBlock = null;
                using (DbSnapshot snapshot = pool.PoolDBStore.GetSnapshot())
                {
                    var str = snapshot.Get($"PoolBlock_{___height}");
                    if (!string.IsNullOrEmpty(str))
                    {
                        poolBlock = JsonHelper.FromJson <PoolBlock>(str);
                        if (poolBlock != null && Wallet.CheckAddress(poolBlock.Address))
                        {
                            return(new Block()
                            {
                                hash = poolBlock.hash, Address = poolBlock.Address, random = poolBlock.random
                            });
                        }
                    }
                }

                HttpMessage quest = new HttpMessage();
                quest.map = new Dictionary <string, string>();
                quest.map.Add("cmd", "GetMcBlock");
                quest.map.Add("version", version);
                quest.map.Add("height", ___height.ToString());
                var result = ComponentNetworkHttp.QueryStringSync($"http://{poolUrl}", quest, 5);
                if (string.IsNullOrEmpty(result))
                {
                    return(null);
                }
                poolBlock = JsonHelper.FromJson <PoolBlock>(result);
                if (poolBlock != null && Wallet.CheckAddress(poolBlock.Address))
                {
                    using (DbSnapshot snapshot = pool.PoolDBStore.GetSnapshot())
                    {
                        snapshot.Add($"PoolBlock_{___height}", JsonHelper.ToJson(poolBlock));
                        snapshot.Commit();
                    }
                    return(new Block()
                    {
                        hash = poolBlock.hash, Address = poolBlock.Address, random = poolBlock.random
                    });
                }
            }
            catch (Exception)
            {
            }
            return(null);
        }
예제 #6
0
 void LoadTransferFromDB()
 {
     using (DbSnapshot snapshot = Entity.Root.GetComponent <Pool>().PoolDBStore.GetSnapshot())
     {
         string str = snapshot.Get($"TransferProcess");
         if (str != null)
         {
             transfers = JsonHelper.FromJson <List <TransferHandle> >(str);
         }
     }
 }
예제 #7
0
        // 奖励上一周期的rule、本周期的MC出块rule  , 出块的rule会得到两次奖励
        public void ApplyReward(DbSnapshot dbSnapshot, Block mcblk)
        {
            var rewardKey = $"{mcblk.height}_Reward";

            if (dbSnapshot.Get(rewardKey) == "1")
            {
                return;
            }
            dbSnapshot.Add(rewardKey, "1");

            var amount     = GetReward(mcblk.height).ToString();
            var amountRule = GetRewardRule(mcblk.height).ToString();

            Transfer Reward_Rule = null;
            Transfer Reward      = null;

            if (transferShow)
            {
                Reward_Rule = new Transfer()
                {
                    hash = "", type = "Reward_Rule", nonce = mcblk.height, amount = amountRule
                };
                Reward_Rule.hash   = Reward_Rule.ToHash();
                Reward_Rule.height = mcblk.height;
                dbSnapshot.Transfers.Add(Reward_Rule.hash, Reward_Rule);

                Reward = new Transfer()
                {
                    hash = "", type = "Reward_Mc", nonce = mcblk.height, data = mcblk.height.ToString(), amount = amount
                };
                Reward.height = mcblk.height;
                dbSnapshot.Transfers.Add(Reward.hash = Reward.ToHash(), Reward);
            }

            // rule奖励
            int ruleCount = 0;

            for (int ii = 0; ii < mcblk.linksblk.Count; ii++)
            {
                Block linkblk = blockMgr.GetBlock(mcblk.linksblk[ii]);
                if (linkblk != null && IsRule(mcblk.height, linkblk.Address))
                {
                    ruleCount++;
                    Account linkAccount = dbSnapshot.Accounts.Get(linkblk.Address);
                    if (linkAccount == null)
                    {
                        linkAccount = new Account()
                        {
                            address = linkblk.Address, amount = "0", index = 0, nonce = 0
                        }
                    }
                    ;
                    linkAccount.amount = BigInt.Add(linkAccount.amount, amountRule);
                    linkAccount.index += 1;
                    dbSnapshot.Accounts.Add(linkAccount.address, linkAccount);
                    if (transferShow)
                    {
                        dbSnapshot.BindTransfer2Account(linkAccount.address, linkAccount.index, Reward_Rule.hash);
                    }
                }
            }

            // 出块奖励
            Account account = dbSnapshot.Accounts.Get(mcblk.Address);

            if (account == null)
            {
                account = new Account()
                {
                    address = mcblk.Address, amount = "0", index = 0, nonce = 0
                }
            }
            ;
            account.amount = BigInt.Add(account.amount, amount);
            account.index += 1;
            dbSnapshot.Accounts.Add(account.address, account);

            if (transferShow)
            {
                dbSnapshot.BindTransfer2Account(account.address, account.index, Reward.hash);
            }
        }

        LuaVMEnv luaVMEnv = Entity.Root.GetComponent <LuaVMEnv>();
예제 #8
0
        public MinerView GetMinerViewAbstract(string address)
        {
            if (minerViewAbstractTimePass.IsPassSet())
            {
                minerViewAbstractCache.Clear();
            }
            if (minerViewAbstractCache.TryGetValue(address, out MinerView minerViewLast))
            {
                return(minerViewLast);
            }

            var minerView = new MinerView();
            // pool name
            var httpPoolRelay = Entity.Root.GetComponent <HttpPoolRelay>();

            if (httpPoolRelay != null)
            {
                minerView.address = httpPoolRelay.number;
            }
            else
            {
                minerView.address = "Ruler";
            }

            Dictionary <string, BlockSub> minerTransferCache = null;

            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
            {
                var str = snapshot.Get($"Pool_Cache_MinerReward");
                if (!string.IsNullOrEmpty(str))
                {
                    minerTransferCache = JsonHelper.FromJson <Dictionary <string, BlockSub> >(str);
                }
            }

            var transfers_cur = minerTransferCache?.Values.FirstOrDefault(c => c.addressOut == address);

            if (transfers_cur != null)
            {
                minerView.amount_cur = transfers_cur.amount;
                minerView.share      = transfers_cur.type;
            }

            // 当前总算力
            var    miners     = httpPool.GetMinerRewardMin(out long miningHeight);
            var    minerList  = miners?.Values.Where((x) => x.address == address).ToList();
            double totalPower = 0L;

            if (minerList != null)
            {
                minerList.Sort((MinerTask a, MinerTask b) => {
                    return(a.number.CompareTo(b.number));
                });

                for (var ii = 0; ii < minerList.Count; ii++)
                {
                    var miner = minerList[ii];
                    if (double.TryParse(miner.power_average, out double power_average))
                    {
                        totalPower += power_average;
                    }
                }
                minerView.totalMiners = minerList.Count;
            }
            minerView.totalPower = CalculatePower.GetPowerCompany(totalPower);

            minerViewAbstractCache.Add(address, minerView);
            return(minerView);
        }
예제 #9
0
        public MinerView GetMinerView(string address, long transferIndex, long transferColumn, long minerIndex, long minerColumn)
        {
            if (getMinerViewTimePass.IsPassSet())
            {
                getMinerViewCache.Clear();
            }
            if (getMinerViewCache.TryGetValue($"{address}_{transferIndex}_{transferColumn}_{minerIndex}_{minerColumn}", out MinerView minerViewLast))
            {
                return(minerViewLast);
            }

            transferColumn = Math.Min(transferColumn, 100);
            minerColumn    = Math.Min(minerColumn, 100);

            var minerView = new MinerView();

            minerView.address = address;

            Dictionary <string, BlockSub> minerTransferCache = null;

            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
            {
                var str = snapshot.Get($"Pool_Cache_MinerReward");
                if (!string.IsNullOrEmpty(str))
                {
                    minerTransferCache = JsonHelper.FromJson <Dictionary <string, BlockSub> >(str);
                }
            }

            var transfers_cur = minerTransferCache?.Values.FirstOrDefault(c => c.addressOut == address);

            if (transfers_cur != null)
            {
                minerView.amount_cur = transfers_cur.amount;
                minerView.share      = transfers_cur.type;
            }

            // 交易确认
            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
            {
                int TopIndex = snapshot.Queue.GetTopIndex($"Pool_MT_{address}");
                for (int ii = 1; ii <= (int)transferColumn; ii++)
                {
                    var value = snapshot.Queue.Get($"Pool_MT_{address}", TopIndex - (int)transferIndex - ii);
                    if (!string.IsNullOrEmpty(value))
                    {
                        var transfer = JsonHelper.FromJson <BlockSub>(value);
                        if (transfer != null)
                        {
                            minerView.transfers.Add(transfer);
                        }
                    }
                }

                foreach (var transfer in minerView.transfers)
                {
                    // 节点使用自己的地址挖矿
                    if (transfer.addressIn == transfer.addressOut)
                    {
                        transfer.hash = transfer.addressIn;
                    }
                    else
                    {
                        transfer.hash = TransferProcess.GetMinerTansfer(snapshot, transfer.data);
                    }
                }
            }

            var    miners     = httpPool.GetMinerRewardMin(out long miningHeight);
            var    minerList  = miners?.Values.Where((x) => x.address == address).ToList();
            double totalPower = 0L;

            if (minerList != null)
            {
                minerList.Sort((MinerTask a, MinerTask b) => {
                    return(a.number.CompareTo(b.number));
                });

                // 当前页矿机算力
                for (var ii = 0; ii < minerColumn; ii++)
                {
                    if ((minerIndex + ii) >= minerList.Count)
                    {
                        break;
                    }
                    var miner = minerList[(int)minerIndex + ii];

                    if (string.IsNullOrEmpty(miner.power_cur))
                    {
                        miner.power_cur = CalculatePower.GetPowerCompany(CalculatePower.Power(miner.diff));
                    }

                    var minerdata = new MinerViewData();
                    minerdata.number    = miner.number;
                    minerdata.lasttime  = miner.time;
                    minerdata.power_cur = miner.power_cur;

                    double.TryParse(miner.power_average, out double power_average);
                    minerdata.power_average = CalculatePower.GetPowerCompany(power_average);
                    minerView.miners.Add(minerdata);
                }

                // 当前总算力
                for (var ii = 0; ii < minerList.Count; ii++)
                {
                    var miner = minerList[ii];
                    if (double.TryParse(miner.power_average, out double power_average))
                    {
                        totalPower += power_average;
                    }
                }
                minerView.totalMiners = minerList.Count;
            }

            minerView.totalPower = CalculatePower.GetPowerCompany(totalPower);

            getMinerViewCache.Add($"{address}_{transferIndex}_{transferColumn}_{minerIndex}_{minerColumn}", minerView);
            return(minerView);
        }
예제 #10
0
        // Miner reward, only after confirming that it cannot be rolled back
        public Dictionary <string, BlockSub> GetMinerReward_PPLNS(long minHeight, long maxHeight)
        {
            Dictionary <string, BlockSub> minerTransfer = new Dictionary <string, BlockSub>();

            if (httpPool != null)
            {
                string addressIn = Wallet.GetWallet().GetCurWallet().ToAddress();

                for (long rewardheight = minHeight; rewardheight < maxHeight; rewardheight++)
                {
                    Dictionary <string, MinerTask> miners = null;
                    using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
                    {
                        string json = snapshot.Get("Pool_H2_" + rewardheight);
                        if (!string.IsNullOrEmpty(json))
                        {
                            miners = JsonHelper.FromJson <Dictionary <string, MinerTask> >(json);
                        }
                    }

                    if (miners != null)
                    {
                        var mcblk = GetMcBlock(rewardheight);
                        if (mcblk == null)
                        {
                            throw new Exception($"GetMcBlock({rewardheight}) return null");
                        }

                        if (mcblk != null && mcblk.Address == ownerAddress)
                        {
                            double reward = Consensus.GetReward(rewardheight);
                            reward = reward * (1.0f - GetServiceFee());

                            var miner = miners.Values.FirstOrDefault(c => c.random.IndexOf(mcblk.random) != -1);
                            if (miner == null)
                            {
                                continue;
                            }

                            // Total power
                            double powerSum = 0;
                            var    Values   = miners.Values.ToList();
                            for (var ii = 0; ii < Values.Count; ii++)
                            {
                                var dic = Values[ii];
                                if (string.IsNullOrEmpty(dic.address))
                                {
                                    continue;
                                }
                                double power = CalculatePower.Power(dic.diff);
                                if (power < HttpPool.ignorePower)
                                {
                                    continue;
                                }
                                powerSum += power;
                            }

                            // Reward for participation
                            BlockSub transfer = null;
                            for (var ii = 0; ii < Values.Count; ii++)
                            {
                                var dic = Values[ii];
                                if (string.IsNullOrEmpty(dic.address))
                                {
                                    continue;
                                }
                                double power = CalculatePower.Power(dic.diff);
                                double pay   = Math.Round(power * reward / powerSum, 8);

                                if (minerTransfer.TryGetValue(dic.address, out transfer))
                                {
                                    if (power < HttpPool.ignorePower)
                                    {
                                        transfer.height += 1; // 这里表示无效提交数
                                        continue;
                                    }

                                    transfer.nonce += 1; // 这里表示有效提交数
                                    transfer.amount = BigHelper.Add(transfer.amount, pay.ToString("N8"));
                                }
                                else
                                if (pay >= 0.002)
                                {
                                    transfer            = new BlockSub();
                                    transfer.nonce      = 1; // 这里表示有效提交数
                                    transfer.addressIn  = addressIn;
                                    transfer.addressOut = dic.address;
                                    transfer.amount     = BigHelper.Sub(pay.ToString("N8"), "0.002"); // 扣除交易手续费
                                    transfer.data       = CryptoHelper.Sha256($"{mcblk.hash}_{maxHeight}_{ownerAddress}_{dic.address}_MinerReward");
                                    if (power < HttpPool.ignorePower)
                                    {
                                        transfer.height += 1; // 这里表示无效提交数
                                        continue;
                                    }

                                    minerTransfer.Add(transfer.addressOut, transfer);
                                }
                            }
                        }
                    }
                }

                // 有效提交次数越多收益越高
                var totalAmount1 = "0"; // 总账1
                var totalAmount2 = "0"; // 总账2
                foreach (var transfer in minerTransfer.Values)
                {
                    try
                    {
                        totalAmount1 = BigHelper.Add(totalAmount1, transfer.amount);
                        var totalSubmit = transfer.nonce + transfer.height;
                        var share       = (float)transfer.nonce / (float)totalSubmit;
                        transfer.type    = $"{Math.Round(share * 100, 2)}%"; // 有效提交百分比
                        share           *= share;
                        transfer.remarks = BigHelper.Mul(share.ToString(), transfer.amount);
                        totalAmount2     = BigHelper.Add(totalAmount2, transfer.remarks);
                    }
                    catch (Exception)
                    {
                        transfer.type    = "0%";
                        transfer.remarks = "0";
                    }
                }

                var totalAmount3 = "0"; // 总账3
                foreach (var transfer in minerTransfer.Values)
                {
                    try
                    {
                        transfer.amount = BigHelper.Div(BigHelper.Mul(transfer.remarks, totalAmount1), totalAmount2);
                        totalAmount3    = BigHelper.Add(totalAmount3, transfer.amount);
                    }
                    catch (Exception)
                    {
                    }
                }

                //if (BigHelper.Greater(BigHelper.Abs(BigHelper.Sub(totalAmount1, totalAmount3)), "0.002", true))
                //{
                //    Log.Warning($"|totalAmount1 - totalAmount3| > 0.002 {BigHelper.Sub(totalAmount1, totalAmount3)}");
                //}
            }
            return(minerTransfer);
        }
예제 #11
0
        public Dictionary <string, BlockSub> MinerReward(bool saveDB = true)
        {
            long counted   = 0;
            long minHeight = -1;
            long maxHeight = -1;

            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot(0, true))
            {
                string str_Counted = snapshot.Get("Pool_Counted");
                long.TryParse(str_Counted, out counted);
                string        str_MR          = snapshot.Get($"Pool_MR_{str_Counted}");
                MinerRewardDB minerRewardLast = null;
                if (!string.IsNullOrEmpty(str_MR))
                {
                    minerRewardLast = JsonHelper.FromJson <MinerRewardDB>(str_MR);
                }
                if (minerRewardLast == null)
                {
                    if (httpPool.height <= 2) // 还没有获取到最新高度
                    {
                        return(null);
                    }
                    snapshot.Add("Pool_Counted", "0");
                    var minerRewardNew = new MinerRewardDB();
                    minerRewardNew.counted   = 0;
                    minerRewardNew.minHeight = httpPool.height;
                    minerRewardNew.maxHeight = httpPool.height;
                    minerRewardNew.time      = TimeHelper.time.ToString();
                    snapshot.Add($"Pool_MR_{0}", JsonHelper.ToJson(minerRewardNew));
                    snapshot.Commit();
                    return(null);
                }
                minHeight = minerRewardLast.maxHeight;

                string json = snapshot.Get("Pool_H_Miner");
                if (!string.IsNullOrEmpty(json))
                {
                    long.TryParse(json, out maxHeight);
                }
            }

            // 超过一天的数据忽略
            if (maxHeight - minHeight > 5760)
            {
                Log.Warning($"MinerReward maxHeight - minHeight > 5760, {maxHeight} - {minHeight} = {maxHeight - minHeight}");
            }

            // 设置步长
            if (maxHeight - minHeight >= RewardInterval)
            {
                maxHeight = minHeight + RewardInterval;
                runSleep  = saveDB ? 10 : runSleep; // 加快处理速度
            }

            // 缓存===========================================================================
            Dictionary <string, BlockSub> minerTransferCache = null;

            if (MinerReward_TimePass.IsPassSet())
            {
                minerTransferCache = MinerReward(false);
                if (minerTransferCache != null)
                {
                    using (DbSnapshot snapshot = PoolDBStore.GetSnapshot(0, true))
                    {
                        snapshot.Add($"Pool_Cache_MinerReward", JsonHelper.ToJson(minerTransferCache));
                        snapshot.Commit();
                    }
                }
            }
            // ===============================================================================

            if (maxHeight - minHeight < RewardInterval && saveDB)
            {
                runSleep = 7500;
                return(null);
            }

            Dictionary <string, BlockSub> minerTransfer = null;

            if (style == "PPLNS")
            {
                minerTransfer = minerTransferCache ?? GetMinerReward_PPLNS(minHeight, maxHeight);
            }
            if (style == "SOLO")
            {
                minerTransfer = minerTransferCache ?? GetMinerReward_SOLO(minHeight, maxHeight);
            }

            if (saveDB)
            {
                foreach (var it in minerTransfer)
                {
                    transferProcess.AddTransferHandle(it.Value.addressIn, it.Value.addressOut, it.Value.amount, it.Value.data);
                }

                using (DbSnapshot snapshot = PoolDBStore.GetSnapshot(0, true))
                {
                    counted += 1;
                    snapshot.Add("Pool_Counted", counted.ToString());
                    var minerRewardNew = new MinerRewardDB();
                    minerRewardNew.counted   = counted;
                    minerRewardNew.minHeight = minHeight;
                    minerRewardNew.maxHeight = maxHeight;
                    minerRewardNew.time      = DateTime.Now.Ticks.ToString();
                    snapshot.Add($"Pool_MR_{counted}", JsonHelper.ToJson(minerRewardNew));

                    // Pool_MT
                    var depend = new DateTime(DateTime.Now.Ticks).ToString("yyyy-MM-dd HH:mm:ss");
                    foreach (var it in minerTransfer)
                    {
                        it.Value.depend = depend;
                        snapshot.Queue.Push($"Pool_MT_{it.Value.addressOut}", JsonHelper.ToJson(it.Value));
                    }
                    snapshot.Commit();
                }
            }

            return(minerTransfer);
        }
예제 #12
0
 public static string GetMinerTansfer(DbSnapshot dbSnapshot, string unique)
 {
     return(dbSnapshot.Get($"unique_{unique}")); // Query transaction cross reference table
 }
예제 #13
0
        // Miner reward, only after confirming that it cannot be rolled back
        public Dictionary <string, BlockSub> MinerReward_PPLNS(string today, long minHeight, long maxHeight)
        {
            Dictionary <string, BlockSub> minerTransfer = new Dictionary <string, BlockSub>();

            if (httpPool != null)
            {
                WalletKey walletKey = Wallet.GetWallet().GetCurWallet();
                for (long rewardheight = minHeight; rewardheight < maxHeight; rewardheight++)
                {
                    Dictionary <string, MinerTask> miners = null;
                    using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
                    {
                        string json = snapshot.Get("Pool_H_" + rewardheight);
                        if (!string.IsNullOrEmpty(json))
                        {
                            miners = JsonHelper.FromJson <Dictionary <string, MinerTask> >(json);
                        }
                    }

                    //var miners = httpPool.GetMiner(rewardheight);
                    if (miners != null)
                    {
                        string ownerAddress = Wallet.GetWallet().GetCurWallet().ToAddress();

                        var mcblk = BlockChainHelper.GetMcBlock(rewardheight);
                        if (mcblk != null && mcblk.Address == ownerAddress)
                        {
                            BigFloat reward = new BigFloat(Consensus.GetReward(rewardheight));
                            reward = reward * (1.0f - serviceFee);

                            var miner = miners.Values.FirstOrDefault(c => c.random == mcblk.random);
                            if (miner == null)
                            {
                                continue;
                            }

                            // Total power
                            BigFloat diffsum = new BigFloat(0);
                            foreach (var dic in miners.Values)
                            {
                                if (string.IsNullOrEmpty(dic.address))
                                {
                                    continue;
                                }
                                if (dic.diff < 0.99999f)
                                {
                                    continue;
                                }
                                diffsum += new BigFloat(dic.diff);
                            }

                            // Reward for participation
                            foreach (var dic in miners.Values)
                            {
                                if (string.IsNullOrEmpty(dic.address))
                                {
                                    continue;
                                }
                                if (dic.diff < 0.99999f)
                                {
                                    continue;
                                }

                                var    v   = new BigFloat(dic.diff);
                                string pay = BigHelper.Round8((v * reward / diffsum).ToString());

                                if (minerTransfer.TryGetValue(dic.address, out BlockSub transfer))
                                {
                                    transfer.amount = BigHelper.Add(transfer.amount, pay);
                                }
                                else
                                if (BigHelper.Greater(pay, "0.002", false))
                                {
                                    transfer            = new BlockSub();
                                    transfer.addressIn  = ownerAddress;
                                    transfer.addressOut = dic.address;
                                    transfer.amount     = BigHelper.Sub(pay, "0.002"); // 扣除交易手续费
                                    transfer.type       = "transfer";
                                    transfer.data       = CryptoHelper.Sha256($"{today}_{maxHeight}_{ownerAddress}_{dic.address}_MinerReward");
                                    minerTransfer.Add(transfer.addressOut, transfer);
                                }
                            }
                        }
                    }
                }
            }
            return(minerTransfer);
        }
예제 #14
0
        public Dictionary <string, BlockSub> MinerReward_PPLNS(bool saveDB = true)
        {
            var today = DateTime.UtcNow.ToString("yyyy-MM-dd");

            long counted   = 0;
            long minHeight = -1;
            long maxHeight = -1;

            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
            {
                string str_Counted = snapshot.Get("Pool_Counted");
                long.TryParse(str_Counted, out counted);
                string        str_MR          = snapshot.Get($"Pool_MR_{str_Counted}");
                MinerRewardDB minerRewardLast = null;
                if (!string.IsNullOrEmpty(str_MR))
                {
                    minerRewardLast = JsonHelper.FromJson <MinerRewardDB>(str_MR);
                }
                if (minerRewardLast == null)
                {
                    snapshot.Add("Pool_Counted", "0");
                    var minerRewardNew = new MinerRewardDB();
                    minerRewardNew.counted   = 0;
                    minerRewardNew.minHeight = httpPool.height;
                    minerRewardNew.maxHeight = httpPool.height;
                    minerRewardNew.time      = TimeHelper.time.ToString();
                    snapshot.Add($"Pool_MR_{0}", JsonHelper.ToJson(minerRewardNew));
                    snapshot.Commit();
                    return(null);
                }
                minHeight = minerRewardLast.maxHeight;

                string json = snapshot.Get("Pool_H_Miner");
                if (!string.IsNullOrEmpty(json))
                {
                    long.TryParse(json, out maxHeight);
                }
            }

            if (maxHeight - minHeight < RewardInterval && saveDB)
            {
                return(null);
            }

            var minerTransfer = MinerReward_PPLNS(today, minHeight, maxHeight);

            if (saveDB)
            {
                using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
                {
                    foreach (var it in minerTransfer)
                    {
                        transferProcess.AddTransferHandle(it.Value.addressIn, it.Value.addressOut, it.Value.amount, it.Value.data);
                    }

                    counted += 1;
                    snapshot.Add("Pool_Counted", counted.ToString());
                    var minerRewardNew = new MinerRewardDB();
                    minerRewardNew.counted   = counted;
                    minerRewardNew.minHeight = minHeight;
                    minerRewardNew.maxHeight = maxHeight;
                    minerRewardNew.time      = DateTime.UtcNow.Ticks.ToString();
                    snapshot.Add($"Pool_MR_{counted}", JsonHelper.ToJson(minerRewardNew));

                    // Pool_MT
                    var depend = new DateTime(DateTime.UtcNow.Ticks, DateTimeKind.Utc).ToString("yyyy-MM-dd HH:mm:ss");
                    foreach (var it in minerTransfer)
                    {
                        it.Value.depend = depend;
                        snapshot.Queue.Push($"Pool_MT_{it.Value.addressOut}", JsonHelper.ToJson(it.Value));
                    }

                    snapshot.Commit();
                }

                transferProcess.SaveTransferToDB();
            }

            return(minerTransfer);
        }
예제 #15
0
        public MinerView GetMinerView(string address, long transferIndex, long transferColumn, long minerIndex, long minerColumn)
        {
            var minerView = new MinerView();

            minerView.address = address;

            var transfers_cur = MinerReward_PPLNS(false)?.Values.FirstOrDefault(c => c.addressOut == address);

            if (transfers_cur != null)
            {
                minerView.amount_cur = transfers_cur.amount;
            }

            long counted = 0;

            using (DbSnapshot snapshot = PoolDBStore.GetSnapshot())
            {
                string str_Counted = snapshot.Get("Pool_Counted");
                if (long.TryParse(str_Counted, out counted))
                {
                    counted = counted - transferIndex;
                    for (int i = 0; i < transferColumn; i++)
                    {
                        string str_MT = snapshot.Get($"Pool_MT_{counted-i}");
                        Dictionary <string, BlockSub> minerTransfer = null;
                        if (!string.IsNullOrEmpty(str_MT))
                        {
                            minerTransfer = JsonHelper.FromJson <Dictionary <string, BlockSub> >(str_MT);
                            if (minerTransfer != null)
                            {
                                var transfer = minerTransfer?.Values.FirstOrDefault(c => c.addressOut == address);
                                if (transfer != null)
                                {
                                    string        str_MR          = snapshot.Get($"Pool_MR_{counted - i}");
                                    MinerRewardDB minerRewardLast = null;
                                    if (!string.IsNullOrEmpty(str_MR))
                                    {
                                        minerRewardLast = JsonHelper.FromJson <MinerRewardDB>(str_MR);
                                    }

                                    long.TryParse(minerRewardLast.time, out long time);
                                    transfer.depend = new DateTime(time).ToString("yyyy-MM-dd HH:mm:ss");
                                    minerView.transfers.Add(transfer);
                                }
                            }
                        }
                    }
                }
            }

            // Is the query successful
            using (var dbSnapshot = PoolDBStore.GetSnapshot(0))
            {
                foreach (var transfer in minerView.transfers)
                {
                    transfer.hash = transferProcess.GetMinerTansfer(dbSnapshot, transfer.data);
                }
            }

            var miners    = httpPool.GetMinerReward(out long miningHeight);
            var minerList = miners?.Values.Where((x) => x.address == address).ToList();

            double totalPower = 0L;

            if (minerList != null)
            {
                minerList.Sort((MinerTask a, MinerTask b) => {
                    return(a.number.CompareTo(b.number));
                });

                for (var ii = 0; ii < minerColumn; ii++)
                {
                    if ((minerIndex + ii) >= minerList.Count)
                    {
                        break;
                    }
                    var miner = minerList[(int)minerIndex + ii];

                    if (string.IsNullOrEmpty(miner.power_cur))
                    {
                        miner.power_cur = CalculatePower.GetPowerCompany(CalculatePower.Power(miner.diff));
                    }

                    var minerdata = new MinerViewData();
                    minerdata.number    = miner.number;
                    minerdata.lasttime  = miner.time;
                    minerdata.power_cur = miner.power_cur;

                    double.TryParse(miner.power_average, out double power_average);
                    minerdata.power_average = CalculatePower.GetPowerCompany(power_average);
                    minerView.miners.Add(minerdata);

                    totalPower += power_average;
                }
                minerView.totalMiners = minerList.Count;
            }

            minerView.totalPower = CalculatePower.GetPowerCompany(totalPower);

            return(minerView);
        }