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; }); }
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); }
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); }
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); }
// 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); }
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("导出完成"); } } }
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}"); } } }
// 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); }
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); }