Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve implicit access rules requirements #826

Merged
merged 33 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
dfc36f8
api schema
PawelPawelec-RDX Feb 7, 2025
485b82b
database model.
PawelPawelec-RDX Feb 7, 2025
001baa5
aggregation.
PawelPawelec-RDX Feb 7, 2025
18de286
fix aggregation for entities by role requirement.
PawelPawelec-RDX Feb 7, 2025
4039179
api surface.
PawelPawelec-RDX Feb 7, 2025
f24eb40
schema
PawelPawelec-RDX Feb 7, 2025
90ac11f
move resource_address to AccountDepositPreValidationNonFungibleBadge,…
PawelPawelec-RDX Feb 7, 2025
175fee2
api schema.
PawelPawelec-RDX Feb 10, 2025
4980765
db model updated.
PawelPawelec-RDX Feb 10, 2025
f9cde59
api surface
PawelPawelec-RDX Feb 10, 2025
755cdb5
aggregator
PawelPawelec-RDX Feb 10, 2025
5d91b70
changelog update.
PawelPawelec-RDX Feb 10, 2025
3eb154a
fix indexes.
PawelPawelec-RDX Feb 11, 2025
c176e35
docs.
PawelPawelec-RDX Feb 11, 2025
c2529a3
db.
PawelPawelec-RDX Feb 11, 2025
79bc06b
optimize DA.
PawelPawelec-RDX Feb 11, 2025
383a977
optimize query.
PawelPawelec-RDX Feb 11, 2025
180e74a
docs update.
PawelPawelec-RDX Feb 11, 2025
0198790
fix when querying only for system execution resources.
PawelPawelec-RDX Feb 12, 2025
4044318
docs: Mention the toolkit classification update in the CHANGELOG (#827)
dhedey Feb 12, 2025
9931d27
make sure to throw if new type of transaction is observed on ledger.
PawelPawelec-RDX Feb 13, 2025
a71df95
document indexes, cleanup type registration.
PawelPawelec-RDX Feb 13, 2025
5571081
iterate over request items to preserve order of queried elements.
PawelPawelec-RDX Feb 13, 2025
c88f601
fixed performance of inserting entities by role requirements (two sep…
PawelPawelec-RDX Feb 13, 2025
cfad281
cleanup usings.
PawelPawelec-RDX Feb 13, 2025
b855a98
cleanup processors.
PawelPawelec-RDX Feb 10, 2025
cb9422e
cleanup.
PawelPawelec-RDX Feb 13, 2025
357a9d8
update yaml with suggested changes, regenerate client after yaml upda…
PawelPawelec-RDX Feb 13, 2025
ebd4dbe
Merge branch 'develop' into resolve-implicit-access-rules-requirements
PawelPawelec-RDX Feb 13, 2025
88ebb44
sync networkconfigurationprovider as hosted service with async initia…
PawelPawelec-RDX Feb 14, 2025
89f6c54
cleanup usings.
PawelPawelec-RDX Feb 14, 2025
4b9e14f
add exponential back off for reading network config when starting ser…
PawelPawelec-RDX Feb 14, 2025
edb7cf2
Update src/RadixDlt.NetworkGateway.Abstractions/ServiceCollectionExte…
PawelPawelec-RDX Feb 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.OpenApi.Readers" Version="1.6.13" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
<PackageVersion Include="Polly" Version="8.3.0" />
<PackageVersion Include="prometheus-net" Version="8.2.1" />
Expand Down
32 changes: 0 additions & 32 deletions apps/DataAggregator/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -458,27 +458,6 @@
"Newtonsoft.Json": "12.0.1"
}
},
"Nito.AsyncEx.Tasks": {
"type": "Transitive",
"resolved": "5.1.2",
"contentHash": "jEkCfR2/M26OK/U4G7SEN063EU/F4LiVA06TtpZILMdX/quIHCg+wn31Zerl2LC+u1cyFancjTY3cNAr2/89PA==",
"dependencies": {
"Nito.Disposables": "2.2.1"
}
},
"Nito.Collections.Deque": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "CU0/Iuv5VDynK8I8pDLwkgF0rZhbQoZahtodfL0M3x2gFkpBRApKs8RyMyNlAi1mwExE4gsmqQXk4aFVvW9a4Q=="
},
"Nito.Disposables": {
"type": "Transitive",
"resolved": "2.2.1",
"contentHash": "6sZ5uynQeAE9dPWBQGKebNmxbY4xsvcc5VplB5WkYEESUS7oy4AwnFp0FhqxTSKm/PaFrFqLrYr696CYN8cugg==",
"dependencies": {
"System.Collections.Immutable": "1.7.1"
}
},
"Npgsql": {
"type": "Transitive",
"resolved": "8.0.2",
Expand Down Expand Up @@ -635,7 +614,6 @@
"Microsoft.Extensions.Hosting": "[8.0.0, )",
"Microsoft.Extensions.Logging.Abstractions": "[8.0.0, )",
"Newtonsoft.Json": "[13.0.3, )",
"Nito.AsyncEx.Coordination": "[5.1.2, )",
"RadixDlt.CoreApiSdk": "[1.10.0-develop, )"
}
},
Expand Down Expand Up @@ -831,16 +809,6 @@
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
},
"Nito.AsyncEx.Coordination": {
"type": "CentralTransitive",
"requested": "[5.1.2, )",
"resolved": "5.1.2",
"contentHash": "QMyUfsaxov//0ZMbOHWr9hJaBFteZd66DV1ay4J5wRODDb8+K/uHC7+3VsOflo6SVw/29mu8OWZp8vMDSuzc0w==",
"dependencies": {
"Nito.AsyncEx.Tasks": "5.1.2",
"Nito.Collections.Deque": "1.1.1"
}
},
"Npgsql.EntityFrameworkCore.PostgreSQL": {
"type": "CentralTransitive",
"requested": "[8.0.2, )",
Expand Down
32 changes: 0 additions & 32 deletions apps/DatabaseMigrations/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -391,27 +391,6 @@
"System.CodeDom": "4.4.0"
}
},
"Nito.AsyncEx.Tasks": {
"type": "Transitive",
"resolved": "5.1.2",
"contentHash": "jEkCfR2/M26OK/U4G7SEN063EU/F4LiVA06TtpZILMdX/quIHCg+wn31Zerl2LC+u1cyFancjTY3cNAr2/89PA==",
"dependencies": {
"Nito.Disposables": "2.2.1"
}
},
"Nito.Collections.Deque": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "CU0/Iuv5VDynK8I8pDLwkgF0rZhbQoZahtodfL0M3x2gFkpBRApKs8RyMyNlAi1mwExE4gsmqQXk4aFVvW9a4Q=="
},
"Nito.Disposables": {
"type": "Transitive",
"resolved": "2.2.1",
"contentHash": "6sZ5uynQeAE9dPWBQGKebNmxbY4xsvcc5VplB5WkYEESUS7oy4AwnFp0FhqxTSKm/PaFrFqLrYr696CYN8cugg==",
"dependencies": {
"System.Collections.Immutable": "1.7.1"
}
},
"Npgsql": {
"type": "Transitive",
"resolved": "8.0.2",
Expand Down Expand Up @@ -568,7 +547,6 @@
"Microsoft.Extensions.Hosting": "[8.0.0, )",
"Microsoft.Extensions.Logging.Abstractions": "[8.0.0, )",
"Newtonsoft.Json": "[13.0.3, )",
"Nito.AsyncEx.Coordination": "[5.1.2, )",
"RadixDlt.CoreApiSdk": "[1.10.0-develop, )"
}
},
Expand Down Expand Up @@ -756,16 +734,6 @@
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
},
"Nito.AsyncEx.Coordination": {
"type": "CentralTransitive",
"requested": "[5.1.2, )",
"resolved": "5.1.2",
"contentHash": "QMyUfsaxov//0ZMbOHWr9hJaBFteZd66DV1ay4J5wRODDb8+K/uHC7+3VsOflo6SVw/29mu8OWZp8vMDSuzc0w==",
"dependencies": {
"Nito.AsyncEx.Tasks": "5.1.2",
"Nito.Collections.Deque": "1.1.1"
}
},
"Npgsql.EntityFrameworkCore.PostgreSQL": {
"type": "CentralTransitive",
"requested": "[8.0.2, )",
Expand Down
4 changes: 2 additions & 2 deletions apps/GatewayApi/Controllers/StatusController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ public StatusController(IStatusHandler statusHandler, INetworkConfigurationProvi
}

[HttpPost("network-configuration")]
public async Task<GatewayModel.NetworkConfigurationResponse> NetworkConfiguration(CancellationToken token)
public GatewayModel.NetworkConfigurationResponse NetworkConfiguration()
{
var networkConfiguration = await _networkConfigurationProvider.GetNetworkConfiguration(token);
var networkConfiguration = _networkConfigurationProvider.GetNetworkConfiguration();
var wellKnownAddresses = networkConfiguration.WellKnownAddresses;

return new GatewayModel.NetworkConfigurationResponse(
Expand Down
2 changes: 1 addition & 1 deletion apps/GatewayApi/OpenApiDocumentHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ private static async Task<PlaceholderReplacements> GetPlaceholderReplacementsAsy
CancellationToken token)
{
var placeholderReplacements = new PlaceholderReplacements();
var networkConfiguration = await networkConfigurationProvider.GetNetworkConfiguration(token);
var networkConfiguration = networkConfigurationProvider.GetNetworkConfiguration();

try
{
Expand Down
32 changes: 0 additions & 32 deletions apps/GatewayApi/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -490,27 +490,6 @@
"Newtonsoft.Json": "12.0.1"
}
},
"Nito.AsyncEx.Tasks": {
"type": "Transitive",
"resolved": "5.1.2",
"contentHash": "jEkCfR2/M26OK/U4G7SEN063EU/F4LiVA06TtpZILMdX/quIHCg+wn31Zerl2LC+u1cyFancjTY3cNAr2/89PA==",
"dependencies": {
"Nito.Disposables": "2.2.1"
}
},
"Nito.Collections.Deque": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "CU0/Iuv5VDynK8I8pDLwkgF0rZhbQoZahtodfL0M3x2gFkpBRApKs8RyMyNlAi1mwExE4gsmqQXk4aFVvW9a4Q=="
},
"Nito.Disposables": {
"type": "Transitive",
"resolved": "2.2.1",
"contentHash": "6sZ5uynQeAE9dPWBQGKebNmxbY4xsvcc5VplB5WkYEESUS7oy4AwnFp0FhqxTSKm/PaFrFqLrYr696CYN8cugg==",
"dependencies": {
"System.Collections.Immutable": "1.7.1"
}
},
"Npgsql": {
"type": "Transitive",
"resolved": "8.0.2",
Expand Down Expand Up @@ -693,7 +672,6 @@
"Microsoft.Extensions.Hosting": "[8.0.0, )",
"Microsoft.Extensions.Logging.Abstractions": "[8.0.0, )",
"Newtonsoft.Json": "[13.0.3, )",
"Nito.AsyncEx.Coordination": "[5.1.2, )",
"RadixDlt.CoreApiSdk": "[1.10.0-develop, )"
}
},
Expand Down Expand Up @@ -889,16 +867,6 @@
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
},
"Nito.AsyncEx.Coordination": {
"type": "CentralTransitive",
"requested": "[5.1.2, )",
"resolved": "5.1.2",
"contentHash": "QMyUfsaxov//0ZMbOHWr9hJaBFteZd66DV1ay4J5wRODDb8+K/uHC7+3VsOflo6SVw/29mu8OWZp8vMDSuzc0w==",
"dependencies": {
"Nito.AsyncEx.Tasks": "5.1.2",
"Nito.Collections.Deque": "1.1.1"
}
},
"Npgsql.EntityFrameworkCore.PostgreSQL": {
"type": "CentralTransitive",
"requested": "[8.0.2, )",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@
*/

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Nito.AsyncEx;
using Polly;
using RadixDlt.NetworkGateway.Abstractions.Configuration;
using RadixDlt.NetworkGateway.Abstractions.CoreCommunications;
using RadixDlt.NetworkGateway.Abstractions.Extensions;
Expand All @@ -80,16 +81,17 @@ namespace RadixDlt.NetworkGateway.Abstractions.Network;

public interface INetworkConfigurationProvider
{
public Task<NetworkConfiguration> GetNetworkConfiguration(CancellationToken token = default);
public NetworkConfiguration GetNetworkConfiguration();
}

public sealed class NetworkConfigurationProvider : INetworkConfigurationProvider
public sealed class NetworkConfigurationProvider : IHostedService, INetworkConfigurationProvider
{
private readonly ILogger<NetworkConfigurationProvider> _logger;
private readonly NetworkOptions _networkOptions;
private readonly IServiceProvider _serviceProvider;
private readonly IEnumerable<INetworkConfigurationReaderObserver> _observers;
private readonly AsyncLazy<NetworkConfiguration> _factory;

private NetworkConfiguration? _networkConfiguration;

public NetworkConfigurationProvider(
IOptions<NetworkOptions> networkOptions,
Expand All @@ -101,15 +103,32 @@ public NetworkConfigurationProvider(
_serviceProvider = serviceProvider;
_observers = observers;
_logger = logger;
_factory = new AsyncLazy<NetworkConfiguration>(ReadNetworkConfiguration, AsyncLazyFlags.RetryOnFailure);
}

public Task<NetworkConfiguration> GetNetworkConfiguration(CancellationToken token = default)
public NetworkConfiguration GetNetworkConfiguration()
{
if (_networkConfiguration == null)
{
throw new Exception("Network configuration is not available.");
}

return _networkConfiguration;
}

public async Task StartAsync(CancellationToken cancellationToken)
{
var policy = Policy.Handle<Exception>()
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

await policy.ExecuteAsync(async () => _networkConfiguration = await ReadNetworkConfiguration(cancellationToken));
}

public Task StopAsync(CancellationToken cancellationToken)
{
return _factory.Task;
return Task.CompletedTask;
}

private async Task<NetworkConfiguration> ReadNetworkConfiguration()
private async Task<NetworkConfiguration> ReadNetworkConfiguration(CancellationToken cancellationToken)
{
using var scope = _serviceProvider.CreateScope();
var coreApiNode = scope.ServiceProvider.GetRequiredService<IOptionsMonitor<NetworkOptions>>().CurrentValue.CoreApiNodes.GetRandomEnabledNode();
Expand All @@ -118,8 +137,8 @@ private async Task<NetworkConfiguration> ReadNetworkConfiguration()

try
{
var configuration = await coreApiProvider.StatusApi.StatusNetworkConfigurationPostAsync();
var status = await coreApiProvider.StatusApi.StatusNetworkStatusPostAsync(new CoreModel.NetworkStatusRequest(_networkOptions.NetworkName));
var configuration = await coreApiProvider.StatusApi.StatusNetworkConfigurationPostAsync(cancellationToken);
var status = await coreApiProvider.StatusApi.StatusNetworkStatusPostAsync(new CoreModel.NetworkStatusRequest(_networkOptions.NetworkName), cancellationToken);

var addressTypeDefinitions = new List<AddressTypeDefinition>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<PackageReference Include="Microsoft.Extensions.Hosting" /> <!-- can't use .Abstractions as we rely on .ValidateOnStart() -->
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Nito.AsyncEx.Coordination" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,16 @@ public static IServiceCollection AddNetworkGatewayAbstractions(this IServiceColl
return services;
}

public static IServiceCollection AddNetworkGatewayCoreServices(this IServiceCollection services)
public static IServiceCollection AddNetworkConfigurationProvider(this IServiceCollection services)
{
services.TryAddSingleton<INetworkConfigurationProvider, NetworkConfigurationProvider>();
// NetworkConfigurationProvider is registered as HostedService as we want to fetch network configuration on app starup using StartAsync() method.
// NetworkConfigurationProvider is registered as singleton as we want to reuse fetched network configuration once it's fetched.
// To provide better separation it's also registered as INetworkConfigurationProvider (no need to share NetworkConfigurationProvider which contains also HostedService methods).
// https://stackoverflow.com/questions/58397807/how-to-resolve-hostedservice-in-controller

services.AddSingleton<NetworkConfigurationProvider>();
services.AddSingleton<INetworkConfigurationProvider, NetworkConfigurationProvider>(serviceProvider => serviceProvider.GetRequiredService<NetworkConfigurationProvider>());
services.AddHostedService<NetworkConfigurationProvider>(serviceProvider => serviceProvider.GetRequiredService<NetworkConfigurationProvider>());

return services;
}
Expand Down
36 changes: 0 additions & 36 deletions src/RadixDlt.NetworkGateway.Abstractions/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,6 @@
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
},
"Nito.AsyncEx.Coordination": {
"type": "Direct",
"requested": "[5.1.2, )",
"resolved": "5.1.2",
"contentHash": "QMyUfsaxov//0ZMbOHWr9hJaBFteZd66DV1ay4J5wRODDb8+K/uHC7+3VsOflo6SVw/29mu8OWZp8vMDSuzc0w==",
"dependencies": {
"Nito.AsyncEx.Tasks": "5.1.2",
"Nito.Collections.Deque": "1.1.1"
}
},
"StyleCop.Analyzers": {
"type": "Direct",
"requested": "[1.2.0-beta.556, )",
Expand Down Expand Up @@ -308,27 +298,6 @@
"resolved": "8.0.0",
"contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
},
"Nito.AsyncEx.Tasks": {
"type": "Transitive",
"resolved": "5.1.2",
"contentHash": "jEkCfR2/M26OK/U4G7SEN063EU/F4LiVA06TtpZILMdX/quIHCg+wn31Zerl2LC+u1cyFancjTY3cNAr2/89PA==",
"dependencies": {
"Nito.Disposables": "2.2.1"
}
},
"Nito.Collections.Deque": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "CU0/Iuv5VDynK8I8pDLwkgF0rZhbQoZahtodfL0M3x2gFkpBRApKs8RyMyNlAi1mwExE4gsmqQXk4aFVvW9a4Q=="
},
"Nito.Disposables": {
"type": "Transitive",
"resolved": "2.2.1",
"contentHash": "6sZ5uynQeAE9dPWBQGKebNmxbY4xsvcc5VplB5WkYEESUS7oy4AwnFp0FhqxTSKm/PaFrFqLrYr696CYN8cugg==",
"dependencies": {
"System.Collections.Immutable": "1.7.1"
}
},
"Polly.Core": {
"type": "Transitive",
"resolved": "8.3.0",
Expand All @@ -339,11 +308,6 @@
"resolved": "1.2.0.556",
"contentHash": "zvn9Mqs/ox/83cpYPignI8hJEM2A93s2HkHs8HYMOAQW0PkampyoErAiIyKxgTLqbbad29HX/shv/6LGSjPJNQ=="
},
"System.Collections.Immutable": {
"type": "Transitive",
"resolved": "1.7.1",
"contentHash": "B43Zsz5EfMwyEbnObwRxW5u85fzJma3lrDeGcSAV1qkhSRTNY5uXAByTn9h9ddNdhM+4/YoLc/CI43umjwIl9Q=="
},
"System.Diagnostics.DiagnosticSource": {
"type": "Transitive",
"resolved": "8.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public NetworkStatusReader(
{
return await _coreApiProvider.StatusApi.StatusNetworkStatusPostAsync(
new CoreModel.NetworkStatusRequest(
network: (await _networkConfigurationProvider.GetNetworkConfiguration(token)).Name
network: _networkConfigurationProvider.GetNetworkConfiguration().Name
),
token
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public TransactionStreamReader(
{
return await _coreApiProvider.StreamApi.StreamTransactionsPostWithHttpInfoAsync(
new CoreModel.StreamTransactionsRequest(
network: (await _networkConfigurationProvider.GetNetworkConfiguration(token)).Name,
network: _networkConfigurationProvider.GetNetworkConfiguration().Name,
fromStateVersion: fromStateVersion,
limit: count,
transactionFormatOptions: new CoreModel.TransactionFormatOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static DataAggregatorBuilder AddNetworkGatewayDataAggregatorCore(this ISe
{
services
.AddNetworkGatewayAbstractions()
.AddNetworkGatewayCoreServices();
.AddNetworkConfigurationProvider();

services
.AddValidatableOptionsAtSection<NetworkOptions, NetworkOptionsValidator>("DataAggregator:Network")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public LedgerTransactionsProcessor(

public async Task ProcessTransactions(CancellationToken token)
{
var networkConfiguration = await _networkConfigurationProvider.GetNetworkConfiguration(token);
var networkConfiguration = _networkConfigurationProvider.GetNetworkConfiguration();
var lastCommittedTransactionSummary = await _topOfLedgerProvider.GetTopOfLedger(token);
await _observers.ForEachAsync(x => x.PreHandleLedgerExtension(_clock.UtcNow));

Expand Down
Loading