Skip to content

Commit

Permalink
refactor check if address is pre allocated.
Browse files Browse the repository at this point in the history
  • Loading branch information
PawelPawelec-RDX committed Oct 10, 2024
1 parent 36e75c6 commit 5d15863
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 116 deletions.
2 changes: 2 additions & 0 deletions src/RadixDlt.NetworkGateway.Abstractions/EntityAddress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ private EntityAddress(string address)

public bool IsAccount => _address.StartsWith("account_");

public bool IsIdentity => _address.StartsWith("identity_");

public bool IsResource => _address.StartsWith("resource_");

public static implicit operator string(EntityAddress ra) => ra._address;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ namespace RadixDlt.NetworkGateway.Abstractions.Network;

public sealed record DecodedRadixAddress(string Hrp, byte[] Data, Bech32Codec.Variant Variant)
{
private const byte Secp256kPreAllocatedAccountPrefix = 209;
private const byte Secp256kPreAllocatedIdentityPrefix = 210;
private const byte Ed25519PreAllocatedAccountPrefix = 81;
private const byte Ed25519PreAllocatedIdentityPrefix = 82;

public bool IsPreAllocated() => IsPreAllocatedAccountAddress() || IsPreAllocatedIdentityAddress();

public bool IsSecp256k() => DiscriminatorByte is Secp256kPreAllocatedAccountPrefix or Secp256kPreAllocatedIdentityPrefix;

public bool IsEd25519() => DiscriminatorByte is Ed25519PreAllocatedAccountPrefix or Ed25519PreAllocatedIdentityPrefix;

public bool IsPreAllocatedAccountAddress() => DiscriminatorByte is Secp256kPreAllocatedAccountPrefix or Ed25519PreAllocatedAccountPrefix;

public bool IsPreAllocatedIdentityAddress() => DiscriminatorByte is Secp256kPreAllocatedIdentityPrefix or Ed25519PreAllocatedIdentityPrefix;

public byte DiscriminatorByte => Data[0];

public byte[] AddressBytes => Data[1..];
Expand All @@ -90,7 +105,7 @@ public static string Encode(string hrp, ReadOnlySpan<byte> addressData)
return Bech32Codec.Encode(hrp, EncodeAddressDataInBase32(addressData), Bech32Codec.Variant.Bech32M);
}

public static DecodedRadixAddress Decode(string encoded)
public static DecodedRadixAddress Decode(string encoded, bool strict = false)
{
var (hrp, rawBase32Data, variant) = Bech32Codec.Decode(encoded);
var addressData = DecodeBase32IntoAddressData(rawBase32Data);
Expand All @@ -102,7 +117,12 @@ public static DecodedRadixAddress Decode(string encoded)

if (variant != Bech32Codec.Variant.Bech32M)
{
throw new AddressException("Only Bech32M addresses are supported");
throw new AddressException($"Only Bech32M addresses are supported, decoded variant: {variant}");
}

if (strict && addressData.Length != 30)
{
throw new AddressException($"Expected address to be 30 bytes in length. But was {addressData.Length}");
}

return new DecodedRadixAddress(hrp, addressData, variant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,28 @@ internal static class ManifestAddressesExtractor
{
internal record PresentedProof(EntityAddress AccountAddress, EntityAddress ResourceAddress);

internal record AddressWithEntityType(ToolkitModel.EntityType EntityType, EntityAddress Address);

internal record ManifestAddresses(
List<EntityAddress> PackageAddresses,
List<EntityAddress> ComponentAddresses,
List<EntityAddress> ResourceAddresses,
List<AddressWithEntityType> AccountAddresses,
List<AddressWithEntityType> AccountsRequiringAuth,
List<AddressWithEntityType> AccountsWithdrawnFrom,
List<AddressWithEntityType> AccountsDepositedInto,
List<AddressWithEntityType> IdentityAddresses,
List<AddressWithEntityType> IdentitiesRequiringAuth,
List<EntityAddress> AccountAddresses,
List<EntityAddress> AccountsRequiringAuth,
List<EntityAddress> AccountsWithdrawnFrom,
List<EntityAddress> AccountsDepositedInto,
List<EntityAddress> IdentityAddresses,
List<EntityAddress> IdentitiesRequiringAuth,
List<PresentedProof> PresentedProofs)
{
public List<EntityAddress> All() =>
PackageAddresses
.Concat(ComponentAddresses)
.Concat(ResourceAddresses)
.Concat(AccountAddresses.Select(x => x.Address))
.Concat(AccountsRequiringAuth.Select(x => x.Address))
.Concat(AccountsWithdrawnFrom.Select(x => x.Address))
.Concat(AccountsDepositedInto.Select(x => x.Address))
.Concat(IdentityAddresses.Select(x => x.Address))
.Concat(IdentitiesRequiringAuth.Select(x => x.Address))
.Concat(AccountAddresses)
.Concat(AccountsRequiringAuth)
.Concat(AccountsWithdrawnFrom)
.Concat(AccountsDepositedInto)
.Concat(IdentityAddresses)
.Concat(IdentitiesRequiringAuth)
.Concat(PresentedProofs.Select(x => x.AccountAddress))
.Concat(PresentedProofs.Select(x => x.ResourceAddress))
.Distinct()
Expand All @@ -111,10 +109,10 @@ public static ManifestAddresses ExtractAddresses(ToolkitModel.TransactionManifes
var manifestSummary = manifest.Summary(networkId);

var presentedProofs = ExtractProofs(manifestSummary.presentedProofs);
var accountsRequiringAuth = manifestSummary.accountsRequiringAuth.Select(x => new AddressWithEntityType(x.EntityType(), (EntityAddress)x.AddressString())).ToList();
var accountsWithdrawnFrom = manifestSummary.accountsWithdrawnFrom.Select(x => new AddressWithEntityType(x.EntityType(), (EntityAddress)x.AddressString())).ToList();
var accountsDepositedInto = manifestSummary.accountsDepositedInto.Select(x => new AddressWithEntityType(x.EntityType(), (EntityAddress)x.AddressString())).ToList();
var identitiesRequiringAuth = manifestSummary.identitiesRequiringAuth.Select(x => new AddressWithEntityType(x.EntityType(), (EntityAddress)x.AddressString())).ToList();
var accountsRequiringAuth = manifestSummary.accountsRequiringAuth.Select(x => (EntityAddress)x.AddressString()).ToList();
var accountsWithdrawnFrom = manifestSummary.accountsWithdrawnFrom.Select(x => (EntityAddress)x.AddressString()).ToList();
var accountsDepositedInto = manifestSummary.accountsDepositedInto.Select(x => (EntityAddress)x.AddressString()).ToList();
var identitiesRequiringAuth = manifestSummary.identitiesRequiringAuth.Select(x => (EntityAddress)x.AddressString()).ToList();

var packageAddresses = allAddresses
.Where(x => x.Key == ToolkitModel.EntityType.GlobalPackage)
Expand All @@ -137,7 +135,7 @@ public static ManifestAddresses ExtractAddresses(ToolkitModel.TransactionManifes
is ToolkitModel.EntityType.GlobalAccount
or ToolkitModel.EntityType.GlobalVirtualEd25519Account
or ToolkitModel.EntityType.GlobalVirtualSecp256k1Account)
.SelectMany(x => x.Value.Select(y => new AddressWithEntityType(y.EntityType(), (EntityAddress)y.AddressString())))
.SelectMany(x => x.Value.Select(y => (EntityAddress)y.AddressString()))
.ToList();

var identityAddresses = allAddresses
Expand All @@ -146,7 +144,7 @@ or ToolkitModel.EntityType.GlobalVirtualEd25519Account
is ToolkitModel.EntityType.GlobalIdentity
or ToolkitModel.EntityType.GlobalVirtualEd25519Identity
or ToolkitModel.EntityType.GlobalVirtualSecp256k1Identity)
.SelectMany(x => x.Value.Select(y => new AddressWithEntityType(y.EntityType(), (EntityAddress)y.AddressString())))
.SelectMany(x => x.Value.Select(y => (EntityAddress)y.AddressString()))
.ToList();

return new ManifestAddresses(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ private IEnumerable<LedgerTransactionMarker> CreateMarkersForManifestAddresses()
});
}

foreach (var addressWithEntityType in extractedAddresses.AccountsRequiringAuth)
foreach (var entityAddress in extractedAddresses.AccountsRequiringAuth)
{
if (_referencedEntities.TryGet(addressWithEntityType.Address, out var referencedEntity))
if (_referencedEntities.TryGet(entityAddress, out var referencedEntity))
{
ledgerTransactionMarkersToAdd.Add(
new ManifestAddressLedgerTransactionMarker
Expand All @@ -226,15 +226,15 @@ private IEnumerable<LedgerTransactionMarker> CreateMarkersForManifestAddresses()
EntityId = referencedEntity.DatabaseId,
});
}
else if (addressWithEntityType.EntityType is not (ToolkitModel.EntityType.GlobalVirtualEd25519Account or ToolkitModel.EntityType.GlobalVirtualSecp256k1Account))
else if (!RadixAddressCodec.Decode(entityAddress).IsPreAllocatedAccountAddress())
{
throw new UnreachableException($"Entity: {addressWithEntityType.Address} was not present in referenced entities dictionary.");
throw new UnreachableException($"Entity: {entityAddress} was not present in referenced entities dictionary.");
}
}

foreach (var addressWithEntityType in extractedAddresses.AccountsDepositedInto)
foreach (var entityAddress in extractedAddresses.AccountsDepositedInto)
{
if (_referencedEntities.TryGet(addressWithEntityType.Address, out var referencedEntity))
if (_referencedEntities.TryGet(entityAddress, out var referencedEntity))
{
ledgerTransactionMarkersToAdd.Add(
new ManifestAddressLedgerTransactionMarker
Expand All @@ -245,15 +245,15 @@ private IEnumerable<LedgerTransactionMarker> CreateMarkersForManifestAddresses()
EntityId = referencedEntity.DatabaseId,
});
}
else if (addressWithEntityType.EntityType is not (ToolkitModel.EntityType.GlobalVirtualEd25519Account or ToolkitModel.EntityType.GlobalVirtualSecp256k1Account))
else if (!RadixAddressCodec.Decode(entityAddress).IsPreAllocatedAccountAddress())
{
throw new UnreachableException($"Entity: {addressWithEntityType.Address} was not present in referenced entities dictionary.");
throw new UnreachableException($"Entity: {entityAddress} was not present in referenced entities dictionary.");
}
}

foreach (var addressWithEntityType in extractedAddresses.AccountsWithdrawnFrom)
foreach (var entityAddress in extractedAddresses.AccountsWithdrawnFrom)
{
if (_referencedEntities.TryGet(addressWithEntityType.Address, out var referencedEntity))
if (_referencedEntities.TryGet(entityAddress, out var referencedEntity))
{
ledgerTransactionMarkersToAdd.Add(
new ManifestAddressLedgerTransactionMarker
Expand All @@ -264,9 +264,9 @@ private IEnumerable<LedgerTransactionMarker> CreateMarkersForManifestAddresses()
EntityId = referencedEntity.DatabaseId,
});
}
else if (addressWithEntityType.EntityType is not (ToolkitModel.EntityType.GlobalVirtualEd25519Account or ToolkitModel.EntityType.GlobalVirtualSecp256k1Account))
else if (!RadixAddressCodec.Decode(entityAddress).IsPreAllocatedAccountAddress())
{
throw new UnreachableException($"Entity: {addressWithEntityType.Address} was not present in referenced entities dictionary.");
throw new UnreachableException($"Entity: {entityAddress} was not present in referenced entities dictionary.");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@

using Microsoft.EntityFrameworkCore;
using RadixDlt.NetworkGateway.Abstractions;
using RadixDlt.NetworkGateway.Abstractions.Network;
using RadixDlt.NetworkGateway.GatewayApi.Exceptions;
using RadixDlt.NetworkGateway.PostgresIntegration.Models;
using RadixDlt.NetworkGateway.PostgresIntegration.Services;
Expand Down Expand Up @@ -113,7 +114,7 @@ public async Task<TEntity> GetEntity<TEntity>(EntityAddress address, GatewayApiS

if (entity == null)
{
entity = await TryResolveAsPreAllocatedEntity(address);
entity = TryResolveAsPreAllocatedEntity(address);

if (entity == null)
{
Expand Down Expand Up @@ -188,7 +189,7 @@ public async Task<ICollection<Entity>> GetEntities(List<EntityAddress> addresses

foreach (var address in addresses.Except(entities.Keys))
{
var preAllocatedEntity = await TryResolveAsPreAllocatedEntity(address);
var preAllocatedEntity = TryResolveAsPreAllocatedEntity(address);

if (preAllocatedEntity != null)
{
Expand All @@ -199,14 +200,14 @@ public async Task<ICollection<Entity>> GetEntities(List<EntityAddress> addresses
return entities.Values;
}

private async Task<Entity?> TryResolveAsPreAllocatedEntity(EntityAddress address)
private static Entity? TryResolveAsPreAllocatedEntity(EntityAddress address)
{
if (await _preAllocatedEntityDataProvider.IsPreAllocatedAccountAddress(address))
if (address.IsAccount && RadixAddressCodec.Decode(address).IsPreAllocatedAccountAddress())
{
return new PreAllocatedAccountComponentEntity(address);
}

if (await _preAllocatedEntityDataProvider.IsPreAllocatedIdentityAddress(address))
if (address.IsIdentity && RadixAddressCodec.Decode(address).IsPreAllocatedIdentityAddress())
{
return new PreAllocatedIdentityEntity(address);
}
Expand Down
Loading

0 comments on commit 5d15863

Please sign in to comment.