Exemple #1
0
        /// <inheritdoc />
        public override async Task <bool> OnExecute()
        {
            if (Runner.GlobalState.ReorgMode == true)
            {
                // null the store tip so the document count will be taken form disk
                Runner.GlobalState.StoreTip = null;

                // rewind the data in store
                Runner.GlobalState.StoreTip = await syncOperations.RewindToBestChain(syncConnection);

                Runner.GlobalState.PullingTip = null;
                Queue.Clear();
                Runner.GlobalState.ReorgMode = false;
                return(false);
            }

            if (Runner.GlobalState.IndexMode)
            {
                return(false);
            }

            if (!TryDequeue(out StorageBatch batch))
            {
                return(await Task.FromResult(false));
            }

            ValidateBatch(batch);

            watch.Restart();

            Runner.GlobalState.StoreTip = storageOperations.PushStorageBatch(batch);

            watch.Stop();

            if (Runner.GlobalState.StoreTip == null)
            {
                throw new ApplicationException("Store tip was not persisted");
            }

            long   totalBlocks     = batch.BlockTable.Count;     // insertStats.Sum((tuple => tuple.count));
            double totalSeconds    = watch.Elapsed.TotalSeconds; // insertStats.Sum((tuple => tuple.seconds));
            double blocksPerSecond = totalBlocks / totalSeconds;
            double secondsPerBlock = totalSeconds / totalBlocks;

            log.LogInformation($"Store - blocks={batch.BlockTable.Count}, outputs={batch.OutputTable.Count}, inputs={batch.InputTable.Count}, trx={batch.TransactionBlockTable.Count}, total Size = {((decimal)batch.TotalSize / 1000000):0.00}mb, tip={Runner.GlobalState.StoreTip.BlockIndex}, Seconds = {watch.Elapsed.TotalSeconds}, inserts = {blocksPerSecond:0.00}b/s ({secondsPerBlock:0.00}s/b)");

            foreach (BlockTable mapBlocksValue in batch.BlockTable.Values)
            {
                syncConnection.RecentItems.Add((DateTime.UtcNow, TimeSpan.FromSeconds(blocksPerSecond), mapBlocksValue.BlockSize));
            }

            var notifications = new AddressNotifications {
                Addresses = new List <string>()
            };                                                                           // count.Items.Where(ad => ad.Addresses != null).SelectMany(s => s.Addresses).Distinct().ToList() };

            Runner.Get <Notifier>().Enqueue(notifications);

            return(await Task.FromResult(true));
        }
Exemple #2
0
        public override async Task OnExecute()
        {
            IBlockchainClient client = clientFactory.Create(connection);

            List <string> allIndexes = mongoData.GetBlockIndexIndexes();

            if (allIndexes.Count == BlockIndexer.ExpectedNumberOfIndexes)
            {
                Runner.GlobalState.IndexModeCompleted = true;
            }

            Runner.GlobalState.PullingTip = null;
            Runner.GlobalState.StoreTip   = null;

            Runner.GlobalState.StoreTip = await syncOperations.RewindToLastCompletedBlockAsync();

            if (Runner.GlobalState.StoreTip == null)
            {
                // No blocks in store start from zero
                // push the genesis block to store
                int    start       = 0;
                string genesisHash = await client.GetblockHashAsync(start);


                log.LogInformation($"Processing genesis hash = {genesisHash}");

                BlockInfo genesisBlock = await client.GetBlockAsync(genesisHash);

                SyncBlockTransactionsOperation block = syncOperations.FetchFullBlock(connection, genesisBlock);

                StorageBatch genesisBatch = new StorageBatch();
                storageOperations.AddToStorageBatch(genesisBatch, block);
                Runner.GlobalState.StoreTip = storageOperations.PushStorageBatch(genesisBatch);
            }

            BlockInfo fetchedBlock = await client.GetBlockAsync(Runner.GlobalState.StoreTip.BlockHash);

            if (fetchedBlock == null)
            {
                // check if the fullnode is ahead of the indexer height
                int fullnodeTipHeight = client.GetBlockCount();
                if (fullnodeTipHeight < Runner.GlobalState.StoreTip.BlockIndex)
                {
                    throw new ApplicationException($"Full node at height {fullnodeTipHeight} which is behind the Indexer at height {Runner.GlobalState.StoreTip.BlockIndex}");
                }

                // reorg happend while indexer was offline rewind the indexer database
                Runner.GlobalState.PullingTip = null;
                Runner.GlobalState.StoreTip   = null;

                Runner.GlobalState.StoreTip = await syncOperations.RewindToBestChain(connection);
            }

            // update the chains tip
            Runner.GlobalState.ChainTipHeight = syncOperations.GetBlockCount(client);
        }