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); }
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)); }
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); }
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()); }
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)); } }
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; } }
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}" })); } }
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); }