-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1021 from Portkey-Wallet/release/3.1.2
Asynchronous message processing
- Loading branch information
Showing
35 changed files
with
1,923 additions
and
1,135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
src/CAServer.Application.Contracts/Commons/AelfClientConstant.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace CAServer.Commons; | ||
|
||
public static class AelfClientConstant | ||
{ | ||
public const string MainChainClient = "MainChainClient"; | ||
public const string SideChainClient = "SideChainClient"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/CAServer.Application/Common/AelfClient/IContractClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using AElf.Client.Dto; | ||
using AElf.Types; | ||
using Google.Protobuf; | ||
|
||
namespace CAServer.Common.AelfClient; | ||
|
||
public interface IContractClient | ||
{ | ||
Task<Transaction> GenerateTransactionAsync( | ||
string from, | ||
string to, | ||
string methodName, | ||
IMessage input); | ||
|
||
Task<BlockDto> GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false); | ||
|
||
Task<SendTransactionOutput> SendTransactionAsync(SendTransactionInput input); | ||
|
||
Task<TransactionResultDto> GetTransactionResultAsync(string transactionId); | ||
Task<string> ExecuteTransactionAsync(ExecuteTransactionDto input); | ||
|
||
Transaction SignTransaction(string privateKeyHex, Transaction transaction); | ||
} | ||
|
28 changes: 28 additions & 0 deletions
28
src/CAServer.Application/Common/AelfClient/IContractClientSelector.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using CAServer.Commons; | ||
using Volo.Abp.DependencyInjection; | ||
|
||
namespace CAServer.Common.AelfClient; | ||
|
||
public interface IContractClientSelector | ||
{ | ||
IContractClient GetContractClient(string chainId); | ||
} | ||
|
||
public class ContractClientSelector : IContractClientSelector, ISingletonDependency | ||
{ | ||
private readonly IEnumerable<IContractClient> _contractClients; | ||
|
||
public ContractClientSelector(IEnumerable<IContractClient> contractClients) | ||
{ | ||
_contractClients = contractClients; | ||
} | ||
|
||
public IContractClient GetContractClient(string chainId) | ||
{ | ||
return chainId == CommonConstant.MainChainId | ||
? _contractClients.FirstOrDefault(t => t.GetType().Name == nameof(MainChainContractClient)) | ||
: _contractClients.FirstOrDefault(t => t.GetType().Name == nameof(SideChainContractClient)); | ||
} | ||
} |
185 changes: 185 additions & 0 deletions
185
src/CAServer.Application/Common/AelfClient/MainChainContractClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Net.Mime; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using AElf; | ||
using AElf.Client.Dto; | ||
using AElf.Cryptography; | ||
using AElf.Types; | ||
using CAServer.Commons; | ||
using Google.Protobuf; | ||
using Microsoft.Extensions.Logging; | ||
using Newtonsoft.Json; | ||
using Volo.Abp; | ||
|
||
namespace CAServer.Common.AelfClient; | ||
|
||
public class MainChainContractClient : IContractClient | ||
{ | ||
private readonly IHttpClientFactory _httpClientFactory; | ||
private readonly ILogger<MainChainContractClient> _logger; | ||
|
||
public MainChainContractClient(IHttpClientFactory httpClientFactory, ILogger<MainChainContractClient> logger) | ||
{ | ||
_httpClientFactory = httpClientFactory; | ||
_logger = logger; | ||
} | ||
|
||
public async Task<Transaction> GenerateTransactionAsync( | ||
string from, | ||
string to, | ||
string methodName, | ||
IMessage input) | ||
{ | ||
try | ||
{ | ||
var chainStatusAsync = await GetChainStatusAsync(); | ||
return new Transaction() | ||
{ | ||
From = Address.FromBase58(from), | ||
To = Address.FromBase58(to), | ||
MethodName = methodName, | ||
Params = input.ToByteString(), | ||
RefBlockNumber = chainStatusAsync.BestChainHeight, | ||
RefBlockPrefix = ByteString.CopyFrom(Hash.LoadFromHex(chainStatusAsync.BestChainHash).Value | ||
.Take<byte>(4).ToArray<byte>()) | ||
}; | ||
} | ||
catch (Exception ex) | ||
{ | ||
_logger.LogError(ex, "[ContractClient.GenerateTransactionAsync] error, msg:{0},trace:{1}", ex.Message, | ||
ex.StackTrace ?? "-"); | ||
return (Transaction)null; | ||
} | ||
} | ||
|
||
public async Task<BlockDto> GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false) | ||
{ | ||
var uri = string.Format("api/blockChain/blockByHeight?blockHeight={0}&includeTransactions={1}", | ||
blockHeight, includeTransactions); | ||
return await GetAsync<BlockDto>(uri); | ||
} | ||
|
||
public async Task<SendTransactionOutput> SendTransactionAsync(SendTransactionInput input) | ||
{ | ||
var uri = "api/blockChain/sendTransaction"; | ||
var param = new Dictionary<string, string>() | ||
{ | ||
{ | ||
"RawTransaction", | ||
input.RawTransaction | ||
} | ||
}; | ||
return await PostAsync<SendTransactionOutput>(uri, param); | ||
} | ||
|
||
public async Task<TransactionResultDto> GetTransactionResultAsync(string transactionId) | ||
{ | ||
var url = "api/blockChain/transactionResult?transactionId=" + transactionId; | ||
return await GetAsync<TransactionResultDto>(url); | ||
} | ||
|
||
public async Task<string> ExecuteTransactionAsync(ExecuteTransactionDto input) | ||
{ | ||
var url = "api/blockChain/executeTransaction"; | ||
var param = new Dictionary<string, string>() | ||
{ | ||
{ | ||
"RawTransaction", | ||
input.RawTransaction | ||
} | ||
}; | ||
return await PostAsync(url, param); | ||
} | ||
|
||
public Transaction SignTransaction(string privateKeyHex, Transaction transaction) | ||
{ | ||
byte[] byteArray = transaction.GetHash().ToByteArray(); | ||
byte[] numArray = | ||
CryptoHelper.SignWithPrivateKey(ByteArrayHelper.HexStringToByteArray(privateKeyHex), byteArray); | ||
transaction.Signature = ByteString.CopyFrom(numArray); | ||
return transaction; | ||
} | ||
|
||
public async Task<ChainStatusDto> GetChainStatusAsync() | ||
{ | ||
var uri = "api/blockChain/chainStatus"; | ||
return await GetAsync<ChainStatusDto>(uri); | ||
} | ||
|
||
public async Task<T> GetAsync<T>(string url) | ||
{ | ||
var client = _httpClientFactory.CreateClient(AelfClientConstant.MainChainClient); | ||
var response = await client.GetAsync(url); | ||
var content = await response.Content.ReadAsStringAsync(); | ||
if (!ResponseSuccess(response.StatusCode)) | ||
{ | ||
_logger.LogError( | ||
"[ContractClientError] MainChainContractClient GetError Response not success, url:{url}, code:{code}, message: {message}", | ||
url, response.StatusCode, content); | ||
|
||
throw new UserFriendlyException(content, ((int)response.StatusCode).ToString()); | ||
} | ||
|
||
return JsonConvert.DeserializeObject<T>(content); | ||
} | ||
|
||
public async Task<T> PostAsync<T>(string url, object paramObj) | ||
{ | ||
var requestInput = paramObj == null ? string.Empty : JsonConvert.SerializeObject(paramObj, Formatting.None); | ||
|
||
var requestContent = new StringContent( | ||
requestInput, | ||
Encoding.UTF8, | ||
MediaTypeNames.Application.Json); | ||
|
||
var client = _httpClientFactory.CreateClient(AelfClientConstant.MainChainClient); | ||
|
||
var response = await client.PostAsync(url, requestContent); | ||
var content = await response.Content.ReadAsStringAsync(); | ||
|
||
if (!ResponseSuccess(response.StatusCode)) | ||
{ | ||
_logger.LogError( | ||
"[ContractClientError] MainChainContractClient PostError Response not success, url:{url}, code:{code}, message: {message}, params:{param}", | ||
url, response.StatusCode, content, JsonConvert.SerializeObject(paramObj)); | ||
|
||
throw new UserFriendlyException(content, ((int)response.StatusCode).ToString()); | ||
} | ||
|
||
return JsonConvert.DeserializeObject<T>(content); | ||
} | ||
|
||
public async Task<string> PostAsync(string url, object paramObj) | ||
{ | ||
var requestInput = paramObj == null ? string.Empty : JsonConvert.SerializeObject(paramObj, Formatting.None); | ||
|
||
var requestContent = new StringContent( | ||
requestInput, | ||
Encoding.UTF8, | ||
MediaTypeNames.Application.Json); | ||
|
||
var client = _httpClientFactory.CreateClient(AelfClientConstant.MainChainClient); | ||
|
||
var response = await client.PostAsync(url, requestContent); | ||
var content = await response.Content.ReadAsStringAsync(); | ||
|
||
if (!ResponseSuccess(response.StatusCode)) | ||
{ | ||
_logger.LogError( | ||
"[ContractClientError] MainChainContractClient PostError Response not success, url:{url}, code:{code}, message: {message}, params:{param}", | ||
url, response.StatusCode, content, JsonConvert.SerializeObject(paramObj)); | ||
|
||
throw new UserFriendlyException(content, ((int)response.StatusCode).ToString()); | ||
} | ||
|
||
return content; | ||
} | ||
|
||
private bool ResponseSuccess(HttpStatusCode statusCode) => | ||
statusCode is HttpStatusCode.OK or HttpStatusCode.NoContent; | ||
} |
Oops, something went wrong.