diff --git a/.github/workflows/sonarqube.yaml b/.github/workflows/sonarqube.yaml
index dbfca652b6..b87ff0cf93 100644
--- a/.github/workflows/sonarqube.yaml
+++ b/.github/workflows/sonarqube.yaml
@@ -15,7 +15,7 @@ jobs:
with:
dotnet-version: '8.0'
- name: Create temporary global.json
- run: echo '{"sdk":{"version":"8.0.303"}}' > ./global.json
+ run: echo '{"sdk":{"version":"8.0.*"}}' > ./global.json
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 9cae4c73c7..638b5c27f1 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -1,20 +1,20 @@
# Azure Pipelines configuration file
jobs:
-# - template: templates/build-template-window.yml
-# parameters:
-# parts: 3
-# n: 1
-# codecoverage: true
-# - template: templates/build-template-window.yml
-# parameters:
-# parts: 3
-# n: 2
-# codecoverage: false
-# - template: templates/build-template-window.yml
-# parameters:
-# parts: 3
-# n: 3
-# codecoverage: false
+ # - template: templates/build-template-window.yml
+ # parameters:
+ # parts: 3
+ # n: 1
+ # codecoverage: true
+ # - template: templates/build-template-window.yml
+ # parameters:
+ # parts: 3
+ # n: 2
+ # codecoverage: false
+ # - template: templates/build-template-window.yml
+ # parameters:
+ # parts: 3
+ # n: 3
+ # codecoverage: false
- template: templates/build-template-linux.yml
parameters:
parts: 3
@@ -40,9 +40,9 @@ jobs:
parts: 3
n: 2
codecoverage: true
- - template: templates/build-template-macos.yml
- parameters:
- parts: 3
- n: 3
- codecoverage: true
+ # - template: templates/build-template-macos.yml
+ # parameters:
+ # parts: 3
+ # n: 3
+ # codecoverage: true
\ No newline at end of file
diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs
index 88632c10ff..b708306d99 100644
--- a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs
+++ b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs
@@ -127,10 +127,12 @@ private void ProcessNextRound(NextRoundInput input)
{
var minersCount = GetMinersCount(nextRound);
if (minersCount != 0 && State.ElectionContract.Value != null)
+ {
State.ElectionContract.UpdateMinersCount.Send(new UpdateMinersCountInput
{
MinersCount = minersCount
});
+ }
}
}
diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs b/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs
index 6adcf01a2a..7c24cb4151 100644
--- a/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs
+++ b/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs
@@ -691,6 +691,35 @@ public override Int32Value GetMaxBatchApproveCount(Empty input)
};
}
+ public override Empty ExtendSeedExpirationTime(ExtendSeedExpirationTimeInput input)
+ {
+ var tokenInfo = GetTokenInfo(input.Symbol);
+ if (tokenInfo == null)
+ {
+ throw new AssertionException("Seed NFT does not exist.");
+ }
+
+ Assert(tokenInfo.Owner == Context.Sender, "Sender is not Seed NFT owner.");
+ var oldExpireTimeLong = 0L;
+ if (tokenInfo.ExternalInfo.Value.TryGetValue(TokenContractConstants.SeedExpireTimeExternalInfoKey,
+ out var oldExpireTime))
+ {
+ long.TryParse(oldExpireTime, out oldExpireTimeLong);
+ }
+
+ tokenInfo.ExternalInfo.Value[TokenContractConstants.SeedExpireTimeExternalInfoKey] =
+ input.ExpirationTime.ToString();
+ State.TokenInfos[input.Symbol] = tokenInfo;
+ Context.Fire(new SeedExpirationTimeUpdated
+ {
+ ChainId = tokenInfo.IssueChainId,
+ Symbol = input.Symbol,
+ OldExpirationTime = oldExpireTimeLong,
+ NewExpirationTime = input.ExpirationTime
+ });
+ return new Empty();
+ }
+
private int GetMaxBatchApproveCount()
{
return State.MaxBatchApproveCount.Value == 0
diff --git a/global.json b/global.json
index b76a0b882f..70976d298f 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "8.0.x"
+ "version": "8.0.*"
}
}
\ No newline at end of file
diff --git a/nuget.config b/nuget.config
index 8b19203c51..e75cd52656 100644
--- a/nuget.config
+++ b/nuget.config
@@ -1,6 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/protobuf/aelf/core.proto b/protobuf/aelf/core.proto
index 4fe3a5bcf4..d2812d46f7 100644
--- a/protobuf/aelf/core.proto
+++ b/protobuf/aelf/core.proto
@@ -59,6 +59,8 @@ enum TransactionResultStatus {
PENDING_VALIDATION = 5;
// Transaction validation failed.
NODE_VALIDATION_FAILED = 6;
+ // Transaction is expired
+ EXPIRED = 7;
}
message TransactionResult {
diff --git a/protobuf/token_contract_impl.proto b/protobuf/token_contract_impl.proto
index 5885914e80..3ae6ffa2c5 100644
--- a/protobuf/token_contract_impl.proto
+++ b/protobuf/token_contract_impl.proto
@@ -182,6 +182,9 @@ service TokenContractImpl {
rpc GetMaxBatchApproveCount (google.protobuf.Empty) returns (google.protobuf.Int32Value) {
}
+
+ rpc ExtendSeedExpirationTime (ExtendSeedExpirationTimeInput) returns (google.protobuf.Empty) {
+ }
}
message AdvanceResourceTokenInput {
@@ -444,4 +447,17 @@ message ModifyTokenIssuerAndOwnerInput {
message SetTokenIssuerAndOwnerModificationEnabledInput{
bool enabled = 1;
+}
+
+message ExtendSeedExpirationTimeInput {
+ string symbol = 1;
+ int64 expiration_time = 2;
+}
+
+message SeedExpirationTimeUpdated {
+ option (aelf.is_event) = true;
+ int32 chain_id = 1;
+ string symbol = 2;
+ int64 old_expiration_time = 3;
+ int64 new_expiration_time = 4;
}
\ No newline at end of file
diff --git a/protobuf/virtual_transaction.proto b/protobuf/virtual_transaction.proto
index 8abb9db10c..914ef1e76f 100644
--- a/protobuf/virtual_transaction.proto
+++ b/protobuf/virtual_transaction.proto
@@ -17,4 +17,4 @@ message VirtualTransactionCreated {
string method_name = 4 [(aelf.is_indexed) = true];
bytes params = 5;
aelf.Address signatory = 6 [(aelf.is_indexed) = true];
-}
\ No newline at end of file
+}
diff --git a/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj b/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj
index dc5501294c..74a45d8ccf 100644
--- a/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj
+++ b/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj
@@ -10,8 +10,7 @@
-
-
+
diff --git a/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs b/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs
index 5a58387f14..08fced5f36 100644
--- a/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs
+++ b/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Threading;
using AElf.CSharp.Core;
+using AElf.Types;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Volo.Abp.DependencyInjection;
@@ -24,7 +25,7 @@ public class ArrayValidator : IValidator, ITransientDependency
.LimitByTotalSize(typeof(decimal), sizeof(decimal))
.LimitByTotalSize(typeof(char), sizeof(char))
.LimitByTotalSize(typeof(String), 128) // Need to limit the size of strings by disallowing String.Concat
-
+ .LimitByTotalSize(typeof(BigIntValue), 128)
// It isn't possible to estimate runtime sizes for below, so limit by count
.LimitByCount(typeof(Type), 5)
.LimitByCount(typeof(Object), 5) // Support object in Linq queries
diff --git a/src/AElf.CSharp.CodeOps/Validators/Module/ContractStructureValidator.cs b/src/AElf.CSharp.CodeOps/Validators/Module/ContractStructureValidator.cs
index 59f4209d5a..5fb83cd951 100644
--- a/src/AElf.CSharp.CodeOps/Validators/Module/ContractStructureValidator.cs
+++ b/src/AElf.CSharp.CodeOps/Validators/Module/ContractStructureValidator.cs
@@ -231,6 +231,8 @@ private bool IsBadStateField(FieldDefinition field)
if (_allowedStateTypes.Contains(field.FieldType.FullName))
return false;
+ if(field.FieldType.Resolve().BaseType.FullName == typeof(StructuredState).FullName)
+ return false;
// If not ContractReferenceState then it is not allowed
return field.FieldType.Resolve().BaseType.FullName != typeof(ContractReferenceState).FullName;
}
diff --git a/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs b/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs
index d488b1057e..41e3ba704d 100644
--- a/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs
+++ b/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs
@@ -5,6 +5,9 @@
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
+using AElf.Cryptography.Bn254;
+using AElf.Cryptography.EdDSA;
+using AElf.Cryptography.Keccak;
using AElf.Cryptography.SecretSharing;
using AElf.CSharp.Core;
using AElf.Kernel.SmartContract;
@@ -50,7 +53,6 @@ private void WhitelistAssemblies(Whitelist whitelist)
.Assembly(typeof(SecretSharingHelper).Assembly, Trust.Partial) // AElf.Cryptography
.Assembly(typeof(ISmartContractBridgeContext).Assembly, Trust.Full) // AElf.Kernel.SmartContract.Shared
.Assembly(typeof(Groth16.Net.Verifier).Assembly, Trust.Full) // AElf.Cryptography.ECDSA
- .Assembly(typeof(Poseidon.Net.Poseidon).Assembly, Trust.Full)
;
}
@@ -64,6 +66,15 @@ private void WhitelistSystemTypes(Whitelist whitelist)
.Type("Func`1", Permission.Allowed) // Required for protobuf generated code
.Type("Func`2", Permission.Allowed) // Required for protobuf generated code
.Type("Func`3", Permission.Allowed) // Required for protobuf generated code
+ .Type("Func`4", Permission.Allowed)
+ .Type("ValueTuple`1", Permission.Allowed)
+ .Type("ValueTuple`2", Permission.Allowed)
+ .Type("ValueTuple`3", Permission.Allowed)
+ .Type("ValueTuple`4", Permission.Allowed)
+ .Type("ValueTuple`5", Permission.Allowed)
+ .Type("ValueTuple`6", Permission.Allowed)
+ .Type("ValueTuple`7", Permission.Allowed)
+ .Type("ValueTuple`8", Permission.Allowed)
.Type("Nullable`1", Permission.Allowed) // Required for protobuf generated code
.Type(typeof(BitConverter), Permission.Denied, member => member
.Member(nameof(BitConverter.GetBytes), Permission.Allowed))
@@ -160,6 +171,27 @@ private void WhitelistOthers(Whitelist whitelist)
)
;
}
+
+ private void WhitelistCryptographyHelpers(Whitelist whitelist)
+ {
+ whitelist
+ // Selectively allowed types and members
+ .Namespace("AElf.Cryptography.Bn254", Permission.Denied, type => type
+ .Type(typeof(Bn254Helper), Permission.Denied, member => member
+ .Member(nameof(Bn254Helper.Bn254Pairing), Permission.Allowed)
+ .Member(nameof(Bn254Helper.Bn254G1Add), Permission.Allowed)
+ .Member(nameof(Bn254Helper.Bn254G1Mul), Permission.Allowed)
+ ))
+ .Namespace("AElf.Cryptography.EdDSA", Permission.Denied, type => type
+ .Type(typeof(EdDsaHelper), Permission.Denied, member => member
+ .Member(nameof(EdDsaHelper.Ed25519Verify), Permission.Allowed)
+ ))
+ .Namespace("AElf.Cryptography.Keccak", Permission.Denied, type => type
+ .Type(typeof(KeccakHelper), Permission.Denied, member => member
+ .Member(nameof(KeccakHelper.Keccak256), Permission.Allowed)
+ ))
+ ;
+ }
private Whitelist CreateWhitelist()
{
@@ -169,6 +201,7 @@ private Whitelist CreateWhitelist()
WhitelistReflectionTypes(whitelist);
WhitelistLinqAndCollections(whitelist);
WhitelistOthers(whitelist);
+ WhitelistCryptographyHelpers(whitelist);
return whitelist;
}
}
diff --git a/src/AElf.Cryptography/AElf.Cryptography.csproj b/src/AElf.Cryptography/AElf.Cryptography.csproj
index 1f5c07064d..641e967bdd 100644
--- a/src/AElf.Cryptography/AElf.Cryptography.csproj
+++ b/src/AElf.Cryptography/AElf.Cryptography.csproj
@@ -10,6 +10,9 @@
+
+
+
diff --git a/src/AElf.Cryptography/Bn254/Bn254Helper.cs b/src/AElf.Cryptography/Bn254/Bn254Helper.cs
new file mode 100644
index 0000000000..0cf74fc3bc
--- /dev/null
+++ b/src/AElf.Cryptography/Bn254/Bn254Helper.cs
@@ -0,0 +1,38 @@
+using Bn254.Net;
+using NetBn254 = Bn254.Net;
+
+namespace AElf.Cryptography.Bn254
+{
+ public static class Bn254Helper
+ {
+ public static (byte[] x, byte[] y) Bn254G1Mul(byte[] x1, byte[] y1, byte[] s)
+ {
+ var (xUInt256, yUInt256) = NetBn254.Bn254.Mul(UInt256.FromBigEndianBytes(x1),
+ UInt256.FromBigEndianBytes(y1),
+ UInt256.FromBigEndianBytes(s));
+ return (xUInt256.ToBigEndianBytes(), yUInt256.ToBigEndianBytes());
+ }
+
+ public static (byte[] x3, byte[] y3) Bn254G1Add(byte[] x1, byte[] y1, byte[] x2, byte[] y2)
+ {
+ var (x3UInt256, y3UInt256) = NetBn254.Bn254.Add(UInt256.FromBigEndianBytes(x1),
+ UInt256.FromBigEndianBytes(y1),
+ UInt256.FromBigEndianBytes(x2), UInt256.FromBigEndianBytes(y2));
+ return (x3UInt256.ToBigEndianBytes(), y3UInt256.ToBigEndianBytes());
+ }
+
+ public static bool Bn254Pairing((byte[], byte[], byte[], byte[], byte[], byte[])[] input)
+ {
+ var elements = new (UInt256, UInt256, UInt256, UInt256, UInt256, UInt256)[input.Length];
+ for (var i = 0; i < input.Length; i++)
+ {
+ var (x1, y1, x2, y2, x3, y3) = input[i];
+ elements[i] = (UInt256.FromBigEndianBytes(x1), UInt256.FromBigEndianBytes(y1),
+ UInt256.FromBigEndianBytes(x2), UInt256.FromBigEndianBytes(y2),
+ UInt256.FromBigEndianBytes(x3), UInt256.FromBigEndianBytes(y3));
+ }
+
+ return NetBn254.Bn254.Pairing(elements);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AElf.Cryptography/EdDSA/EdDsaHelper.cs b/src/AElf.Cryptography/EdDSA/EdDsaHelper.cs
new file mode 100644
index 0000000000..02046e8a02
--- /dev/null
+++ b/src/AElf.Cryptography/EdDSA/EdDsaHelper.cs
@@ -0,0 +1,22 @@
+using System;
+using Rebex.Security.Cryptography;
+
+namespace AElf.Cryptography.EdDSA
+{
+ public static class EdDsaHelper
+ {
+ public static bool Ed25519Verify(byte[] signature, byte[] message, byte[] publicKey)
+ {
+ try
+ {
+ var instance = new Ed25519();
+ instance.FromPublicKey(publicKey);
+ return instance.VerifyMessage(message, signature);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AElf.Cryptography/Keccak/KeccakHelper.cs b/src/AElf.Cryptography/Keccak/KeccakHelper.cs
new file mode 100644
index 0000000000..dbb182f29c
--- /dev/null
+++ b/src/AElf.Cryptography/Keccak/KeccakHelper.cs
@@ -0,0 +1,12 @@
+using Nethereum.Util;
+
+namespace AElf.Cryptography.Keccak
+{
+ public static class KeccakHelper
+ {
+ public static byte[] Keccak256(byte[] message)
+ {
+ return Sha3Keccack.Current.CalculateHash(message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AElf.Kernel.FeatureDisable.Core/AElf.Kernel.FeatureDisable.Core.csproj b/src/AElf.Kernel.FeatureDisable.Core/AElf.Kernel.FeatureDisable.Core.csproj
index 7b39f518d5..991781b591 100644
--- a/src/AElf.Kernel.FeatureDisable.Core/AElf.Kernel.FeatureDisable.Core.csproj
+++ b/src/AElf.Kernel.FeatureDisable.Core/AElf.Kernel.FeatureDisable.Core.csproj
@@ -4,6 +4,8 @@
net8.0
enable
enable
+ Release
+ true
diff --git a/src/AElf.Kernel.FeatureDisable/AElf.Kernel.FeatureDisable.csproj b/src/AElf.Kernel.FeatureDisable/AElf.Kernel.FeatureDisable.csproj
index fae7fc0cdf..04323c5ffe 100644
--- a/src/AElf.Kernel.FeatureDisable/AElf.Kernel.FeatureDisable.csproj
+++ b/src/AElf.Kernel.FeatureDisable/AElf.Kernel.FeatureDisable.csproj
@@ -4,6 +4,8 @@
net8.0
enable
enable
+ Release
+ true
diff --git a/src/AElf.Kernel.SmartContract/Application/IExecutionObserverThresholdProvider.cs b/src/AElf.Kernel.SmartContract/Application/IExecutionObserverThresholdProvider.cs
index 22df31d5a3..1515ab0c20 100644
--- a/src/AElf.Kernel.SmartContract/Application/IExecutionObserverThresholdProvider.cs
+++ b/src/AElf.Kernel.SmartContract/Application/IExecutionObserverThresholdProvider.cs
@@ -33,7 +33,7 @@ public IExecutionObserverThreshold GetExecutionObserverThreshold(IBlockIndex blo
var branchCountObserverThreshold = GetBlockExecutedData(blockIndex, BranchCountThresholdKey)?.Value ??
SmartContractConstants.ExecutionBranchThreshold;
var callCountObserverThreshold = GetBlockExecutedData(blockIndex, CallCountThresholdKey)?.Value ??
- SmartContractConstants.ExecutionBranchThreshold;
+ SmartContractConstants.ExecutionCallThreshold;
return new ExecutionObserverThreshold
{
ExecutionBranchThreshold = branchCountObserverThreshold,
diff --git a/src/AElf.Types/Types/BigIntValue.cs b/src/AElf.Types/Types/BigIntValue.cs
index 38ddc94df6..bd8c446065 100644
--- a/src/AElf.Types/Types/BigIntValue.cs
+++ b/src/AElf.Types/Types/BigIntValue.cs
@@ -5,9 +5,30 @@
namespace AElf.Types
{
-
public partial class BigIntValue : IComparable, IComparable
{
+ #region Frequent Values
+
+ public static BigIntValue Zero => new BigIntValue { Value = "0" };
+ public static BigIntValue One => new BigIntValue { Value = "1" };
+
+ #endregion
+
+ public static BigIntValue FromBigEndianBytes(byte[] bigEndianBytes)
+ {
+ var bigInteger = new BigInteger(bigEndianBytes, true, true);
+ return new BigIntValue
+ {
+ Value = bigInteger.ToString()
+ };
+ }
+
+ public byte[] ToBigEndianBytes()
+ {
+ var bigInteger = ConvertStringToBigInteger(Value);
+ return bigInteger.ToByteArray(true, true);
+ }
+
public int CompareTo(object obj)
{
if (!(obj is BigIntValue bigInt)) throw new InvalidOperationException();
@@ -126,6 +147,43 @@ private static bool LessThan(in BigIntValue a, in BigIntValue b)
return aBigInt < bBigInt;
}
+ #region Operators
+
+ public static BigIntValue operator %(BigIntValue a, BigIntValue b)
+ {
+ return BigInteger.Remainder(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value))
+ .ToString();
+ }
+
+ public static BigIntValue operator +(BigIntValue a, BigIntValue b)
+ {
+ return BigInteger.Add(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value)).ToString();
+ }
+
+ public static BigIntValue operator -(BigIntValue a, BigIntValue b)
+ {
+ return BigInteger.Subtract(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value))
+ .ToString();
+ }
+
+ public static BigIntValue operator *(BigIntValue a, BigIntValue b)
+ {
+ return BigInteger.Multiply(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value))
+ .ToString();
+ }
+
+ public static bool operator ==(BigIntValue a, BigIntValue b)
+ {
+ return ConvertStringToBigInteger(a?.Value ?? "0") == ConvertStringToBigInteger(b?.Value ?? "0");
+ }
+
+ public static bool operator !=(BigIntValue a, BigIntValue b)
+ {
+ return !(a == b);
+ }
+
+ #endregion
+
#region < <= > >=
public static bool operator <(in BigIntValue a, in BigIntValue b)
diff --git a/src/AElf.WebApp.Application.Chain/Dto/TransactionResultDto.cs b/src/AElf.WebApp.Application.Chain/Dto/TransactionResultDto.cs
index e76f92a941..49459d3dc5 100644
--- a/src/AElf.WebApp.Application.Chain/Dto/TransactionResultDto.cs
+++ b/src/AElf.WebApp.Application.Chain/Dto/TransactionResultDto.cs
@@ -1,10 +1,15 @@
+using System;
+
namespace AElf.WebApp.Application.Chain.Dto;
public class TransactionResultDto
{
public string TransactionId { get; set; }
+ [Obsolete("The Status is obsolete. Use StatusWithBVP instead.")]
public string Status { get; set; }
+
+ public string StatusWithBVP { get; set; }
public LogEventDto[] Logs { get; set; }
diff --git a/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs b/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs
index 483dbb4366..c382c0a8de 100644
--- a/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs
+++ b/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs
@@ -25,6 +25,8 @@ public interface ITransactionResultAppService
{
Task GetTransactionResultAsync(string transactionId);
+ Task GetTransactionResultWithBVPAsync(string transactionId);
+
Task> GetTransactionResultsAsync(string blockHash, int offset = 0,
int limit = 10);
@@ -118,9 +120,73 @@ await _transactionResultProxyService.InvalidTransactionResultService.GetInvalidT
return output;
}
}
+ return output;
+ }
+ ///
+ /// Get the current status of a transaction, available since V1.12.0
+ ///
+ /// transaction id
+ ///
+ public async Task GetTransactionResultWithBVPAsync(string transactionId)
+ {
+ Hash transactionIdHash;
+ try
+ {
+ transactionIdHash = Hash.LoadFromHex(transactionId);
+ }
+ catch
+ {
+ throw new UserFriendlyException(Error.Message[Error.InvalidTransactionId],
+ Error.InvalidTransactionId.ToString());
+ }
+
+ var transactionResult = await GetTransactionResultAsync(transactionIdHash);
+ var output = _objectMapper.GetMapper()
+ .Map(transactionResult,
+ opt => opt.Items[TransactionProfile.ErrorTrace] = _webAppOptions.IsDebugMode);
+ output.StatusWithBVP = output.Status;
+
+ var transaction = await _transactionManager.GetTransactionAsync(transactionResult.TransactionId);
+ output.Transaction = _objectMapper.Map(transaction);
+ output.TransactionSize = transaction?.CalculateSize() ?? 0;
+
+ var chain = await _blockchainService.GetChainAsync();
+ if (transactionResult.Status == TransactionResultStatus.Pending &&
+ chain.BestChainHeight - output.Transaction?.RefBlockNumber > KernelConstants.ReferenceBlockValidPeriod)
+ {
+ output.StatusWithBVP = TransactionResultStatus.Expired.ToString().ToUpper();
+ return output;
+ }
+
+ if (transactionResult.Status != TransactionResultStatus.NotExisted)
+ {
+ await FormatTransactionParamsAsync(output.Transaction, transaction.Params);
+ return output;
+ }
+
+ var validationStatus = _transactionResultStatusCacheProvider.GetTransactionResultStatus(transactionIdHash);
+ if (validationStatus != null)
+ {
+ output.StatusWithBVP = validationStatus.TransactionResultStatus.ToString().ToUpper();
+ output.Error =
+ TransactionErrorResolver.TakeErrorMessage(validationStatus.Error, _webAppOptions.IsDebugMode);
+ return output;
+ }
+
+ if (_transactionOptions.StoreInvalidTransactionResultEnabled)
+ {
+ var failedTransactionResult =
+ await _transactionResultProxyService.InvalidTransactionResultService.GetInvalidTransactionResultAsync(
+ transactionIdHash);
+ if (failedTransactionResult != null)
+ {
+ output.StatusWithBVP = failedTransactionResult.Status.ToString().ToUpper();
+ output.Error = failedTransactionResult.Error;
+ return output;
+ }
+ }
return output;
-
}
///
diff --git a/test/AElf.Contracts.Economic.TestBase/ContractsPreparation.cs b/test/AElf.Contracts.Economic.TestBase/ContractsPreparation.cs
index cde20e76c9..5aeca9457c 100644
--- a/test/AElf.Contracts.Economic.TestBase/ContractsPreparation.cs
+++ b/test/AElf.Contracts.Economic.TestBase/ContractsPreparation.cs
@@ -18,7 +18,6 @@
using AElf.Cryptography.ECDSA;
using AElf.CSharp.Core.Extension;
using AElf.Kernel;
-using AElf.Sdk.CSharp;
using AElf.Standards.ACS3;
using AElf.Types;
using Google.Protobuf;
diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs
index 201e56d6e6..24d06e3eec 100644
--- a/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs
+++ b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs
@@ -1893,4 +1893,15 @@ public async Task TokenIssuerAndOwnerModification_Test()
result.TransactionResult.Error.ShouldContain("Set token issuer and owner disabled.");
}
+
+ [Theory]
+ [InlineData("SEED-0", 1731927992000)]
+ public async Task ExtendSeedExpirationTime_Test(string symbol, long expirationTime)
+ {
+ ExtendSeedExpirationTimeInput input = new ExtendSeedExpirationTimeInput();
+ input.Symbol = symbol;
+ input.ExpirationTime = expirationTime;
+
+ await TokenContractStub.ExtendSeedExpirationTime.CallAsync(input);
+ }
}
\ No newline at end of file
diff --git a/test/AElf.Contracts.TestContract.VirtualTransactionEvent/Action.cs b/test/AElf.Contracts.TestContract.VirtualTransactionEvent/Action.cs
index 99fa3348e2..9703205edf 100644
--- a/test/AElf.Contracts.TestContract.VirtualTransactionEvent/Action.cs
+++ b/test/AElf.Contracts.TestContract.VirtualTransactionEvent/Action.cs
@@ -1,5 +1,4 @@
-using AElf.Sdk.CSharp;
-using AElf.Types;
+using AElf.Types;
using Google.Protobuf.WellKnownTypes;
namespace AElf.Contracts.TestContract.VirtualTransactionEvent;
diff --git a/test/AElf.Cryptography.Tests/Bn254HelperTest.cs b/test/AElf.Cryptography.Tests/Bn254HelperTest.cs
new file mode 100644
index 0000000000..5a46f165bc
--- /dev/null
+++ b/test/AElf.Cryptography.Tests/Bn254HelperTest.cs
@@ -0,0 +1,111 @@
+using AElf.Cryptography.Bn254;
+using AElf.Types;
+using Bn254.Net;
+using Shouldly;
+using Xunit;
+using NetBn254 = Bn254.Net;
+
+namespace AElf.Cryptography.Tests;
+
+public class EdDsaHelperTest
+{
+ public static byte[] ToBytes32(BigIntValue value)
+ {
+ var bytes = value.ToBigEndianBytes();
+ var newArray = new byte[32];
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ newArray[31 - i] = bytes[bytes.Length - 1 - i];
+ }
+
+ return newArray;
+ }
+
+ [Fact]
+ public void Bn254G1Mul_Test()
+ {
+ // Arrange
+ byte[] x1 = ToBytes32(new BigIntValue(0));
+ byte[] y1 = ToBytes32(new BigIntValue(0));
+ byte[] scalar = ToBytes32(new BigIntValue(0));
+
+ // use raw api to compute result
+ var (expectedXuInt256, expectedYuInt256) = NetBn254.Bn254.Mul(
+ UInt256.FromBigEndianBytes(x1),
+ UInt256.FromBigEndianBytes(y1),
+ UInt256.FromBigEndianBytes(scalar)
+ );
+ var expectedX = expectedXuInt256.ToBigEndianBytes();
+ var expectedY = expectedYuInt256.ToBigEndianBytes();
+
+ // Act
+ var (xResult, yResult) = Bn254Helper.Bn254G1Mul(x1, y1, scalar);
+
+ // Assert
+ xResult.ShouldBe(expectedX);
+ yResult.ShouldBe(expectedY);
+ }
+
+ [Fact]
+ public void Bn254G1Add_Test()
+ {
+ // Arrange
+ byte[] x1 = ToBytes32(new BigIntValue(0));
+ byte[] y1 = ToBytes32(new BigIntValue(0));
+ byte[] x2 = ToBytes32(new BigIntValue(0));
+ byte[] y2 = ToBytes32(new BigIntValue(0));
+
+ // Use raw API to compute expected results
+ var (expectedX3UInt256, expectedY3UInt256) = NetBn254.Bn254.Add(
+ UInt256.FromBigEndianBytes(x1),
+ UInt256.FromBigEndianBytes(y1),
+ UInt256.FromBigEndianBytes(x2),
+ UInt256.FromBigEndianBytes(y2)
+ );
+ var expectedX3 = expectedX3UInt256.ToBigEndianBytes();
+ var expectedY3 = expectedY3UInt256.ToBigEndianBytes();
+
+ // Act
+ var (x3Result, y3Result) = Bn254Helper.Bn254G1Add(x1, y1, x2, y2);
+
+ // Assert
+ x3Result.ShouldBe(expectedX3);
+ y3Result.ShouldBe(expectedY3);
+ }
+
+ [Fact]
+ public void Bn254Pairing_Test()
+ {
+ // Arrange
+ var input = new (byte[], byte[], byte[], byte[], byte[], byte[])[]
+ {
+ (
+ ToBytes32(new BigIntValue(0)),
+ ToBytes32(new BigIntValue(0)),
+ ToBytes32(new BigIntValue(0)),
+ ToBytes32(new BigIntValue(0)),
+ ToBytes32(new BigIntValue(0)),
+ ToBytes32(new BigIntValue(0))
+ )
+ };
+
+ // Use raw API to compute expected results
+ bool expected = NetBn254.Bn254.Pairing(new (UInt256, UInt256, UInt256, UInt256, UInt256, UInt256)[]
+ {
+ (
+ UInt256.FromBigEndianBytes(input[0].Item1),
+ UInt256.FromBigEndianBytes(input[0].Item2),
+ UInt256.FromBigEndianBytes(input[0].Item3),
+ UInt256.FromBigEndianBytes(input[0].Item4),
+ UInt256.FromBigEndianBytes(input[0].Item5),
+ UInt256.FromBigEndianBytes(input[0].Item6)
+ )
+ });
+
+ // Act
+ bool result = Bn254Helper.Bn254Pairing(input);
+
+ // Assert
+ result.ShouldBe(expected);
+ }
+}
\ No newline at end of file
diff --git a/test/AElf.Cryptography.Tests/EdDsaHelperTest.cs b/test/AElf.Cryptography.Tests/EdDsaHelperTest.cs
new file mode 100644
index 0000000000..443415463c
--- /dev/null
+++ b/test/AElf.Cryptography.Tests/EdDsaHelperTest.cs
@@ -0,0 +1,25 @@
+using AElf.Cryptography.EdDSA;
+using Shouldly;
+using Xunit;
+
+namespace AElf.Cryptography.Tests;
+
+public class Bn254HelperTest
+{
+ [Fact]
+ public void Ed25519Verify_Test()
+ {
+ var publicKey = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a";
+ var message = "";
+ var signature =
+ "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b";
+
+ var publicKeyBytes = ByteArrayHelper.HexStringToByteArray(publicKey);
+ var messageBytes = ByteArrayHelper.HexStringToByteArray(message);
+ var signatureBytes = ByteArrayHelper.HexStringToByteArray(signature);
+
+ var ed25519VerifyResult = EdDsaHelper.Ed25519Verify(signatureBytes, messageBytes, publicKeyBytes);
+
+ ed25519VerifyResult.ShouldBe(true);
+ }
+}
\ No newline at end of file
diff --git a/test/AElf.Cryptography.Tests/KeccakHelperTest.cs b/test/AElf.Cryptography.Tests/KeccakHelperTest.cs
new file mode 100644
index 0000000000..d6c8faa3fa
--- /dev/null
+++ b/test/AElf.Cryptography.Tests/KeccakHelperTest.cs
@@ -0,0 +1,22 @@
+using System.Text;
+using AElf.Cryptography.Keccak;
+using Nethereum.Util;
+using Shouldly;
+using Xunit;
+
+namespace AElf.Cryptography.Tests;
+
+public class KeccakHelperTest
+{
+ [Fact]
+ public void Keccak256_Test()
+ {
+ byte[] message = Encoding.UTF8.GetBytes("Test message");
+
+ var expectedHash = Sha3Keccack.Current.CalculateHash(message);
+
+ var computedHash = KeccakHelper.Keccak256(message);
+
+ computedHash.ShouldBe(expectedHash);
+ }
+}
\ No newline at end of file
diff --git a/test/AElf.Types.Tests/BigIntegerTest.cs b/test/AElf.Types.Tests/BigIntegerTest.cs
new file mode 100644
index 0000000000..056fcca2a9
--- /dev/null
+++ b/test/AElf.Types.Tests/BigIntegerTest.cs
@@ -0,0 +1,176 @@
+using System;
+using System.Numerics;
+using Xunit;
+
+namespace AElf.Types.Tests;
+
+public class BigIntegerTest
+{
+ [Fact]
+ public void Zero_Should_Be_Zero()
+ {
+ var zero = BigIntValue.Zero;
+ Assert.Equal("0", zero.Value);
+ }
+
+ [Fact]
+ public void One_Should_Be_One()
+ {
+ var one = BigIntValue.One;
+ Assert.Equal("1", one.Value);
+ }
+
+ [Fact]
+ public void BigIntValue_FromBigEndianBytes_Should_Work()
+ {
+ var bytes = new byte[] { 0x01, 0x00 }; // 256 in big endian
+ var bigIntValue = BigIntValue.FromBigEndianBytes(bytes);
+ Assert.Equal("256", bigIntValue.Value);
+ }
+
+ [Fact]
+ public void ToBigEndianBytes_Should_Work()
+ {
+ var bigIntValue = new BigIntValue { Value = "256" };
+ var bytes = bigIntValue.ToBigEndianBytes();
+ Assert.Equal(new byte[] { 0x01, 0x00 }, bytes);
+ }
+
+ [Theory]
+ [InlineData("123", "123", 0)]
+ [InlineData("123", "456", -1)]
+ [InlineData("456", "123", 1)]
+ public void CompareTo_Should_Correctly_Compare(string a, string b, int expected)
+ {
+ var bigIntValueA = new BigIntValue { Value = a };
+ var bigIntValueB = new BigIntValue { Value = b };
+
+ Assert.Equal(expected, bigIntValueA.CompareTo(bigIntValueB));
+ }
+
+ [Fact]
+ public void Implicit_Conversion_From_String_Should_Work()
+ {
+ BigIntValue bigIntValue = "123";
+ Assert.Equal("123", bigIntValue.Value);
+ }
+
+ [Fact]
+ public void Implicit_Conversion_From_Long_Should_Work()
+ {
+ BigIntValue bigIntValue = 456L;
+ Assert.Equal("456", bigIntValue.Value);
+ }
+
+ [Fact]
+ public void Addition_Operator_Should_Work()
+ {
+ BigIntValue a = "123";
+ BigIntValue b = "456";
+ BigIntValue result = a + b;
+ Assert.Equal("579", result.Value);
+ }
+
+ [Fact]
+ public void Subtraction_Operator_Should_Work()
+ {
+ BigIntValue a = "123";
+ BigIntValue b = "23";
+ BigIntValue result = a - b;
+ Assert.Equal("100", result.Value);
+ }
+
+ [Fact]
+ public void Multiplication_Operator_Should_Work()
+ {
+ BigIntValue a = "10";
+ BigIntValue b = "20";
+ BigIntValue result = a * b;
+ Assert.Equal("200", result.Value);
+ }
+
+ [Fact]
+ public void Modulus_Operator_Should_Work()
+ {
+ BigIntValue a = "10";
+ BigIntValue b = "3";
+ BigIntValue result = a % b;
+ Assert.Equal("1", result.Value);
+ }
+
+ [Fact]
+ public void Equality_Operator_Should_Work()
+ {
+ BigIntValue a = "123";
+ BigIntValue b = "123";
+ Assert.True(a == b);
+
+ BigIntValue c = "456";
+ Assert.False(a == c);
+ }
+
+ [Fact]
+ public void Inequality_Operator_Should_Work()
+ {
+ BigIntValue a = "123";
+ BigIntValue b = "456";
+ Assert.True(a != b);
+
+ BigIntValue c = "123";
+ Assert.False(a != c);
+ }
+
+ [Fact]
+ public void LessThanOperator_Should_Work()
+ {
+ BigIntValue a = "123";
+ BigIntValue b = "456";
+ Assert.True(a < b);
+ Assert.False(b < a);
+ }
+
+ [Fact]
+ public void GreaterThanOperator_Should_Work()
+ {
+ BigIntValue a = "456";
+ BigIntValue b = "123";
+ Assert.True(a > b);
+ Assert.False(b > a);
+ }
+
+ [Fact]
+ public void LessThanOrEqualOperator_Should_Work()
+ {
+ BigIntValue a = "123";
+ BigIntValue b = "123";
+ BigIntValue c = "456";
+ Assert.True(a <= b);
+ Assert.True(a <= c);
+ Assert.False(c <= a);
+ }
+
+ [Fact]
+ public void GreaterThanOrEqualOperator_Should_Work()
+ {
+ BigIntValue a = "123";
+ BigIntValue b = "123";
+ BigIntValue c = "456";
+ Assert.True(a >= b);
+ Assert.True(c >= a);
+ Assert.False(a >= c);
+ }
+
+ [Theory]
+ [InlineData("0", 0)]
+ [InlineData("123456789", 123456789)]
+ [InlineData("-987654321", -987654321)]
+ [InlineData("1_000_000_000", 1000000000)]
+ [InlineData("-1_234_567", -1234567)]
+ public void ConvertStringToBigInteger_ValidStrings_Should_ParseCorrectly(string input, long expected)
+ {
+ BigIntValue bigIntValue = input;
+ BigInteger result = bigIntValue; // Implicit conversion to BigInteger
+ Assert.Equal(new BigInteger(expected), result);
+ }
+
+}
\ No newline at end of file
diff --git a/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs b/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs
index 67e9db0b83..d72f7d6d4d 100644
--- a/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs
+++ b/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs
@@ -685,6 +685,37 @@ public async Task Get_TransactionResult_Success_Test()
response.BlockNumber.ShouldBe(block.Height);
response.BlockHash.ShouldBe(block.GetHash().ToHex());
}
+
+ [Fact]
+ public async Task Get_TransactionResultWithBVP_Expired_Test()
+ {
+ // Generate a transaction
+ var transaction = await _osTestHelper.GenerateTransferTransaction();
+
+ // Push chain height to be ref_block_number + at least 512
+ await MineSomeBlocks(520);
+ var transactionHex = transaction.GetHash().ToHex();
+
+ // Broadcast expired transaction
+ await _osTestHelper.BroadcastTransactions(new List { transaction });
+
+ // Check transaction status
+ var response = await GetResponseAsObjectAsync(
+ $"/api/blockChain/transactionResultWithBVP?transactionId={transactionHex}");
+ response.StatusWithBVP.ShouldBe(TransactionResultStatus.Expired.ToString().ToUpper());
+ }
+
+ private async Task MineSomeBlocks(int blockNumber)
+ {
+ var heightBefore = (await _osTestHelper.GetChainContextAsync()).BlockHeight;
+ for (var i = 0; i < blockNumber; i++)
+ {
+ await _osTestHelper.MinedOneBlock();
+ }
+
+ var heightAfter = (await _osTestHelper.GetChainContextAsync()).BlockHeight;
+ heightAfter.ShouldBe(heightBefore + blockNumber);
+ }
[Fact]
public async Task Get_Failed_TransactionResult_Success_Test()