Skip to content

Commit

Permalink
feat: txns use blockchain indexer
Browse files Browse the repository at this point in the history
  • Loading branch information
mixhsnhd committed Jan 3, 2025
1 parent 611fc84 commit 474c173
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@

namespace EoaServer.Provider.Dto.Indexer;

public class TokenTransferInput : BaseInput
public class GetTokenTransferRequestDto : BaseInput

{
public string Symbol { get; set; } = "";
public string Search { get; set; } = "";
public string CollectionSymbol { get; set; } = "";

public string Address { get; set; } = "";

public List<SymbolType> Types { get; set; } = new() { SymbolType.Token };

public string FuzzySearch { get; set; } = "";

public DateTime? BeginBlockTime { get; set; }

public void SetDefaultSort()
Expand All @@ -29,8 +26,7 @@ public void SetDefaultSort()

OfOrderInfos((SortField.BlockTime, SortDirection.Desc), (SortField.TransactionId, SortDirection.Desc));
}



public void SetBlockTimeSort()
{
if (!OrderBy.IsNullOrEmpty() || !OrderInfos.IsNullOrEmpty())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using EoaServer.Commons;
using EoaServer.Token.Dto;

namespace EoaServer.Provider.Dto.Indexer;

public class IndexerTransactionResultDto
{
public IndexerTransactionListResultDto TransactionInfos { get; set; }
}

public class IndexerTransactionListResultDto
{
public long TotalCount { get; set; }
public List<IndexerTransactionInfoDto> Items { get; set; } = new();
}

public class IndexerTransactionInfoDto
{
public string TransactionId { get; set; }
public long BlockHeight { get; set; }
public string MethodName { get; set; }
public TransactionStatus Status { get; set; }
public string From { get; set; }
public string To { get; set; }
public long TransactionValue { get; set; }
public MetadataDto Metadata { get; set; }
public long Fee { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;

namespace EoaServer.Provider.Dto.Indexer;

public class TransactionsRequestDto : BaseInput
{
public string TransactionId { get; set; } = "";
public int BlockHeight { get; set; }
public long StartTime { get; set; }
public long EndTime { get; set; }
public string Address { get; set; } = "";

public void SetDefaultSort()
{
if (!OrderBy.IsNullOrEmpty() || !OrderInfos.IsNullOrEmpty())
{
return;
}

OfOrderInfos((SortField.BlockTime, SortDirection.Desc), (SortField.TransactionId, SortDirection.Desc));
}


public void SetFirstTransactionSort()
{
if (!OrderBy.IsNullOrEmpty() || !OrderInfos.IsNullOrEmpty())
{
return;
}

OfOrderInfos((SortField.BlockHeight, SortDirection.Asc), (SortField.TransactionId, SortDirection.Asc));
}

public void SetLastTransactionSort()
{
if (!OrderBy.IsNullOrEmpty() || !OrderInfos.IsNullOrEmpty())
{
return;
}

OfOrderInfos((SortField.BlockHeight, SortDirection.Desc), (SortField.TransactionId, SortDirection.Desc));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ namespace EoaServer.Provider;

public interface IGraphQLProvider
{
public Task<IndexerTokenTransferListDto> GetTokenTransferInfoAsync(TokenTransferInput input);
Task<IndexerTokenTransferListDto> GetTokenTransferInfoAsync(GetTokenTransferRequestDto requestDto);
Task<IndexerTransactionListResultDto> GetTransactionsAsync(TransactionsRequestDto input);
}
84 changes: 74 additions & 10 deletions src/EoaServer.Application/Provider/GraphQLProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EoaServer.Options;
using EoaServer.Provider.Dto.Indexer;
Expand Down Expand Up @@ -38,10 +39,10 @@ public GraphQLProvider(IClusterClient clusterClient,
_tokenAppService = tokenAppService;
}

public async Task<IndexerTokenTransferListDto> GetTokenTransferInfoAsync(TokenTransferInput input)
public async Task<IndexerTokenTransferListDto> GetTokenTransferInfoAsync(GetTokenTransferRequestDto requestDto)
{
input.SetDefaultSort();
var indexerResult = await _tokenIndexerClient.SendQueryAsync<IndexerTokenTransfersDto>(new GraphQLRequest
requestDto.SetDefaultSort();
var graphQlResponse = await _tokenIndexerClient.SendQueryAsync<IndexerTokenTransfersDto>(new GraphQLRequest
{
Query =
@"query($chainId:String!,$symbol:String!,$address:String,$collectionSymbol:String,
Expand All @@ -65,14 +66,77 @@ public async Task<IndexerTokenTransferListDto> GetTokenTransferInfoAsync(TokenTr
}",
Variables = new
{
chainId = input.ChainId, symbol = input.Symbol, address = input.Address, search = input.Search,
skipCount = input.SkipCount, maxResultCount = input.MaxResultCount,
collectionSymbol = input.CollectionSymbol,
sort = input.Sort, fuzzySearch = input.FuzzySearch,
orderInfos = input.OrderInfos, searchAfter = input.SearchAfter, beginBlockTime = input.BeginBlockTime
chainId = requestDto.ChainId, symbol = requestDto.Symbol, address = requestDto.Address, search = requestDto.Search,
skipCount = requestDto.SkipCount, maxResultCount = requestDto.MaxResultCount,
collectionSymbol = requestDto.CollectionSymbol,
sort = requestDto.Sort, fuzzySearch = requestDto.FuzzySearch,
orderInfos = requestDto.OrderInfos, searchAfter = requestDto.SearchAfter, beginBlockTime = requestDto.BeginBlockTime
}
});
return indexerResult == null || indexerResult.Data == null ?
new IndexerTokenTransferListDto() : indexerResult.Data.TransferInfo;

if (graphQlResponse.Errors != null)
{
ErrorLog(graphQlResponse.Errors);
return new IndexerTokenTransferListDto();
}

return graphQlResponse.Data.TransferInfo;
}

public async Task<IndexerTransactionListResultDto> GetTransactionsAsync(TransactionsRequestDto requestDto)
{
requestDto.SetDefaultSort();
var graphQlResponse = await _blockChainIndexerClient.SendQueryAsync<IndexerTransactionResultDto>(new GraphQLRequest
{
Query =
@"query($chainId:String,$skipCount:Int!,$maxResultCount:Int!,$startTime:Long!,$endTime:Long!,$address:String!,$searchAfter:[String],$orderInfos:[OrderInfo]){
transactionInfos(input: {chainId:$chainId,skipCount:$skipCount,maxResultCount:$maxResultCount,startTime:$startTime,endTime:$endTime,address:$address,searchAfter:$searchAfter,orderInfos:$orderInfos})
{
totalCount
items {
transactionId
blockHeight
chainId
methodName
status
from
to
transactionValue
fee
metadata {
chainId
block {
blockHash
blockHeight
blockTime
}
}
}
}
}",
Variables = new
{
chainId = requestDto.ChainId, skipCount = requestDto.SkipCount, maxResultCount = requestDto.MaxResultCount,
startTime = requestDto.StartTime,
endTime = requestDto.EndTime, address = requestDto.Address,
orderInfos = requestDto.OrderInfos, searchAfter = requestDto.SearchAfter
}
});

if (graphQlResponse.Errors != null)
{
ErrorLog(graphQlResponse.Errors);
return new IndexerTransactionListResultDto();
}

return graphQlResponse.Data.TransactionInfos;
}

private void ErrorLog(GraphQLError[] errors)
{
errors.ToList().ForEach(error =>
{
_logger.Error("GraphQL error: {message}", error.Message);
});
}
}
95 changes: 60 additions & 35 deletions src/EoaServer.Application/UserActivity/UserActivityAppService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,59 @@ public async Task<GetActivityDto> GetActivityAsync(GetActivityRequestDto request
var tokenMap = await GetTokenMapAsync(tokens);
return await ConvertDtoAsync(request.ChainId, txnDto.List[0], tokenMap, 0, 0, request.AddressInfos[0].Address);
}

public List<TransactionInfo> MergeTxns(IndexerTransactionListResultDto txns, IndexerTokenTransferListDto tokenTransfers)
{
var result = new List<TransactionInfo>();
if (txns != null)
{
foreach (var txn in txns.Items)
{
result.Add(new TransactionInfo()
{
ChainId = txn.Metadata.ChainId,
TransactionId = txn.TransactionId,
Timestamp = DateTimeHelper.ToUnixTimeSeconds(txn.Metadata.Block.BlockTime)
});
}
}

if (tokenTransfers != null)
{
foreach (var transfer in tokenTransfers.Items)
{
var txn = txns.Items.FirstOrDefault(t => t.TransactionId == transfer.TransactionId);
if (txn == null)
{
result.Add(new TransactionInfo
{
TransactionId = transfer.TransactionId,
ChainId = transfer.Metadata.ChainId,
Timestamp = DateTimeHelper.ToUnixTimeSeconds(transfer.Metadata.Block.BlockTime)
});
}
}
}

return result;
}

public async Task<GetActivitiesDto> GetActivitiesAsync(GetActivitiesRequestDto request)
{
var address = request.AddressInfos[0].Address;
var chainId = request.AddressInfos.Count == 1 ? request.AddressInfos[0].ChainId : "";

var txns = new TransactionsResponseDto();
var txns = new IndexerTransactionListResultDto();
var tokenTransfers = new IndexerTokenTransferListDto();

var txnsTask = _aelfScanDataProvider.GetAddressTransactionsAsync(chainId, address, 0, request.SkipCount + request.MaxResultCount);
var tokenTransfersTask = _graphqlProvider.GetTokenTransferInfoAsync(new TokenTransferInput()
var txnsTask = _graphqlProvider.GetTransactionsAsync(new TransactionsRequestDto()
{
ChainId = chainId,
Address = address,
SkipCount = 0,
MaxResultCount = request.SkipCount + request.MaxResultCount
});
var tokenTransfersTask = _graphqlProvider.GetTokenTransferInfoAsync(new GetTokenTransferRequestDto()
{
Address = address,
ChainId = chainId,
Expand All @@ -99,43 +141,19 @@ public async Task<GetActivitiesDto> GetActivitiesAsync(GetActivitiesRequestDto r
});

await Task.WhenAll(txnsTask, tokenTransfersTask);

txns = await txnsTask;
if (txns == null)
{
txns = new TransactionsResponseDto();
}
tokenTransfers = await tokenTransfersTask;
var transactions = MergeTxns(txns, tokenTransfers);

if (tokenTransfers != null)
{
foreach (var transfer in tokenTransfers.Items)
{
var txn = txns.Transactions.FirstOrDefault(t => t.TransactionId == transfer.TransactionId);
if (txn == null)
{
txns.Transactions.Add(new TransactionResponseDto
{
TransactionId = transfer.TransactionId,
ChainIds = new List<string>(){transfer.Metadata.ChainId},
Timestamp = DateTimeHelper.ToUnixTimeSeconds(transfer.Metadata.Block.BlockTime)
});
}
}
}

txns.Transactions = txns.Transactions.OrderByDescending(item => item.Timestamp)
transactions = transactions.OrderByDescending(item => item.Timestamp)
.Skip(request.SkipCount)
.Take(request.MaxResultCount)
.ToList();

var mapTasks = txns.Transactions.Select(async txn =>
var mapTasks = transactions.Select(async txn =>
{
if (txn.ChainIds.Count < 1)
{
return null;
}
return await _aelfScanDataProvider.GetTransactionDetailAsync(txn.ChainIds[0], txn.TransactionId);
return await _aelfScanDataProvider.GetTransactionDetailAsync(txn.ChainId, txn.TransactionId);
}).ToList();

var txnDetailMap = (await Task.WhenAll(mapTasks))
Expand All @@ -153,15 +171,15 @@ public async Task<GetActivitiesDto> GetActivitiesAsync(GetActivitiesRequestDto r

var tokenMap = await GetTokenMapAsync(tokens);
var activityDtos = new List<GetActivityDto>();
foreach (var txn in txns.Transactions)
foreach (var txn in transactions)
{
if (txnDetailMap.ContainsKey(txn.TransactionId) && txnDetailMap[txn.TransactionId] != null)
{
activityDtos.Add(await ConvertDtoAsync(txn.ChainIds[0], txnDetailMap[txn.TransactionId], tokenMap, request.Width, request.Height, request.AddressInfos[0].Address));
activityDtos.Add(await ConvertDtoAsync(txn.ChainId, txnDetailMap[txn.TransactionId], tokenMap, request.Width, request.Height, request.AddressInfos[0].Address));
}
else
{
_logger.LogError($"Get transaction detail error. ChainId: {txn.ChainIds[0]}, TransactionId: {txn.TransactionId}");
_logger.LogError($"Get transaction detail error. ChainId: {txn.ChainId}, TransactionId: {txn.TransactionId}");
}
}

Expand Down Expand Up @@ -421,4 +439,11 @@ private async Task<GetActivityDto> ConvertDtoAsync(string chainId, TransactionDe

return activityDto;
}

public class TransactionInfo
{
public string ChainId { get; set; }
public string TransactionId { get; set; }
public long Timestamp { get; set; }
}
}
Loading

0 comments on commit 474c173

Please sign in to comment.