Skip to content

Commit f21fc2d

Browse files
authored
Merge pull request #3625 from AElfProject/feature/transaction-result-optimize
Transaction status result optimization
2 parents 85e9efd + 39398fa commit f21fc2d

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

protobuf/aelf/core.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ enum TransactionResultStatus {
5959
PENDING_VALIDATION = 5;
6060
// Transaction validation failed.
6161
NODE_VALIDATION_FAILED = 6;
62+
// Transaction is expired
63+
EXPIRED = 7;
6264
}
6365

6466
message TransactionResult {

src/AElf.WebApp.Application.Chain/Dto/TransactionResultDto.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
using System;
2+
13
namespace AElf.WebApp.Application.Chain.Dto;
24

35
public class TransactionResultDto
46
{
57
public string TransactionId { get; set; }
68

9+
[Obsolete("The Status is obsolete. Use StatusV2 instead.")]
710
public string Status { get; set; }
11+
12+
public string StatusV2 { get; set; }
813

914
public LogEventDto[] Logs { get; set; }
1015

src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ namespace AElf.WebApp.Application.Chain;
2424
public interface ITransactionResultAppService
2525
{
2626
Task<TransactionResultDto> GetTransactionResultAsync(string transactionId);
27+
28+
Task<TransactionResultDto> GetTransactionResultV2Async(string transactionId);
2729

2830
Task<List<TransactionResultDto>> GetTransactionResultsAsync(string blockHash, int offset = 0,
2931
int limit = 10);
@@ -130,6 +132,72 @@ await _transactionResultProxyService.InvalidTransactionResultService.GetInvalidT
130132
}
131133
return output;
132134
}
135+
/// <summary>
136+
/// Get the current status of a transaction, available since V1.12.0
137+
/// </summary>
138+
/// <param name="transactionId">transaction id</param>
139+
/// <returns></returns>
140+
public async Task<TransactionResultDto> GetTransactionResultV2Async(string transactionId)
141+
{
142+
Hash transactionIdHash;
143+
try
144+
{
145+
transactionIdHash = Hash.LoadFromHex(transactionId);
146+
}
147+
catch
148+
{
149+
throw new UserFriendlyException(Error.Message[Error.InvalidTransactionId],
150+
Error.InvalidTransactionId.ToString());
151+
}
152+
153+
var transactionResult = await GetTransactionResultAsync(transactionIdHash);
154+
var output = _objectMapper.GetMapper()
155+
.Map<TransactionResult, TransactionResultDto>(transactionResult,
156+
opt => opt.Items[TransactionProfile.ErrorTrace] = _webAppOptions.IsDebugMode);
157+
output.StatusV2 = output.Status;
158+
159+
var transaction = await _transactionManager.GetTransactionAsync(transactionResult.TransactionId);
160+
output.Transaction = _objectMapper.Map<Transaction, TransactionDto>(transaction);
161+
output.TransactionSize = transaction?.CalculateSize() ?? 0;
162+
163+
var chain = await _blockchainService.GetChainAsync();
164+
if (transactionResult.Status == TransactionResultStatus.Pending &&
165+
chain.BestChainHeight - output.Transaction?.RefBlockNumber > KernelConstants.ReferenceBlockValidPeriod)
166+
{
167+
output.StatusV2 = TransactionResultStatus.Expired.ToString().ToUpper();
168+
return output;
169+
}
170+
171+
if (transactionResult.Status != TransactionResultStatus.NotExisted)
172+
{
173+
await FormatTransactionParamsAsync(output.Transaction, transaction.Params);
174+
return output;
175+
}
176+
177+
var validationStatus = _transactionResultStatusCacheProvider.GetTransactionResultStatus(transactionIdHash);
178+
if (validationStatus != null)
179+
{
180+
output.StatusV2 = validationStatus.TransactionResultStatus.ToString().ToUpper();
181+
output.Error =
182+
TransactionErrorResolver.TakeErrorMessage(validationStatus.Error, _webAppOptions.IsDebugMode);
183+
return output;
184+
}
185+
186+
if (_transactionOptions.StoreInvalidTransactionResultEnabled)
187+
{
188+
var failedTransactionResult =
189+
await _transactionResultProxyService.InvalidTransactionResultService.GetInvalidTransactionResultAsync(
190+
transactionIdHash);
191+
if (failedTransactionResult != null)
192+
{
193+
output.StatusV2 = failedTransactionResult.Status.ToString().ToUpper();
194+
output.Error = failedTransactionResult.Error;
195+
return output;
196+
}
197+
}
198+
199+
return output;
200+
}
133201

134202
/// <summary>
135203
/// Get multiple transaction results.

test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,37 @@ public async Task Get_TransactionResult_Success_Test()
685685
response.BlockNumber.ShouldBe(block.Height);
686686
response.BlockHash.ShouldBe(block.GetHash().ToHex());
687687
}
688+
689+
[Fact]
690+
public async Task Get_TransactionResultV2_Expired_Test()
691+
{
692+
// Generate a transaction
693+
var transaction = await _osTestHelper.GenerateTransferTransaction();
694+
695+
// Push chain height to be ref_block_number + at least 512
696+
await MineSomeBlocks(520);
697+
var transactionHex = transaction.GetHash().ToHex();
698+
699+
// Broadcast expired transaction
700+
await _osTestHelper.BroadcastTransactions(new List<Transaction> { transaction });
701+
702+
// Check transaction status
703+
var response = await GetResponseAsObjectAsync<TransactionResultDto>(
704+
$"/api/blockChain/transactionResultV2?transactionId={transactionHex}");
705+
response.StatusV2.ShouldBe(TransactionResultStatus.Expired.ToString().ToUpper());
706+
}
707+
708+
private async Task MineSomeBlocks(int blockNumber)
709+
{
710+
var heightBefore = (await _osTestHelper.GetChainContextAsync()).BlockHeight;
711+
for (var i = 0; i < blockNumber; i++)
712+
{
713+
await _osTestHelper.MinedOneBlock();
714+
}
715+
716+
var heightAfter = (await _osTestHelper.GetChainContextAsync()).BlockHeight;
717+
heightAfter.ShouldBe(heightBefore + blockNumber);
718+
}
688719

689720
[Fact]
690721
public async Task Get_Failed_TransactionResult_Success_Test()

0 commit comments

Comments
 (0)