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(); })); }
/// <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); }
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); } } } }
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++; } }
/// <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); }
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); }
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); }
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(); })); }