public MergeSealValidator(
     IPoSSwitcher poSSwitcher,
     ISealValidator preMergeSealValidator)
 {
     _poSSwitcher           = poSSwitcher;
     _preMergeSealValidator = preMergeSealValidator;
 }
Пример #2
0
        public Synchronizer(
            ISpecProvider specProvider,
            IBlockTree blockTree,
            IReceiptStorage receiptStorage,
            IBlockValidator blockValidator,
            ISealValidator sealValidator,
            IEthSyncPeerPool peerPool,
            ISyncConfig syncConfig,
            INodeDataDownloader nodeDataDownloader,
            ISyncReport syncReport,
            ILogManager logManager)
        {
            _logger             = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _specProvider       = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _blockTree          = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _receiptStorage     = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _syncConfig         = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig));
            _syncPeerPool       = peerPool ?? throw new ArgumentNullException(nameof(peerPool));
            _nodeDataDownloader = nodeDataDownloader ?? throw new ArgumentNullException(nameof(nodeDataDownloader));
            _syncReport         = syncReport ?? throw new ArgumentNullException(nameof(syncReport));

            SyncProgressResolver syncProgressResolver = new SyncProgressResolver(_blockTree, receiptStorage, _nodeDataDownloader, syncConfig, logManager);

            _syncMode = new SyncModeSelector(syncProgressResolver, _syncPeerPool, _syncConfig, logManager);

            _blockDownloader = new BlockDownloader(_blockTree, blockValidator, sealValidator, syncReport, receiptStorage, specProvider, logManager);

            if (syncConfig.FastBlocks)
            {
                FastBlocksFeed feed = new FastBlocksFeed(_specProvider, _blockTree, _receiptStorage, _syncPeerPool, syncConfig, _syncReport, logManager);
                _fastBlockDownloader = new FastBlocksDownloader(_syncPeerPool, feed, blockValidator, sealValidator, logManager);
            }
        }
Пример #3
0
        public Synchronizer(IBlockTree blockTree,
                            IBlockValidator blockValidator,
                            ISealValidator sealValidator,
                            IEthSyncPeerPool peerPool,
                            ISyncConfig syncConfig,
                            INodeDataDownloader nodeDataDownloader,
                            ILogManager logManager)
        {
            _logger             = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _syncConfig         = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig));
            _nodeDataDownloader = nodeDataDownloader ?? throw new ArgumentNullException(nameof(nodeDataDownloader));
            _syncPeerPool       = peerPool ?? throw new ArgumentNullException(nameof(peerPool));
            _blockTree          = blockTree ?? throw new ArgumentNullException(nameof(blockTree));

            _syncMode          = new SyncModeSelector(_syncPeerPool, _syncConfig, logManager);
            _syncMode.Changed += (s, e) => RequestSynchronization(SyncTriggerType.SyncModeChange);
            _syncMode.Changed += (s, e) =>
            {
                if (_blocksSyncAllocation == null && _syncMode.Current != SyncMode.StateNodes)
                {
                    AllocateBlocksSync();
                }

                if (_syncMode.Current == SyncMode.StateNodes)
                {
                    FreeBlocksSyncAllocation();
                }
            };

            // make ctor parameter?
            _blockDownloader = new BlockDownloader(_blockTree, blockValidator, sealValidator, logManager);
        }
Пример #4
0
        public SyncServer(
            ISnapshotableDb stateDb,
            ISnapshotableDb codeDb,
            IBlockTree blockTree,
            IReceiptFinder receiptFinder,
            IBlockValidator blockValidator,
            ISealValidator sealValidator,
            ISyncPeerPool pool,
            ISyncModeSelector syncModeSelector,
            ISyncConfig syncConfig,
            ILogManager logManager,
            CanonicalHashTrie cht = null)
        {
            _syncConfig       = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig));
            _pool             = pool ?? throw new ArgumentNullException(nameof(pool));
            _syncModeSelector = syncModeSelector ?? throw new ArgumentNullException(nameof(syncModeSelector));
            _sealValidator    = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
            _stateDb          = stateDb ?? throw new ArgumentNullException(nameof(stateDb));
            _codeDb           = codeDb ?? throw new ArgumentNullException(nameof(codeDb));
            _blockTree        = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _receiptFinder    = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder));
            _blockValidator   = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _logger           = logManager.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _cht         = cht;
            _pivotNumber = _syncConfig.PivotNumberParsed;

            _blockTree.NewHeadBlock += OnNewHeadBlock;
            _pivotHash = new Keccak(_syncConfig.PivotHash ?? Keccak.Zero.ToString());
        }
Пример #5
0
        public void GetNodeData_returns_cached_trie_nodes()
        {
            Context        ctx            = new();
            BlockTree      localBlockTree = Build.A.BlockTree().OfChainLength(600).TestObject;
            ISealValidator sealValidator  = Substitute.For <ISealValidator>();
            MemDb          stateDb        = new();
            TrieStore      trieStore      = new(stateDb, Prune.WhenCacheReaches(10.MB()), NoPersistence.Instance, LimboLogs.Instance);

            ctx.SyncServer = new SyncServer(
                trieStore,
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                Always.Valid,
                sealValidator,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            Keccak   nodeKey = TestItem.KeccakA;
            TrieNode node    = new(NodeType.Leaf, nodeKey, TestItem.KeccakB.Bytes);

            trieStore.CommitNode(1, new NodeCommitInfo(node));
            trieStore.FinishBlockCommit(TrieType.State, 1, node);

            stateDb.KeyExists(nodeKey).Should().BeFalse();
            ctx.SyncServer.GetNodeData(new[] { nodeKey }, NodeDataType.All).Should().BeEquivalentTo(new[] { TestItem.KeccakB.Bytes });
        }
Пример #6
0
        public Synchronizer(
            IDbProvider dbProvider,
            ISpecProvider specProvider,
            IBlockTree blockTree,
            IReceiptStorage receiptStorage,
            IBlockValidator blockValidator,
            ISealValidator sealValidator,
            ISyncPeerPool peerPool,
            INodeStatsManager nodeStatsManager,
            ISyncModeSelector syncModeSelector,
            ISyncConfig syncConfig,
            ILogManager logManager)
        {
            _dbProvider       = dbProvider ?? throw new ArgumentNullException(nameof(dbProvider));
            _syncMode         = syncModeSelector ?? throw new ArgumentNullException(nameof(syncModeSelector));
            _logger           = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _specProvider     = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _blockTree        = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _receiptStorage   = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _blockValidator   = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _sealValidator    = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
            _syncConfig       = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig));
            _syncPeerPool     = peerPool ?? throw new ArgumentNullException(nameof(peerPool));
            _nodeStatsManager = nodeStatsManager ?? throw new ArgumentNullException(nameof(nodeStatsManager));
            _logManager       = logManager;

            _syncReport = new SyncReport(_syncPeerPool, _nodeStatsManager, _syncMode, syncConfig, logManager);
        }
 public MergeBlockDownloaderFactory(IPoSSwitcher poSSwitcher,
                                    IBeaconPivot beaconPivot,
                                    ISpecProvider specProvider,
                                    IBlockTree blockTree,
                                    IBlockCacheService blockCacheService,
                                    IReceiptStorage receiptStorage,
                                    IBlockValidator blockValidator,
                                    ISealValidator sealValidator,
                                    ISyncPeerPool peerPool,
                                    ISyncConfig syncConfig,
                                    IBetterPeerStrategy betterPeerStrategy,
                                    ISyncReport syncReport,
                                    ISyncProgressResolver syncProgressResolver,
                                    ILogManager logManager)
 {
     _poSSwitcher          = poSSwitcher ?? throw new ArgumentNullException(nameof(poSSwitcher));
     _beaconPivot          = beaconPivot ?? throw new ArgumentNullException(nameof(beaconPivot));
     _specProvider         = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
     _blockTree            = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
     _receiptStorage       = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
     _blockValidator       = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
     _sealValidator        = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
     _syncPeerPool         = peerPool ?? throw new ArgumentNullException(nameof(peerPool));
     _betterPeerStrategy   = betterPeerStrategy ?? throw new ArgumentNullException(nameof(betterPeerStrategy));
     _logManager           = logManager ?? throw new ArgumentNullException(nameof(logManager));
     _syncReport           = syncReport ?? throw new ArgumentNullException(nameof(syncReport));
     _chainLevelHelper     = new ChainLevelHelper(_blockTree, _beaconPivot, syncConfig, _logManager);
     _syncProgressResolver = syncProgressResolver ?? throw new ArgumentNullException(nameof(syncProgressResolver));;
 }
Пример #8
0
 public HeaderValidator(IBlockTree blockTree, ISealValidator sealValidator, ISpecProvider specProvider, ILogManager logManager)
 {
     _logger         = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
     _blockTree      = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
     _sealValidator  = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
     _daoBlockNumber = specProvider?.DaoBlockNumber;
 }
Пример #9
0
        public void Can_accept_new_valid_blocks(bool sealOk, bool validationOk, bool accepted)
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            ISealValidator  sealValidator  = sealOk ? Always.Valid : Always.Invalid;
            IBlockValidator blockValidator = validationOk ? Always.Valid : Always.Invalid;

            _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, blockValidator, sealValidator, _peerPool, StaticSelector.Full, new SyncConfig(), LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            if (!accepted)
            {
                Assert.Throws <EthSyncException>(() => _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock));
            }
            else
            {
                _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock);
            }

            if (accepted)
            {
                Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
            else
            {
                Assert.AreNotEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
        }
Пример #10
0
        public void Rejects_new_old_blocks()
        {
            Context   ctx             = new();
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(600).TestObject;

            ISealValidator sealValidator = Substitute.For <ISealValidator>();

            ctx.SyncServer = new SyncServer(
                new MemDb(),
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                Always.Valid,
                sealValidator,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);

            sealValidator.DidNotReceive().ValidateSeal(Arg.Any <BlockHeader>(), Arg.Any <bool>());
        }
Пример #11
0
 public FastBlocksDownloader(IEthSyncPeerPool syncPeerPool, IFastBlocksFeed fastBlocksFeed, IBlockValidator blockValidator, ISealValidator sealValidator, ILogManager logManager)
 {
     _syncPeerPool   = syncPeerPool ?? throw new ArgumentNullException(nameof(syncPeerPool));
     _fastBlocksFeed = fastBlocksFeed ?? throw new ArgumentNullException(nameof(fastBlocksFeed));
     _blockValidator = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
     _sealValidator  = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
     _logger         = logManager.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
 }
 public AuRaHeaderValidator(
     IBlockTree blockTree,
     ISealValidator sealValidator,
     ISpecProvider specProvider,
     ILogManager logManager,
     IList <long> blockGasLimitContractTransitions)
     : base(blockTree, sealValidator, specProvider, logManager)
 {
     _blockGasLimitContractTransitions = blockGasLimitContractTransitions ?? throw new ArgumentNullException(nameof(blockGasLimitContractTransitions));
 }
Пример #13
0
        public BlockDownloader(IBlockTree blockTree, IBlockValidator blockValidator, ISealValidator sealValidator, ILogManager logManager)
        {
            _blockTree      = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _blockValidator = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _sealValidator  = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
            _logger         = logManager.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));

            _syncBatchSize = new SyncBatchSize(logManager);
            _syncStats     = new SyncStats("Blocks", logManager);
        }
Пример #14
0
 public MergeSealEngine(
     ISealEngine preMergeSealEngine,
     IPoSSwitcher?poSSwitcher,
     ISealValidator mergeSealValidator,
     ILogManager?logManager)
 {
     _preMergeSealValidator =
         preMergeSealEngine ?? throw new ArgumentNullException(nameof(preMergeSealEngine));
     _poSSwitcher        = poSSwitcher ?? throw new ArgumentNullException(nameof(poSSwitcher));
     _mergeSealValidator = mergeSealValidator;
 }
Пример #15
0
        public SyncServer(ISnapshotableDb stateDb, ISnapshotableDb codeDb, IBlockTree blockTree, IReceiptStorage receiptStorage, ISealValidator sealValidator, IEthSyncPeerPool pool, ISynchronizer synchronizer, ILogManager logManager)
        {
            _synchronizer   = synchronizer ?? throw new ArgumentNullException(nameof(synchronizer));
            _pool           = pool ?? throw new ArgumentNullException(nameof(pool));
            _sealValidator  = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
            _stateDb        = stateDb ?? throw new ArgumentNullException(nameof(stateDb));
            _codeDb         = codeDb ?? throw new ArgumentNullException(nameof(codeDb));
            _blockTree      = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _logger         = logManager.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));

            _blockTree.NewHeadBlock += OnNewHeadBlock;
        }
 public MergeHeaderValidator(
     IPoSSwitcher poSSwitcher,
     IHeaderValidator preMergeHeaderValidator,
     IBlockTree blockTree,
     ISpecProvider specProvider,
     ISealValidator sealValidator,
     ILogManager logManager)
     : base(blockTree, sealValidator, specProvider, logManager)
 {
     _poSSwitcher             = poSSwitcher;
     _preMergeHeaderValidator = preMergeHeaderValidator;
     _blockTree    = blockTree;
     _specProvider = specProvider;
 }
Пример #17
0
        public void Rejects_new_old_blocks()
        {
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(600).TestObject;

            ISealValidator sealValidator = Substitute.For <ISealValidator>();

            _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, Always.Valid, sealValidator, _peerPool, StaticSelector.Full, new SyncConfig(), LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock);

            sealValidator.DidNotReceive().ValidateSeal(Arg.Any <BlockHeader>(), Arg.Any <bool>());
        }
Пример #18
0
        public void Setup()
        {
            _genesisBlock   = Build.A.Block.WithNumber(0).TestObject;
            _blockTree      = Build.A.BlockTree(_genesisBlock).OfChainLength(1).TestObject;
            _stateDb        = new MemDb();
            _receiptsDb     = new MemDb();
            _receiptStorage = Substitute.For <IReceiptStorage>();
            BlockchainConfig quickConfig = new BlockchainConfig();

            quickConfig.SyncTimerInterval = 100;

            ISealValidator        sealValidator        = Build.A.SealValidator.ThatAlwaysReturnsTrue.TestObject;
            IBlockValidator       blockValidator       = Build.A.BlockValidator.ThatAlwaysReturnsTrue.TestObject;
            ITransactionValidator transactionValidator = Build.A.TransactionValidator.ThatAlwaysReturnsTrue.TestObject;

            _manager = new QueueBasedSyncManager(_stateDb, _blockTree, blockValidator, sealValidator, transactionValidator, NullLogManager.Instance, quickConfig, new NodeStatsManager(new StatsConfig(), LimboLogs.Instance), new PerfService(NullLogManager.Instance), _receiptStorage);
        }
Пример #19
0
        public BlockDownloader(IBlockTree blockTree,
                               IBlockValidator blockValidator,
                               ISealValidator sealValidator,
                               ISyncReport syncReport,
                               IReceiptStorage receiptStorage,
                               ISpecProvider specProvider,
                               ILogManager logManager)
        {
            _blockTree      = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _blockValidator = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _sealValidator  = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
            _syncReport     = syncReport ?? throw new ArgumentNullException(nameof(syncReport));
            _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _specProvider   = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _logger         = logManager.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));

            _syncBatchSize = new SyncBatchSize(logManager);
        }
Пример #20
0
        public void Setup()
        {
            DifficultyCalculator calculator = new DifficultyCalculator(new SingleReleaseSpecProvider(Frontier.Instance, ChainId.MainNet));

            _ethash     = new EthashSealValidator(NullLogManager.Instance, calculator, new Ethash(NullLogManager.Instance));
            _testLogger = new TestLogger();
            BlockTree blockStore = new BlockTree(new MemDb(), new MemDb(), new MemDb(), FrontierSpecProvider.Instance, Substitute.For <ITxPool>(), NullLogManager.Instance);

            _validator   = new HeaderValidator(blockStore, _ethash, new SingleReleaseSpecProvider(Byzantium.Instance, 3), new OneLoggerLogManager(_testLogger));
            _parentBlock = Build.A.Block.WithDifficulty(1).TestObject;
            _block       = Build.A.Block.WithParent(_parentBlock)
                           .WithDifficulty(131072)
                           .WithMixHash(new Keccak("0xd7db5fdd332d3a65d6ac9c4c530929369905734d3ef7a91e373e81d0f010b8e8"))
                           .WithNonce(0).TestObject;

            blockStore.SuggestBlock(_parentBlock);
            blockStore.SuggestBlock(_block);
        }
Пример #21
0
        public void Can_accept_new_valid_blocks(bool sealOk, bool validationOk, bool accepted)
        {
            Context   ctx             = new();
            BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject;
            BlockTree localBlockTree  = Build.A.BlockTree().OfChainLength(9).TestObject;

            ISealValidator  sealValidator  = sealOk ? Always.Valid : Always.Invalid;
            IBlockValidator blockValidator = validationOk ? Always.Valid : Always.Invalid;

            ctx.SyncServer = new SyncServer(
                new MemDb(),
                new MemDb(),
                localBlockTree,
                NullReceiptStorage.Instance,
                blockValidator,
                sealValidator,
                ctx.PeerPool,
                StaticSelector.Full,
                new SyncConfig(),
                NullWitnessCollector.Instance,
                Policy.FullGossip,
                MainnetSpecProvider.Instance,
                LimboLogs.Instance);

            Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None);

            if (!accepted)
            {
                Assert.Throws <EthSyncException>(() => ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock));
            }
            else
            {
                ctx.SyncServer.AddNewBlock(block, ctx.NodeWhoSentTheBlock);
            }

            if (accepted)
            {
                Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
            else
            {
                Assert.AreNotEqual(localBlockTree.BestSuggestedHeader, block.Header);
            }
        }
Пример #22
0
 public BlockDownloaderFactory(
     ISpecProvider specProvider,
     IBlockTree blockTree,
     IReceiptStorage receiptStorage,
     IBlockValidator blockValidator,
     ISealValidator sealValidator,
     ISyncPeerPool peerPool,
     IBetterPeerStrategy betterPeerStrategy,
     ISyncReport syncReport,
     ILogManager logManager)
 {
     _specProvider       = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
     _blockTree          = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
     _receiptStorage     = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
     _blockValidator     = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
     _sealValidator      = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
     _syncPeerPool       = peerPool ?? throw new ArgumentNullException(nameof(peerPool));
     _betterPeerStrategy = betterPeerStrategy ?? throw new ArgumentNullException(nameof(betterPeerStrategy));
     _syncReport         = syncReport ?? throw new ArgumentNullException(nameof(syncReport));
     _logManager         = logManager ?? throw new ArgumentNullException(nameof(logManager));
 }
Пример #23
0
        public void Setup()
        {
            EthashDifficultyCalculator calculator = new(new SingleReleaseSpecProvider(Frontier.Instance, ChainId.Mainnet));

            _ethash     = new EthashSealValidator(LimboLogs.Instance, calculator, new CryptoRandom(), new Ethash(LimboLogs.Instance), Timestamper.Default);
            _testLogger = new TestLogger();
            MemDb blockInfoDb = new();

            _blockTree    = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), FrontierSpecProvider.Instance, Substitute.For <IBloomStorage>(), LimboLogs.Instance);
            _specProvider = new SingleReleaseSpecProvider(Byzantium.Instance, 3);

            _validator   = new HeaderValidator(_blockTree, _ethash, _specProvider, new OneLoggerLogManager(_testLogger));
            _parentBlock = Build.A.Block.WithDifficulty(1).TestObject;
            _block       = Build.A.Block.WithParent(_parentBlock)
                           .WithDifficulty(131072)
                           .WithMixHash(new Keccak("0xd7db5fdd332d3a65d6ac9c4c530929369905734d3ef7a91e373e81d0f010b8e8"))
                           .WithNonce(0).TestObject;

            _blockTree.SuggestBlock(_parentBlock);
            _blockTree.SuggestBlock(_block);
        }
Пример #24
0
        public Synchronizer(IBlockTree blockTree,
                            IBlockValidator blockValidator,
                            ISealValidator sealValidator,
                            IEthSyncPeerPool peerPool,
                            ISyncConfig syncConfig,
                            INodeDataDownloader nodeDataDownloader,
                            ILogManager logManager)
        {
            _logger             = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _syncConfig         = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig));
            _nodeDataDownloader = nodeDataDownloader ?? throw new ArgumentNullException(nameof(nodeDataDownloader));
            _syncPeerPool       = peerPool ?? throw new ArgumentNullException(nameof(peerPool));
            _blockTree          = blockTree ?? throw new ArgumentNullException(nameof(blockTree));

            SyncProgressResolver syncProgressResolver = new SyncProgressResolver(_blockTree, _nodeDataDownloader, logManager);

            _syncMode = new SyncModeSelector(syncProgressResolver, _syncPeerPool, _syncConfig, logManager);

            // make ctor parameter?
            _blockDownloader = new BlockDownloader(_blockTree, blockValidator, sealValidator, logManager);
        }
        public void Setup()
        {
            _genesisBlock   = Build.A.Block.WithNumber(0).TestObject;
            _blockTree      = Build.A.BlockTree(_genesisBlock).OfChainLength(1).TestObject;
            _stateDb        = new StateDb();
            _codeDb         = new StateDb();
            _receiptsDb     = new MemDb();
            _receiptStorage = Substitute.For <IReceiptStorage>();
            SyncConfig quickConfig = new SyncConfig();

            quickConfig.FastSync = false;

            ISealValidator  sealValidator  = Build.A.SealValidator.ThatAlwaysReturnsTrue.TestObject;
            IBlockValidator blockValidator = Build.A.BlockValidator.ThatAlwaysReturnsTrue.TestObject;
            ITxValidator    txValidator    = Build.A.TransactionValidator.ThatAlwaysReturnsTrue.TestObject;

            var stats = new NodeStatsManager(new StatsConfig(), LimboLogs.Instance);

            _pool         = new EthSyncPeerPool(_blockTree, stats, quickConfig, 25, LimboLogs.Instance);
            _synchronizer = new Synchronizer(MainNetSpecProvider.Instance, _blockTree, NullReceiptStorage.Instance, blockValidator, sealValidator, _pool, quickConfig, Substitute.For <INodeDataDownloader>(), LimboLogs.Instance);
            _syncServer   = new SyncServer(_stateDb, _codeDb, _blockTree, _receiptStorage, sealValidator, _pool, _synchronizer, quickConfig, LimboLogs.Instance);
        }
Пример #26
0
        public BlockDownloader(
            ISyncFeed <BlocksRequest> feed,
            ISyncPeerPool syncPeerPool,
            IBlockTree blockTree,
            IBlockValidator blockValidator,
            ISealValidator sealValidator,
            ISyncReport syncReport,
            IReceiptStorage receiptStorage,
            ISpecProvider specProvider,
            ILogManager logManager)
            : base(feed, syncPeerPool, new BlocksSyncPeerAllocationStrategyFactory(), logManager)
        {
            _blockTree      = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _blockValidator = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _sealValidator  = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
            _syncReport     = syncReport ?? throw new ArgumentNullException(nameof(syncReport));
            _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _specProvider   = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _logger         = logManager.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));

            _syncBatchSize           = new SyncBatchSize(logManager);
            _blockTree.NewHeadBlock += BlockTreeOnNewHeadBlock;
        }
Пример #27
0
        public BlockDownloader(
            ISyncFeed <BlocksRequest?>?feed,
            ISyncPeerPool?syncPeerPool,
            IBlockTree?blockTree,
            IBlockValidator?blockValidator,
            ISealValidator?sealValidator,
            ISyncReport?syncReport,
            IReceiptStorage?receiptStorage,
            ISpecProvider?specProvider,
            ILogManager?logManager)
            : base(feed, syncPeerPool, new BlocksSyncPeerAllocationStrategyFactory(), logManager)
        {
            _blockTree      = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
            _blockValidator = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _sealValidator  = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
            _syncReport     = syncReport ?? throw new ArgumentNullException(nameof(syncReport));
            _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _specProvider   = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _logger         = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));

            _receiptsRecovery        = new ReceiptsRecovery(new EthereumEcdsa(_specProvider.ChainId, logManager), _specProvider);
            _syncBatchSize           = new SyncBatchSize(logManager);
            _blockTree.NewHeadBlock += BlockTreeOnNewHeadBlock;
        }
Пример #28
0
        private async Task InitializeNetwork(
            IReceiptStorage receiptStorage,
            ISealValidator sealValidator,
            TransactionValidator txValidator)
        {
            if (!_initConfig.NetworkEnabled)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Skipping network init due to ({nameof(IInitConfig.NetworkEnabled)} set to false)");
                }
                return;
            }

            _syncManager = new QueueBasedSyncManager(
                _dbProvider.StateDb,
                _blockTree,
                _blockValidator,
                sealValidator,
                txValidator,
                _logManager,
                _configProvider.GetConfig <IBlockchainConfig>(),
                _nodeStatsManager,
                _perfService,
                receiptStorage);

            InitDiscovery();
            await InitPeer().ContinueWith(initPeerTask =>
            {
                if (initPeerTask.IsFaulted)
                {
                    _logger.Error("Unable to init peer manager.", initPeerTask.Exception);
                }
            });

            ;

            await StartSync().ContinueWith(initNetTask =>
            {
                if (initNetTask.IsFaulted)
                {
                    _logger.Error("Unable to start sync.", initNetTask.Exception);
                }
            });

            await StartDiscovery().ContinueWith(initDiscoveryTask =>
            {
                if (initDiscoveryTask.IsFaulted)
                {
                    _logger.Error("Unable to start discovery protocol.", initDiscoveryTask.Exception);
                }
            });

            try
            {
                StartPeer();
            }
            catch (Exception e)
            {
                _logger.Error("Unable to start peer manager.", e);
            }

            ;

            if (_logger.IsInfo)
            {
                _logger.Info($"Node is up and listening on {_enode.IpAddress}:{_enode.P2PPort}");
            }
            if (_logger.IsInfo)
            {
                _logger.Info($"{ClientVersion.Description}");
            }
            if (_logger.IsInfo)
            {
                _logger.Info(_enode.Info);
            }
            if (_logger.IsInfo)
            {
                _logger.Info($"enode address for test purposes: {_enode.Address}");
            }
        }
Пример #29
0
        private async Task InitBlockchain()
        {
            /* spec */
            if (_chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                _specProvider = RopstenSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId)
            {
                _specProvider = MainNetSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == RinkebySpecProvider.Instance.ChainId)
            {
                _specProvider = RinkebySpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == GoerliSpecProvider.Instance.ChainId)
            {
                _specProvider = GoerliSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == SturebySpecProvider.Instance.ChainId)
            {
                _specProvider = SturebySpecProvider.Instance;
            }
            else
            {
                _specProvider = new SingleReleaseSpecProvider(LatestRelease.Instance, _chainSpec.ChainId);
            }

            /* sync */
            IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>();

            foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties())
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}");
                }
            }

            _dbProvider = HiveEnabled
                ? (IDbProvider) new MemDbProvider()
                : new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts);

            _ethereumEcdsa   = new EthereumEcdsa(_specProvider, _logManager);
            _transactionPool = new TransactionPool(
                new PersistentTransactionStorage(_dbProvider.PendingTxsDb, _specProvider),
                new PendingTransactionThresholdValidator(_initConfig.ObsoletePendingTransactionInterval,
                                                         _initConfig.RemovePendingTransactionInterval), new Timestamp(),
                _ethereumEcdsa, _specProvider, _logManager, _initConfig.RemovePendingTransactionInterval,
                _initConfig.PeerNotificationThreshold);
            _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _specProvider);

//            IDbProvider debugRecorder = new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig);
//            _dbProvider = new RpcDbProvider(_jsonSerializer, new BasicJsonRpcClient(KnownRpcUris.NethVm1, _jsonSerializer, _logManager), _logManager, debugRecorder);

//            IDbProvider debugReader = new ReadOnlyDbProvider(new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig));
//            _dbProvider = debugReader;

            _blockTree = new BlockTree(
                _dbProvider.BlocksDb,
                _dbProvider.BlockInfosDb,
                _specProvider,
                _transactionPool,
                _logManager);

            _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _transactionPool);

            CliqueConfig cliqueConfig = null;

            _snapshotManager = null;
            switch (_chainSpec.SealEngineType)
            {
            case SealEngineType.None:
                _sealer           = NullSealEngine.Instance;
                _sealValidator    = NullSealEngine.Instance;
                _rewardCalculator = NoBlockRewards.Instance;
                break;

            case SealEngineType.Clique:
                _rewardCalculator        = NoBlockRewards.Instance;
                cliqueConfig             = new CliqueConfig();
                cliqueConfig.BlockPeriod = _chainSpec.CliquePeriod;
                cliqueConfig.Epoch       = _chainSpec.CliqueEpoch;
                _snapshotManager         = new SnapshotManager(cliqueConfig, _dbProvider.BlocksDb, _blockTree, _ethereumEcdsa, _logManager);
                _sealValidator           = new CliqueSealValidator(cliqueConfig, _snapshotManager, _logManager);
                _recoveryStep            = new CompositeDataRecoveryStep(_recoveryStep, new AuthorRecoveryStep(_snapshotManager));
                if (_initConfig.IsMining)
                {
                    _sealer = new CliqueSealer(new BasicWallet(_nodeKey), cliqueConfig, _snapshotManager, _nodeKey.Address, _logManager);
                }
                else
                {
                    _sealer = NullSealEngine.Instance;
                }
                break;

            case SealEngineType.NethDev:
                _sealer           = NullSealEngine.Instance;
                _sealValidator    = NullSealEngine.Instance;
                _rewardCalculator = NoBlockRewards.Instance;
                break;

            case SealEngineType.Ethash:
                _rewardCalculator = new RewardCalculator(_specProvider);
                var difficultyCalculator = new DifficultyCalculator(_specProvider);
                if (_initConfig.IsMining)
                {
                    _sealer = new EthashSealer(new Ethash(_logManager), _logManager);
                }
                else
                {
                    _sealer = NullSealEngine.Instance;
                }

                _sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager));
                break;

            default:
                throw new NotSupportedException($"Seal engine type {_chainSpec.SealEngineType} is not supported in Nethermind");
            }

            /* validation */
            var headerValidator = new HeaderValidator(
                _blockTree,
                _sealValidator,
                _specProvider,
                _logManager);

            var ommersValidator = new OmmersValidator(
                _blockTree,
                headerValidator,
                _logManager);

            var txValidator = new TransactionValidator(
                new SignatureValidator(_specProvider.ChainId));

            _blockValidator = new BlockValidator(
                txValidator,
                headerValidator,
                ommersValidator,
                _specProvider,
                _logManager);

            var stateTree = new StateTree(_dbProvider.StateDb);

            var stateProvider = new StateProvider(
                stateTree,
                _dbProvider.CodeDb,
                _logManager);

            _stateProvider = stateProvider;

            var storageProvider = new StorageProvider(
                _dbProvider.StateDb,
                stateProvider,
                _logManager);

            _transactionPoolInfoProvider = new TransactionPoolInfoProvider(stateProvider);

            /* blockchain processing */
            var blockhashProvider = new BlockhashProvider(
                _blockTree);

            var virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            var transactionProcessor = new TransactionProcessor(
                _specProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                _logManager);

            _blockProcessor = new BlockProcessor(
                _specProvider,
                _blockValidator,
                _rewardCalculator,
                transactionProcessor,
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _dbProvider.TraceDb,
                stateProvider,
                storageProvider,
                _transactionPool,
                _receiptStorage,
                _logManager);

            _blockchainProcessor = new BlockchainProcessor(
                _blockTree,
                _blockProcessor,
                _recoveryStep,
                _logManager,
                _initConfig.StoreReceipts,
                _initConfig.StoreTraces);

            // create shared objects between discovery and peer manager
            IStatsConfig statsConfig = _configProvider.GetConfig <IStatsConfig>();

            _nodeStatsManager = new NodeStatsManager(statsConfig, _logManager, !statsConfig.CaptureNodeStatsEventHistory);

            if (_initConfig.IsMining)
            {
                IReadOnlyDbProvider minerDbProvider = new ReadOnlyDbProvider(_dbProvider, false);
                AlternativeChain    producerChain   = new AlternativeChain(_blockTree, _blockValidator, _rewardCalculator,
                                                                           _specProvider, minerDbProvider, _recoveryStep, _logManager, _transactionPool, _receiptStorage);

                switch (_chainSpec.SealEngineType)
                {
                case SealEngineType.Clique:
                {
                    // TODO: need to introduce snapshot provider for clique and pass it here instead of CliqueSealEngine
                    if (_logger.IsWarn)
                    {
                        _logger.Warn("Starting Clique block producer & sealer");
                    }
                    _blockProducer = new CliqueBlockProducer(_transactionPool, producerChain.Processor,
                                                             _blockTree, _timestamp, _cryptoRandom, producerChain.StateProvider, _snapshotManager, (CliqueSealer)_sealer, _nodeKey.Address, cliqueConfig, _logManager);
                    break;
                }

                case SealEngineType.NethDev:
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn("Starting Dev block producer & sealer");
                    }
                    _blockProducer = new DevBlockProducer(_transactionPool, producerChain.Processor, _blockTree,
                                                          _timestamp, _logManager);
                    break;
                }

                default:
                    throw new NotSupportedException($"Mining in {_chainSpec.SealEngineType} mode is not supported");
                }

                _blockProducer.Start();
            }

            if (!HiveEnabled)
            {
                _blockchainProcessor.Start();
                LoadGenesisBlock(_chainSpec, string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash), _blockTree, stateProvider, _specProvider);
                if (_initConfig.ProcessingEnabled)
                {
#pragma warning disable 4014
                    LoadBlocksFromDb();
#pragma warning restore 4014
                }
                else
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn($"Shutting down processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false");
                    }
                    await _blockchainProcessor.StopAsync();
                }
            }

            await InitializeNetwork(
                _receiptStorage,
                _sealValidator,
                txValidator);
        }
Пример #30
0
        new protected async Task StartRunners(IConfigProvider configProvider)
        {
            InitRlp();
            _configProvider = configProvider;
            _initConfig     = _configProvider.GetConfig <IInitConfig>();
            _logManager     = new NLogManager(_initConfig.LogFileName, _initConfig.LogDirectory);
            _logger         = _logManager.GetClassLogger();
            _networkHelper  = new NetworkHelper(_logger);
            SetupKeyStore();
            LoadChainSpec();
            IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>();

            _dbProvider = new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts);

            var stateProvider = new StateProvider(
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _logManager);

            _stateProvider = stateProvider;



            /* blockchain processing */


            if (_chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                _specProvider = RopstenSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId)
            {
                _specProvider = MainNetSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == RinkebySpecProvider.Instance.ChainId)
            {
                _specProvider = RinkebySpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == GoerliSpecProvider.Instance.ChainId)
            {
                _specProvider = GoerliSpecProvider.Instance;
            }
            else
            {
                _specProvider = new SingleReleaseSpecProvider(Latest.Release, _chainSpec.ChainId);
            }

            _ethereumEcdsa = new EthereumEcdsa(_specProvider, _logManager);
            _txPool        = new TxPool(
                new PersistentTransactionStorage(_dbProvider.PendingTxsDb, _specProvider),
                new PendingTransactionThresholdValidator(_initConfig.ObsoletePendingTransactionInterval,
                                                         _initConfig.RemovePendingTransactionInterval), new Timestamp(),
                _ethereumEcdsa, _specProvider, _logManager, _initConfig.RemovePendingTransactionInterval,
                _initConfig.PeerNotificationThreshold);
            _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _specProvider);

            _blockTree = new BlockTree(
                _dbProvider.BlocksDb,
                _dbProvider.HeadersDb,
                _dbProvider.BlockInfosDb,
                _specProvider,
                _txPool,
                _logManager);
            _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _txPool, _logManager);
            CliqueConfig cliqueConfig = null;

            _snapshotManager = null;
            switch (_chainSpec.SealEngineType)
            {
            case SealEngineType.None:
                _sealer           = NullSealEngine.Instance;
                _sealValidator    = NullSealEngine.Instance;
                _rewardCalculator = NoBlockRewards.Instance;
                break;

            case SealEngineType.Clique:
                _rewardCalculator        = NoBlockRewards.Instance;
                cliqueConfig             = new CliqueConfig();
                cliqueConfig.BlockPeriod = _chainSpec.Clique.Period;
                cliqueConfig.Epoch       = _chainSpec.Clique.Epoch;
                _snapshotManager         = new SnapshotManager(cliqueConfig, _dbProvider.BlocksDb, _blockTree, _ethereumEcdsa, _logManager);
                _sealValidator           = new CliqueSealValidator(cliqueConfig, _snapshotManager, _logManager);
                _recoveryStep            = new CompositeDataRecoveryStep(_recoveryStep, new AuthorRecoveryStep(_snapshotManager));
                if (_initConfig.IsMining)
                {
                    _sealer = new CliqueSealer(new BasicWallet(_nodeKey), cliqueConfig, _snapshotManager, _nodeKey.Address, _logManager);
                }
                else
                {
                    _sealer = NullSealEngine.Instance;
                }

                break;

            case SealEngineType.NethDev:
                _sealer           = NullSealEngine.Instance;
                _sealValidator    = NullSealEngine.Instance;
                _rewardCalculator = NoBlockRewards.Instance;
                break;

            case SealEngineType.Ethash:
                _rewardCalculator = new RewardCalculator(_specProvider);
                var difficultyCalculator = new DifficultyCalculator(_specProvider);
                if (_initConfig.IsMining)
                {
                    _sealer = new EthashSealer(new Ethash(_logManager), _logManager);
                }
                else
                {
                    _sealer = NullSealEngine.Instance;
                }

                _sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager));
                break;

            default:
                throw new NotSupportedException($"Seal engine type {_chainSpec.SealEngineType} is not supported in Nethermind");
            }


            _headerValidator = new HeaderValidator(
                _blockTree,
                _sealValidator,
                _specProvider,
                _logManager);

            var ommersValidator = new OmmersValidator(
                _blockTree,
                _headerValidator,
                _logManager);
            var storageProvider = new StorageProvider(
                _dbProvider.StateDb,
                stateProvider,
                _logManager);

            var txValidator = new TxValidator(_specProvider.ChainId);

            _blockValidator = new BlockValidator(
                txValidator,
                _headerValidator,
                ommersValidator,
                _specProvider,
                _logManager);



            var blockhashProvider = new BlockhashProvider(
                _blockTree, _logManager);

            var virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            var transactionProcessor = new TransactionProcessor(
                _specProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                _logManager);

            _blockProcessor = new BlockProcessor(
                _specProvider,
                _blockValidator,
                _rewardCalculator,
                transactionProcessor,
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _dbProvider.TraceDb,
                stateProvider,
                storageProvider,
                _txPool,
                _receiptStorage,
                _configProvider.GetConfig <ISyncConfig>(),
                _logManager);

            _blockchainProcessor = new BlockchainProcessor(
                _blockTree,
                _blockProcessor,
                _recoveryStep,
                _logManager,
                _initConfig.StoreReceipts,
                _initConfig.StoreTraces);


            string chainFile = Path.Join(Path.GetDirectoryName(_initConfig.ChainSpecPath), "chain.rlp");

            if (!File.Exists(chainFile))
            {
                _logger.Info($"Chain file does not exist: {chainFile}, skipping");
                return;
            }

            var chainFileContent = File.ReadAllBytes(chainFile);
            var context          = new Rlp.DecoderContext(chainFileContent);
            var blocks           = new List <Block>();

            while (context.ReadNumberOfItemsRemaining() > 0)
            {
                context.PeekNextItem();
                blocks.Add(Rlp.Decode <Block>(context));
            }

            for (int i = 0; i < blocks.Count; i++)
            {
                ProcessBlock(blocks[i]);
            }
        }