Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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()));
        }