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; }); }
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); }
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 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); }