示例#1
0
        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;
            }
        }
示例#3
0
        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();
            }
        }
示例#4
0
        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();
            }
        }