private static bool ConfirmTransaction(JSONRPC_Client rpc, Logger logger, string host, Hash hash, int maxTries = 99999) { var hashStr = hash.ToString(); int tryCount = 0; int delay = 250; do { var response = rpc.SendRequest(logger, host, "getConfirmations", hashStr); if (response == null) { logger.Error("Transfer request failed"); return(false); } var confirmations = response.GetInt32("confirmations"); if (confirmations > 0) { logger.Success("Confirmations: " + confirmations); return(true); } tryCount--; if (tryCount >= maxTries) { return(false); } Thread.Sleep(delay); delay *= 2; } while (true); }
private static Hash SendTransfer(JSONRPC_Client rpc, Logger logger, string nexusName, string host, PhantasmaKeys from, Address to, BigInteger amount) { Throw.IfNull(rpc, nameof(rpc)); Throw.IfNull(logger, nameof(logger)); var script = ScriptUtils.BeginScript().AllowGas(from.Address, Address.Null, 1, 9999).TransferTokens("SOUL", from.Address, to, amount).SpendGas(from.Address).EndScript(); var tx = new Transaction(nexusName, "main", script, Timestamp.Now + TimeSpan.FromMinutes(30)); tx.Sign(from); var bytes = tx.ToByteArray(true); //log.Debug("RAW: " + Base16.Encode(bytes)); var response = rpc.SendRequest(logger, host, "sendRawTransaction", Base16.Encode(bytes)); if (response == null) { logger.Error($"Error sending {amount} {DomainSettings.FuelTokenSymbol} from {from.Address} to {to}..."); return(Hash.Null); } if (response.HasNode("error")) { var error = response.GetString("error"); logger.Error("Error: " + error); return(Hash.Null); } var hash = response.Value; return(Hash.Parse(hash)); }
private static BigInteger FetchBalance(JSONRPC_Client rpc, Logger logger, string host, Address address) { var response = rpc.SendRequest(logger, host, "getAccount", address.ToString()); if (response == null) { logger.Error($"Error fetching balance of {address}..."); return(0); } var balances = response["balances"]; if (balances == null) { logger.Error($"Error fetching balance of {address}..."); return(0); } BigInteger total = 0; foreach (var entry in balances.Children) { var chain = entry.GetString("chain"); var symbol = entry.GetString("symbol"); if (symbol == DomainSettings.FuelTokenSymbol) { total += BigInteger.Parse(entry.GetString("amount")); } } return(total); }
private void RunSender(string wif, string nexusName, string host, int threadCount, int addressesListSize) { logger.Message("Running in sender mode."); running = true; Console.CancelKeyPress += delegate { running = false; logger.Message("Stopping sender..."); }; var masterKeys = PhantasmaKeys.FromWIF(wif); var rpc = new JSONRPC_Client(); logger.Message($"Fetch initial balance from {masterKeys.Address}..."); BigInteger initialAmount = FetchBalance(rpc, logger, host, masterKeys.Address); if (initialAmount <= 0) { logger.Message($"Could not obtain funds"); return; } logger.Message($"Initial balance: {UnitConversion.ToDecimal(initialAmount, DomainSettings.FuelTokenDecimals)} SOUL"); initialAmount /= 10; // 10% initialAmount /= threadCount; logger.Message($"Estimated amount per thread: {UnitConversion.ToDecimal(initialAmount, DomainSettings.FuelTokenDecimals)} SOUL"); for (int i = 1; i <= threadCount; i++) { logger.Message($"Starting thread #{i}..."); try { new Thread(() => { SenderSpawn(i, masterKeys, nexusName, host, initialAmount, addressesListSize); }).Start(); Thread.Sleep(200); } catch (Exception e) { logger.Error(e.ToString()); break; } } this.Run(); }
private void SenderSpawn(int ID, PhantasmaKeys masterKeys, string nexusName, string host, BigInteger initialAmount, int addressesListSize) { Throw.IfNull(logger, nameof(logger)); Thread.CurrentThread.IsBackground = true; BigInteger fee = 9999; // TODO calculate the real fee BigInteger amount = initialAmount; var tcp = new TcpClient("localhost", 7073); var peer = new TCPPeer(tcp.Client); var peerKey = PhantasmaKeys.Generate(); logger.Message($"#{ID}: Connecting to peer: {host} with address {peerKey.Address.Text}"); var request = new RequestMessage(RequestKind.None, nexusName, peerKey.Address); request.Sign(peerKey); peer.Send(request); int batchCount = 0; var rpc = new JSONRPC_Client(); { logger.Message($"#{ID}: Sending funds to address {peerKey.Address.Text}"); var hash = SendTransfer(rpc, logger, nexusName, host, masterKeys, peerKey.Address, initialAmount); if (hash == Hash.Null) { logger.Error($"#{ID}:Stopping, fund transfer failed"); return; } if (!ConfirmTransaction(rpc, logger, host, hash)) { logger.Error($"#{ID}:Stopping, fund confirmation failed"); return; } } logger.Message($"#{ID}: Beginning send mode"); bool returnPhase = false; var txs = new List <Transaction>(); var addressList = new List <PhantasmaKeys>(); int waveCount = 0; while (true) { bool shouldConfirm; try { txs.Clear(); if (returnPhase) { foreach (var target in addressList) { var script = ScriptUtils.BeginScript().AllowGas(target.Address, Address.Null, 1, 9999).TransferTokens("SOUL", target.Address, peerKey.Address, 1).SpendGas(target.Address).EndScript(); var tx = new Transaction(nexusName, "main", script, Timestamp.Now + TimeSpan.FromMinutes(30)); tx.Sign(target); txs.Add(tx); } addressList.Clear(); returnPhase = false; waveCount = 0; shouldConfirm = true; } else { amount -= fee * 2 * addressesListSize; if (amount <= 0) { break; } for (int j = 0; j < addressesListSize; j++) { var target = PhantasmaKeys.Generate(); addressList.Add(target); var script = ScriptUtils.BeginScript().AllowGas(peerKey.Address, Address.Null, 1, 9999).TransferTokens("SOUL", peerKey.Address, target.Address, 1 + fee).SpendGas(peerKey.Address).EndScript(); var tx = new Transaction(nexusName, "main", script, Timestamp.Now + TimeSpan.FromMinutes(30)); tx.Sign(peerKey); txs.Add(tx); } waveCount++; if (waveCount > 10) { returnPhase = true; shouldConfirm = true; } else { shouldConfirm = false; } } returnPhase = !returnPhase; var msg = new MempoolAddMessage(peerKey.Address, txs); msg.Sign(peerKey); peer.Send(msg); } catch (Exception e) { logger.Error($"#{ID}:Fatal error : {e}"); return; } if (txs.Any()) { if (shouldConfirm) { var confirmation = ConfirmTransaction(rpc, logger, host, txs.Last().Hash); if (!confirmation) { logger.Error($"#{ID}:Confirmation failed, aborting..."); } } else { Thread.Sleep(500); } batchCount++; logger.Message($"#{ID}:Sent {txs.Count} transactions (batch #{batchCount})"); } else { logger.Message($"#{ID}: No transactions left"); return; } } logger.Message($"#{ID}: Thread ran out of funds"); }
public API(string host) { this.Host = host; _client = new JSONRPC_Client(); }