Пример #1
0
        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);
        }
Пример #2
0
        public BranchedChain(PendingBlock first)
        {
            PendingBlocks.Add(first);

            PendingBlocks.SortByBlockIndex();
            EndHeight = PendingBlocks.Last().Block.Header.Index;
        }
Пример #3
0
        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())) + "]");
            }
        }
Пример #4
0
        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;
        }
Пример #5
0
        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;
        }
Пример #6
0
        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;
        }
Пример #7
0
 public PendingBlock GetBlock(byte[] hash)
 {
     return(PendingBlocks?.FirstOrDefault(p => p.BlockHash.BytesEqual(hash)));
 }
Пример #8
0
        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.");
                }
            }
        }
Пример #9
0
 public List <PendingBlock> GetPendingBlocks()
 {
     return(PendingBlocks.OrderBy(pb => pb.Block.Header.Index).ToList());
 }