public async Task Start()
    {
        await _eth2BlockProducer.Start();

        if (_poSSwitcher.HasEverReachedTerminalBlock() == false && HasPreMergeProducer)
        {
            await _preMergeProducer !.Start();
        }
    }
Exemple #2
0
        public ulong?MaxSecondsIntervalForProcessingBlocksHint()
        {
            if (_poSSwitcher.HasEverReachedTerminalBlock())
            {
                return(12 + 3);
            }

            return(_healthHintService.MaxSecondsIntervalForProcessingBlocksHint());
        }
    public void Should_allocate_by_speed_post_merge()
    {
        ulong[]           totalDifficulties = { 1, 3, 2 };
        int[]             averageSpeed      = { 5, 8, 10 };
        PublicKey[]       publicKeys        = { TestItem.PublicKeyA, TestItem.PublicKeyB, TestItem.PublicKeyC };
        PeerInfo[]        peers             = new PeerInfo[3];
        INodeStatsManager _nodeStatsManager = Substitute.For <INodeStatsManager>();

        for (int i = 0; i < 3; i++)
        {
            ISyncPeer syncPeer = Substitute.For <ISyncPeer>();
            syncPeer.IsInitialized.Returns(true);
            Node node = new Node(publicKeys[i], "192.168.1.18", i);
            syncPeer.Node.Returns(node);
            syncPeer.TotalDifficulty.Returns(new UInt256(totalDifficulties[i]));
            peers[i] = new PeerInfo(syncPeer);
            peers[i].HeadNumber.Returns(1);
            INodeStats nodeStats = Substitute.For <INodeStats>();
            nodeStats.GetAverageTransferSpeed(Arg.Any <TransferSpeedType>()).Returns(averageSpeed[i]);
            _nodeStatsManager.GetOrAdd(peers[i].SyncPeer.Node).Returns(nodeStats);
        }
        IPoSSwitcher poSSwitcher = Substitute.For <IPoSSwitcher>();

        poSSwitcher.TerminalTotalDifficulty.Returns(new UInt256(1));
        poSSwitcher.HasEverReachedTerminalBlock().Returns(true);

        IBeaconPivot beaconPivot = Substitute.For <IBeaconPivot>();

        IPeerAllocationStrategy mergePeerAllocationStrategy =
            (new MergeBlocksSyncPeerAllocationStrategyFactory(poSSwitcher, beaconPivot, Substitute.For <ILogManager>())).Create(new BlocksRequest());
        IBlockTree _blockTree = Substitute.For <IBlockTree>();
        PeerInfo?  info       = mergePeerAllocationStrategy.Allocate(null, peers, _nodeStatsManager, _blockTree);

        Assert.AreEqual(info, peers[2]);    // peer with highest highest speed
    }
        public bool CanSeal(long blockNumber, Keccak parentHash)
        {
            if (_poSSwitcher.HasEverReachedTerminalBlock())
            {
                return(true);
            }

            return(_preMergeSealValidator.CanSeal(blockNumber, parentHash));
        }
Exemple #5
0
        public MergeFinalizationManager(IManualBlockFinalizationManager manualBlockFinalizationManager,
                                        IBlockFinalizationManager?blockFinalizationManager, IPoSSwitcher poSSwitcher)
        {
            _manualBlockFinalizationManager = manualBlockFinalizationManager;
            _auRaBlockFinalizationManager   = blockFinalizationManager as IAuRaBlockFinalizationManager;

            poSSwitcher.TerminalBlockReached += OnSwitchHappened;
            if (poSSwitcher.HasEverReachedTerminalBlock())
            {
                IsPostMerge = true;
            }

            _manualBlockFinalizationManager.BlocksFinalized += OnBlockFinalized;
            if (HasAuRaFinalizationManager)
            {
                _auRaBlockFinalizationManager !.BlocksFinalized += OnBlockFinalized;
            }
        }
        public override async Task <long> DownloadBlocks(PeerInfo?bestPeer, BlocksRequest blocksRequest,
                                                         CancellationToken cancellation)
        {
            if (_beaconPivot.BeaconPivotExists() == false && _poSSwitcher.HasEverReachedTerminalBlock() == false)
            {
                return(await base.DownloadBlocks(bestPeer, blocksRequest, cancellation));
            }

            if (bestPeer == null)
            {
                string message = $"Not expecting best peer to be null inside the {nameof(BlockDownloader)}";
                if (_logger.IsError)
                {
                    _logger.Error(message);
                }
                throw new ArgumentNullException(message);
            }

            DownloaderOptions options = blocksRequest.Options;
            bool downloadReceipts     = (options & DownloaderOptions.WithReceipts) == DownloaderOptions.WithReceipts;
            bool shouldProcess        = (options & DownloaderOptions.Process) == DownloaderOptions.Process;
            bool shouldMoveToMain     = (options & DownloaderOptions.MoveToMain) == DownloaderOptions.MoveToMain;

            int  blocksSynced  = 0;
            long currentNumber = _blockTree.BestKnownNumber;

            if (_logger.IsTrace)
            {
                _logger.Trace(
                    $"MergeBlockDownloader GetCurrentNumber: currentNumber {currentNumber}, beaconPivotExists: {_beaconPivot.BeaconPivotExists()}, BestSuggestedBody: {_blockTree.BestSuggestedBody?.Number}, BestKnownNumber: {_blockTree.BestKnownNumber}, BestPeer: {bestPeer}, BestKnownBeaconNumber {_blockTree.BestKnownBeaconNumber}");
            }

            bool HasMoreToSync(out BlockHeader[]?headers, out int headersToRequest)
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"Continue full sync with {bestPeer} (our best {_blockTree.BestKnownNumber})");
                }

                headersToRequest = Math.Min(_syncBatchSize.Current, bestPeer.MaxHeadersPerRequest());
                if (_logger.IsTrace)
                {
                    _logger.Trace(
                        $"Full sync request {currentNumber}+{headersToRequest} to peer {bestPeer} with {bestPeer.HeadNumber} blocks. Got {currentNumber} and asking for {headersToRequest} more.");
                }

                // Note: blocksRequest.NumberOfLatestBlocksToBeIgnored not accounted for
                headers = _chainLevelHelper.GetNextHeaders(headersToRequest, bestPeer.HeadNumber);
                if (headers == null || headers.Length <= 1)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace("Chain level helper got no headers suggestion");
                    }
                    return(false);
                }

                return(true);
            }

            while (HasMoreToSync(out BlockHeader[]? headers, out int headersToRequest))
            {
                if (cancellation.IsCancellationRequested)
                {
                    return(blocksSynced);                                      // check before every heavy operation
                }
                Block[]? blocks          = null;
                TxReceipt[]?[]? receipts = null;
                if (_logger.IsTrace)
                {
                    _logger.Trace(
                        $"Downloading blocks from peer. CurrentNumber: {currentNumber}, BeaconPivot: {_beaconPivot.PivotNumber}, BestPeer: {bestPeer}, HeaderToRequest: {headersToRequest}");
                }

                BlockDownloadContext context = new(_specProvider, bestPeer, headers !, downloadReceipts, _receiptsRecovery);

                if (cancellation.IsCancellationRequested)
                {
                    return(blocksSynced);                                      // check before every heavy operation
                }
                await RequestBodies(bestPeer, cancellation, context);

                if (downloadReceipts)
                {
                    if (cancellation.IsCancellationRequested)
                    {
                        return(blocksSynced); // check before every heavy operation
                    }
                    await RequestReceipts(bestPeer, cancellation, context);
                }

                _sinceLastTimeout++;
                if (_sinceLastTimeout > 2)
                {
                    _syncBatchSize.Expand();
                }

                blocks   = context.Blocks;
                receipts = context.ReceiptsForBlocks;

                if (!(blocks?.Length > 0))
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace("Break early due to no blocks.");
                    }
                    break;
                }

                for (int blockIndex = 0; blockIndex < blocks.Length; blockIndex++)
                {
                    if (cancellation.IsCancellationRequested)
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace("Peer sync cancelled");
                        }
                        break;
                    }

                    Block currentBlock = blocks[blockIndex];
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Received {currentBlock} from {bestPeer}");
                    }

                    if (currentBlock.IsBodyMissing)
                    {
                        throw new EthSyncException($"{bestPeer} didn't send body for block {currentBlock.ToString(Block.Format.Short)}.");
                    }

                    // can move this to block tree now?
                    if (!_blockValidator.ValidateSuggestedBlock(currentBlock))
                    {
                        throw new EthSyncException($"{bestPeer} sent an invalid block {currentBlock.ToString(Block.Format.Short)}.");
                    }

                    if (shouldProcess)
                    {
                        // covering edge case during fastSyncTransition when we're trying to SuggestBlock without the state
                        bool headIsGenesis = _blockTree.Head?.IsGenesis ?? false;
                        bool toBeProcessedIsNotBlockOne = currentBlock.Number > 1;
                        bool isFastSyncTransition       = headIsGenesis && toBeProcessedIsNotBlockOne;
                        if (isFastSyncTransition)
                        {
                            long bestFullState = _syncProgressResolver.FindBestFullState();
                            shouldProcess = currentBlock.Number > bestFullState && bestFullState != 0;
                            if (!shouldProcess)
                            {
                                if (_logger.IsInfo)
                                {
                                    _logger.Info($"Skipping processing during fastSyncTransition, currentBlock: {currentBlock}, bestFullState: {bestFullState}");
                                }
                                downloadReceipts = true;
                            }
                        }
                    }

                    if (downloadReceipts)
                    {
                        TxReceipt[]? contextReceiptsForBlock = receipts ![blockIndex];
                        if (currentBlock.Header.HasBody && contextReceiptsForBlock == null)
                        {
                            throw new EthSyncException($"{bestPeer} didn't send receipts for block {currentBlock.ToString(Block.Format.Short)}.");
                        }
                    }