internal List <PendingBlock> GetBlocksToExecute() { // Calculate the next batch to execute var ordered = PendingBlocks.Where(p => p.IsSynced).OrderBy(p => p.Block.Header.Index).ToList(); if (ordered.Count <= 0) { return(new List <PendingBlock>()); } var pending = new List <PendingBlock>(); var currentIndex = (int)ordered[0].Block.Header.Index; if (ShouldDoInitialSync && currentIndex > CurrentExecHeight) { return(null); } for (var i = 0; i < ordered.Count; i++) { pending.Add(ordered[i]); if (i + 1 >= ordered.Count || (int)ordered[i + 1].Block.Header.Index > currentIndex + 1) { break; } currentIndex = (int)ordered[i + 1].Block.Header.Index; } return(pending); }
public BranchedChain(PendingBlock first) { PendingBlocks.Add(first); PendingBlocks.SortByBlockIndex(); EndHeight = PendingBlocks.Last().Block.Header.Index; }
private void RequestMissingTxs() { var listOfMissingTxToRequest = new List <KeyValuePair <byte[], IPeer> >(); foreach (var pdBlock in PendingBlocks.OrderBy(x => x.Block.Header.Index)) { if (!pdBlock.IsSynced) { _logger?.Debug($"{pdBlock.MissingTxs.Count} missing txn for block {pdBlock.Block.Header.Index}"); foreach (var tx in pdBlock.MissingTxs.Where(m => !m.IsRequestInProgress)) { if (listOfMissingTxToRequest.Count >= MaxOngoingTxRequests) { break; } listOfMissingTxToRequest.Add(new KeyValuePair <byte[], IPeer>(tx.Hash, pdBlock.Peer)); tx.IsRequestInProgress = true; } break; } } if (listOfMissingTxToRequest.Any()) { _networkManager.QueueTransactionRequest(listOfMissingTxToRequest.Select(kvp => kvp.Key).ToList(), listOfMissingTxToRequest.First().Value); _logger?.Debug($"Requested the following {listOfMissingTxToRequest.Count} transactions [" + string.Join(", ", listOfMissingTxToRequest.Select(kvp => kvp.Key.ToHex())) + "]"); } }
public BranchedChain(IEnumerable <PendingBlock> list, PendingBlock last) { foreach (var pendingBlock in list) { PendingBlocks.Add(pendingBlock); } PendingBlocks.Add(last); PendingBlocks.SortByBlockIndex(); EndHeight = PendingBlocks.Last().Block.Header.Index; }
public BranchedChain(PendingBlock first, IReadOnlyCollection <PendingBlock> list) { PendingBlocks.Add(first); foreach (var pendingBlock in list) { PendingBlocks.Add(pendingBlock); } PendingBlocks.SortByBlockIndex(); EndHeight = PendingBlocks.Last().Block.Header.Index; }
public BranchedChain(IEnumerable <PendingBlock> list1, IReadOnlyCollection <PendingBlock> list2) { foreach (var pendingBlock in list1) { PendingBlocks.Add(pendingBlock); } foreach (var pendingBlock in list2) { PendingBlocks.Add(pendingBlock); } PendingBlocks.SortByBlockIndex(); EndHeight = PendingBlocks.Last().Block.Header.Index; }
public PendingBlock GetBlock(byte[] hash) { return(PendingBlocks?.FirstOrDefault(p => p.BlockHash.BytesEqual(hash))); }
private void DoSync() { // Main work loop. while (true) { Job job = null; try { job = _jobQueue.Take(); } catch (Exception e) { _logger?.Error("Error while dequeuing " + job?.Block.GetHash().DumpHex()); continue; } // The next block of code will process the Job (Transactions to process or a block) // 1. Take job // 2. Exec // 3. Request try { if (job.Transactions != null) { // Some transactions were queued for processing SetTransactions(job.Transactions); } else { // A block was queued for processing var succeed = AddBlockToSync(job.Block, job.Peer, job.MsgType).Result; /* print candidates */ if (!succeed) { _logger?.Warn("Could not add block to sync"); } } if (PendingBlocks == null || PendingBlocks.Count <= 0) { _logger.Trace("No pending blocks"); continue; } // Log sync info var syncedCount = PendingBlocks.Count(pb => pb.IsSynced); _logger?.Trace( $"There's {PendingBlocks.Count} pending blocks, with synced : {syncedCount}, non-synced : {PendingBlocks.Count - syncedCount}"); // Get the blocks that are fully synced var pendingBlocks = GetBlocksToExecute(); if (pendingBlocks != null && pendingBlocks.Any()) { var str2 = pendingBlocks.Select(bb => bb.ToString()).Aggregate((i, jf) => i + " || " + jf); _logger?.Trace("Chosen for execution: " + str2); if (string.IsNullOrEmpty(str2)) { _logger?.Trace("Nobody chosen for execution."); } if (pendingBlocks != null && pendingBlocks.Count > 0) { // exec var executedBlocks = TryExecuteBlocks(pendingBlocks).Result; _logger?.Trace("Executed the blocks with the following index(es) : " + GetPendingBlockListLog(executedBlocks)); } } // After execution request the following batch of transactions RequestMissingTxs(); if (IsInitialSyncInProgress) { RequestNextBlocks(); } } catch (Exception e) { _logger?.Error(e, "Error while dequeuing and processing job."); } } }
public List <PendingBlock> GetPendingBlocks() { return(PendingBlocks.OrderBy(pb => pb.Block.Header.Index).ToList()); }