public void AddTransferHandle(string addressIn, string addressOut, string amount, string unique, long height = 0)
        {
            if (string.IsNullOrEmpty(unique))
            {
                return;
            }
            if (BigHelper.Less(amount, "0", true))
            {
                return;
            }

            AddRunAction(() => {
                var old = transfers.Find((x) => x.unique == unique);
                if (old != null)
                {
                    return;
                }

                // 节点使用自己的地址挖矿
                if (addressIn == addressOut)
                {
                    return;
                }

                transfers.Add(new TransferHandle()
                {
                    lastHeight = height, miniindex = 0, sendCount = 0, addressIn = addressIn, addressOut = addressOut, amount = amount, unique = unique
                });
                return;
            });
        }
Example #2
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);
        }
Example #3
0
        static public bool Transfer(string addressIn, string addressOut, string amount)
        {
            var transfer     = LuaVMStack.s_transfer;
            var dbSnapshot   = LuaVMStack.s_dbSnapshot;
            var height       = LuaVMStack.s_transfer.height;
            var transferShow = Entity.Root.GetComponent <Consensus>().transferShow;

            if (BigHelper.Less(amount, "0", true))
            {
                throw new Exception("Transfer amount Less 0");
            }

            if (transfer.addressIn != addressIn && LuaVMStack.s_consAddress != addressIn && LuaVMStack.s_sender != addressIn)
            {
                throw new Exception("Transfer address error");
            }

            if (height != 1)
            {
                Account accountIn = dbSnapshot.Accounts.Get(addressIn);
                if (accountIn == null)
                {
                    throw new Exception("Transfer accountIn error");
                }
                if (BigHelper.Less(accountIn.amount, amount, false))
                {
                    throw new Exception("Transfer accountIn.amount is not enough");
                }
                accountIn.amount = BigHelper.Sub(accountIn.amount, amount);
                dbSnapshot.Accounts.Add(accountIn.address, accountIn);
                if (transferShow)
                {
                    dbSnapshot.BindTransfer2Account(addressIn, transfer.hash);
                }
            }

            Account accountOut = dbSnapshot.Accounts.Get(addressOut) ?? new Account()
            {
                address = addressOut, amount = "0", nonce = 0
            };

            accountOut.amount = BigHelper.Add(accountOut.amount, amount);
            dbSnapshot.Accounts.Add(accountOut.address, accountOut);

            if (transferShow)
            {
                dbSnapshot.BindTransfer2Account(addressOut, transfer.hash);
                transfer.height = height;
                dbSnapshot.Transfers.Add(transfer.hash, transfer);
            }
            return(true);
        }
Example #4
0
        public int AddTransfer(BlockSub transfer, bool checkFull = true)
        {
            transfer.hash = transfer.ToHash();

            if (!Wallet.Verify(transfer.sign, transfer.hash, transfer.addressIn))
            {
                return(-2);
            }

            Account account = null;

            using (var snapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot())
            {
                account = snapshot.Accounts.Get(transfer.addressIn);

                if (snapshot.Transfers.Get(transfer.hash) != null)
                {
                    return(-9);
                }
            }

            if (account == null)
            {
                return(-4);
            }

            if (BigHelper.Less(account.amount, "0.002", false))
            {
                return(-3);
            }

            if (transfer.type == "transfer")
            {
                if (BigHelper.Less(account.amount, BigHelper.Add(transfer.amount, "0.002"), false))
                {
                    return(-5);
                }

                if (!BigHelper.Equals(BigHelper.Round8(transfer.amount), transfer.amount))
                {
                    return(-6);
                }

                if (!Wallet.CheckAddress(transfer.addressOut))
                {
                    return(-10);
                }
            }
            else
            {
            }

            if (transfer.addressIn == transfer.addressOut)
            {
                return(-8);
            }

            lock (blockSubs)
            {
                if (blockSubs.Count >= 600)
                {
                    blockSubQueue.Enqueue(blockSubs);
                    blockSubs = new Dictionary <string, BlockSub>();
                }

                if (IsTransferFull(checkFull))
                {
                    return(-1);
                }

                blockSubs.Remove(transfer.hash);
                blockSubs.Add(transfer.hash, transfer);
            }

            var length = JsonHelper.ToJson(transfer).Length;

            if (length > 1024 * 4)
            {
                return(-11);
            }

            if (!consensus.IsRule(height, Wallet.GetWallet().GetCurWallet().ToAddress()))
            {
                return(-1);
            }

            return(1);
        }
Example #5
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);
        }
Example #6
0
        static public void test_ergodic2(long height, string filename)
        {
            //
            //DBTests tests = new DBTests();
            //tests.SetUp();
            //tests.Snapshot();
            //var tempPath = System.IO.Directory.GetCurrentDirectory();
            //var randName = "Data\\LevelDB1";
            //var DatabasePath = System.IO.Path.Combine(tempPath, randName);
            //LevelDBStore dbstore = new LevelDBStore().Init(DatabasePath);
            LevelDBStore dbstore = Entity.Root.GetComponent <LevelDBStore>();

            // Create new iterator
            lock (dbstore.db)
            {
                string sum = "0";
                dbstore.UndoTransfers(height);
                using (var it = dbstore.db.CreateIterator())
                {
                    File.Delete("./" + filename + ".csv");
                    File.AppendAllText("./" + filename + ".csv", "height:" + height + "版本:" + NodeManager.networkIDCur + "\n");
                    // Iterate in reverse to print the values as strings
                    for (it.SeekToFirst(); it.IsValid(); it.Next())
                    {
                        //Log.Info($"Value as string: {it.KeyAsString()}");
                        if ((!it.KeyAsString().Contains("undo")) && (!it.KeyAsString().Contains("Undo")))
                        {
                            if (it.KeyAsString().IndexOf("Accounts___") == 0)
                            {
                                try
                                {
                                    Console.WriteLine($"Value as string: {it.ValueAsString()}");
                                    Dictionary <string, Dictionary <string, object> > kv = JsonHelper.FromJson <Dictionary <string, Dictionary <string, object> > >(it.ValueAsString());
                                    //all += long.Parse(kv["obj"]["amount"].ToString());
                                    File.AppendAllText("./" + filename + ".csv", kv["obj"]["address"].ToString() + "," + kv["obj"]["amount"].ToString() + "\n");
                                    BigHelper.Add(kv["obj"]["amount"].ToString(), sum);
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine(it.KeyAsString());
                                    Console.WriteLine($"出错了: {it.ValueAsString()}");
                                    Console.WriteLine(e.Message);
                                    break;
                                }
                            }
                            else
                            if (it.KeyAsString().Contains("Storages"))
                            {
                                var kv   = JsonHelper.FromJson <Dictionary <string, Dictionary <string, byte[]> > >(it.ValueAsString());
                                var json = SortJson(JToken.Parse(kv["obj"]["jsonData"].ToStr()), null);

                                File.AppendAllText("./" + filename + ".csv", it.KeyAsString().Replace("Storages___", "") + "," + json + "\n");
                            }
                            else
                            if (it.KeyAsString().Contains("StgMap"))
                            {
                                Console.WriteLine($"Value as string: {it.ValueAsString()}");
                                File.AppendAllText("./" + filename + ".csv", $"{it.KeyAsString()},{it.ValueAsString()}\n");
                            }
                        }
                    }
                    File.AppendAllText("./" + filename + ".csv", "All" + "," + sum + "\n");

                    long posProduct    = 0;
                    long powProduct    = 0;
                    long posOriginally = 0;
                    long powOriginally = 0;
                    for (long i = 1; i <= height; i++)
                    {
                        Block block        = BlockChainHelper.GetMcBlock(i);
                        long  posNodeCount = block.linksblk.Count;
                        posProduct    += posNodeCount * Consensus.GetRewardRule(i);
                        powProduct    += Consensus.GetReward(i);
                        posOriginally += 25 * Consensus.GetRewardRule(i);
                        powOriginally += Consensus.GetReward(i);
                    }

                    long All_Product = posProduct + powProduct;
                    File.AppendAllText("./" + filename + ".csv", "All_Product" + "," + All_Product + "\n");
                    File.AppendAllText("./" + filename + ".csv", "posProduct" + "," + posProduct + "\n");
                    File.AppendAllText("./" + filename + ".csv", "posOriginally" + "," + posOriginally + "\n");
                    File.AppendAllText("./" + filename + ".csv", "powOriginally" + "," + powOriginally + "\n");

                    Console.WriteLine("导出完成");
                }
            }
        }
Example #7
0
        public async void Run()
        {
            await Task.Delay(2000);

            var httpRpc = Entity.Root.Find("HttpRpc")?.GetComponent <HttpRpc>();

            if (httpRpc == null)
            {
                return;
            }
            var consensus = Entity.Root.GetComponent <Consensus>();
            var luaVMEnv  = Entity.Root.GetComponent <LuaVMEnv>();

            var    httpMessage = new HttpMessage();
            string address     = Wallet.GetWallet().GetCurWallet().ToAddress();
            string consAddress = "";
            int    delayTime   = 60 * 1000 * 2;

            while (true)
            {
                await Task.Delay(delayTime);

                try
                {
                    if (consensus.IsRule(consensus.transferHeight, address))
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(consAddress))
                    {
                        if (httpMessage.map == null)
                        {
                            httpMessage.map = new Dictionary <string, string>();
                            httpMessage.map.Add("1", consensus.PledgeFactory);
                            httpMessage.map.Add("2", $"getPair(\"{address}\")");
                        }
                        httpRpc.callFun(httpMessage);
                        if (!httpMessage.result.Contains("error"))
                        {
                            consAddress = JsonHelper.FromJson <string>(httpMessage.result);
                            using (DbSnapshot dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot())
                            {
                                if (!luaVMEnv.IsERC(dbSnapshot, consAddress, null))
                                {
                                    consAddress = "";
                                }
                            }
                        }
                    }
                    if (string.IsNullOrEmpty(consAddress))
                    {
                        continue;
                    }

                    if (!Wallet.CheckAddress(consAddress))
                    {
                        continue;
                    }

                    Account account = null;
                    using (DbSnapshot dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0))
                    {
                        account = dbSnapshot.Accounts.Get(consAddress);
                    }
                    if (account == null)
                    {
                        continue;
                    }

                    var rulers = consensus.GetRule(consensus.transferHeight);
                    if (rulers == null)
                    {
                        continue;
                    }

                    int    rulerCount     = 0;
                    string rulerAmountMin = "";
                    foreach (RuleInfo info in rulers.Values)
                    {
                        if (info.End == -1 || info.End > consensus.transferHeight)
                        {
                            rulerCount++;
                            rulerAmountMin = rulerAmountMin == "" ? info.Amount : BigHelper.Min(rulerAmountMin, info.Amount);
                        }
                    }

                    if ((rulerCount < 25 && BigHelper.Greater(account.amount, "3000000", true)) ||
                        BigHelper.Greater(account.amount, rulerAmountMin, false))
                    {
                        httpRpc.OnBeRulerReal(httpMessage);
                    }
                }
                catch (Exception)
                {
                }
            }
        }
        public void ThreadRun(object data)
        {
            System.Threading.Thread.Sleep(1000);

            // check url
            rulerRpc = rulerRpc ?? Entity.Root.Find("SmartxRpc")?.GetComponent <SmartxRpc>()?.GetIPEndPoint();
            if (httpPoolRelay != null && GetHeight(rulerRpc, 5) == 0)
            {
                Log.Error($"rulerRpc: {rulerRpc} can't connect");
                System.Diagnostics.Process.GetCurrentProcess().Kill();
                return;
            }

            LoadTransferFromDB();

            List <TransferHandle>        transfersDel = new List <TransferHandle>();
            Dictionary <string, Account> accounts     = new Dictionary <string, Account>();
            var timePassInfo = new TimePass(15 * 6);

            while (true)
            {
                System.Threading.Thread.Sleep(1000);

                // Query success
                try
                {
                    lock (this)
                    {
                        if (runAction != null)
                        {
                            runAction?.Invoke();
                            runAction = null;
                            SaveTransferToDB();
                        }
                    }

                    if (!timePassInfo.IsPassSet())
                    {
                        continue;
                    }

                    transfersDel.Clear();
                    for (int ii = 0; ii < transfers.Count; ii++)
                    {
                        if (transfers[ii].sendCount <= 5)
                        {
                            if (string.IsNullOrEmpty(transfers[ii].unique))
                            {
                                transfersDel.Add(transfers[ii]);
                                continue;
                            }

                            var transfer = GetUniqueTransfer(rulerRpc, transfers[ii].unique);
                            if (transfer != null)
                            {
                                if (transfer.data == transfers[ii].unique && transfer.height != 0)
                                {
                                    transfers[ii].hash = transfer.hash;
                                    transfersDel.Add(transfers[ii]);
                                }
                            }
                        }
                        else
                        {
                            File.AppendAllText("./TransferBad.csv", JsonHelper.ToJson(transfers[ii]) + "\n", Encoding.UTF8);
                            transfersDel.Add(transfers[ii]);
                        }
                    }

                    using (DbSnapshot snapshot = Entity.Root.GetComponent <Pool>().PoolDBStore.GetSnapshot())
                    {
                        bool remove = transfersDel.Count != 0;
                        // Successfully deleted from table
                        foreach (var it in transfersDel)
                        {
                            if (!string.IsNullOrEmpty(it.unique) && !string.IsNullOrEmpty(it.hash))
                            {
                                snapshot.Add($"unique_{it.unique}", it.hash); // Add to transaction cross reference table
                            }
                            transfers.Remove(it);
                        }
                        if (remove)
                        {
                            snapshot.Commit();
                        }
                    }

                    accounts.Clear();

                    long curHeight = GetHeight(rulerRpc);
                    if (curHeight == 0)
                    {
                        Log.Warning($"rulerRpc: {rulerRpc} can't connect");
                        continue;
                    }

                    // Start a new deal
                    bool bSaveDb = false;
                    for (int ii = transfers.Count - 1; ii >= 0; ii--)
                    {
                        if (transfers[ii].lastHeight < curHeight - 18 && transfers[ii].sendCount <= 5)
                        {
                            transfers[ii].lastHeight = curHeight;
                            transfers[ii].sendCount++;

                            if (BigHelper.Less(transfers[ii].amount, "0", true))
                            {
                                transfers.RemoveAt(ii);
                                continue;
                            }

                            Account account = null;
                            if (!accounts.TryGetValue(transfers[ii].addressIn, out account))
                            {
                                account = GetAccount(rulerRpc, transfers[ii].addressIn);
                                if (account == null)
                                {
                                    continue;
                                }
                                accounts.Add(transfers[ii].addressIn, account);
                            }

                            BlockSub transfer = new BlockSub();
                            transfer.addressIn  = transfers[ii].addressIn;
                            transfer.addressOut = transfers[ii].addressOut;
                            transfer.amount     = transfers[ii].amount;
                            transfer.type       = "transfer";
                            transfer.nonce      = ++account.nonce;
                            transfer.timestamp  = TimeHelper.Now();
                            transfer.data       = transfers[ii].unique;
                            transfer.extend     = new List <string>();
                            //transfer.extend.Add($"deadline:{curHeight + 16}");
                            transfer.extend.Add($"unique");

                            transfer.hash = transfer.ToHash();
                            transfer.sign = transfer.ToSign(Wallet.GetWallet().GetCurWallet());

                            //int rel = Entity.Root.GetComponent<Rule>().AddTransfer(transfer, false);
                            int rel = SendTransfer(rulerRpc, transfer);
                            if (rel == -1)
                            {
                                transfers[ii].sendCount--;
                                continue;
                            }
                            if (rel != 1)
                            {
                                File.AppendAllText("./TransferBad.csv", JsonHelper.ToJson(transfers[ii]) + "\n", Encoding.UTF8);
                                Log.Error($"TransferProcess: aAddTransfer  Error! {rel}");
                                transfers.RemoveAt(ii);
                            }
                            bSaveDb = true;
                        }
                    }
                    if (bSaveDb)
                    {
                        SaveTransferToDB();
                    }
                }
                catch (Exception)
                {
                    Log.Warning($"TransferProcess throw Exception: {rulerRpc}");
                }
            }
        }
Example #9
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);
        }
Example #10
0
        public int AddTransfer(BlockSub transfer)
        {
            if (!consensus.IsRule(height, Wallet.GetWallet().GetCurWallet().ToAddress()))
            {
                return(-1);
            }

            transfer.hash = transfer.ToHash();

            if (!Wallet.Verify(transfer.sign, transfer.hash, transfer.addressIn))
            {
                return(-2);
            }

            if (transfer.type == "transfer")
            {
                if (BigHelper.Less(transfer.amount, "0", false))
                {
                    return(-3);
                }

                Account account = null;
                using (var snapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot())
                {
                    account = snapshot.Accounts.Get(transfer.addressIn);
                }
                if (account == null)
                {
                    return(-4);
                }

                if (BigHelper.Less(account.amount, transfer.amount, false))
                {
                    return(-5);
                }

                if (BigHelper.Round8(transfer.amount) != transfer.amount)
                {
                    return(-6);
                }
            }
            else
            {
            }

            if (transfer.addressIn == transfer.addressOut)
            {
                return(-6);
            }

            lock (blockSubs)
            {
                // 出块权限
                if (blockSubs.Count > 6000)
                {
                    return(-7);
                }

                blockSubs.Remove(transfer.hash);
                blockSubs.Add(transfer.hash, transfer);
            }
            return(1);
        }