Skip to content

Commit

Permalink
Merge pull request #852 from Portkey-Wallet/feature/tg-login-opt
Browse files Browse the repository at this point in the history
TG login process Optimization
  • Loading branch information
Edward-BXS authored Sep 30, 2024
2 parents da0e458 + 30263fb commit 654f1a5
Show file tree
Hide file tree
Showing 27 changed files with 4,647 additions and 3,578 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ namespace CAServer.Dtos;

public class AccountResultDto
{
public AccountResultDto() {}
public AccountResultDto(string sessionId)
{
this.SessionId = sessionId;
}

public string SessionId { get; set; }

public string CaHash { get; set; }

public string CaAddress { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CAServer.CAAccount.Dtos;

public class ManagerCacheDto
{
public string CaHash { get; set; }
public string CaAddress { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CAServer.CAAccount.Dtos;

public class ManagerDto
{
public string Address { get; set; }
public string ExtraData { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace CAServer.CAAccount.Dtos;

public class ProverResponse
{
public bool Valid { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using CAServer.CAAccount;
using CAServer.CAAccount.Dtos;
using CAServer.CAAccount.Dtos.Zklogin;
using CAServer.Commons;
Expand All @@ -17,6 +18,8 @@ public class RecoveryRequestDto : IValidatableObject
[Required] public string ChainId { get; set; }
[Required] public HubRequestContextDto Context { get; set; }
public ReferralInfo ReferralInfo { get; set; }

public RequestSource Source { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using AElf.Types;

namespace CAServer.CAAccount.Dtos;

public class VerificationDocInfo
{
public string GuardianType { get; set; }
public Hash IdentifierHash { get; set; }
public string VerificationTime { get; set; }
public Address VerifierAddress { get; set; }
public string Salt { get; set; }
public string OperationType { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace CAServer.CAAccount.Enums;

public enum OperationTypeInContract
{
Unknown = 0,
CreateCAHolder = 1,
SocialRecovery = 2,
AddGuardian = 3,
RemoveGuardian = 4,
UpdateGuardian = 5,
RemoveOtherManagerInfo = 6,
SetLoginAccount = 7,
Approve = 8,
ModifyTransferLimit = 9,
GuardianApproveTransfer = 10,
UnSetLoginAccount = 11,
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ public interface ICAAccountAppService
Task<CancelCheckResultDto> RevokeValidateAsync(Guid userId, string type);

Task<CAHolderExistsResponseDto> VerifyCaHolderExistByAddressAsync(string address);

Task<ManagerCacheDto> GetManagerFromCache(string manager);

Task<bool> CheckSocialRecoveryStatus(string chainId, string manager, string caHash);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using CAServer.Account;
using CAServer.CAAccount.Dtos;

namespace CAServer.CAAccount;

public interface IPreValidationProvider
{
public Task<bool> ValidateSocialRecovery(RequestSource source, string caHash,
string chainId, string manager, List<GuardianInfo> guardiansApproved, List<ManagerDto> existedManagers);

public Task SaveManagerInCache(string manager, string caHash, string caAddress);

public Task<ManagerCacheDto> GetManagerFromCache(string manager);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace CAServer.CAAccount;

public enum PreValidationType
{
Signature = 0,
ZkLogin = 1,
TonWallet = 2,

}
10 changes: 10 additions & 0 deletions src/CAServer.Application.Contracts/CAAccount/RequestSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace CAServer.CAAccount;

public enum RequestSource
{
UnKnown = 0,
Android = 1,
Ios = 2,
Web = 3,
Sdk = 4
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public static class AElfContractMethodName
public const string SetTransferLimit = "SetTransferLimit";
public const string RemoveManagerInfo = "RemoveManagerInfo";
public const string GuardianApproveTransfer = "GuardianApproveTransfer";
public const string VerifyZkLogin = "VerifyZkLogin";
public const string VerifySignature = "VerifySignature";
public static List<string> MethodNames = new List<string>()
{
CreateCAHolder,
Expand Down
6,198 changes: 2,841 additions & 3,357 deletions src/CAServer.Application.Contracts/Contracts/CaContract.g.cs

Large diffs are not rendered by default.

244 changes: 136 additions & 108 deletions src/CAServer.Application.Contracts/Contracts/CaContractImpl.c.cs

Large diffs are not rendered by default.

1,282 changes: 1,186 additions & 96 deletions src/CAServer.Application.Contracts/Contracts/CaContractImpl.g.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ public class VerifierServerInfo
{
public List<string> EndPoints { get; set; }
public string Id { get; set; }


public List<string> VerifierAddresses { get; set; }
}
50 changes: 42 additions & 8 deletions src/CAServer.Application/CAAccount/CAAccountAppService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -71,6 +72,7 @@ public class CAAccountAppService : CAServerAppService, ICAAccountAppService
private readonly IContractService _contractService;
private readonly IZkLoginProvider _zkLoginProvider;
private readonly IDistributedCache<string> _distributedCache;
private readonly IPreValidationProvider _preValidationProvider;

public CAAccountAppService(IClusterClient clusterClient,
IDistributedEventBus distributedEventBus,
Expand All @@ -90,7 +92,8 @@ public CAAccountAppService(IClusterClient clusterClient,
IVerifierAppService verifierAppService,
IContractService contractService,
IZkLoginProvider zkLoginProvider,
IDistributedCache<string> distributedCache)
IDistributedCache<string> distributedCache,
IPreValidationProvider preValidationProvider)
{
_distributedEventBus = distributedEventBus;
_clusterClient = clusterClient;
Expand All @@ -111,6 +114,7 @@ public CAAccountAppService(IClusterClient clusterClient,
_contractService = contractService;
_zkLoginProvider = zkLoginProvider;
_distributedCache = distributedCache;
_preValidationProvider = preValidationProvider;
}

public async Task<AccountResultDto> RegisterRequestAsync(RegisterRequestDto input)
Expand Down Expand Up @@ -267,20 +271,33 @@ public async Task<AccountResultDto> RecoverRequestAsync(RecoveryRequestDto input
throw new UserFriendlyException(result.Message);
}

var caHash = await GetCAHashAsync(input.ChainId, guardianGrainDto.IdentifierHash);

var holderInfo = await GetCAHashAsync(input.ChainId, guardianGrainDto.IdentifierHash);
var caHash = holderInfo?.CaHash?.ToHex();
if (caHash != null)
{
result.Data.ManagerInfo.ExtraData =
await _deviceAppService.EncryptExtraDataAsync(result.Data.ManagerInfo.ExtraData, caHash);
}

var recoverCreateEto = ObjectMapper.Map<RecoveryGrainDto, AccountRecoverCreateEto>(result.Data);
recoverCreateEto.IpAddress = _ipInfoAppService.GetRemoteIp(input.ReferralInfo?.Random);
await CheckAndResetReferralInfo(input.ReferralInfo, recoverCreateEto.IpAddress);
await _distributedEventBus.PublishAsync(recoverCreateEto);

return new AccountResultDto(recoveryDto.Id.ToString());

var existedManagers = ObjectMapper.Map<List<ManagerInfo>, List<ManagerDto>>(new List<ManagerInfo>(holderInfo?.ManagerInfos));
var preValidateResult = await _preValidationProvider.ValidateSocialRecovery(input.Source, caHash, input.ChainId, input.Manager, recoveryDto.GuardianApproved, existedManagers);
if (!preValidateResult)
{
throw new UserFriendlyException("social recovery validation failed, please try again later");
}

await _preValidationProvider.SaveManagerInCache(input.Manager, caHash, holderInfo?.CaAddress?.ToBase58());
return new AccountResultDto()
{
SessionId = recoveryDto.Id.ToString(),
CaHash = caHash,
CaAddress = holderInfo?.CaAddress?.ToBase58()
};
}

private async Task CheckAndResetReferralInfo(ReferralInfo referralInfo, string ipAddress)
Expand Down Expand Up @@ -786,14 +803,31 @@ await _distributedEventBus.PublishAsync(
return guardianGrainDto.Data;
}

private async Task<string> GetCAHashAsync(string chainId, string loginGuardianIdentifierHash)
private async Task<GetHolderInfoOutput> GetCAHashAsync(string chainId, string loginGuardianIdentifierHash)
{
var output =
await _contractProvider.GetHolderInfoAsync(null, Hash.LoadFromHex(loginGuardianIdentifierHash),
chainId);
_logger.LogInformation("GetHolderInfoAsync loginGuardianIdentifierHash:{0},chainId:{1},output:{2}",
loginGuardianIdentifierHash, chainId, JsonConvert.SerializeObject(output));
return output?.CaHash?.ToHex();
return output;
}

public async Task<ManagerCacheDto> GetManagerFromCache(string manager)
{
return await _preValidationProvider.GetManagerFromCache(manager);
}

public async Task<bool> CheckSocialRecoveryStatus(string chainId, string manager, string caHash)
{
var output =
await _contractProvider.GetHolderInfoAsync(Hash.LoadFromHex(caHash), null, chainId);
if (output == null || output.ManagerInfos.IsNullOrEmpty())
{
return false;
}

return output.ManagerInfos.Any(mg => mg.Address.ToBase58().Equals(manager));
}

private async Task PublishExtraInfoAsync(string grainId, Dictionary<string, object> extraInfo)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Threading.Tasks;
using CAServer.Account;
using CAServer.Dtos;

namespace CAServer.CAAccount.Provider;

public interface IPreValidationStrategy
{
public PreValidationType Type { get; }

public bool ValidateParameters(GuardianInfo guardian);

public Task<bool> PreValidateGuardian(string chainId, string caHash, string manager, GuardianInfo guardian);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using CAServer.Account;
using CAServer.CAAccount.Dtos;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.Caching;

namespace CAServer.CAAccount.Provider;

[RemoteService(false)]
[DisableAuditing]
public class PreValidationProvider : CAServerAppService, IPreValidationProvider
{
private readonly IEnumerable<IPreValidationStrategy> _preValidationStrategies;
private readonly IDistributedCache<string> _distributedCache;
private readonly ILogger<PreValidationProvider> _logger;

public PreValidationProvider(IEnumerable<IPreValidationStrategy> preValidationStrategies,
IDistributedCache<string> distributedCache,
ILogger<PreValidationProvider> logger)
{
_preValidationStrategies = preValidationStrategies;
_distributedCache = distributedCache;
_logger = logger;
}

public async Task<bool> ValidateSocialRecovery(RequestSource source, string caHash,
string chainId, string manager, List<GuardianInfo> guardiansApproved, List<ManagerDto> existedManagers)
{
if (!RequestSource.Sdk.Equals(source))
{
return true;
}
var sw = new Stopwatch();
sw.Start();
//1 manager check
if (!existedManagers.IsNullOrEmpty() && existedManagers.Any(mg => mg.Address.Equals(manager)))
{
_logger.LogWarning("manager exists error. chainId:{0} caHash:{1} manager:{2}", chainId, caHash, manager);
return false;
}
//2 guardian check
foreach (var guardianInfo in guardiansApproved)
{
foreach (var preValidationStrategy in _preValidationStrategies)
{
if (!preValidationStrategy.ValidateParameters(guardianInfo))
{
continue;
}

var result = await preValidationStrategy.PreValidateGuardian(chainId, caHash, manager, guardianInfo);
if (result)
{
continue;
}

_logger.LogInformation("preValidationStrategy failed type:{0} chainId:{1} caHash:{2} manager:{3} guardianInfo:{4}",
preValidationStrategy.Type, chainId, caHash, manager, JsonConvert.SerializeObject(guardianInfo));
return false;
}
}
sw.Stop();
_logger.LogInformation("ValidateSocialRecovery cost:{0}ms", sw.ElapsedMilliseconds);
return true;
}

public async Task SaveManagerInCache(string manager, string caHash, string caAddress)
{
var managerCacheDto = new ManagerCacheDto()
{
CaHash = caHash,
CaAddress = caAddress
};
await _distributedCache.SetAsync(GetCacheKey(manager), JsonConvert.SerializeObject(managerCacheDto), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1) });
}

public async Task<ManagerCacheDto> GetManagerFromCache(string manager)
{
var result = await _distributedCache.GetAsync(GetCacheKey(manager));
if (result.IsNullOrEmpty())
{
return null;
}
return JsonConvert.DeserializeObject<ManagerCacheDto>(result);
}

private string GetCacheKey(string manager)
{
return "Portkey:SocialRecover:" + manager;
}
}
Loading

0 comments on commit 654f1a5

Please sign in to comment.