private async Task SaveMatches(Block block) { block.Header.PrecomputeHash(false, false); Download o; if (_InFlights.ContainsKey(block.GetHash())) { var currentLocation = Chain.GetLocator(block.GetHash()); if (currentLocation == null) { return; } CurrentLocation = currentLocation; if (_InFlights.TryRemove(block.GetHash(), out o)) { foreach (var tx in block.Transactions) { tx.PrecomputeHash(false, true); } var blockHash = block.GetHash(); DateTimeOffset now = DateTimeOffset.UtcNow; var matches = block.Transactions .Select(tx => Repository.GetMatches(tx, blockHash, now)) .ToArray(); await Task.WhenAll(matches); await SaveMatches(matches.SelectMany((Task <TrackedTransaction[]> m) => m.GetAwaiter().GetResult()).ToArray(), blockHash, now); //Save index progress everytimes if not synching, or once every 100 blocks otherwise if (!IsSynching() || blockHash.GetLow32() % 100 == 0) { await Repository.SetIndexProgress(currentLocation); } var slimBlockHeader = Chain.GetBlock(blockHash); if (slimBlockHeader != null) { var blockEvent = new Models.NewBlockEvent() { CryptoCode = _Repository.Network.CryptoCode, Hash = blockHash, Height = slimBlockHeader.Height, PreviousBlockHash = slimBlockHeader.Previous }; var saving = Repository.SaveEvent(blockEvent); _EventAggregator.Publish(blockEvent); await saving; } } if (_InFlights.Count == 0) { AskBlocks(); } } }
private async Task SaveMatches(Block block) { block.Header.PrecomputeHash(false, false); foreach (var tx in block.Transactions) { tx.PrecomputeHash(false, true); } var blockHash = block.GetHash(); var delay = TimeSpan.FromSeconds(1); retry: try { DateTimeOffset now = DateTimeOffset.UtcNow; var matches = (await Repository.GetMatches(block.Transactions, blockHash, now, true)) .ToArray(); await SaveMatches(matches, blockHash, now, true); var slimBlockHeader = Chain.GetBlock(blockHash); if (slimBlockHeader != null) { var blockEvent = new Models.NewBlockEvent() { CryptoCode = _Repository.Network.CryptoCode, Hash = blockHash, Height = slimBlockHeader.Height, PreviousBlockHash = slimBlockHeader.Previous }; await Repository.SaveEvent(blockEvent); _EventAggregator.Publish(blockEvent); _EventAggregator.Publish(new RawBlockEvent(block, this.Network), true); } } catch (ObjectDisposedException) { throw; } catch (Exception ex) { Logs.Explorer.LogWarning(ex, $"{Network.CryptoCode}: Error while saving block in database, retrying in {delay.TotalSeconds} seconds ({ex.Message})"); await Task.Delay(delay, _Cts.Token); delay = delay * 2; var maxDelay = TimeSpan.FromSeconds(60); if (delay > maxDelay) { delay = maxDelay; } goto retry; } }
private async Task SaveMatches(Block block) { block.Header.PrecomputeHash(false, false); foreach (var tx in block.Transactions) { tx.PrecomputeHash(false, true); } var blockHash = block.GetHash(); DateTimeOffset now = DateTimeOffset.UtcNow; var matches = block.Transactions .Select(tx => Repository.GetMatches(tx, blockHash, now)) .ToArray(); await Task.WhenAll(matches); await SaveMatches(matches.SelectMany((Task <TrackedTransaction[]> m) => m.GetAwaiter().GetResult()).ToArray(), blockHash, now); var slimBlockHeader = Chain.GetBlock(blockHash); if (slimBlockHeader != null) { var blockEvent = new Models.NewBlockEvent() { CryptoCode = _Repository.Network.CryptoCode, Hash = blockHash, Height = slimBlockHeader.Height, PreviousBlockHash = slimBlockHeader.Previous }; var saving = Repository.SaveEvent(blockEvent); _EventAggregator.Publish(blockEvent); await saving; } if (_InFlights.TryRemove(blockHash, out var unused) && _InFlights.IsEmpty) { var highestInFlight = _HighestInFlight; _HighestInFlight = null; if (highestInFlight != null) { CurrentLocation = highestInFlight; await Repository.SetIndexProgress(highestInFlight); } AskBlocks(); } }
private async Task SaveMatches(Block block) { block.Header.PrecomputeHash(false, false); foreach (var tx in block.Transactions) { tx.PrecomputeHash(false, true); } var blockHash = block.GetHash(); var delay = TimeSpan.FromSeconds(1); retry: try { DateTimeOffset now = DateTimeOffset.UtcNow; var matches = block.Transactions .Select(tx => Repository.GetMatches(tx, blockHash, now, true)) .ToArray(); await Task.WhenAll(matches); await SaveMatches(matches.SelectMany((Task <TrackedTransaction[]> m) => m.GetAwaiter().GetResult()).ToArray(), blockHash, now); var slimBlockHeader = Chain.GetBlock(blockHash); if (slimBlockHeader != null) { var blockEvent = new Models.NewBlockEvent() { CryptoCode = _Repository.Network.CryptoCode, Hash = blockHash, Height = slimBlockHeader.Height, PreviousBlockHash = slimBlockHeader.Previous }; var saving = Repository.SaveEvent(blockEvent); _EventAggregator.Publish(blockEvent); await saving; } } catch (Exception ex) { Logs.Explorer.LogWarning(ex, $"{Network.CryptoCode}: Error while saving block in database, retrying in {delay.TotalSeconds} seconds"); await Task.Delay(delay); delay = delay * 2; var maxDelay = TimeSpan.FromSeconds(60); if (delay > maxDelay) { delay = maxDelay; } goto retry; } if (_InFlights.TryRemove(blockHash, out var unused) && _InFlights.IsEmpty) { var highestInFlight = _HighestInFlight; _HighestInFlight = null; if (highestInFlight != null) { CurrentLocation = highestInFlight; await Repository.SetIndexProgress(highestInFlight); } AskBlocks(); } }