コード例 #1
0
        public Task Save(ConcurrentChain chain)
        {
            Guard.NotNull(chain, nameof(chain));

            return(this._Session.Do(() =>
            {
                var fork = this._Locator == null ? null : chain.FindFork(this._Locator);
                var tip = chain.Tip;
                var toSave = tip;

                List <ChainedBlock> blocks = new List <ChainedBlock>();
                while (toSave != fork)
                {
                    blocks.Add(toSave);
                    toSave = toSave.Previous;
                }

                //DBreeze faster on ordered insert
                var orderedChainedBlocks = blocks.OrderBy(b => b.Height);
                foreach (var block in orderedChainedBlocks)
                {
                    this._Session.Transaction.Insert <int, BlockHeader>("Chain", block.Height, block.Header);
                }
                this._Locator = tip.GetLocator();
                this._Session.Transaction.Commit();
            }));
        }
コード例 #2
0
        /// <inheritdoc />
        public Task SaveAsync(ConcurrentChain chain)
        {
            Guard.NotNull(chain, nameof(chain));

            Task task = Task.Run(() =>
            {
                using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
                {
                    ChainedHeader fork   = this.locator == null ? null : chain.FindFork(this.locator);
                    ChainedHeader tip    = chain.Tip;
                    ChainedHeader toSave = tip;

                    var headers = new List <ChainedHeader>();
                    while (toSave != fork)
                    {
                        headers.Add(toSave);
                        toSave = toSave.Previous;
                    }

                    // DBreeze is faster on ordered insert.
                    IOrderedEnumerable <ChainedHeader> orderedChainedHeaders = headers.OrderBy(b => b.Height);
                    foreach (ChainedHeader block in orderedChainedHeaders)
                    {
                        transaction.Insert("Chain", block.Height, block.Header);
                    }

                    this.locator = tip.GetLocator();
                    transaction.Commit();
                }
            });

            return(task);
        }
コード例 #3
0
        void StartScan(object unused)
        {
            var node = AttachedNode;

            if (_RunningPing != null)
            {
                _PlannedScan = true;
                return;
            }
            if (!IsScanning(node))
            {
                if (Monitor.TryEnter(cs))
                {
                    try
                    {
                        if (!IsScanning(node))
                        {
                            GetDataPayload payload = new GetDataPayload();
                            var            fork    = _Chain.FindFork(_CurrentProgress);
                            foreach (var block in _Chain
                                     .EnumerateAfter(fork)
                                     .Where(b => b.Header.BlockTime + TimeSpan.FromHours(5.0) > _SkipBefore)                            //Take 5 more hours, block time might not be right
                                     .Partition(10000)
                                     .FirstOrDefault() ?? new List <ChainedBlock>())
                            {
                                if (block.HashBlock != _LastSeen)
                                {
                                    payload.Inventory.Add(new InventoryVector(InventoryType.MSG_FILTERED_BLOCK, block.HashBlock));
                                    _InFlight.TryAdd(block.HashBlock, block.HashBlock);
                                }
                            }
                            if (payload.Inventory.Count > 0)
                            {
                                node.SendMessageAsync(payload);
                            }
                        }
                    }
                    finally
                    {
                        Monitor.Exit(cs);
                    }
                }
            }
        }
コード例 #4
0
        public IEnumerable <IBlockInfo> GetBlocks()
        {
            var fork    = _chain.FindFork(LastProcessed.GetLocator());
            var headers = _chain
                          .EnumerateAfter(fork).Where(h => h.Height <= ToHeight)
                          .ToList();

            var first = headers.FirstOrDefault();

            if (first == null)
            {
                yield break;
            }

            var height = first.Height;

            if (first.Height == 1)
            {
                var headersWithGenesis = new List <ChainedBlock> {
                    fork
                };
                headers = headersWithGenesis.Concat(headers).ToList();
                height  = 0;
            }

            foreach (var block in _nodeBlocks.GetBlocks(headers.Select(_ => _.HashBlock), CancellationToken))
            {
                var header = _chain.GetBlock(height);

                if (block == null)
                {
                    var storeTip = _nodeBlocks.GetStoreTip();
                    if (storeTip != null)
                    {
                        // Store is caught up with Chain but the block is missing from the store.
                        if (header.Header.BlockTime <= storeTip.Header.BlockTime)
                        {
                            throw new InvalidOperationException($"Chained block not found in store (height = { height }). Re-create the block store.");
                        }
                    }

                    // Allow Store to catch up with Chain.
                    break;
                }

                LastProcessed = header;
                yield return(new BlockInfoModel()
                {
                    Block = block,
                    Hash = header.HashBlock,
                    Height = header.Height
                });

                height++;
            }
        }
コード例 #5
0
        /// <inheritdoc />
        public Task SaveAsync(ConcurrentChain chain)
        {
            Guard.NotNull(chain, nameof(chain));

            Task task = Task.Run(() =>
            {
                using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
                {
                    ChainedHeader fork   = this.locator == null ? null : chain.FindFork(this.locator);
                    ChainedHeader tip    = chain.Tip;
                    ChainedHeader toSave = tip;

                    var headers = new List <ChainedHeader>();
                    while (toSave != fork)
                    {
                        headers.Add(toSave);
                        toSave = toSave.Previous;
                    }

                    // DBreeze is faster on ordered insert.
                    IOrderedEnumerable <ChainedHeader> orderedChainedHeaders = headers.OrderBy(b => b.Height);
                    foreach (ChainedHeader block in orderedChainedHeaders)
                    {
                        BlockHeader header = block.Header;
                        if (header is ProvenBlockHeader)
                        {
                            // copy the header parameters, untill we dont make PH a normal header we store it in its own repo.
                            BlockHeader newHeader    = chain.Network.Consensus.ConsensusFactory.CreateBlockHeader();
                            newHeader.Bits           = header.Bits;
                            newHeader.Time           = header.Time;
                            newHeader.Nonce          = header.Nonce;
                            newHeader.Version        = header.Version;
                            newHeader.HashMerkleRoot = header.HashMerkleRoot;
                            newHeader.HashPrevBlock  = header.HashPrevBlock;

                            header = newHeader;
                        }

                        transaction.Insert("Chain", block.Height, this.dBreezeSerializer.Serialize(header));
                    }

                    this.locator = tip.GetLocator();
                    transaction.Commit();
                }
            });

            return(task);
        }
コード例 #6
0
        private void AssertFork(ConcurrentChain chain, ConcurrentChain chain2, ChainedBlock expectedFork)
        {
            var fork = chain.FindFork(chain2);

            Assert.Equal(expectedFork, fork);
            fork = chain.Tip.FindFork(chain2.Tip);
            Assert.Equal(expectedFork, fork);

            var temp = chain;

            chain  = chain2;
            chain2 = temp;

            fork = chain.FindFork(chain2);
            Assert.Equal(expectedFork, fork);
            fork = chain.Tip.FindFork(chain2.Tip);
            Assert.Equal(expectedFork, fork);
        }
コード例 #7
0
        public async Task Initialize(CancellationToken cancellationToken)
        {
            foreach (var type in Enum.GetValues(typeof(IndexType)).OfType <IndexType>())
            {
                var tip = await _checkpointStore.GetCheckpointAsync(type).ConfigureAwait(false);

                _indexers.Add(type, new IndexerTarget
                {
                    Type       = type,
                    Checkpoint = tip,
                    Tip        = _chain.FindFork(tip.BlockLocator)
                });
            }

            Indexers = new ReadOnlyCollection <IIndexerTarget>(_indexers.Values.ToList());

            var minHeight = _indexers.Values.Min(i => i.Tip.Height);

            Tip = _settings.IgnoreCheckpoints ? _chain.GetBlock(_settings.From) : _chain.GetBlock(minHeight);
        }
コード例 #8
0
        public Task Save(ConcurrentChain chain)
        {
            Guard.NotNull(chain, nameof(chain));

            return(_Session.Do(() =>
            {
                var fork = _Locator == null ? null : chain.FindFork(_Locator);
                var tip = chain.Tip;
                var toSave = tip;
                List <ChainedBlock> blocks = new List <ChainedBlock>();
                while (toSave != fork)
                {
                    //DBreeze faster on ordered insert
                    blocks.Insert(0, toSave);
                    toSave = toSave.Previous;
                }
                foreach (var block in blocks)
                {
                    _Session.Transaction.Insert <int, BlockHeader>("Chain", block.Height, block.Header);
                }
                _Locator = tip.GetLocator();
                _Session.Transaction.Commit();
            }));
        }