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); } } } } }
public void SaveTransferToDB() { using (DbSnapshot snapshot = Entity.Root.GetComponent <Pool>().PoolDBStore.GetSnapshot()) { snapshot.Add($"TransferProcess", JsonHelper.ToJson(transfers)); snapshot.Commit(); } }
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); }
// 奖励上一周期的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>();
public bool ApplyHeight(BlockChain blockChain) { if (blockChain == null) { return(false); } // 应用高度不是下一高度 long.TryParse(levelDBStore.Get("UndoHeight"), out transferHeight); if (blockChain.height - 1 != transferHeight) { return(false); } Block mcblk = blockChain.GetMcBlock(); if (mcblk == null) { return(false); } Block preblk = BlockChainHelper.GetMcBlock(transferHeight); if (mcblk.prehash != preblk.hash) { return(false); } LuaVMEnv luaVMEnv = Entity.Root.GetComponent <LuaVMEnv>(); ruleInfos = luaVMEnv.GetRules(consAddress, transferHeight); // -------------------------------------------------- calculatePower.Insert(mcblk); //Log.Debug($"ApplyHeight={blockChain.height}, {calculatePower.GetPower()}, {mcblk.GetDiff()}"); using (DbSnapshot dbSnapshot = levelDBStore.GetSnapshotUndo(blockChain.height)) { blockChain.Apply(dbSnapshot); ApplyReward(dbSnapshot, mcblk); if (GetRuleCount(mcblk.height - 1, 2) >= 2 && BlockChainHelper.IsIrreversible(this, mcblk)) { dbSnapshot.Add("2F1Height", mcblk.height.ToString()); } // 连接块交易 for (int ii = 0; ii < mcblk.linksblk.Count; ii++) { Block linkblk = blockMgr.GetBlock(mcblk.linksblk[ii]); if (linkblk == null) { return(false); } if (linkblk.height != 1) { for (int jj = 0; jj < linkblk.linkstran.Count; jj++) { if (!ApplyTransfer(dbSnapshot, linkblk.linkstran[jj], linkblk.height)) { return(false); } if (!ApplyContract(dbSnapshot, linkblk.linkstran[jj], linkblk.height)) { return(false); } } } } dbSnapshot.Commit(); } ruleInfos = luaVMEnv.GetRules(consAddress, mcblk.height, true); return(true); }
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); }
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}"); } } }
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); }
public async void Run() { await Task.Delay(1000); LoadTransferFromDB(); List <TransferHandle> transfersDel = new List <TransferHandle>(); var rule = Entity.Root.GetComponent <Rule>(); while (true) { await Task.Delay(15000 * 6); // Query success using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0)) { transfersDel.Clear(); for (int ii = 0; ii < transfers.Count; ii++) { if (transfers[ii].sendCount <= 5) { string hasht = dbSnapshot.Get($"unique_{transfers[ii].unique}"); if (!string.IsNullOrEmpty(hasht)) { var transfer = dbSnapshot.Transfers.Get(hasht); if (transfer != null) { if (transfer.data == transfers[ii].unique) { transfers[ii].hash = hasht; transfersDel.Add(transfers[ii]); } } } } else { 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(); } } // Start a new deal for (int ii = transfers.Count - 1; ii >= 0; ii--) { if (transfers[ii].lastHeight < rule.height + 6 && transfers[ii].sendCount <= 5) { transfers[ii].lastHeight = rule.height; transfers[ii].sendCount++; var account = dbSnapshot.Accounts.Get(transfers[ii].addressIn); 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.hash = transfer.ToHash(); transfer.sign = transfer.ToSign(Wallet.GetWallet().GetCurWallet()); dbSnapshot.Accounts.Add(transfers[ii].addressIn, account); // account.nonce Count accumulation int rel = Entity.Root.GetComponent <Rule>().AddTransfer(transfer); if (rel != 1) { Log.Error($"TransferProcess: aAddTransfer Error! {transfers[ii]}"); transfers.RemoveAt(ii); } } } } } }