public static HistoryModel ToHistoryModel(this OrderEventModel orderEvent)
        {
            var status = HistoryState.InProgress;

            if (orderEvent.Status == OrderStatus.Cancelled)
            {
                status = HistoryState.Canceled;
            }

            return(new HistoryModel
            {
                Id = orderEvent.Id.ToString(),
                DateTime = orderEvent.Timestamp,
                Type = HistoryType.OrderEvent,
                Amount = orderEvent.Volume,
                AssetPair = orderEvent.AssetPairId,
                State = status,
                Price = orderEvent.Price
            });
        }
예제 #2
0
        public async Task ScanOrdersByEventsAsync()
        {
            string latestScannedBlockKey = "OrderLatestScannedBlock";
            var    abi = await _abiProvider.GetCrowdsaleAbiAsync();

            var contract   = _nethereumClient.Eth.GetContract(abi, _ethSettings.EtherDeltaContractAddress);
            var orderEvent = contract.GetEvent("Order");

            var blockNumHex = await _nethereumClient.Eth.Blocks.GetBlockNumber.SendRequestAsync();

            var blockNumLong = Convert.ToInt64(blockNumHex.Value.ToString());

            //to avoid races conditions between services
            blockNumLong -= 5;

            var latestScannedBlock = await _parametersService.GetLatestScannedBlockAsync(latestScannedBlockKey);

            var fromBlock = new BlockParameter(Convert.ToUInt64(latestScannedBlock + 1));

            var filterInput = orderEvent.CreateFilterInput(fromBlock);

            var logs = await _etherscanService.GetEventsAsync(filterInput, latestScannedBlock + 1, blockNumLong);

            var eventLogsAll = orderEvent.DecodeAllEventsForEvent <OrderEvent>(logs);

            var detectedTransactionHashes = eventLogsAll.Select(l => l.Log.TransactionHash).ToList();

            var existingDbTransactions = _context.OrderEvent
                                         .Where(t => detectedTransactionHashes.Contains(t.TransactionHash))
                                         .ToDictionary(t => t.TransactionHash, t => t);

            foreach (var eventEntry in eventLogsAll)
            {
                if (existingDbTransactions.TryGetValue(eventEntry.Log.TransactionHash, out var dbTransaction))
                {
                    continue;
                }

                var transaction = await _nethereumClient.Eth.Transactions.GetTransactionByHash.SendRequestAsync(eventEntry.Log.TransactionHash);

                var receipt = await _nethereumClient.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventEntry.Log.TransactionHash);

                var block = await _nethereumClient.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(transaction.BlockNumber);

                var epoch = Convert.ToInt64(block.Timestamp.Value.ToString());

                var dbEvent = new OrderEventModel
                {
                    TokenGet   = eventEntry.Event.TokenGet,
                    AmountGet  = eventEntry.Event.AmountGet.ToString(),
                    TokenGive  = eventEntry.Event.TokenGive,
                    AmountGive = eventEntry.Event.AmountGive.ToString(),
                    Expires    = eventEntry.Event.Expires.ToString(),
                    Nonce      = eventEntry.Event.Nonce.ToString(),
                    User       = eventEntry.Event.User,

                    Hash            = ComputeHash(eventEntry.Event as OrderEvent),
                    TransactionHash = eventEntry.Log.TransactionHash,
                    Timestamp       = DateTimeOffset.FromUnixTimeSeconds(epoch),
                    BlockNum        = Convert.ToInt64(transaction.BlockNumber.Value.ToString()),
                    GasPriceWei     = Convert.ToInt64(transaction.GasPrice.Value.ToString()),
                    GasUsed         = Convert.ToInt64(receipt.GasUsed.Value.ToString()),
                };
                await _context.OrderEvent.AddAsync(dbEvent);
            }

            await _parametersService.SetLatestScannedBlockAsync(latestScannedBlockKey, blockNumLong);

            await _context.SaveChangesAsync();
        }