Skip to content

Commit 187a4c5

Browse files
committed
Merge branch 'dev' into feature/whitelist-to-sdk
2 parents d38683f + 187d3ed commit 187a4c5

File tree

9 files changed

+161
-12
lines changed

9 files changed

+161
-12
lines changed

contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,35 @@ public override Int32Value GetMaxBatchApproveCount(Empty input)
691691
};
692692
}
693693

694+
public override Empty ExtendSeedExpirationTime(ExtendSeedExpirationTimeInput input)
695+
{
696+
var tokenInfo = GetTokenInfo(input.Symbol);
697+
if (tokenInfo == null)
698+
{
699+
throw new AssertionException("Seed NFT does not exist.");
700+
}
701+
702+
Assert(tokenInfo.Owner == Context.Sender, "Sender is not Seed NFT owner.");
703+
var oldExpireTimeLong = 0L;
704+
if (tokenInfo.ExternalInfo.Value.TryGetValue(TokenContractConstants.SeedExpireTimeExternalInfoKey,
705+
out var oldExpireTime))
706+
{
707+
long.TryParse(oldExpireTime, out oldExpireTimeLong);
708+
}
709+
710+
tokenInfo.ExternalInfo.Value[TokenContractConstants.SeedExpireTimeExternalInfoKey] =
711+
input.ExpirationTime.ToString();
712+
State.TokenInfos[input.Symbol] = tokenInfo;
713+
Context.Fire(new SeedExpirationTimeUpdated
714+
{
715+
ChainId = tokenInfo.IssueChainId,
716+
Symbol = input.Symbol,
717+
OldExpirationTime = oldExpireTimeLong,
718+
NewExpirationTime = input.ExpirationTime
719+
});
720+
return new Empty();
721+
}
722+
694723
private int GetMaxBatchApproveCount()
695724
{
696725
return State.MaxBatchApproveCount.Value == 0

contract/AElf.Contracts.MultiToken/TokenContract_Helper.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,10 @@ private Address ExtractTokenContractAddress(ByteString bytes)
215215
private void AssertCrossChainTransaction(Transaction originalTransaction, Address validAddress,
216216
params string[] validMethodNames)
217217
{
218-
var validateResult = validMethodNames.Contains(MaybeRecoverInlineTransactionFunctionName(originalTransaction.MethodName))
218+
var validateResult = validMethodNames.Contains(originalTransaction.MethodName)
219219
&& originalTransaction.To == validAddress;
220220
Assert(validateResult, "Invalid transaction.");
221221
}
222-
223-
private static string MaybeRecoverInlineTransactionFunctionName(string methodName)
224-
{
225-
var parts = methodName.Split('.');
226-
return parts.Length > 1 ? parts[^2] : methodName;
227-
}
228222

229223
private void RegisterTokenInfo(TokenInfo tokenInfo)
230224
{

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 {

protobuf/token_contract_impl.proto

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ service TokenContractImpl {
182182
rpc GetMaxBatchApproveCount (google.protobuf.Empty) returns (google.protobuf.Int32Value) {
183183

184184
}
185+
186+
rpc ExtendSeedExpirationTime (ExtendSeedExpirationTimeInput) returns (google.protobuf.Empty) {
187+
}
185188
}
186189

187190
message AdvanceResourceTokenInput {
@@ -444,4 +447,17 @@ message ModifyTokenIssuerAndOwnerInput {
444447

445448
message SetTokenIssuerAndOwnerModificationEnabledInput{
446449
bool enabled = 1;
450+
}
451+
452+
message ExtendSeedExpirationTimeInput {
453+
string symbol = 1;
454+
int64 expiration_time = 2;
455+
}
456+
457+
message SeedExpirationTimeUpdated {
458+
option (aelf.is_event) = true;
459+
int32 chain_id = 1;
460+
string symbol = 2;
461+
int64 old_expiration_time = 3;
462+
int64 new_expiration_time = 4;
447463
}

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 StatusWithBVP instead.")]
710
public string Status { get; set; }
11+
12+
public string StatusWithBVP { get; set; }
813

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

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

Lines changed: 63 additions & 5 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);
@@ -118,16 +120,72 @@ await _transactionResultProxyService.InvalidTransactionResultService.GetInvalidT
118120
return output;
119121
}
120122
}
123+
return output;
124+
}
125+
/// <summary>
126+
/// Get the current status of a transaction, available since V1.12.0
127+
/// </summary>
128+
/// <param name="transactionId">transaction id</param>
129+
/// <returns></returns>
130+
public async Task<TransactionResultDto> GetTransactionResultV2Async(string transactionId)
131+
{
132+
Hash transactionIdHash;
133+
try
134+
{
135+
transactionIdHash = Hash.LoadFromHex(transactionId);
136+
}
137+
catch
138+
{
139+
throw new UserFriendlyException(Error.Message[Error.InvalidTransactionId],
140+
Error.InvalidTransactionId.ToString());
141+
}
142+
143+
var transactionResult = await GetTransactionResultAsync(transactionIdHash);
144+
var output = _objectMapper.GetMapper()
145+
.Map<TransactionResult, TransactionResultDto>(transactionResult,
146+
opt => opt.Items[TransactionProfile.ErrorTrace] = _webAppOptions.IsDebugMode);
147+
output.StatusWithBVP = output.Status;
148+
149+
var transaction = await _transactionManager.GetTransactionAsync(transactionResult.TransactionId);
150+
output.Transaction = _objectMapper.Map<Transaction, TransactionDto>(transaction);
151+
output.TransactionSize = transaction?.CalculateSize() ?? 0;
121152

122153
var chain = await _blockchainService.GetChainAsync();
123-
if (chain.BestChainHeight - output.Transaction.RefBlockNumber > KernelConstants.ReferenceBlockValidPeriod
124-
&& transactionResult.Status == TransactionResultStatus.NotExisted)
154+
if (transactionResult.Status == TransactionResultStatus.Pending &&
155+
chain.BestChainHeight - output.Transaction?.RefBlockNumber > KernelConstants.ReferenceBlockValidPeriod)
125156
{
126-
// set a the Error message to the output to infer that the transaction will never succeed.
127-
var error = "The transaction is already expired, and it will never succeed.";
128-
output.Error = TransactionErrorResolver.TakeErrorMessage(error, _webAppOptions.IsDebugMode);
157+
output.StatusWithBVP = TransactionResultStatus.Expired.ToString().ToUpper();
129158
return output;
130159
}
160+
161+
if (transactionResult.Status != TransactionResultStatus.NotExisted)
162+
{
163+
await FormatTransactionParamsAsync(output.Transaction, transaction.Params);
164+
return output;
165+
}
166+
167+
var validationStatus = _transactionResultStatusCacheProvider.GetTransactionResultStatus(transactionIdHash);
168+
if (validationStatus != null)
169+
{
170+
output.StatusWithBVP = validationStatus.TransactionResultStatus.ToString().ToUpper();
171+
output.Error =
172+
TransactionErrorResolver.TakeErrorMessage(validationStatus.Error, _webAppOptions.IsDebugMode);
173+
return output;
174+
}
175+
176+
if (_transactionOptions.StoreInvalidTransactionResultEnabled)
177+
{
178+
var failedTransactionResult =
179+
await _transactionResultProxyService.InvalidTransactionResultService.GetInvalidTransactionResultAsync(
180+
transactionIdHash);
181+
if (failedTransactionResult != null)
182+
{
183+
output.StatusWithBVP = failedTransactionResult.Status.ToString().ToUpper();
184+
output.Error = failedTransactionResult.Error;
185+
return output;
186+
}
187+
}
188+
131189
return output;
132190
}
133191

test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,4 +1893,15 @@ public async Task TokenIssuerAndOwnerModification_Test()
18931893
result.TransactionResult.Error.ShouldContain("Set token issuer and owner disabled.");
18941894

18951895
}
1896+
1897+
[Theory]
1898+
[InlineData("SEED-0", 1731927992000)]
1899+
public async Task ExtendSeedExpirationTime_Test(string symbol, long expirationTime)
1900+
{
1901+
ExtendSeedExpirationTimeInput input = new ExtendSeedExpirationTimeInput();
1902+
input.Symbol = symbol;
1903+
input.ExpirationTime = expirationTime;
1904+
1905+
await TokenContractStub.ExtendSeedExpirationTime.CallAsync(input);
1906+
}
18961907
}

test/AElf.Contracts.MultiToken.Tests/MultiTokenContractTestBase.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,7 @@ internal async Task<IExecutionResult<Empty>> CreateMutiTokenWithExceptionAsync(
240240
await CreateSeedNftAsync(stub, createInput);
241241
return await stub.Create.SendWithExceptionAsync(createInput);
242242
}
243+
244+
245+
243246
}

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.StatusWithBVP.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)