示例#1
0
        private async Task SyncBlockAsync(BlockSyncRequest blockSyncRequest)
        {
            var blockBuilder    = Builders <Block> .Filter;
            var blockFilter     = blockBuilder.Where(x => x.BlockNumber == blockSyncRequest.BlockNumber);
            var excistingBlocks = await _blockRepository.FindAsync(blockFilter, null);

            var blockExists = excistingBlocks.Count() > 0;

            Web3.Models.DTOs.Block block;
            try
            {
                block = await _blockService.GetBlockFromNodeAsync(blockSyncRequest.BlockNumber);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error getting block {blockSyncRequest.BlockNumber} from the node.");
                return;
            }

            if (block == null)
            {
                Console.WriteLine($"Block {blockSyncRequest.BlockNumber} could not be find in the node.");
                return;
            }

            var dbBlock = await _blockService.ConvertToDbBlockAsync(block, _tokenRepository, _priceRepository, _currentPrice);

            if (!blockExists)
            {
                await SaveBlock(dbBlock);
            }

            var transactions = new List <Transaction>();

            foreach (var transaction in dbBlock.Transactions)
            {
                var builder        = Builders <Transaction> .Filter;
                var filter         = builder.Where(x => x.TransactionHash == transaction.TransactionHash);
                var dbTransactions = await _transactionRepository.FindAsync(filter, null);

                var dbTransaction = dbTransactions.FirstOrDefault();
                if (dbTransaction == null)
                {
                    transactions.Add(transaction);
                }
                else
                {
                    dbTransaction.BlockHash   = dbBlock.Hash;
                    dbTransaction.BlockNumber = dbBlock.BlockNumber;
                    dbTransaction.Timestamp   = dbBlock.Timestamp;
                    transactions.Add(dbTransaction);
                }
            }

            await SaveTransactions(transactions);

            blockSyncRequest.Processed = true;
            await _blockSyncRequestRepository.SaveAsync(blockSyncRequest);
        }
示例#2
0
        public async Task <IActionResult> GetTransactions(string address, int pageNumber)
        {
            pageNumber = pageNumber == 0 ? 1 : pageNumber;
            var builder = Builders <Caladan.Models.Transaction> .Filter;
            var filter  = builder.Where(x => (x.From == address.ToLower() || x.To == address.ToLower()) && x.ShowOnAccountPage);
            var sort    = Builders <Caladan.Models.Transaction> .Sort.Descending("block_number");

            var transactions = await _transactionRepository.FindAsync(filter, sort, 15, pageNumber == 1? 0 : ((pageNumber - 1) * 15));

            var result = transactions.Select(x => new ViewModels.SimpleTransaction()
            {
                BlockNumber             = x.BlockNumber,
                Found                   = true,
                From                    = x.From,
                Gas                     = x.Gas,
                GasPrice                = x.GasPrice,
                To                      = x.To,
                TransactionHash         = x.TransactionHash,
                Value                   = x.Value.FromHexWei(x.Decimals),
                Symbol                  = string.IsNullOrEmpty(x.Symbol) ? _configuration["AppSettings:MainCurrencySymbol"] : x.Symbol,
                Timestamp               = x.Timestamp,
                ConfirmedOnFormatted    = x.Created.ToString(),
                OriginalTransactionHash = x.OriginalTransactionHash
            });

            return(Ok(result));
        }
示例#3
0
        private async Task SyncTransactionReceiptAsync(Transaction transaction)
        {
            if (transaction.TransactionHash.Length != 66 && transaction.TransactionHash.Length != 64)
            {
                return;
            }

            var transactionReceiptBuilder    = Builders <TransactionReceipt> .Filter;
            var transactionReceiptFilter     = transactionReceiptBuilder.Where(x => x.TransactionHash == transaction.TransactionHash);
            var excistingTransactionReceipts = await _transactionReceiptRepository.FindAsync(transactionReceiptFilter, null);

            var transactionReceiptExists = excistingTransactionReceipts.Count() > 0;

            if (!transactionReceiptExists)
            {
                var transactionReceipt = await _transactionService.GetTransactionReceiptFromNodeAsync(transaction.TransactionHash);

                if (transactionReceipt != null)
                {
                    var dbTransactionReceipt = _transactionService.ConvertToDbTransactionReceipt(transactionReceipt);
                    try
                    {
                        await _transactionReceiptRepository.SaveAsync(dbTransactionReceipt);
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
            }

            transaction.ReceiptSynchronized = true;
            await _transactionRepository.SaveAsync(transaction);
        }
        public async Task <FileResult> Get(string address, bool includeTokens = false)
        {
            Chilkat.Csv csv = new Chilkat.Csv
            {
                HasColumnNames = true
            };

            csv.SetColumnName(0, "Hash");
            csv.SetColumnName(1, "From");
            csv.SetColumnName(2, "To");
            csv.SetColumnName(3, "Value");
            csv.SetColumnName(4, "Symbol");
            csv.SetColumnName(5, "Timestamp");
            csv.SetColumnName(6, "Date");

            var builder = Builders <Caladan.Models.Transaction> .Filter;
            var filter  = builder.Where(x => x.From == address || x.To == address);
            var sort    = Builders <Caladan.Models.Transaction> .Sort.Descending("block_number");

            var transactions = await _transactionRepository.FindAsync(filter, sort);

            var i = 0;

            foreach (var transaction in transactions)
            {
                if (!string.IsNullOrEmpty(transaction.Symbol) && !includeTokens)
                {
                    continue;
                }

                csv.SetCell(i, 0, transaction.TransactionHash);
                csv.SetCell(i, 1, transaction.From);
                csv.SetCell(i, 2, transaction.To);
                csv.SetCell(i, 3, transaction.To.ToLower() == address.ToLower() ?
                            transaction.Value.FromHexWei(transaction.Decimals).ToString() :
                            (transaction.Value.FromHexWei(transaction.Decimals) * -1).ToString());
                csv.SetCell(i, 4, string.IsNullOrEmpty(transaction.Symbol) ? _configuration["AppSettings:MainCurrencySymbol"] : transaction.Symbol);
                csv.SetCell(i, 5, transaction.Timestamp.ToString());
                csv.SetCell(i, 6, transaction.Created.ToString());

                i++;
            }

            string csvDoc = csv.SaveToString();
            var    bytes  = Encoding.ASCII.GetBytes(csvDoc);

            if (includeTokens)
            {
                return(File(bytes, "text/csv", $"{address}-withtokens.csv"));
            }
            return(File(bytes, "text/csv", $"{address}.csv"));
        }
        public async Task DeleteAsyncByPredicateShouldSucceed()
        {
            var itemsDoc = new List <MockDocument> {
                _mockDocument98, _mockDocument99
            };

            foreach (var item in itemsDoc)
            {
                item.IsActive = false;
            }

            await _mockDocumentRepo.CreateAsync(itemsDoc);

            var searchDocResults = await _mockDocumentRepo.FindAsync();

            var count = searchDocResults.Count;

            var searchObjResults = await _mockObjectRepo.FindAsync();

            count += searchObjResults.Count;

            var deleteCount = await _mockDocumentRepo.DeleteAsync(x => !x.IsActive);

            searchDocResults = await _mockDocumentRepo.FindAsync();

            deleteCount += await _mockObjectRepo.DeleteAsync(x => true);

            searchObjResults = await _mockObjectRepo.FindAsync();

            Assert.Equal(3, count);
            Assert.Equal(3, deleteCount);

            Assert.NotNull(searchDocResults);
            Assert.NotNull(searchObjResults);
            Assert.Collection(searchDocResults);
            Assert.Collection(searchObjResults);
            Assert.Empty(searchDocResults);
            Assert.Empty(searchObjResults);
        }
示例#6
0
        public static async Task ProcessPendingBlockSyncRequests()
        {
            var builder = Builders <Models.BlockSyncRequest> .Filter;
            var filter  = builder.Where(x => !x.Processed);

            IEnumerable <BlockSyncRequest> blockSyncRequests;

            using (var _blockSyncRequestRepository = new MongoRepository <BlockSyncRequest>())
            {
                blockSyncRequests = await _blockSyncRequestRepository.FindAsync(filter, null);
            }

            var synchronizationService = new SynchronizationService();
            await synchronizationService.SynchronizeNewBlocksAsync(blockSyncRequests.ToList());
        }
示例#7
0
        public async Task <IActionResult> Get(string address, string symbol = null, int?pageNumber = 1, int?pageSize = 1000)
        {
            if (symbol != null && symbol.ToUpper() == _configuration["AppSettings:MainCurrencySymbol"])
            {
                symbol = null;
            }

            if (!string.IsNullOrWhiteSpace(symbol))
            {
                symbol = symbol.ToUpper();
            }

            pageNumber = pageNumber == 0 ? 1 : pageNumber;
            using (var transactionRepository = new MongoRepository <Caladan.Models.Transaction>())
            {
                var builder = Builders <Caladan.Models.Transaction> .Filter;
                var filter  = builder.Where(x => (x.From == address.ToLower() || x.To == address.ToLower()) && x.ShowOnAccountPage && x.Symbol == symbol);
                var sort    = Builders <Caladan.Models.Transaction> .Sort.Descending("block_number");

                var numberOfTransactions = transactionRepository.GetQueryable(x => (x.From == address.ToLower() || x.To == address.ToLower()) && x.ShowOnAccountPage && x.Symbol == symbol).Count();
                var transactions         = await transactionRepository.FindAsync(filter, sort, pageSize, pageNumber == 1? 0 : ((pageNumber - 1) * pageSize));

                var result = new Models.Api.TransactionList()
                {
                    PageNumber   = pageNumber.Value,
                    PageSize     = pageSize.Value,
                    TotalCount   = numberOfTransactions,
                    Transactions = transactions.Select(transaction => new Models.Api.Transaction()
                    {
                        BlockHash        = transaction.BlockHash,
                        BlockNumber      = transaction.BlockNumber,
                        From             = transaction.From,
                        Gas              = transaction.Gas,
                        GasPrice         = transaction.GasPrice,
                        Input            = transaction.Input,
                        Nonce            = transaction.Nonce,
                        To               = transaction.To,
                        TransactionHash  = transaction.TransactionHash.Replace("tokenreceiver_", ""),
                        TransactionIndex = transaction.TransactionIndex,
                        Value            = transaction.Value.FromHexWei(transaction.Decimals),
                        Symbol           = string.IsNullOrEmpty(transaction.Symbol) ? _configuration["AppSettings:MainCurrencySymbol"] : transaction.Symbol,
                        Timestamp        = transaction.Timestamp
                    }).ToArray()
                };

                return(Ok(result));
            }
        }
示例#8
0
        private static async Task GetTransactionReceipt(string transactionHash, TransactionService transactionService, MongoRepository <Caladan.Models.Transaction> transactionRepository,
                                                        MongoRepository <Caladan.Models.TransactionReceipt> transactionReceiptRepository, Caladan.Models.Transaction transaction)
        {
            if (transaction.BlockNumber > 0)
            {
                var transactionReceiptBuilder = Builders <Caladan.Models.TransactionReceipt> .Filter;
                var transactionReceiptFilter  = transactionReceiptBuilder.Where(x => x.TransactionHash == transactionHash.ToLower());
                var transactionReceipts       = await transactionReceiptRepository.FindAsync(transactionReceiptFilter, null);

                var transactionReceipt = transactionReceipts.FirstOrDefault();

                if (transactionReceipt == null)
                {
                    transactionReceipt = await transactionService.GetTransactionReceiptAsync(transactionHash.ToLower());
                }

                transaction.Receipt = transactionReceipt;
            }
        }
示例#9
0
        public async Task <IActionResult> Get(string address, int pageNumber)
        {
            using (var accountService = new AccountService(_nodeUrls, _transactionRepository, _accountRepository))
            {
                var getAccount = accountService.GetAccountAsync(address, _configuration["AppSettings:MainCurrencySymbol"], false, 25, true);

                var builder = Builders <Caladan.Models.Block> .Filter;
                var filter  = builder.Where(x => x.Miner == address.ToLower());
                var orderBy = Builders <Caladan.Models.Block> .Sort.Descending("block_number");

                var getMinedBlocks = _blockRepository.FindAsync(filter, orderBy, 200);

                await Task.WhenAll(getAccount, getMinedBlocks);

                var account     = getAccount.Result;
                var minedBlocks = getMinedBlocks.Result;

                var base64Icon = "";
                if (account != null)
                {
                    var blockiesHelper = new Blockies(address.ToLower());
                    base64Icon = blockiesHelper.GetBase64Image(128);
                }

                return(Ok(account == null ? new ViewModels.Account()
                {
                    Found = false
                } : new ViewModels.Account()
                {
                    Address = account.Address,
                    Balance = account.Balance,
                    BalanceBtc = account.BalanceBtc,
                    BalanceEur = account.BalanceEur,
                    BalanceUsd = account.BalanceUsd,
                    Found = true,
                    LastSeenInBlock = account.LastSeenInBlock,
                    Name = account.Name,
                    NumberOfTransactions = account.NumberOfTransactions,
                    Identicon = base64Icon,
                    Transactions = account.Transactions.Select(x => new ViewModels.SimpleTransaction()
                    {
                        BlockNumber = x.BlockNumber,
                        Found = true,
                        From = x.From,
                        Gas = x.Gas,
                        GasPrice = x.GasPrice,
                        To = x.To,
                        TransactionHash = x.TransactionHash,
                        Value = x.Value.FromHexWei(x.Decimals),
                        Symbol = string.IsNullOrEmpty(x.Symbol) ? _configuration["AppSettings:MainCurrencySymbol"] : x.Symbol,
                        Timestamp = x.Timestamp,
                        ConfirmedOnFormatted = x.Created.ToString(),
                        OriginalTransactionHash = x.OriginalTransactionHash
                    }).ToArray(),
                    Tokens = account.Tokens.OrderBy(x => x.Name).Select(x => new ViewModels.TokenBalance()
                    {
                        Address = x.Address,
                        Balance = x.Balance,
                        Name = x.Name,
                        Symbol = x.Symbol,
                        Logo = x.Logo
                    }).ToArray(),
                    Blocks = minedBlocks.Select(x => new ViewModels.Block()
                    {
                        BlockNumber = x.BlockNumber,
                        Hash = x.Hash,
                        Miner = x.Miner,
                        NumberOfTransactions = x.NumberOfTransactions,
                        Difficulty = x.Difficulty,
                        ExtraData = x.ExtraData,
                        GasLimit = x.GasLimit,
                        GasUsed = x.GasUsed,
                        LogsBloom = x.LogsBloom,
                        Nonce = x.Nonce,
                        ParentHash = x.ParentHash,
                        Sha3Uncles = x.Sha3Uncles,
                        Size = x.Size,
                        StateRoot = x.StateRoot,
                        Timestamp = x.Timestamp,
                        TotalDifficulty = x.TotalDifficulty,
                        TransactionsRoot = x.TransactionsRoot,
                        Found = true
                    }).ToArray(),
                    Url = $"/account/{account.Address}"
                }));
            }
        }
示例#10
0
        public async Task CreateAsyncByItemShouldSucceed()
        {
            await _mockObjectRepo.CreateAsync(_mockObject);

            await _mockDocumentRepo.CreateAsync(_mockDocument98);

            var item = await _mockDocumentRepo.FindAsync(_mockDocument98.Id);

            Assert.Equal(_mockDocument98.Id, item.Id);
            Assert.Equal(_mockDocument98.Name, item.Name);
            Assert.Equal(_mockDocument98.Value, item.Value);
            Assert.True(_mockDocument98.CreationDate.EqualsMongoDateTime(item.CreationDate));
            Assert.Equal(_mockDocument98.IsActive, item.IsActive);
        }