Пример #1
0
        /// <inheritdoc />
        public Task SaveAsync(ChainIndexer chainIndexer)
        {
            Guard.NotNull(chainIndexer, nameof(chainIndexer));

            Task task = Task.Run(() =>
            {
                using (var batch = new WriteBatch())
                {
                    ChainedHeader fork   = this.locator == null ? null : chainIndexer.FindFork(this.locator);
                    ChainedHeader tip    = chainIndexer.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)
                    {
                        batch.Put(BitConverter.GetBytes(block.Height), this.dataStoreSerializer.Serialize(block.Header));
                    }

                    this.locator = tip.GetLocator();
                    this.leveldb.Write(batch);
                }
            });

            return(task);
        }
Пример #2
0
        /// <inheritdoc />
        public Task SaveAsync(ChainIndexer chainIndexer)
        {
            Guard.NotNull(chainIndexer, nameof(chainIndexer));

            Task task = Task.Run(() =>
            {
                ChainedHeader fork   = this.locator == null ? null : chainIndexer.FindFork(this.locator);
                ChainedHeader tip    = chainIndexer.Tip;
                ChainedHeader toSave = tip;

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

                var items = headers.OrderBy(b => b.Height).Select(h => new ChainDataItem
                {
                    Height = h.Height,
                    Data   = new ChainData {
                        Hash = h.HashBlock, Work = h.ChainWorkBytes
                    }
                });

                this.chainStore.PutChainData(items);

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

            return(task);
        }
Пример #3
0
        /// <summary>
        /// Returns the first common chained block header between two chains.
        /// </summary>
        /// <param name="chainSrc">The source chain.</param>
        /// <param name="otherChain">The other chain.</param>
        /// <returns>First common chained block header or <c>null</c>.</returns>
        private ChainedHeader FindFork(ChainIndexer chainSrc, ChainIndexer otherChain)
        {
            if (otherChain == null)
            {
                throw new ArgumentNullException("otherChain");
            }

            return(chainSrc.FindFork(otherChain.Tip.EnumerateToGenesis().Select(o => o.HashBlock)));
        }
Пример #4
0
        /// <inheritdoc />
        public Task SaveAsync(ChainIndexer chainIndexer)
        {
            Guard.NotNull(chainIndexer, nameof(chainIndexer));

            Task task = Task.Run(() =>
            {
                using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
                {
                    ChainedHeader fork   = this.locator == null ? null : chainIndexer.FindFork(this.locator);
                    ChainedHeader tip    = chainIndexer.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    = chainIndexer.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);
        }