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 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); }
public static decimal GetCoinRate(string baseSymbol, string quoteSymbol, string cryptoCompApiKey, bool cgEnabled, PricerSupportedToken[] supportedTokens, Logger logger) { try { Decimal cGeckoPrice = 0; Decimal cComparePrice = 0; cComparePrice = CryptoCompareUtils.GetCoinRate(baseSymbol, quoteSymbol, cryptoCompApiKey, supportedTokens, logger); if (cgEnabled) { cGeckoPrice = CoinGeckoUtils.GetCoinRate(baseSymbol, quoteSymbol, supportedTokens, logger); } if ((cGeckoPrice > 0) && (cComparePrice > 0)) { return((cGeckoPrice + cComparePrice) / 2); } if ((cGeckoPrice > 0) && (cComparePrice <= 0)) { return(cGeckoPrice); } if ((cComparePrice > 0) && (cGeckoPrice <= 0)) { return(cComparePrice); } return(0); } catch (Exception ex) { var errorMsg = ex.ToString(); logger.Error($"Pricer error: {errorMsg}"); return(0); } }
public static decimal GetCoinRate(string baseSymbol, string quoteSymbol, PricerSupportedToken[] supportedTokens, Logger logger) { string json; string baseticker = ""; foreach (var token in supportedTokens) { if (token.ticker == baseSymbol) { baseticker = token.coingeckoId; break; } } if (String.IsNullOrEmpty(baseticker)) { return(0); } var url = $"https://api.coingecko.com/api/v3/simple/price?ids={baseticker}&vs_currencies={quoteSymbol}"; try { using (var wc = new System.Net.WebClient()) { json = wc.DownloadString(url); } if (String.IsNullOrEmpty(json)) { return(0); } var root = JSONReader.ReadFromString(json); // hack for goati price .10 if (baseticker == "GOATI") { var price = 0.10m; return(price); } else { root = root[baseticker]; var price = root.GetDecimal(quoteSymbol.ToLower()); return(price); } } catch (Exception ex) { var errorMsg = ex.Message; logger.Error($"Error while trying to query {baseticker} price from CoinGecko API: {errorMsg}"); return(0); } }
private T Read <T>(string platform, string chainName, Hash hash, StorageConst type) { var storageKey = type + chainName + hash.ToString(); var keyStore = _keyValueStore[platform + type] as KeyValueStore <string, T>; try { if (keyStore.TryGet(storageKey, out T data)) { return(data); } } catch (Exception e) { logger.Error(e.ToString()); return(default(T)); } return(default(T)); }
public static decimal GetCoinRate(string baseSymbol, string quoteSymbol, string APIKey, PricerSupportedToken[] supportedTokens, Logger logger) { string baseticker = ""; foreach (var token in supportedTokens) { if (token.ticker == baseSymbol) { baseticker = token.cryptocompareId; break; } } if (String.IsNullOrEmpty(baseticker)) { return(0); } var url = $"https://min-api.cryptocompare.com/data/price?fsym={baseticker}&tsyms={quoteSymbol}&api_key={APIKey}"; string json; try { using (var wc = new System.Net.WebClient()) { json = wc.DownloadString(url); } if (String.IsNullOrEmpty(json)) { return(0); } var root = JSONReader.ReadFromString(json); var price = root.GetDecimal(quoteSymbol); return(price); } catch (Exception ex) { var errorMsg = ex.Message; logger.Error($"Error while trying to query {baseticker} price from CryptoCompare API: {errorMsg}"); return(0); } }
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"); }