diff --git a/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs b/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs index f2480f7ca..ff50ccc98 100644 --- a/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs +++ b/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs @@ -638,8 +638,7 @@ public ITrie Trie public BlockHash? BlockHash { - get; - set; + get => default; } public IValue? GetState(Address address) diff --git a/NineChronicles.Headless/ActionEvaluationPublisher.cs b/NineChronicles.Headless/ActionEvaluationPublisher.cs index 5e3616a72..bee439ace 100644 --- a/NineChronicles.Headless/ActionEvaluationPublisher.cs +++ b/NineChronicles.Headless/ActionEvaluationPublisher.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Diagnostics.Metrics; using System.IO; using System.IO.Compression; @@ -103,7 +104,7 @@ public async Task AddClient(Address clientAddress) }; GrpcChannel channel = GrpcChannel.ForAddress($"http://{_host}:{_port}", options); - Client client = await Client.CreateAsync(channel, clientAddress, _context, _sentryTraces); + Client client = await Client.CreateAsync(channel, _blockChainStates, clientAddress, _context, _sentryTraces); if (_clients.TryAdd(clientAddress, client)) { if (clientAddress == default) @@ -223,6 +224,7 @@ private async void RemoveClient(string clientAddressHex) private sealed class Client : IAsyncDisposable { private readonly IActionEvaluationHub _hub; + private readonly IBlockChainStates _blockChainStates; private readonly RpcContext _context; private readonly Address _clientAddress; @@ -240,11 +242,13 @@ private sealed class Client : IAsyncDisposable private Client( IActionEvaluationHub hub, + IBlockChainStates blockChainStates, Address clientAddress, RpcContext context, ConcurrentDictionary sentryTraces) { _hub = hub; + _blockChainStates = blockChainStates; _clientAddress = clientAddress; _context = context; TargetAddresses = ImmutableHashSet
.Empty; @@ -253,6 +257,7 @@ private Client( public static async Task CreateAsync( GrpcChannel channel, + IBlockChainStates blockChainStates, Address clientAddress, RpcContext context, ConcurrentDictionary sentryTraces) @@ -263,7 +268,7 @@ public static async Task CreateAsync( ); await hub.JoinAsync(clientAddress.ToHex()); - return new Client(hub, clientAddress, context, sentryTraces); + return new Client(hub, blockChainStates, clientAddress, context, sentryTraces); } public void Subscribe( @@ -302,10 +307,20 @@ await _hub.BroadcastRenderBlockAsync( { try { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); ActionBase? pa = ev.Action is RewardGold ? null : ev.Action; var extra = new Dictionary(); + IAccountState output = _blockChainStates.GetAccountState(ev.OutputState); + IAccountState input = _blockChainStates.GetAccountState(ev.PreviousState); + AccountDiff diff = AccountDiff.Create(input, output); + if (!TargetAddresses.Any(diff.StateDiffs.Keys.Append(ev.Signer).Contains)) + { + return; + } + var encodeElapsedMilliseconds = stopwatch.ElapsedMilliseconds; var eval = new NCActionEvaluation(pa, ev.Signer, ev.BlockIndex, ev.OutputState, ev.Exception, ev.PreviousState, ev.RandomSeed, extra); var encoded = MessagePackSerializer.Serialize(eval); @@ -325,6 +340,21 @@ await _hub.BroadcastRenderBlockAsync( ); await _hub.BroadcastRenderAsync(compressed); + stopwatch.Stop(); + + var broadcastElapsedMilliseconds = stopwatch.ElapsedMilliseconds - encodeElapsedMilliseconds; + Log + .ForContext("tag", "Metric") + .ForContext("subtag", "ActionEvaluationPublisherElapse") + .Information( + "[{ClientAddress}], #{BlockIndex}, {Action}," + + " {EncodeElapsedMilliseconds}, {BroadcastElapsedMilliseconds}, {TotalElapsedMilliseconds}", + _clientAddress, + ev.BlockIndex, + ev.Action.GetType(), + encodeElapsedMilliseconds, + broadcastElapsedMilliseconds, + encodeElapsedMilliseconds + broadcastElapsedMilliseconds); } catch (SerializationException se) { @@ -411,14 +441,14 @@ private bool ContainsAddressToBroadcast(ActionEvaluation ev) private bool ContainsAddressToBroadcastLocal(ActionEvaluation ev) { - var updatedAddresses = ev.OutputState.Delta.UpdatedAddresses; - return _context.AddressesToSubscribe.Any(updatedAddresses.Add(ev.Signer).Contains); + int t =ev.RandomSeed; + return true; } private bool ContainsAddressToBroadcastRemoteClient(ActionEvaluation ev) { - var updatedAddresses = ev.OutputState.Delta.UpdatedAddresses; - return TargetAddresses.Any(updatedAddresses.Add(ev.Signer).Contains); + int r = ev.RandomSeed; + return true; } } }