public void Update() { try { if (this.platforms == null) { if (!Nexus.HasGenesis) { return; } var platforms = Nexus.GetPlatforms(Nexus.RootStorage); this.platforms = platforms.Select(x => Nexus.GetPlatformInfo(Nexus.RootStorage, x)).ToArray(); if (this.platforms.Length == 0) { Logger.Warning("No interop platforms found. Make sure that the Nexus was created correctly."); return; } _swappers["neo"] = new NeoInterop(this, neoAPI, interopBlocks["neo"], Settings.Oracle.NeoQuickSync); SwapAddresses["neo"] = _swappers["neo"].LocalAddress; _swappers["ethereum"] = new EthereumInterop(this, ethAPI, interopBlocks["ethereum"], Nexus.GetPlatformTokenHashes("ethereum", Nexus.RootStorage).Select(x => x.ToString().Substring(0, 40)).ToArray(), Settings.Oracle.EthConfirmations); SwapAddresses["ethereum"] = _swappers["ethereum"].LocalAddress; Logger.Message("Available swap addresses:"); foreach (var x in SwapAddresses) { Logger.Message("platform: " + x.Key + " address: " + x.Value); } } if (this.platforms.Length == 0) { return; } else { if (taskDict.Count == 0) { foreach (var platform in this.platforms) { taskDict.Add(platform.Name, null); } } } lock (StateModificationLock) { var pendingList = new StorageList(PendingTag, this.Storage); int i = 0; var count = pendingList.Count(); while (i < count) { var settlement = pendingList.Get <PendingFee>(i); if (UpdatePendingSettle(pendingList, i)) { pendingList.RemoveAt(i); count--; } else { i++; } } } ProcessCompletedTasks(); for (var j = 0; j < taskDict.Count; j++) { var platform = taskDict.Keys.ElementAt(j); var task = taskDict[platform]; if (task == null) { if (_swappers.TryGetValue(platform, out ChainSwapper finder)) { taskDict[platform] = new Task <IEnumerable <PendingSwap> >(() => { return(finder.Update()); }); } } } // start new tasks foreach (var entry in taskDict) { var task = entry.Value; if (task != null && task.Status.Equals(TaskStatus.Created)) { task.ContinueWith(t => { Console.WriteLine($"===> task {task.ToString()} failed"); }, TaskContinuationOptions.OnlyOnFaulted); task.Start(); } } } catch (Exception e) { var logMessage = "TokenSwapper.Update() exception caught:\n" + e.Message; var inner = e.InnerException; while (inner != null) { logMessage += "\n---> " + inner.Message + "\n\n" + inner.StackTrace; inner = inner.InnerException; } logMessage += "\n\n" + e.StackTrace; Logger.Error(logMessage); } }
public static Tuple <InteropBlock, InteropTransaction[]> MakeInteropBlock(Nexus nexus, Logger logger, EthAPI api , BigInteger height, string[] contracts, uint confirmations, string[] swapAddress) { Hash blockHash = Hash.Null; var interopTransactions = new List <InteropTransaction>(); //TODO HACK var combinedAddresses = contracts.ToList(); combinedAddresses.AddRange(swapAddress); Dictionary <string, Dictionary <string, List <InteropTransfer> > > transfers = new Dictionary <string, Dictionary <string, List <InteropTransfer> > >(); try { Func <string, Address> addressEncoder = (address) => { return(EthereumWallet.EncodeAddress(address)); }; Func <Nethereum.RPC.Eth.DTOs.Transaction, Address> addressExtractor = (tx) => { return(EthereumInterop.ExtractInteropAddress(tx, logger)); }; var crawler = new EvmBlockCrawler(logger, combinedAddresses.ToArray(), confirmations, api, addressEncoder, addressExtractor, EthereumWallet.EthereumPlatform); // fetch blocks crawler.Fetch(height); transfers = crawler.ExtractInteropTransfers(nexus, logger, swapAddress); } catch (Exception e) { logger.Error("Failed to fetch eth blocks: " + e); } if (transfers.Count == 0) { var emptyBlock = new InteropBlock(EthereumWallet.EthereumPlatform, EthereumWallet.EthereumPlatform, Hash.Null, new Hash[] {}); return(Tuple.Create(emptyBlock, interopTransactions.ToArray())); } blockHash = Hash.Parse(transfers.FirstOrDefault().Key); foreach (var block in transfers) { var txTransferDict = block.Value; foreach (var tx in txTransferDict) { var interopTx = MakeInteropTx(logger, tx.Key, tx.Value); if (interopTx.Hash != Hash.Null) { interopTransactions.Add(interopTx); } } } var hashes = interopTransactions.Select(x => x.Hash).ToArray(); InteropBlock interopBlock = (interopTransactions.Count() > 0) ? new InteropBlock(EthereumWallet.EthereumPlatform, EthereumWallet.EthereumPlatform, blockHash, hashes) : new InteropBlock(EthereumWallet.EthereumPlatform, EthereumWallet.EthereumPlatform, Hash.Null, hashes); return(Tuple.Create(interopBlock, interopTransactions.ToArray())); }