public ChainedBlock GetChainedBlock(ChainBase chain) { ChainedBlock chainedBlock; if (Special != null && Special.Value == SpecialFeature.Last) { chainedBlock = chain.Tip; } else if (Height != -1) { var h = chain.GetBlock(Height); if (h == null) { return(null); } chainedBlock = h; } else { chainedBlock = chain.GetBlock(BlockId); } if (chainedBlock != null) { var height = chainedBlock.Height + Offset; height = Math.Max(0, height); chainedBlock = chain.GetBlock(height); } return(chainedBlock); }
public BlockFetcher(Checkpoint checkpoint, IBlocksRepository blocksRepository, ChainBase chain, ChainedHeader lastProcessed, ILoggerFactory loggerFactory) { this.loggerFactory = loggerFactory; this.logger = this.loggerFactory.CreateLogger(GetType().FullName); if (blocksRepository == null) { throw new ArgumentNullException("blocksRepository"); } if (chain == null) { throw new ArgumentNullException("blockHeaders"); } if (checkpoint == null) { throw new ArgumentNullException("checkpoint"); } _BlockHeaders = chain; _BlocksRepository = blocksRepository; _Checkpoint = checkpoint; _LastProcessed = lastProcessed; InitDefault(); }
public void IndexOrderedBalances(ChainBase chain) { IndexBalances(chain, "balances", (txid, tx, blockid, header, height) => { return(OrderedBalanceChange.ExtractScriptBalances(txid, tx, blockid, header, height)); }); }
private void EnqueueJobs(NodeBlocksRepository repo, ChainBase chain, CloudBlockBlob blobLock, string lease) { int cumul = 0; ChainedBlock from = chain.Genesis; int blockCount = 0; foreach (var block in repo.GetBlocks(new[] { chain.Genesis }.Concat(chain.EnumerateAfter(chain.Genesis)).Where(c => c.Height % BlockGranularity == 0).Select(c => c.HashBlock), default(CancellationToken))) { cumul += block.Transactions.Count * BlockGranularity; blockCount += BlockGranularity; if (cumul > TransactionsPerWork) { var nextFrom = chain.GetBlock(chain.GetBlock(block.GetHash()).Height + BlockGranularity); if (nextFrom == null) { break; } EnqueueRange(chain, from, blockCount); from = nextFrom; blockCount = 0; cumul = 0; } } blockCount = (chain.Tip.Height - from.Height) + 1; EnqueueRange(chain, from, blockCount); var bytes = chain.Tip.GetLocator().ToBytes(); blobLock.UploadText(Encoders.Hex.EncodeData(bytes), null, new AccessCondition() { LeaseId = lease }); }
public BalanceSheet(IEnumerable<OrderedBalanceChange> changes, ChainBase chain) { if (chain == null) throw new ArgumentNullException("chain"); _Chain = chain; var all = changes .Where(c => c.SpentCoins != null) //Remove line whose previous coins have not been loadedcould not be deduced .Where(c => c.MempoolEntry || chain.GetBlock(c.BlockId) != null) //Take only mempool entry, or confirmed one .Where(c => !(c.IsCoinbase && c.MempoolEntry)) //There is no such thing as a Coinbase unconfirmed, by definition a coinbase appear in a block .ToList(); var confirmed = all.Where(o => o.BlockId != null).ToDictionary(o => o.TransactionId); Dictionary<uint256, OrderedBalanceChange> unconfirmed = new Dictionary<uint256, OrderedBalanceChange>(); foreach(var item in all.Where(o => o.MempoolEntry && !confirmed.ContainsKey(o.TransactionId))) { unconfirmed.AddOrReplace(item.TransactionId, item); } _Prunable = all.Where(o => o.BlockId == null && confirmed.ContainsKey(o.TransactionId)).ToList(); _All = all.Where(o => (unconfirmed.ContainsKey(o.TransactionId) || confirmed.ContainsKey(o.TransactionId)) && !(o.BlockId == null && confirmed.ContainsKey(o.TransactionId)) ).ToList(); _Confirmed = _All.Where(o => o.BlockId != null && confirmed.ContainsKey(o.TransactionId)).ToList(); _Unconfirmed = _All.Where(o => o.BlockId == null && unconfirmed.ContainsKey(o.TransactionId)).ToList(); }
public long IndexBlocks(ChainBase chain = null) { long blkCount = 0; SetThrottling(); BlockingCollection <Block> blocks = new BlockingCollection <Block>(20); var tasks = CreateTaskPool(blocks, Index, 15); using (IndexerTrace.NewCorrelation("Import blocks to azure started").Open()) { Configuration.GetBlocksContainer().CreateIfNotExists(); using (var storedBlocks = Enumerate("blocks", chain)) { foreach (var block in storedBlocks) { blkCount++; blocks.Add(block.Block); if (storedBlocks.NeedSave) { tasks.Stop(); storedBlocks.SaveCheckpoint(); tasks.Start(); } } tasks.Stop(); storedBlocks.SaveCheckpoint(); } } return(blkCount); }
public void SynchronizeChain(ChainBase chain) { Dictionary <uint256, BlockHeader> headers = new Dictionary <uint256, BlockHeader>(); HashSet <uint256> inChain = new HashSet <uint256>(); inChain.Add(chain.GetBlock(0).HashBlock); foreach (var header in Enumerate(true).Select(b => b.Item.Header)) { var hash = header.GetHash(); headers.Add(hash, header); } List <uint256> toRemove = new List <uint256>(); while (headers.Count != 0) { foreach (var header in headers) { if (inChain.Contains(header.Value.HashPrevBlock)) { toRemove.Add(header.Key); chain.SetTip(header.Value); inChain.Add(header.Key); } } foreach (var item in toRemove) { headers.Remove(item); } if (toRemove.Count == 0) { break; } toRemove.Clear(); } }
public BalanceSheet(IEnumerable <OrderedBalanceChange> changes, ChainBase chain, bool colored) { if (chain == null) { throw new ArgumentNullException("chain"); } _Chain = chain; var all = changes .Where(c => c.SpentCoins != null) //Remove line whose previous coins have not been loaded .Where(c => !colored || c.ColoredBalanceChangeEntry != null) //Remove live whose color could not be deduced .Where(c => c.MempoolEntry || chain.GetBlock(c.BlockId) != null) //Take only mempool entry, or confirmed one .Where(c => !(c.IsCoinbase && c.MempoolEntry)) //There is no such thing as a Coinbase unconfirmed, by definition a coinbase appear in a block .ToList(); var confirmed = all.Where(o => o.BlockId != null).ToDictionary(o => o.TransactionId); var unconfirmed = all.Where(o => o.MempoolEntry && !confirmed.ContainsKey(o.TransactionId)).ToDictionary(o => o.TransactionId); _Prunable = all.Where(o => o.BlockId == null && confirmed.ContainsKey(o.TransactionId)).ToList(); _All = all.Where(o => (unconfirmed.ContainsKey(o.TransactionId) || confirmed.ContainsKey(o.TransactionId)) && !(o.BlockId == null && confirmed.ContainsKey(o.TransactionId)) ).ToList(); _Confirmed = _All.Where(o => o.BlockId != null && confirmed.ContainsKey(o.TransactionId)).ToList(); _Unconfirmed = _All.Where(o => o.BlockId == null && unconfirmed.ContainsKey(o.TransactionId)).ToList(); }
public static void UpdateChain(this IEnumerable <ChainBlockHeader> entries, ChainBase chain) { Stack <ChainBlockHeader> toApply = new Stack <ChainBlockHeader>(); foreach (var entry in entries) { var prev = chain.GetBlock(entry.Header.HashPrevBlock); if (prev == null) { toApply.Push(entry); } else { toApply.Push(entry); break; } } while (toApply.Count > 0) { var newTip = toApply.Pop(); var chained = new ChainedBlock(newTip.Header, newTip.BlockId, chain.GetBlock(newTip.Header.HashPrevBlock)); chain.SetTip(chained); } }
internal void Index(ChainBase chain, int startHeight, CancellationToken cancellationToken = default(CancellationToken)) { List <ChainPartEntry> entries = new List <ChainPartEntry>(((chain.Height - startHeight) / BlockHeaderPerRow) + 5); startHeight = startHeight - (startHeight % BlockHeaderPerRow); ChainPartEntry chainPart = null; for (int i = startHeight; i <= chain.Tip.Height; i++) { if (chainPart == null) { chainPart = new ChainPartEntry() { ChainOffset = i } } ; var block = chain.GetBlock(i); chainPart.BlockHeaders.Add(block.Header); if (chainPart.BlockHeaders.Count == BlockHeaderPerRow) { entries.Add(chainPart); chainPart = null; } } if (chainPart != null) { entries.Add(chainPart); } this.Index(entries, cancellationToken); }
private void EnqueueRange(ChainBase chain, ChainedBlock startCumul, int blockCount) { ListenerTrace.Info("Enqueing from " + startCumul.Height + " " + blockCount + " blocks"); if (blockCount == 0) { return; } var tasks = _IndexTasks .Where(t => chain.FindFork(t.Value.Item1.BlockLocator).Height <= startCumul.Height + blockCount) .Select(t => new BlockRange() { From = startCumul.Height, Count = blockCount, Target = t.Key }) .Select(t => _Conf.Topics.InitialIndexing.AddAsync(t)) .ToArray(); try { Task.WaitAll(tasks); } catch (AggregateException aex) { ExceptionDispatchInfo.Capture(aex.InnerException).Throw(); throw; } }
public WalletTransaction ToWalletTransaction(ChainBase chain, string wallet) { var chainHeight = chain.Height; var tx = new WalletTransaction() { Proof = Proof, Transaction = Transaction, UnconfirmedSeen = UnconfirmedSeen, AddedDate = AddedDate }; tx.ReceivedCoins = GetCoins(ReceivedCoins, _TrackedScripts, wallet); tx.SpentCoins = GetCoins(SpentCoins, _TrackedScripts, wallet); if (BlockId != null) { var header = chain.GetBlock(BlockId); if (header != null) { tx.BlockInformation = new BlockInformation() { Confirmations = chainHeight - header.Height + 1, Height = header.Height, Header = header.Header }; } } return(tx); }
/// <summary> /// Synchronize a given Chain to the tip of the given node if its height is higher. (Thread safe). /// </summary> /// <param name="peer">Node to synchronize the chain for.</param> /// <param name="chain">The chain to synchronize.</param> /// <param name="hashStop">The location until which it synchronize.</param> /// <param name="cancellationToken"></param> /// <returns></returns> private IEnumerable <ChainedHeader> SynchronizeChain(INetworkPeer peer, ChainBase chain, uint256 hashStop = null, CancellationToken cancellationToken = default(CancellationToken)) { ChainedHeader oldTip = chain.Tip; List <ChainedHeader> headers = this.GetHeadersFromFork(peer, oldTip, hashStop, cancellationToken).ToList(); if (headers.Count == 0) { return(new ChainedHeader[0]); } ChainedHeader newTip = headers[headers.Count - 1]; if (newTip.Height <= oldTip.Height) { throw new ProtocolException("No tip should have been recieved older than the local one"); } foreach (ChainedHeader header in headers) { if (!header.Validate(peer.Network)) { throw new ProtocolException("A header which does not pass proof of work verification has been received"); } } chain.SetTip(newTip); return(headers); }
/// <summary> /// Get a block fetcher of the specified chain from the specified checkpoint /// </summary> /// <param name="checkpoint">The checkpoint name to load from</param> /// <param name="chain">The chain to fetcher (default: the Node's main chain)</param> /// <returns>A BlockFetcher for enumerating blocks and saving progression</returns> public BlockFetcher GetBlockFetcher(string checkpointName, Node node, ChainBase chain = null) { if (checkpointName == null) { throw new ArgumentNullException("checkpointName"); } return(this.GetBlockFetcher(this.GetCheckpointRepository().GetCheckpoint(checkpointName), node, chain)); }
/// <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 ChainedBlock FindFork(ChainBase chainSrc, ChainBase otherChain) { if (otherChain == null) { throw new ArgumentNullException("otherChain"); } return(chainSrc.FindFork(otherChain.Tip.EnumerateToGenesis().Select(o => o.HashBlock))); }
public void SynchronizeChain(ChainBase chain) { Dictionary <uint256, Block> blocks = new Dictionary <uint256, Block>(); Dictionary <uint256, ChainedBlock> chainedBlocks = new Dictionary <uint256, ChainedBlock>(); HashSet <uint256> inChain = new HashSet <uint256>(); inChain.Add(chain.GetBlock(0).HashBlock); chainedBlocks.Add(chain.GetBlock(0).HashBlock, chain.GetBlock(0)); foreach (var block in this.Enumerate(false).Select(b => b.Item)) { var hash = block.GetHash(); blocks.Add(hash, block); } List <uint256> toRemove = new List <uint256>(); while (blocks.Count != 0) { // to optimize keep a track of the last block ChainedBlock last = chain.GetBlock(0); foreach (var block in blocks) { if (inChain.Contains(block.Value.Header.HashPrevBlock)) { toRemove.Add(block.Key); ChainedBlock chainedBlock; if (last.HashBlock == block.Value.Header.HashPrevBlock) { chainedBlock = last; } else { if (!chainedBlocks.TryGetValue(block.Value.Header.HashPrevBlock, out chainedBlock)) { break; } } var chainedHeader = new ChainedBlock(block.Value.Header, block.Value.GetHash(), chainedBlock); chain.SetTip(chainedHeader); chainedBlocks.TryAdd(chainedHeader.HashBlock, chainedHeader); inChain.Add(block.Key); last = chainedHeader; } } foreach (var item in toRemove) { blocks.Remove(item); } if (toRemove.Count == 0) { break; } toRemove.Clear(); } }
public IEnumerable <ChainedBlock> SynchronizeChain(ChainBase chain, uint256 hashStop = null, CancellationToken cancellationToken = default(CancellationToken)) { List <ChainedBlock> headers = new List <ChainedBlock>(); foreach (var header in GetHeadersFromFork(chain.Tip, hashStop, cancellationToken)) { chain.SetTip(header); headers.Add(header); } return(headers); }
public void IndexWalletBalances(ChainBase chain) { Configuration.GetWalletBalanceTable().CreateIfNotExists(); Configuration.GetWalletRulesTable().CreateIfNotExists(); var walletRules = Configuration.CreateIndexerClient().GetAllWalletRules(); IndexBalances(chain, "wallets", (txid, tx, blockid, header, height) => { return(OrderedBalanceChange.ExtractWalletBalances(txid, tx, blockid, header, height, walletRules)); }); }
public static bool TryGetHeight(this ChainBase chain, uint256 blockId, out int height) { height = 0; var block = chain.GetBlock(blockId); if (block == null) { return(false); } height = block.Height; return(true); }
public WalletTransactionsCollection GetWalletTransactions(ChainBase chain, string wallet = "default") { lock (cs) { return(new WalletTransactionsCollection(_Operations .Select(op => op.Value) .Where(op => op.CheckProof()) .Select(o => o.ToWalletTransaction(chain, _TrackedScripts, wallet)) .Where(o => o.ReceivedCoins.Length != 0 || o.SpentCoins.Length != 0) .ToArray())); } }
public WalletTransactionsCollection GetWalletTransactions(ChainBase chain, string wallet = "default") { lock (cs) { return(new WalletTransactionsCollection(_Operations .Select(op => op.Value) .Where(op => op.CheckProof()) .Where(op => op.ContainsWallet(wallet)) .Select(o => o.ToWalletTransaction(chain, wallet)) .ToArray())); } }
public IEnumerable <T> Query(ChainBase chain, BalanceQuery query = null) { if (query == null) { query = new BalanceQuery(); } var tableQuery = query.CreateTableQuery(Escape(Scope), ""); return(ExecuteBalanceQuery(Table, tableQuery, query.PageSizes) .Where(_ => chain.Contains(((ConfirmedBalanceLocator)UnEscapeLocator(_.RowKey)).BlockHash)) .Select(_ => Serializer.ToObject <T>(ParseData(_)))); }
public static void UpdateChain(this IEnumerable <ChainBlockHeader> entries, ChainBase chain) { var entriesAsync = new AsyncEnumerable <ChainBlockHeader>(async yield => { foreach (var entry in entries) { await yield.ReturnAsync(entry); } }); UpdateChain(entriesAsync, chain, default(CancellationToken)).GetAwaiter().GetResult(); }
static void Main(string[] args) { try { var options = new IndexerOptions(); if (args.Length == 0) { System.Console.WriteLine(options.GetUsage()); } if (Parser.Default.ParseArguments(args, options)) { System.Console.WriteLine("NBitcoin.Indexer " + typeof(AzureIndexer).Assembly.GetName().Version); var indexer = AzureIndexer.CreateIndexer(); indexer.CheckpointInterval = TimeSpan.Parse(options.CheckpointInterval); indexer.NoSave = options.NoSave; indexer.FromHeight = options.From; indexer.ToHeight = options.To; indexer.TaskCount = options.ThreadCount; ChainBase chain = null; if (options.IndexBlocks) { chain = chain ?? indexer.GetNodeChain(); indexer.IndexBlocks(chain); } if (options.IndexChain) { chain = chain ?? indexer.GetNodeChain(); indexer.IndexChain(chain); } if (options.IndexTransactions) { chain = chain ?? indexer.GetNodeChain(); indexer.IndexTransactions(chain); } if (options.IndexAddresses) { chain = chain ?? indexer.GetNodeChain(); indexer.IndexOrderedBalances(chain); } if (options.IndexWallets) { chain = chain ?? indexer.GetNodeChain(); indexer.IndexWalletBalances(chain); } } } catch (ConfigurationErrorsException ex) { System.Console.WriteLine("LocalSettings.config missing settings : " + ex.Message); } }
public void SynchronizeChain(ChainBase chain) { if (chain.Tip != null && chain.Genesis.HashBlock != Configuration.Network.GetGenesis().GetHash()) { throw new ArgumentException("Incompatible Network between the indexer and the chain", "chain"); } if (chain.Tip == null) { chain.SetTip(new ChainedBlock(Configuration.Network.GetGenesis().Header, 0)); } GetChainChangesUntilFork(chain.Tip, false) .UpdateChain(chain); }
public long IndexTransactions(ChainBase chain = null) { long txCount = 0; SetThrottling(); BlockingCollection <TransactionEntry.Entity[]> transactions = new BlockingCollection <TransactionEntry.Entity[]>(20); var tasks = CreateTaskPool(transactions, (txs) => Index(txs), 30); using (IndexerTrace.NewCorrelation("Import transactions to azure started").Open()) { Configuration.GetTransactionTable().CreateIfNotExists(); var buckets = new MultiValueDictionary <string, TransactionEntry.Entity>(); using (var storedBlocks = Enumerate("transactions", chain)) { foreach (var block in storedBlocks) { foreach (var transaction in block.Block.Transactions) { txCount++; var indexed = new TransactionEntry.Entity(null, transaction, block.BlockId); buckets.Add(indexed.PartitionKey, indexed); var collection = buckets[indexed.PartitionKey]; if (collection.Count == 100) { PushTransactions(buckets, collection, transactions); } if (storedBlocks.NeedSave) { foreach (var kv in buckets.AsLookup().ToArray()) { PushTransactions(buckets, kv, transactions); } tasks.Stop(); storedBlocks.SaveCheckpoint(); tasks.Start(); } } } foreach (var kv in buckets.AsLookup().ToArray()) { PushTransactions(buckets, kv, transactions); } tasks.Stop(); storedBlocks.SaveCheckpoint(); } } return(txCount); }
public void IndexChain(ChainBase chain, CancellationToken cancellationToken = default(CancellationToken)) { this.logger.LogTrace("()"); if (chain == null) { throw new ArgumentNullException("chain"); } this.SetThrottling(); using (IndexerTrace.NewCorrelation("Index main chain to azure started")) { this.Configuration.GetChainTable().CreateIfNotExistsAsync().GetAwaiter().GetResult(); IndexerTrace.InputChainTip(chain.Tip); var client = this.Configuration.CreateIndexerClient(); var changes = client.GetChainChangesUntilFork(chain.Tip, true, cancellationToken).ToList(); var height = 0; if (changes.Count != 0) { this.logger.LogTrace("Changes count: {0}", changes.Count); IndexerTrace.IndexedChainTip(changes[0].BlockId, changes[0].Height); if (changes[0].Height > chain.Tip.Height) { IndexerTrace.InputChainIsLate(); this.logger.LogTrace("(-):LATE"); return; } height = changes[changes.Count - 1].Height + 1; if (height > chain.Height) { IndexerTrace.IndexedChainIsUpToDate(chain.Tip); this.logger.LogTrace("(-):UP_TO_DATE"); return; } } else { this.logger.LogTrace("No work found"); IndexerTrace.NoForkFoundWithStored(); } IndexerTrace.IndexingChain(chain.GetBlock(height), chain.Tip); this.Index(chain, height, cancellationToken); } this.logger.LogTrace("(-)"); }
public void ComputeStakeModifier(ChainBase chainIndex, ChainedBlock pindex, BlockStake blockStake) { var pindexPrev = pindex.Previous; var blockStakePrev = pindexPrev == null ? null : this.stakeChain.Get(pindexPrev.HashBlock); // compute stake modifier var stakeContext = new StakeModifierContext(); this.ComputeNextStakeModifier(chainIndex, pindexPrev, stakeContext); blockStake.SetStakeModifier(stakeContext.StakeModifier, stakeContext.GeneratedStakeModifier); blockStake.StakeModifierV2 = this.ComputeStakeModifierV2( pindexPrev, blockStakePrev, blockStake.IsProofOfWork() ? pindex.HashBlock : blockStake.PrevoutStake.Hash); }
private ChainedBlock CreateBlock(DateTimeOffset now, int offset, ChainBase chain = null) { Block b = new Block(new BlockHeader() { BlockTime = now + TimeSpan.FromMinutes(offset) }); if(chain != null) { b.Header.HashPrevBlock = chain.Tip.HashBlock; return new ChainedBlock(b.Header, null, chain.Tip); } else return new ChainedBlock(b.Header, 0); }
public int IndexWalletBalances(ChainBase chain) { using (IndexerTrace.NewCorrelation("Import wallet balances to azure started")) { using (var node = this.Configuration.ConnectToNode(false)) { node.VersionHandshake(); var task = new IndexBalanceTask(this.Configuration, this.Configuration.CreateIndexerClient().GetAllWalletRules()); task.SaveProgression = !this.IgnoreCheckpoints; task.Index(this.GetBlockFetcher(this.GetCheckpointInternal(IndexerCheckpoints.Wallets), node, chain), this.TaskScheduler); return(task.IndexedEntities); } } }
public long IndexBlocks(ChainBase chain = null) { using (IndexerTrace.NewCorrelation("Import blocks to azure started")) { using (var node = this.Configuration.ConnectToNode(false)) { node.VersionHandshake(); var task = new IndexBlocksTask(this.Configuration); task.SaveProgression = !this.IgnoreCheckpoints; task.Index(this.GetBlockFetcher(this.GetCheckpointInternal(IndexerCheckpoints.Blocks), node, chain), this.TaskScheduler); return(task.IndexedBlocks); } } }
public int IndexOrderedBalances(ChainBase chain) { using (IndexerTrace.NewCorrelation("Import balances to azure started")) { using (var node = Configuration.ConnectToNode(false)) { node.VersionHandshake(); var task = new IndexBalanceTask(Configuration, null); task.SaveProgression = !IgnoreCheckpoints; task.Index(GetBlockFetcher(GetCheckpointInternal(IndexerCheckpoints.Balances), node, chain), TaskScheduler); return(task.IndexedEntities); } } }
public long IndexTransactions(ChainBase chain = null) { using(IndexerTrace.NewCorrelation("Import transactions to azure started").Open()) { using(var node = Configuration.ConnectToNode(false)) { node.VersionHandshake(); var task = new IndexTransactionsTask(Configuration); task.SaveProgression = !IgnoreCheckpoints; task.Index(GetBlockFetcher(GetCheckpointInternal(IndexerCheckpoints.Transactions), node, chain), TaskScheduler); return task.IndexedEntities; } } }
public static void UpdateChain(this IEnumerable<ChainBlockHeader> entries, ChainBase chain) { Stack<ChainBlockHeader> toApply = new Stack<ChainBlockHeader>(); foreach(var entry in entries) { var prev = chain.GetBlock(entry.Header.HashPrevBlock); if(prev == null) toApply.Push(entry); else { toApply.Push(entry); break; } } while(toApply.Count > 0) { var newTip = toApply.Pop(); var chained = new ChainedBlock(newTip.Header, newTip.BlockId, chain.GetBlock(newTip.Header.HashPrevBlock)); chain.SetTip(chained); } }
internal void Index(ChainBase chain, int startHeight) { List<ChainPartEntry> entries = new List<ChainPartEntry>(((chain.Height - startHeight) / BlockHeaderPerRow) + 5); startHeight = startHeight - (startHeight % BlockHeaderPerRow); ChainPartEntry chainPart = null; for(int i = startHeight; i <= chain.Tip.Height; i++) { if(chainPart == null) chainPart = new ChainPartEntry() { ChainOffset = i }; var block = chain.GetBlock(i); chainPart.BlockHeaders.Add(block.Header); if(chainPart.BlockHeaders.Count == BlockHeaderPerRow) { entries.Add(chainPart); chainPart = null; } } if(chainPart != null) entries.Add(chainPart); Index(entries); }
/// <summary> /// Get a block fetcher of the specified chain from the specified checkpoint /// </summary> /// <param name="checkpoint">The checkpoint to load from</param> /// <param name="chain">The chain to fetcher (default: the Node's main chain)</param> /// <returns>A BlockFetcher for enumerating blocks and saving progression</returns> public BlockFetcher GetBlockFetcher(Checkpoint checkpoint, Node node, ChainBase chain = null) { if(checkpoint == null) throw new ArgumentNullException("checkpoint"); if(node == null) throw new ArgumentNullException("node"); chain = chain ?? GetNodeChain(node); IndexerTrace.CheckpointLoaded(chain.FindFork(checkpoint.BlockLocator), checkpoint.CheckpointName); return new BlockFetcher(checkpoint, new NodeBlocksRepository(node), chain) { NeedSaveInterval = CheckpointInterval, FromHeight = FromHeight, ToHeight = ToHeight }; }
/// <summary> /// Get a block fetcher of the specified chain from the specified checkpoint /// </summary> /// <param name="checkpoint">The checkpoint name to load from</param> /// <param name="chain">The chain to fetcher (default: the Node's main chain)</param> /// <returns>A BlockFetcher for enumerating blocks and saving progression</returns> public BlockFetcher GetBlockFetcher(string checkpointName, Node node, ChainBase chain = null) { if(checkpointName == null) throw new ArgumentNullException("checkpointName"); return GetBlockFetcher(GetCheckpointRepository().GetCheckpoint(checkpointName), node, chain); }
public int IndexWalletBalances(ChainBase chain) { using(IndexerTrace.NewCorrelation("Import wallet balances to azure started").Open()) { using(var node = Configuration.ConnectToNode(false)) { node.VersionHandshake(); var task = new IndexBalanceTask(Configuration, Configuration.CreateIndexerClient().GetAllWalletRules()); task.SaveProgression = !IgnoreCheckpoints; task.Index(GetBlockFetcher(GetCheckpointInternal(IndexerCheckpoints.Wallets), node, chain), TaskScheduler); return task.IndexedEntities; } } }
public WalletTransaction ToWalletTransaction(ChainBase chain, ConcurrentDictionary<string, TrackedScript> trackedScripts, string wallet) { var chainHeight = chain.Height; var tx = new WalletTransaction() { Proof = Proof, Transaction = Transaction, UnconfirmedSeen = UnconfirmedSeen, AddedDate = AddedDate }; tx.ReceivedCoins = GetCoins(ReceivedCoins, trackedScripts, wallet); tx.SpentCoins = GetCoins(SpentCoins, trackedScripts, wallet); if(BlockId != null) { var header = chain.GetBlock(BlockId); if(header != null) { tx.BlockInformation = new BlockInformation() { Confirmations = chainHeight - header.Height + 1, Height = header.Height, Header = header.Header }; } } return tx; }
public void IndexChain(ChainBase chain) { if(chain == null) throw new ArgumentNullException("chain"); SetThrottling(); using(IndexerTrace.NewCorrelation("Index main chain to azure started").Open()) { Configuration.GetChainTable().CreateIfNotExists(); IndexerTrace.InputChainTip(chain.Tip); var client = Configuration.CreateIndexerClient(); var changes = client.GetChainChangesUntilFork(chain.Tip, true).ToList(); var height = 0; if(changes.Count != 0) { IndexerTrace.IndexedChainTip(changes[0].BlockId, changes[0].Height); if(changes[0].Height > chain.Tip.Height) { IndexerTrace.InputChainIsLate(); return; } height = changes[changes.Count - 1].Height + 1; if(height > chain.Height) { IndexerTrace.IndexedChainIsUpToDate(chain.Tip); return; } } else { IndexerTrace.NoForkFoundWithStored(); } IndexerTrace.IndexingChain(chain.GetBlock(height), chain.Tip); Index(chain, height); } }
public WalletTransactionsCollection GetWalletTransactions(ChainBase chain, string wallet = "default") { lock(cs) { return new WalletTransactionsCollection(_Operations .Select(op => op.Value) .Where(op => op.CheckProof()) .Where(op => op.ContainsWallet(wallet)) .Select(o => o.ToWalletTransaction(chain, wallet)) .ToArray()); } }
public WalletTransactionsCollection GetWalletTransactions(ChainBase chain, string wallet = "default") { lock(cs) { return new WalletTransactionsCollection(_Operations .Select(op => op.Value) .Where(op => op.CheckProof()) .Select(o => o.ToWalletTransaction(chain, _TrackedScripts, wallet)) .Where(o => o.ReceivedCoins.Length != 0 || o.SpentCoins.Length != 0) .ToArray()); } }