public ProcessingTestContext()
            {
                _logger = _logManager.GetClassLogger();
                MemDb blockDb     = new MemDb();
                MemDb blockInfoDb = new MemDb();
                MemDb headersDb   = new MemDb();

                _blockTree      = new BlockTree(blockDb, headersDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), MainNetSpecProvider.Instance, NullTxPool.Instance, LimboLogs.Instance);
                _blockProcessor = new BlockProcessorMock(_logManager);
                _recoveryStep   = new RecoveryStepMock(_logManager);
                _processor      = new BlockchainProcessor(_blockTree, _blockProcessor, _recoveryStep, LimboLogs.Instance, true, true);
                _resetEvent     = new AutoResetEvent(false);

                _blockTree.NewHeadBlock += (sender, args) =>
                {
                    _logger.Info($"Finished waiting for {args.Block.ToString(Block.Format.Short)} as block became the new head block");
                    _resetEvent.Set();
                };

                _processor.Start();
            }
예제 #2
0
        public async Task Run()
        {
            var web3 = new Web3.Web3(TestConfiguration.BlockchainUrls.Infura.Rinkeby);
            var transactionHandler = new SimpleTransactionHandler();
            var handlers           = new HandlerContainer {
                TransactionHandler = transactionHandler
            };

            var blockProcessor = BlockProcessorFactory.Create(
                web3,
                handlers,
                processTransactionsInParallel: false);

            var processingStrategy  = new ProcessingStrategy(blockProcessor);
            var blockchainProcessor = new BlockchainProcessor(processingStrategy);

            var result = await blockchainProcessor.ExecuteAsync(2830144, 2830145);

            Assert.True(result);
            Assert.Equal(20, transactionHandler.TransactionsHandled?.Count);
            Assert.Equal(5, transactionHandler.ContractCreationsHandled?.Count);
        }
예제 #3
0
        protected BlockProducerContext GetProducerChain()
        {
            BlockProducerContext Create()
            {
                ReadOnlyDbProvider      dbProvider      = new ReadOnlyDbProvider(_api.DbProvider, false);
                ReadOnlyBlockTree       blockTree       = new ReadOnlyBlockTree(_api.BlockTree);
                ReadOnlyTxProcessingEnv txProcessingEnv =
                    new ReadOnlyTxProcessingEnv(dbProvider, blockTree, _api.SpecProvider, _api.LogManager);

                ReadOnlyTxProcessorSource txProcessorSource =
                    new ReadOnlyTxProcessorSource(txProcessingEnv);

                BlockProcessor blockProcessor =
                    CreateBlockProcessor(txProcessingEnv, txProcessorSource, dbProvider);

                IBlockchainProcessor blockchainProcessor =
                    new BlockchainProcessor(
                        blockTree,
                        blockProcessor,
                        _api.RecoveryStep,
                        _api.LogManager,
                        BlockchainProcessor.Options.NoReceipts);

                OneTimeChainProcessor chainProcessor = new OneTimeChainProcessor(
                    dbProvider,
                    blockchainProcessor);

                return(new BlockProducerContext
                {
                    ChainProcessor = chainProcessor,
                    ReadOnlyStateProvider = txProcessingEnv.StateProvider,
                    TxSource = CreateTxSourceForProducer(txProcessingEnv, txProcessorSource),
                    ReadOnlyTxProcessingEnv = txProcessingEnv,
                    ReadOnlyTxProcessorSource = txProcessorSource
                });
            }

            return(_blockProducerContext ??= Create());
        }
예제 #4
0
        public async Task Run()
        {
            var contractAddresses = new[]
            { "0xd2e474c616cc60fb95d8b5f86c1043fa4552611b" };

            const ulong FromBlock = 4347;
            const ulong ToBlock   = 4347;

            var web3geth = new Web3Geth();
            var blockchainProxyService = new BlockchainProxyService(web3geth);
            var transactionHandler     = new SimpleTransactionHandler();
            var vmStackHandler         = new VmStackHandler();
            var contractHandler        = new ContractHandler();

            foreach (var contractAddress in contractAddresses)
            {
                contractHandler.ContractAddresses.Add(contractAddress);
            }

            var handlers = new HandlerContainer {
                ContractHandler = contractHandler, TransactionHandler = transactionHandler, TransactionVmStackHandler = vmStackHandler
            };

            var blockProcessor = BlockProcessorFactory.Create(
                blockchainProxyService,
                handlers,
                processTransactionsInParallel: false,
                postVm: true);

            var processingStrategy = new ProcessingStrategy(blockProcessor)
            {
            };

            var blockchainProcessor = new BlockchainProcessor(processingStrategy);

            var result = await blockchainProcessor.ExecuteAsync(FromBlock, ToBlock);

            Assert.True(result);
        }
        public virtual BlockProducerEnv Create(ITxSource?additionalTxSource = null)
        {
            ReadOnlyDbProvider readOnlyDbProvider = _dbProvider.AsReadOnly(false);
            ReadOnlyBlockTree  readOnlyBlockTree  = _blockTree.AsReadOnly();

            ReadOnlyTxProcessingEnv txProcessingEnv =
                CreateReadonlyTxProcessingEnv(readOnlyDbProvider, readOnlyBlockTree);

            BlockProcessor blockProcessor =
                CreateBlockProcessor(txProcessingEnv,
                                     _specProvider,
                                     _blockValidator,
                                     _rewardCalculatorSource,
                                     _receiptStorage,
                                     _logManager,
                                     _miningConfig);

            IBlockchainProcessor blockchainProcessor =
                new BlockchainProcessor(
                    readOnlyBlockTree,
                    blockProcessor,
                    _blockPreprocessorStep,
                    txProcessingEnv.StateReader,
                    _logManager,
                    BlockchainProcessor.Options.NoReceipts);

            OneTimeChainProcessor chainProcessor = new(
                readOnlyDbProvider,
                blockchainProcessor);

            return(new BlockProducerEnv
            {
                BlockTree = readOnlyBlockTree,
                ChainProcessor = chainProcessor,
                ReadOnlyStateProvider = txProcessingEnv.StateProvider,
                TxSource = CreateTxSourceForProducer(additionalTxSource, txProcessingEnv, _txPool, _miningConfig, _transactionComparerProvider, _logManager),
                ReadOnlyTxProcessingEnv = txProcessingEnv
            });
        }
예제 #6
0
        public async Task Fixer_should_not_suggest_block_with_null_block()
        {
            TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build();

            await testRpc.BlockchainProcessor.StopAsync();

            IBlockTree tree = testRpc.BlockTree;

            SuggestNumberOfBlocks(tree, 1);

            // simulating restarts - we stopped the old blockchain processor and create the new one
            BlockchainProcessor newBlockchainProcessor = new BlockchainProcessor(tree, testRpc.BlockProcessor,
                                                                                 testRpc.BlockPreprocessorStep, LimboLogs.Instance, BlockchainProcessor.Options.Default);

            newBlockchainProcessor.Start();
            testRpc.BlockchainProcessor = newBlockchainProcessor;

            IBlockTreeVisitor fixer  = new StartupBlockTreeFixer(new SyncConfig(), tree, testRpc.DbProvider.StateDb, LimboNoErrorLogger.Instance, 5);
            BlockVisitOutcome result = await fixer.VisitBlock(null, CancellationToken.None);

            Assert.AreEqual(BlockVisitOutcome.None, result);
        }
예제 #7
0
            public AlternativeChain(
                IBlockTree blockTree,
                IBlockValidator blockValidator,
                IRewardCalculator rewardCalculator,
                ISpecProvider specProvider,
                IReadOnlyDbProvider dbProvider,
                IBlockDataRecoveryStep recoveryStep,
                ILogManager logManager,
                ITransactionPool customTransactionPool,
                IReceiptStorage receiptStorage)
            {
                StateProvider = new StateProvider(new StateTree(dbProvider.StateDb), dbProvider.CodeDb, logManager);
                StorageProvider       storageProvider      = new StorageProvider(dbProvider.StateDb, StateProvider, logManager);
                IBlockTree            readOnlyTree         = new ReadOnlyBlockTree(blockTree);
                BlockhashProvider     blockhashProvider    = new BlockhashProvider(readOnlyTree);
                VirtualMachine        virtualMachine       = new VirtualMachine(StateProvider, storageProvider, blockhashProvider, logManager);
                ITransactionProcessor transactionProcessor = new TransactionProcessor(specProvider, StateProvider, storageProvider, virtualMachine, logManager);
                ITransactionPool      transactionPool      = customTransactionPool;
                IBlockProcessor       blockProcessor       = new BlockProcessor(specProvider, blockValidator, rewardCalculator, transactionProcessor, dbProvider.StateDb, dbProvider.CodeDb, dbProvider.TraceDb, StateProvider, storageProvider, transactionPool, receiptStorage, logManager);

                Processor = new BlockchainProcessor(readOnlyTree, blockProcessor, recoveryStep, logManager, false, false);
            }
예제 #8
0
        // TODO: Use BlockProducerEnvFactory
        private BlockProducerEnv GetProducerChain(ITxSource?additionalTxSource)
        {
            ReadOnlyTxProcessingEnv CreateReadonlyTxProcessingEnv(ReadOnlyDbProvider dbProvider, ReadOnlyBlockTree blockTree)
            {
                return(new(dbProvider, _api.ReadOnlyTrieStore, blockTree, _api.SpecProvider, _api.LogManager));
            }

            BlockProducerEnv Create()
            {
                ReadOnlyDbProvider dbProvider = _api.DbProvider.AsReadOnly(false);
                ReadOnlyBlockTree  blockTree  = _api.BlockTree.AsReadOnly();

                ReadOnlyTxProcessingEnv txProcessingEnv = CreateReadonlyTxProcessingEnv(dbProvider, blockTree);
                ReadOnlyTxProcessingEnv constantContractsProcessingEnv = CreateReadonlyTxProcessingEnv(dbProvider, blockTree);
                BlockProcessor          blockProcessor = CreateBlockProcessor(txProcessingEnv, constantContractsProcessingEnv);

                IBlockchainProcessor blockchainProcessor =
                    new BlockchainProcessor(
                        blockTree,
                        blockProcessor,
                        _api.BlockPreprocessor,
                        _api.LogManager,
                        BlockchainProcessor.Options.NoReceipts);

                OneTimeChainProcessor chainProcessor = new(
                    dbProvider,
                    blockchainProcessor);

                return(new BlockProducerEnv()
                {
                    ChainProcessor = chainProcessor,
                    ReadOnlyStateProvider = txProcessingEnv.StateProvider,
                    TxSource = CreateTxSourceForProducer(txProcessingEnv, constantContractsProcessingEnv, additionalTxSource),
                    ReadOnlyTxProcessingEnv = constantContractsProcessingEnv
                });
            }

            return(_blockProducerContext ??= Create());
        }
        public async Task Run()
        {
            var blockchainProxy    = new BlockchainProxyService("https://rinkeby.infura.io/v3/25e7b6dfc51040b3bfc0e47317d38f60");
            var transactionHandler = new SimpleTransactionHandler();
            var handlers           = new HandlerContainer {
                TransactionHandler = transactionHandler
            };

            var blockProcessor = BlockProcessorFactory.Create(
                blockchainProxy,
                handlers,
                processTransactionsInParallel: false);

            var processingStrategy  = new ProcessingStrategy(blockProcessor);
            var blockchainProcessor = new BlockchainProcessor(processingStrategy);

            var result = await blockchainProcessor.ExecuteAsync(2830144, 2830145);

            Assert.True(result);
            Assert.Equal(20, transactionHandler.TransactionsHandled?.Count);
            Assert.Equal(5, transactionHandler.ContractCreationsHandled?.Count);
        }
예제 #10
0
        public async Task IndexingTransferFunctions()
        {
            using (var azureSearchService = new AzureSearchService(AzureSearchServiceName, _azureSearchApiKey))
            {
                await azureSearchService.DeleteIndexAsync(AzureTransferIndexName);

                try
                {
                    using (var azureFunctionMessageIndexer =
                               await azureSearchService.CreateFunctionIndexer <TransferFunction>(
                                   indexName: AzureTransferIndexName))
                    {
                        var transferHandler =
                            new FunctionIndexTransactionHandler <TransferFunction>(azureFunctionMessageIndexer);

                        var web3            = new Web3.Web3(TestConfiguration.BlockchainUrls.Infura.Rinkeby);
                        var blockchainProxy = new BlockchainProxyService(web3);
                        var handlers        = new HandlerContainer {
                            TransactionHandler = transferHandler
                        };
                        var blockProcessor      = BlockProcessorFactory.Create(blockchainProxy, handlers);
                        var processingStrategy  = new ProcessingStrategy(blockProcessor);
                        var blockchainProcessor = new BlockchainProcessor(processingStrategy);

                        var blockRange = new BlockRange(3146684, 3146694);
                        await blockchainProcessor.ProcessAsync(blockRange);

                        await Task.Delay(TimeSpan.FromSeconds(5));

                        //ensure we have written the expected docs to the index
                        Assert.Equal(3, await azureFunctionMessageIndexer.DocumentCountAsync());
                    }
                }
                finally
                {
                    await azureSearchService.DeleteIndexAsync(AzureTransferIndexName);
                }
            }
        }
예제 #11
0
 public Context()
 {
     StepDelay           = TimeSpan.FromMilliseconds(20);
     TransactionSource   = Substitute.For <ITxSource>();
     BlockchainProcessor = Substitute.For <IBlockchainProcessor>();
     Sealer               = Substitute.For <ISealer>();
     BlockTree            = Substitute.For <IBlockTree>();
     BlockProcessingQueue = Substitute.For <IBlockProcessingQueue>();
     StateProvider        = Substitute.For <IStateProvider>();
     Timestamper          = Substitute.For <ITimestamper>();
     AuRaStepCalculator   = Substitute.For <IAuRaStepCalculator>();
     NodeAddress          = TestItem.AddressA;
     TransactionSource.GetTransactions(Arg.Any <BlockHeader>(), Arg.Any <long>()).Returns(Array.Empty <Transaction>());
     Sealer.CanSeal(Arg.Any <long>(), Arg.Any <Keccak>()).Returns(true);
     Sealer.SealBlock(Arg.Any <Block>(), Arg.Any <CancellationToken>()).Returns(c => Task.FromResult(c.Arg <Block>()));
     BlockProcessingQueue.IsEmpty.Returns(true);
     AuRaStepCalculator.TimeToNextStep.Returns(StepDelay);
     BlockTree.BestKnownNumber.Returns(1);
     BlockTree.Head.Returns(Build.A.Block.WithHeader(Build.A.BlockHeader.WithAura(10, Bytes.Empty).TestObject).TestObject);
     BlockchainProcessor.Process(Arg.Any <Block>(), ProcessingOptions.ProducingBlock, Arg.Any <IBlockTracer>()).Returns(c => c.Arg <Block>());
     InitProducer();
 }
        private BlockchainProcessor CreateBlockChainProcessor(TRepositoryFactory repoFactory)
        {
            var web3 = new Web3.Web3(TargetConfiguration.BlockchainUrl);

            var steps = new BlockProcessingSteps();
            steps.BlockStep.AddProcessorHandler((b) => { log.Info($"Processing block {b.Number.Value}, Tx Count: {b.Transactions.Length}"); return Task.CompletedTask; });
            steps.TransactionReceiptStep.AddProcessorHandler((tx) => { log.Info($"\tTransaction: Index: {tx.Transaction.TransactionIndex}, Hash: {tx.TransactionHash}"); return Task.CompletedTask; });
            steps.FilterLogStep.AddProcessorHandler((l) => { log.Info($"\t\tLog: Index: {l.LogIndex}"); return Task.CompletedTask; });

            var orchestrator = new BlockCrawlOrchestrator(web3.Eth, steps);
            orchestrator.ContractCreatedCrawlerStep.RetrieveCode = true;

            var lastConfirmedBlockNumberService = new LastConfirmedBlockNumberService(
                web3.Eth.Blocks.GetBlockNumber, 
                TargetConfiguration.MinimumBlockConfirmations ?? LastConfirmedBlockNumberService.DEFAULT_BLOCK_CONFIRMATIONS, 
                log);

            IBlockProgressRepository progressRepo = repoFactory.CreateBlockProgressRepository();

            var processor = new BlockchainProcessor(orchestrator, progressRepo, lastConfirmedBlockNumberService, log);

            return processor;
        }
예제 #13
0
        public void Setup()
        {
            IDbProvider dbProvider = TestMemDbProvider.Init();

            ChainLevelInfoRepository repository   = new ChainLevelInfoRepository(dbProvider);
            ISpecProvider            specProvider = MainnetSpecProvider.Instance;

            _blockTree = new BlockTree(dbProvider, repository, specProvider, NullBloomStorage.Instance, new SyncConfig(), LimboLogs.Instance);

            TrieStore       trieStore       = new TrieStore(dbProvider.StateDb, LimboLogs.Instance);
            StateProvider   stateProvider   = new StateProvider(trieStore, dbProvider.CodeDb, LimboLogs.Instance);
            StorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, LimboLogs.Instance);

            BlockhashProvider blockhashProvider = new BlockhashProvider(_blockTree, LimboLogs.Instance);

            VirtualMachine virtualMachine = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, LimboLogs.Instance);

            TransactionProcessor transactionProcessor = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, LimboLogs.Instance);

            BlockProcessor blockProcessor = new BlockProcessor(
                specProvider,
                TestBlockValidator.AlwaysValid,
                NoBlockRewards.Instance,
                transactionProcessor,
                stateProvider,
                storageProvider,
                NullTxPool.Instance,
                NullReceiptStorage.Instance,
                NullWitnessCollector.Instance,
                LimboLogs.Instance);

            _processor = new BlockchainProcessor(_blockTree, blockProcessor, new CompositeBlockPreprocessorStep(), LimboLogs.Instance, BlockchainProcessor.Options.NoReceipts);
            Block genesis = Build.A.Block.Genesis.TestObject;

            _blockTree.SuggestBlock(genesis);
            _processor.Process(genesis, ProcessingOptions.None, NullBlockTracer.Instance);
        }
예제 #14
0
        public async Task Fixer_should_not_suggest_block_without_state(int suggestedBlocksAmount)
        {
            TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build();

            await testRpc.BlockchainProcessor.StopAsync();

            IBlockTree tree = testRpc.BlockTree;

            SuggestNumberOfBlocks(tree, suggestedBlocksAmount);

            // simulating restarts - we stopped the old blockchain processor and create the new one
            BlockchainProcessor newBlockchainProcessor = new BlockchainProcessor(tree, testRpc.BlockProcessor,
                                                                                 testRpc.BlockPreprocessorStep, LimboLogs.Instance, BlockchainProcessor.Options.Default);

            newBlockchainProcessor.Start();
            testRpc.BlockchainProcessor = newBlockchainProcessor;

            // we create a new empty db for stateDb so we shouldn't suggest new blocks
            MemDb             stateDb = new MemDb();
            IBlockTreeVisitor fixer   = new StartupBlockTreeFixer(new SyncConfig(), tree, stateDb, LimboNoErrorLogger.Instance, 5);
            BlockVisitOutcome result  = await fixer.VisitBlock(tree.Head !, CancellationToken.None);

            Assert.AreEqual(BlockVisitOutcome.None, result);
        }
예제 #15
0
        private BlockProducerContext GetProducerChain()
        {
            BlockProducerContext Create()
            {
                ReadOnlyDbProvider dbProvider = _api.DbProvider.AsReadOnly(false);
                ReadOnlyBlockTree  blockTree  = _api.BlockTree.AsReadOnly();

                ReadOnlyTxProcessingEnv txProcessingEnv =
                    new ReadOnlyTxProcessingEnv(dbProvider, _api.ReadOnlyTrieStore, blockTree, _api.SpecProvider, _api.LogManager);

                BlockProcessor blockProcessor =
                    CreateBlockProcessor(txProcessingEnv, txProcessingEnv, dbProvider);

                IBlockchainProcessor blockchainProcessor =
                    new BlockchainProcessor(
                        blockTree,
                        blockProcessor,
                        _api.BlockPreprocessor,
                        _api.LogManager,
                        BlockchainProcessor.Options.NoReceipts);

                OneTimeChainProcessor chainProcessor = new OneTimeChainProcessor(
                    dbProvider,
                    blockchainProcessor);

                return(new BlockProducerContext
                {
                    ChainProcessor = chainProcessor,
                    ReadOnlyStateProvider = txProcessingEnv.StateProvider,
                    TxSource = CreateTxSourceForProducer(txProcessingEnv, txProcessingEnv),
                    ReadOnlyTxProcessingEnv = txProcessingEnv
                });
            }

            return(_blockProducerContext ??= Create());
        }
            public ProcessingTestContext()
            {
                MemDb blockDb     = new MemDb();
                MemDb blockInfoDb = new MemDb();

                _blockTree      = new BlockTree(blockDb, blockInfoDb, MainNetSpecProvider.Instance, NullTransactionPool.Instance, NullLogManager.Instance);
                _blockProcessor = new BlockProcessorMock();
                _recoveryStep   = new RecoveryStepMock();
                _processor      = new BlockchainProcessor(_blockTree, _blockProcessor, _recoveryStep, NullLogManager.Instance, true, true);
                _resetEvent     = new AutoResetEvent(false);
//                _blockProcessor.BlockProcessed += (sender, args) =>
//                {
//                    Console.WriteLine($"Finished waiting for {args.Block.ToString(Block.Format.Short)} as block was processed");
//                    _resetEvent.Set();
//                };

                _blockTree.NewHeadBlock += (sender, args) =>
                {
                    Console.WriteLine($"Finished waiting for {args.Block.ToString(Block.Format.Short)} as block became the new head block");
                    _resetEvent.Set();
                };

                _processor.Start();
            }
예제 #17
0
 public BlockchainProcessorTests()
 {
     Processor = new BlockchainProcessor(MockProcessingStrategy.Object, MockBlockProcessor.Object);
 }
예제 #18
0
        private SyncTestContext CreateSyncManager(int index)
        {
            Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly);

            var logManager            = NoErrorLimboLogs.Instance;
            ConsoleAsyncLogger logger = new ConsoleAsyncLogger(LogLevel.Debug, "PEER " + index + " ");
//            var logManager = new OneLoggerLogManager(logger);
            var specProvider = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, MainNetSpecProvider.Instance.ChainId);

            MemDb   traceDb     = new MemDb();
            MemDb   blockDb     = new MemDb();
            MemDb   headerDb    = new MemDb();
            MemDb   blockInfoDb = new MemDb();
            StateDb codeDb      = new StateDb();
            StateDb stateDb     = new StateDb();

            var stateProvider = new StateProvider(stateDb, codeDb, logManager);

            stateProvider.CreateAccount(TestItem.AddressA, 10000.Ether());
            stateProvider.Commit(specProvider.GenesisSpec);
            stateProvider.CommitTree();
            stateDb.Commit();

            var storageProvider = new StorageProvider(stateDb, stateProvider, logManager);
            var receiptStorage  = new InMemoryReceiptStorage();

            var ecdsa             = new EthereumEcdsa(specProvider, logManager);
            var txPool            = new TxPool(new InMemoryTransactionStorage(), new PendingTransactionThresholdValidator(), new Timestamp(), ecdsa, specProvider, logManager);
            var tree              = new BlockTree(blockDb, headerDb, blockInfoDb, specProvider, txPool, logManager);
            var blockhashProvider = new BlockhashProvider(tree, LimboLogs.Instance);
            var virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logManager);

            var sealValidator   = TestSealValidator.AlwaysValid;
            var headerValidator = new HeaderValidator(tree, sealValidator, specProvider, logManager);
            var txValidator     = TestTxValidator.AlwaysValid;
            var ommersValidator = new OmmersValidator(tree, headerValidator, logManager);
            var blockValidator  = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);
//            var blockValidator = TestBlockValidator.AlwaysValid;

            SyncConfig syncConfig = new SyncConfig();

            syncConfig.FastSync = _synchronizerType == SynchronizerType.Fast;

            var rewardCalculator = new RewardCalculator(specProvider);
            var txProcessor      = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            var blockProcessor   = new BlockProcessor(specProvider, blockValidator, rewardCalculator, txProcessor, stateDb, codeDb, traceDb, stateProvider, storageProvider, txPool, receiptStorage, syncConfig, logManager);

            var step      = new TxSignaturesRecoveryStep(ecdsa, txPool, logManager);
            var processor = new BlockchainProcessor(tree, blockProcessor, step, logManager, true, true);

            var nodeStatsManager = new NodeStatsManager(new StatsConfig(), logManager);
            var syncPeerPool     = new EthSyncPeerPool(tree, nodeStatsManager, syncConfig, logManager);

            StateProvider   devState          = new StateProvider(stateDb, codeDb, logManager);
            StorageProvider devStorage        = new StorageProvider(stateDb, devState, logManager);
            var             devEvm            = new VirtualMachine(devState, devStorage, blockhashProvider, logManager);
            var             devTxProcessor    = new TransactionProcessor(specProvider, devState, devStorage, devEvm, logManager);
            var             devBlockProcessor = new BlockProcessor(specProvider, blockValidator, rewardCalculator, devTxProcessor, stateDb, codeDb, traceDb, devState, devStorage, txPool, receiptStorage, syncConfig, logManager);
            var             devChainProcessor = new BlockchainProcessor(tree, devBlockProcessor, step, logManager, false, false);
            var             producer          = new DevBlockProducer(txPool, devChainProcessor, tree, new Timestamp(), logManager);

            NodeDataFeed       feed         = new NodeDataFeed(codeDb, stateDb, logManager);
            NodeDataDownloader downloader   = new NodeDataDownloader(syncPeerPool, feed, logManager);
            Synchronizer       synchronizer = new Synchronizer(
                tree,
                blockValidator,
                sealValidator,
                syncPeerPool, syncConfig, downloader, logManager);
            var syncServer = new SyncServer(stateDb, codeDb, tree, receiptStorage, TestSealValidator.AlwaysValid, syncPeerPool, synchronizer, logManager);

            ManualResetEventSlim waitEvent = new ManualResetEventSlim();

            tree.NewHeadBlock += (s, e) => waitEvent.Set();

            if (index == 0)
            {
                _genesis = Build.A.Block.Genesis.WithStateRoot(stateProvider.StateRoot).TestObject;
                producer.Start();
            }

            syncPeerPool.Start();
            synchronizer.Start();
            processor.Start();
            tree.SuggestBlock(_genesis);

            if (!waitEvent.Wait(1000))
            {
                throw new Exception("No genesis");
            }

            SyncTestContext context = new SyncTestContext();

            context.Ecdsa = ecdsa;
            context.BlockchainProcessor = processor;
            context.PeerPool            = syncPeerPool;
            context.StateProvider       = stateProvider;
            context.Synchronizer        = synchronizer;
            context.SyncServer          = syncServer;
            context.Tree          = tree;
            context.BlockProducer = producer;
            context.TxPool        = txPool;
            context.Logger        = logger;
            return(context);
        }
예제 #19
0
            public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"CREATING NODE {privateKey.Address}");
                }
                _logManagers[privateKey] = LimboLogs.Instance;
//                _logManagers[privateKey] = new OneLoggerLogManager(new ConsoleAsyncLogger(LogLevel.Debug, $"{privateKey.Address} "));
                var nodeLogManager = _logManagers[privateKey];

                AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false);

                _blockEvents.Add(privateKey, newHeadBlockEvent);

                MemDb blocksDb    = new MemDb();
                MemDb headersDb   = new MemDb();
                MemDb blockInfoDb = new MemDb();

                MemDb stateDb = new MemDb();
                MemDb codeDb  = new MemDb();

                ISpecProvider specProvider = RinkebySpecProvider.Instance;

                var           trieStore     = new TrieStore(stateDb, nodeLogManager);
                StateReader   stateReader   = new StateReader(trieStore, codeDb, nodeLogManager);
                StateProvider stateProvider = new StateProvider(trieStore, codeDb, nodeLogManager);

                stateProvider.CreateAccount(TestItem.PrivateKeyD.Address, 100.Ether());
                GoerliSpecProvider goerliSpecProvider = GoerliSpecProvider.Instance;

                stateProvider.Commit(goerliSpecProvider.GenesisSpec);
                stateProvider.CommitTree(0);

                BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), goerliSpecProvider, NullBloomStorage.Instance, nodeLogManager);

                blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); };
                ITransactionComparerProvider transactionComparerProvider =
                    new TransactionComparerProvider(specProvider, blockTree);

                TxPool.TxPool txPool = new TxPool.TxPool(new InMemoryTxStorage(), _ethereumEcdsa, new ChainHeadInfoProvider(new FixedBlockChainHeadSpecProvider(GoerliSpecProvider.Instance), blockTree, stateProvider), new TxPoolConfig(), new TxValidator(goerliSpecProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer());
                _pools[privateKey] = txPool;

                BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);

                _blockTrees.Add(privateKey, blockTree);

                SnapshotManager snapshotManager = new SnapshotManager(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager);

                _snapshotManager[privateKey] = snapshotManager;
                CliqueSealer cliqueSealer = new CliqueSealer(new Signer(ChainId.Goerli, privateKey, LimboLogs.Instance), _cliqueConfig, snapshotManager, nodeLogManager);



                _genesis.Header.StateRoot       = _genesis3Validators.Header.StateRoot = stateProvider.StateRoot;
                _genesis.Header.Hash            = _genesis.Header.CalculateHash();
                _genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash();

                StorageProvider      storageProvider      = new StorageProvider(trieStore, stateProvider, nodeLogManager);
                TransactionProcessor transactionProcessor = new TransactionProcessor(goerliSpecProvider, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, nodeLogManager), nodeLogManager);

                BlockProcessor blockProcessor = new BlockProcessor(
                    goerliSpecProvider,
                    Always.Valid,
                    NoBlockRewards.Instance,
                    transactionProcessor,
                    stateProvider,
                    storageProvider,
                    txPool,
                    NullReceiptStorage.Instance,
                    NullWitnessCollector.Instance,
                    nodeLogManager);

                BlockchainProcessor processor = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, BlockchainProcessor.Options.NoReceipts);

                processor.Start();

                var minerTrieStore = trieStore.AsReadOnly();

                StateProvider        minerStateProvider        = new StateProvider(minerTrieStore, codeDb, nodeLogManager);
                StorageProvider      minerStorageProvider      = new StorageProvider(minerTrieStore, minerStateProvider, nodeLogManager);
                VirtualMachine       minerVirtualMachine       = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, specProvider, nodeLogManager);
                TransactionProcessor minerTransactionProcessor = new TransactionProcessor(goerliSpecProvider, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager);

                BlockProcessor minerBlockProcessor = new BlockProcessor(
                    goerliSpecProvider,
                    Always.Valid,
                    NoBlockRewards.Instance,
                    minerTransactionProcessor,
                    minerStateProvider,
                    minerStorageProvider,
                    txPool,
                    NullReceiptStorage.Instance,
                    NullWitnessCollector.Instance,
                    nodeLogManager);

                BlockchainProcessor minerProcessor = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, BlockchainProcessor.Options.NoReceipts);

                if (withGenesisAlreadyProcessed)
                {
                    ProcessGenesis(privateKey);
                }

                ITxFilterPipeline   txFilterPipeline = TxFilterPipelineBuilder.CreateStandardFilteringPipeline(nodeLogManager, specProvider);
                TxPoolTxSource      txPoolTxSource   = new TxPoolTxSource(txPool, stateReader, specProvider, transactionComparerProvider, nodeLogManager, txFilterPipeline);
                CliqueBlockProducer blockProducer    = new CliqueBlockProducer(
                    txPoolTxSource,
                    minerProcessor,
                    minerStateProvider,
                    blockTree,
                    _timestamper,
                    new CryptoRandom(),
                    snapshotManager,
                    cliqueSealer,
                    new TargetAdjustedGasLimitCalculator(goerliSpecProvider, new MiningConfig()),
                    MainnetSpecProvider.Instance,
                    _cliqueConfig,
                    nodeLogManager);

                blockProducer.Start();

                _producers.Add(privateKey, blockProducer);

                return(this);
            }
예제 #20
0
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

            TimeSpan miningDelay = TimeSpan.FromMilliseconds(50 * timeMultiplier);

            /* logging & instrumentation */
//            OneLoggerLogManager logger = new OneLoggerLogManager(new SimpleConsoleLogger(true));
            ILogManager logManager = NullLogManager.Instance;
            ILogger     logger     = logManager.GetClassLogger();

            /* spec */
            FakeSealer sealer = new FakeSealer(miningDelay);

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

            /* store & validation */

            EthereumEcdsa        ecdsa                = new EthereumEcdsa(specProvider, logManager);
            MemDb                receiptsDb           = new MemDb();
            MemDb                traceDb              = new MemDb();
            TxPool               txPool               = new TxPool(NullTxStorage.Instance, Timestamp.Default, ecdsa, specProvider, new TxPoolConfig(), logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, NullDb.Instance, specProvider, logManager);
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, txPool, logManager);
            Timestamp            timestamp            = new Timestamp();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TxValidator          txValidator          = new TxValidator(ChainId.Ropsten);
            BlockValidator       blockValidator       = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

            /* state & storage */
            StateDb         codeDb          = new StateDb();
            StateDb         stateDb         = new StateDb();
            StateProvider   stateProvider   = new StateProvider(stateDb, codeDb, logManager);
            StorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, logManager);

            TestTransactionsGenerator generator = new TestTransactionsGenerator(txPool, ecdsa, TimeSpan.FromMilliseconds(5 * timeMultiplier), NullLogManager.Instance);

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logManager);
            TransactionProcessor processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            RewardCalculator     rewardCalculator  = new RewardCalculator(specProvider);
            BlockProcessor       blockProcessor    = new BlockProcessor(specProvider, blockValidator, rewardCalculator,
                                                                        processor, stateDb, codeDb, traceDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ecdsa, NullTxPool.Instance, LimboLogs.Instance), logManager, false, false);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = "chainspec.json";

            logManager.GetClassLogger().Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllBytes(path));

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value.Balance);
                if (allocation.Value.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Value.Code);
                    stateProvider.UpdateCodeHash(allocation.Key, codeHash, specProvider.GenesisSpec);
                }
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; // TODO: shall it be HeaderSpec and not BlockHeader?
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);
            if (chainSpec.Genesis.Hash != new Keccak("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"))
            {
                throw new Exception("Unexpected genesis hash");
            }

            /* start processing */
            blockTree.SuggestBlock(chainSpec.Genesis);
            blockchainProcessor.Start();

            MinedBlockProducer minedBlockProducer = new MinedBlockProducer(difficultyCalculator, txPool, blockchainProcessor, sealer, blockTree, timestamp, NullLogManager.Instance);

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 6)
                {
                    manualResetEvent.Set();
                }
            };

            manualResetEvent.Wait(miningDelay * 12 * timeMultiplier);
            await minedBlockProducer.StopAsync();

            int previousCount = 0;
            int totalTx       = 0;

            for (int i = 0; i < 6; i++)
            {
                Block block = blockTree.FindBlock(i);
                logger.Info($"Block {i} with {block.Transactions.Length} txs");

                ManualResetEventSlim blockProcessedEvent = new ManualResetEventSlim(false);
                blockchainProcessor.ProcessingQueueEmpty += (sender, args) => blockProcessedEvent.Set();
                blockchainProcessor.SuggestBlock(block, ProcessingOptions.ForceProcessing | ProcessingOptions.StoreReceipts | ProcessingOptions.ReadOnlyChain);
                blockProcessedEvent.Wait(1000);

                Tracer tracer = new Tracer(blockchainProcessor, receiptStorage, blockTree, new MemDb());

                int currentCount = receiptsDb.Keys.Count;
                logger.Info($"Current count of receipts {currentCount}");
                logger.Info($"Previous count of receipts {previousCount}");

                if (block.Transactions.Length > 0)
                {
                    GethLikeTxTrace trace = tracer.Trace(block.Transactions[0].Hash);
                    Assert.AreSame(GethLikeTxTrace.QuickFail, trace);
                    Assert.AreNotEqual(previousCount, currentCount, $"receipts at block {i}");
                    totalTx += block.Transactions.Length;
                }

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }
예제 #21
0
        public void Initialize()
        {
            Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly);

            _ethSerializer = new EthereumJsonSerializer();
            ISpecProvider   specProvider  = MainNetSpecProvider.Instance;
            IEthereumEcdsa  ethereumEcdsa = new EthereumEcdsa(specProvider, LimboLogs.Instance);
            ITxStorage      txStorage     = new InMemoryTxStorage();
            ISnapshotableDb stateDb       = new StateDb();
            ISnapshotableDb codeDb        = new StateDb();
            IStateReader    stateReader   = new StateReader(stateDb, codeDb, LimboLogs.Instance);
            IStateProvider  stateProvider = new StateProvider(stateDb, codeDb, LimboLogs.Instance);

            stateProvider.CreateAccount(TestItem.AddressA, 1000.Ether());
            stateProvider.CreateAccount(TestItem.AddressB, 1000.Ether());
            stateProvider.CreateAccount(TestItem.AddressC, 1000.Ether());
            byte[] code     = Bytes.FromHexString("0xabcd");
            Keccak codeHash = Keccak.Compute(code);

            stateProvider.UpdateCode(code);
            stateProvider.UpdateCodeHash(TestItem.AddressA, codeHash, specProvider.GenesisSpec);

            IStorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, LimboLogs.Instance);

            storageProvider.Set(new StorageAddress(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef"));
            storageProvider.Commit();

            stateProvider.Commit(specProvider.GenesisSpec);

            ITxPool txPool = new TxPool(txStorage, Timestamper.Default, ethereumEcdsa, specProvider, new TxPoolConfig(), stateProvider, LimboLogs.Instance);

            IDb        blockDb     = new MemDb();
            IDb        headerDb    = new MemDb();
            IDb        blockInfoDb = new MemDb();
            IDb        traceDb     = new MemDb();
            IBlockTree blockTree   = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), specProvider, txPool, LimboLogs.Instance);

            IReceiptStorage      receiptStorage = new InMemoryReceiptStorage();
            VirtualMachine       virtualMachine = new VirtualMachine(stateProvider, storageProvider, new BlockhashProvider(blockTree, LimboLogs.Instance), specProvider, LimboLogs.Instance);
            TransactionProcessor txProcessor    = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, LimboLogs.Instance);
            IBlockProcessor      blockProcessor = new BlockProcessor(specProvider, AlwaysValidBlockValidator.Instance, new RewardCalculator(specProvider), txProcessor, stateDb, codeDb, traceDb, stateProvider, storageProvider, txPool, receiptStorage, LimboLogs.Instance);

            IFilterStore   filterStore   = new FilterStore();
            IFilterManager filterManager = new FilterManager(filterStore, blockProcessor, txPool, LimboLogs.Instance);

            _blockchainBridge = new BlockchainBridge(stateReader, stateProvider, storageProvider, blockTree, txPool, receiptStorage, filterStore, filterManager, NullWallet.Instance, txProcessor, ethereumEcdsa);

            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ethereumEcdsa, txPool, LimboLogs.Instance), LimboLogs.Instance, true, true);

            blockchainProcessor.Start();

            ManualResetEventSlim resetEvent = new ManualResetEventSlim(false);

            blockTree.NewHeadBlock += (s, e) =>
            {
                if (e.Block.Number == 9)
                {
                    resetEvent.Set();
                }
            };

            Block genesis = Build.A.Block.Genesis.WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")).TestObject;

            blockTree.SuggestBlock(genesis);

            Block previousBlock = genesis;

            for (int i = 1; i < 10; i++)
            {
                Block block = Build.A.Block.WithNumber(i).WithParent(previousBlock).WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")).TestObject;
                blockTree.SuggestBlock(block);
                previousBlock = block;
            }

            resetEvent.Wait();
            _ethModule = new EthModule(LimboLogs.Instance, _blockchainBridge);
            _blockTree = blockTree;
        }
예제 #22
0
        private Task InitBlockchain()
        {
            if (_context.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_context.ChainSpec));
            }
            if (_context.DbProvider == null)
            {
                throw new StepDependencyException(nameof(_context.DbProvider));
            }
            if (_context.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(_context.SpecProvider));
            }

            ILogger     logger     = _context.LogManager.GetClassLogger();
            IInitConfig initConfig = _context.Config <IInitConfig>();
            ISyncConfig syncConfig = _context.Config <ISyncConfig>();

            if (syncConfig.DownloadReceiptsInFastSync && !syncConfig.DownloadBodiesInFastSync)
            {
                logger.Warn($"{nameof(syncConfig.DownloadReceiptsInFastSync)} is selected but {nameof(syncConfig.DownloadBodiesInFastSync)} - enabling bodies to support receipts download.");
                syncConfig.DownloadBodiesInFastSync = true;
            }

            if (syncConfig.BeamSync)
            {
                logger.Warn("Welcome to the alpha version of the Nethermind Goerli Beam Sync. I will start by downloading the pivot block header and then will continue to download all the headers from the pivot upwards. After that I will be beam synchronizing the new blocks. Many things can fail - appreciated if you report issues via GitHub or Gitter.");
            }

            Account.AccountStartNonce = _context.ChainSpec.Parameters.AccountStartNonce;

            _context.StateProvider = new StateProvider(
                _context.DbProvider.StateDb,
                _context.DbProvider.CodeDb,
                _context.LogManager);

            _context.EthereumEcdsa = new EthereumEcdsa(_context.SpecProvider, _context.LogManager);
            _context.TxPool        = new TxPool.TxPool(
                new PersistentTxStorage(_context.DbProvider.PendingTxsDb, _context.SpecProvider),
                Timestamper.Default,
                _context.EthereumEcdsa,
                _context.SpecProvider,
                _context.Config <ITxPoolConfig>(),
                _context.StateProvider,
                _context.LogManager);

            _context.ReceiptStorage = new PersistentReceiptStorage(_context.DbProvider.ReceiptsDb, _context.SpecProvider, _context.LogManager);

            var bloomConfig = _context.Config <IBloomConfig>();

            _context.BloomStorage = bloomConfig.Index
                ? new BloomStorage(bloomConfig, _context.DbProvider.BloomDb, new FixedSizeFileStoreFactory(Path.Combine(initConfig.BaseDbPath, DbNames.Bloom), DbNames.Bloom, Bloom.ByteLength))
                : (IBloomStorage)NullBloomStorage.Instance;

            _context.DisposeStack.Push(_context.BloomStorage);

            _context.ChainLevelInfoRepository = new ChainLevelInfoRepository(_context.DbProvider.BlockInfosDb);

            _context.BlockTree = new BlockTree(
                _context.DbProvider.BlocksDb,
                _context.DbProvider.HeadersDb,
                _context.DbProvider.BlockInfosDb,
                _context.ChainLevelInfoRepository,
                _context.SpecProvider,
                _context.TxPool,
                _context.BloomStorage,
                _context.Config <ISyncConfig>(),
                _context.LogManager);

            // Init state if we need system calls before actual processing starts
            if (_context.BlockTree.Head != null)
            {
                _context.StateProvider.StateRoot = _context.BlockTree.Head.StateRoot;
            }

            _context.RecoveryStep = new TxSignaturesRecoveryStep(_context.EthereumEcdsa, _context.TxPool, _context.LogManager);

            _context.StorageProvider = new StorageProvider(
                _context.DbProvider.StateDb,
                _context.StateProvider,
                _context.LogManager);

            // blockchain processing
            BlockhashProvider blockhashProvider = new BlockhashProvider(
                _context.BlockTree, _context.LogManager);

            VirtualMachine virtualMachine = new VirtualMachine(
                _context.StateProvider,
                _context.StorageProvider,
                blockhashProvider,
                _context.SpecProvider,
                _context.LogManager);

            _context.TransactionProcessor = new TransactionProcessor(
                _context.SpecProvider,
                _context.StateProvider,
                _context.StorageProvider,
                virtualMachine,
                _context.LogManager);

            InitSealEngine();
            if (_context.SealValidator == null)
            {
                throw new StepDependencyException(nameof(_context.SealValidator));
            }

            /* validation */
            _context.HeaderValidator = new HeaderValidator(
                _context.BlockTree,
                _context.SealValidator,
                _context.SpecProvider,
                _context.LogManager);

            OmmersValidator ommersValidator = new OmmersValidator(
                _context.BlockTree,
                _context.HeaderValidator,
                _context.LogManager);

            TxValidator txValidator = new TxValidator(_context.SpecProvider.ChainId);

            _context.BlockValidator = new BlockValidator(
                txValidator,
                _context.HeaderValidator,
                ommersValidator,
                _context.SpecProvider,
                _context.LogManager);

            _context.TxPoolInfoProvider = new TxPoolInfoProvider(_context.StateProvider, _context.TxPool);

            _context.MainBlockProcessor = CreateBlockProcessor();

            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(
                _context.BlockTree,
                _context.MainBlockProcessor,
                _context.RecoveryStep,
                _context.LogManager,
                initConfig.StoreReceipts,
                !syncConfig.BeamSync);

            _context.BlockProcessingQueue = blockchainProcessor;
            _context.BlockchainProcessor  = blockchainProcessor;

            if (syncConfig.BeamSync)
            {
                _ = new BeamBlockchainProcessor(
                    new ReadOnlyDbProvider(_context.DbProvider, false),
                    _context.BlockTree,
                    _context.SpecProvider,
                    _context.LogManager,
                    _context.BlockValidator,
                    _context.RecoveryStep,
                    _context.RewardCalculatorSource,
                    _context.BlockProcessingQueue);
            }

            return(Task.CompletedTask);
        }
            public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"CREATING NODE {privateKey.Address}");
                }
                _logManagers[privateKey] = LimboLogs.Instance;
//                _logManagers[privateKey] = new OneLoggerLogManager(new ConsoleAsyncLogger(LogLevel.Debug, $"{privateKey.Address} "));
                var nodeLogManager = _logManagers[privateKey];

                AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false);

                _blockEvents.Add(privateKey, newHeadBlockEvent);

                MemDb blocksDb    = new MemDb();
                MemDb headersDb   = new MemDb();
                MemDb blockInfoDb = new MemDb();

                TxPool txPool = new TxPool(new InMemoryTransactionStorage(), new PendingTransactionThresholdValidator(), _timestamp, _ethereumEcdsa, GoerliSpecProvider.Instance, _logManager);

                _pools[privateKey] = txPool;

                BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfoDb, GoerliSpecProvider.Instance, txPool, nodeLogManager);

                blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); };

                BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree);

                _blockTrees.Add(privateKey, blockTree);

                IBasicWallet    wallet          = new BasicWallet(privateKey);
                SnapshotManager snapshotManager = new SnapshotManager(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager);

                _snapshotManager[privateKey] = snapshotManager;
                CliqueSealer cliqueSealer = new CliqueSealer(wallet, _cliqueConfig, snapshotManager, privateKey.Address, nodeLogManager);

                ISnapshotableDb stateDb = new StateDb();
                ISnapshotableDb codeDb  = new StateDb();
                IDb             traceDb = new MemDb();

                StateProvider stateProvider = new StateProvider(stateDb, codeDb, nodeLogManager);

                stateProvider.CreateAccount(TestItem.PrivateKeyD.Address, 100.Ether());
                stateProvider.Commit(GoerliSpecProvider.Instance.GenesisSpec);

                _genesis.StateRoot       = _genesis3Validators.StateRoot = stateProvider.StateRoot;
                _genesis.Hash            = BlockHeader.CalculateHash(_genesis.Header);
                _genesis3Validators.Hash = BlockHeader.CalculateHash(_genesis3Validators.Header);

                StorageProvider      storageProvider      = new StorageProvider(stateDb, stateProvider, nodeLogManager);
                TransactionProcessor transactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, nodeLogManager), nodeLogManager);
                BlockProcessor       blockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, NoBlockRewards.Instance, transactionProcessor, stateDb, codeDb, traceDb, stateProvider, storageProvider, txPool, NullReceiptStorage.Instance, new SyncConfig(), nodeLogManager);
                BlockchainProcessor  processor            = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false, false);

                processor.Start();

                StateProvider        minerStateProvider        = new StateProvider(stateDb, codeDb, nodeLogManager);
                StorageProvider      minerStorageProvider      = new StorageProvider(stateDb, minerStateProvider, nodeLogManager);
                VirtualMachine       minerVirtualMachine       = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, nodeLogManager);
                TransactionProcessor minerTransactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager);
                BlockProcessor       minerBlockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, NoBlockRewards.Instance, minerTransactionProcessor, stateDb, codeDb, traceDb, minerStateProvider, minerStorageProvider, txPool, NullReceiptStorage.Instance, new SyncConfig(), nodeLogManager);
                BlockchainProcessor  minerProcessor            = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false, false);

                if (withGenesisAlreadyProcessed)
                {
                    ProcessGenesis(privateKey);
                }

                CliqueBlockProducer blockProducer = new CliqueBlockProducer(txPool, minerProcessor, blockTree, _timestamp, new CryptoRandom(), minerStateProvider, snapshotManager, cliqueSealer, privateKey.Address, _cliqueConfig, nodeLogManager);

                blockProducer.Start();

                _producers.Add(privateKey, blockProducer);

                return(this);
            }
예제 #24
0
        private SyncTestContext CreateSyncManager(int index)
        {
            var logManager            = NoErrorLimboLogs.Instance;
            ConsoleAsyncLogger logger = new ConsoleAsyncLogger(LogLevel.Debug, "PEER " + index + " ");
//            var logManager = new OneLoggerLogManager(logger);
            var specProvider = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, MainnetSpecProvider.Instance.ChainId);

            var             dbProvider  = TestMemDbProvider.Init();
            IDb             blockDb     = dbProvider.BlocksDb;
            IDb             headerDb    = dbProvider.HeadersDb;
            IDb             blockInfoDb = dbProvider.BlockInfosDb;
            ISnapshotableDb codeDb      = dbProvider.CodeDb;
            ISnapshotableDb stateDb     = dbProvider.StateDb;

            var stateReader   = new StateReader(stateDb, codeDb, logManager);
            var stateProvider = new StateProvider(stateDb, codeDb, logManager);

            stateProvider.CreateAccount(TestItem.AddressA, 10000.Ether());
            stateProvider.Commit(specProvider.GenesisSpec);
            stateProvider.CommitTree();
            stateProvider.RecalculateStateRoot();
            stateDb.Commit();

            var storageProvider = new StorageProvider(stateDb, stateProvider, logManager);
            var receiptStorage  = new InMemoryReceiptStorage();

            var ecdsa             = new EthereumEcdsa(specProvider.ChainId, logManager);
            var txPool            = new TxPool.TxPool(new InMemoryTxStorage(), ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager);
            var tree              = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, logManager);
            var blockhashProvider = new BlockhashProvider(tree, LimboLogs.Instance);
            var virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, logManager);

            var sealValidator   = Always.Valid;
            var headerValidator = new HeaderValidator(tree, sealValidator, specProvider, logManager);
            var txValidator     = Always.Valid;
            var ommersValidator = new OmmersValidator(tree, headerValidator, logManager);
            var blockValidator  = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

            ISyncConfig syncConfig = _synchronizerType == SynchronizerType.Fast ? SyncConfig.WithFastSync : SyncConfig.WithFullSyncOnly;

            var rewardCalculator = new RewardCalculator(specProvider);
            var txProcessor      = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            var blockProcessor   = new BlockProcessor(specProvider, blockValidator, rewardCalculator, txProcessor, stateDb, codeDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);

            var step      = new RecoverSignatures(ecdsa, txPool, specProvider, logManager);
            var processor = new BlockchainProcessor(tree, blockProcessor, step, logManager, BlockchainProcessor.Options.Default);

            var nodeStatsManager = new NodeStatsManager(logManager);
            var syncPeerPool     = new SyncPeerPool(tree, nodeStatsManager, 25, logManager);

            StateProvider   devState            = new StateProvider(stateDb, codeDb, logManager);
            StorageProvider devStorage          = new StorageProvider(stateDb, devState, logManager);
            var             devEvm              = new VirtualMachine(devState, devStorage, blockhashProvider, specProvider, logManager);
            var             devTxProcessor      = new TransactionProcessor(specProvider, devState, devStorage, devEvm, logManager);
            var             devBlockProcessor   = new BlockProcessor(specProvider, blockValidator, rewardCalculator, devTxProcessor, stateDb, codeDb, devState, devStorage, txPool, receiptStorage, logManager);
            var             devChainProcessor   = new BlockchainProcessor(tree, devBlockProcessor, step, logManager, BlockchainProcessor.Options.NoReceipts);
            var             transactionSelector = new TxPoolTxSource(txPool, stateReader, logManager);
            var             producer            = new DevBlockProducer(
                transactionSelector,
                devChainProcessor,
                stateProvider, tree,
                processor,
                txPool,
                Timestamper.Default,
                logManager);

            SyncProgressResolver  resolver     = new SyncProgressResolver(tree, receiptStorage, stateDb, new MemDb(), syncConfig, logManager);
            MultiSyncModeSelector selector     = new MultiSyncModeSelector(resolver, syncPeerPool, syncConfig, logManager);
            Synchronizer          synchronizer = new Synchronizer(
                dbProvider,
                MainnetSpecProvider.Instance,
                tree,
                NullReceiptStorage.Instance,
                blockValidator,
                sealValidator,
                syncPeerPool,
                nodeStatsManager,
                StaticSelector.Full,
                syncConfig,
                logManager);
            var syncServer = new SyncServer(stateDb, codeDb, tree, receiptStorage, Always.Valid, Always.Valid, syncPeerPool, selector, syncConfig, logManager);

            ManualResetEventSlim waitEvent = new ManualResetEventSlim();

            tree.NewHeadBlock += (s, e) => waitEvent.Set();

            if (index == 0)
            {
                _genesis = Build.A.Block.Genesis.WithStateRoot(stateProvider.StateRoot).TestObject;
                producer.Start();
            }

            syncPeerPool.Start();
            synchronizer.Start();
            processor.Start();
            tree.SuggestBlock(_genesis);

            if (!waitEvent.Wait(1000))
            {
                throw new Exception("No genesis");
            }

            SyncTestContext context = new SyncTestContext();

            context.Ecdsa = ecdsa;
            context.BlockchainProcessor = processor;
            context.PeerPool            = syncPeerPool;
            context.StateProvider       = stateProvider;
            context.Synchronizer        = synchronizer;
            context.SyncServer          = syncServer;
            context.Tree          = tree;
            context.BlockProducer = producer;
            context.TxPool        = txPool;
            context.Logger        = logger;
            return(context);
        }
예제 #25
0
        // It takes dotCover to run it quite long, increased timeouts
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

            TimeSpan miningDelay = TimeSpan.FromMilliseconds(200 * timeMultiplier);

            /* logging & instrumentation */
//            OneLoggerLogManager logger = new OneLoggerLogManager(new SimpleConsoleLogger(true));
            ILogManager logManager = LimboLogs.Instance;
            ILogger     logger     = logManager.GetClassLogger();

            /* spec */
            FakeSealer sealer = new FakeSealer(miningDelay);

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

            /* state & storage */
            StateDb         codeDb          = new StateDb();
            StateDb         stateDb         = new StateDb();
            StateProvider   stateProvider   = new StateProvider(stateDb, codeDb, logManager);
            StorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, logManager);

            /* store & validation */

            EthereumEcdsa ecdsa      = new EthereumEcdsa(specProvider, logManager);
            MemDb         receiptsDb = new MemDb();

            TxPool.TxPool        txPool               = new TxPool.TxPool(NullTxStorage.Instance, Timestamper.Default, ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, specProvider, logManager);
            var                  blockInfoDb          = new MemDb();
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, txPool, NullBloomStorage.Instance, logManager);
            Timestamper          timestamper          = new Timestamper();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TxValidator          txValidator          = new TxValidator(ChainId.Ropsten);
            BlockValidator       blockValidator       = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

            TestTransactionsGenerator generator = new TestTransactionsGenerator(txPool, ecdsa, TimeSpan.FromMilliseconds(50 * timeMultiplier), LimboLogs.Instance);

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, logManager);
            TransactionProcessor processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            RewardCalculator     rewardCalculator  = new RewardCalculator(specProvider);
            BlockProcessor       blockProcessor    = new BlockProcessor(specProvider, blockValidator, rewardCalculator,
                                                                        processor, stateDb, codeDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ecdsa, NullTxPool.Instance, LimboLogs.Instance), logManager, false);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = "chainspec.json";

            logManager.GetClassLogger().Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllText(path));

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value.Balance);
                if (allocation.Value.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Value.Code);
                    stateProvider.UpdateCodeHash(allocation.Key, codeHash, specProvider.GenesisSpec);
                }
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot;
            chainSpec.Genesis.Header.Hash      = chainSpec.Genesis.Header.CalculateHash();
            if (chainSpec.Genesis.Hash != new Keccak("0xafbc3c327d2d18ff2b843e89226ef288fcee379542f854f982e4cfb85916d126"))
            {
                throw new Exception("Unexpected genesis hash");
            }

            /* start processing */
            blockTree.SuggestBlock(chainSpec.Genesis);
            blockchainProcessor.Start();

            var transactionSelector = new PendingTxSelector(txPool, stateProvider, logManager);
            MinedBlockProducer minedBlockProducer = new MinedBlockProducer(transactionSelector, blockchainProcessor, sealer, blockTree, blockchainProcessor, stateProvider, timestamper, LimboLogs.Instance, difficultyCalculator);

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 6)
                {
                    manualResetEvent.Set();
                }
            };

            manualResetEvent.Wait(miningDelay * 100);
            await minedBlockProducer.StopAsync();

            int previousCount = 0;
            int totalTx       = 0;

            for (int i = 0; i < 6; i++)
            {
                Block block = blockTree.FindBlock(i, BlockTreeLookupOptions.None);
                Assert.That(block, Is.Not.Null, $"Block {i} not produced");
                logger.Info($"Block {i} with {block.Transactions.Length} txs");

                ManualResetEventSlim blockProcessedEvent = new ManualResetEventSlim(false);
                blockchainProcessor.ProcessingQueueEmpty += (sender, args) => blockProcessedEvent.Set();
                blockchainProcessor.Enqueue(block, ProcessingOptions.ForceProcessing | ProcessingOptions.StoreReceipts | ProcessingOptions.ReadOnlyChain);
                blockProcessedEvent.Wait(miningDelay);

                GethStyleTracer gethStyleTracer = new GethStyleTracer(blockchainProcessor, receiptStorage, blockTree);

                int currentCount = receiptsDb.Keys.Count;
                logger.Info($"Current count of receipts {currentCount}");
                logger.Info($"Previous count of receipts {previousCount}");

                if (block.Transactions.Length > 0)
                {
                    Assert.AreNotEqual(previousCount, currentCount, $"receipts at block {i}");
                    totalTx += block.Transactions.Length;
                }

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }
예제 #26
0
        private void Initialize(bool auRa = false)
        {
            ISpecProvider  specProvider  = MainnetSpecProvider.Instance;
            IEthereumEcdsa ethereumEcdsa = new EthereumEcdsa(specProvider, LimboLogs.Instance);
            ITxStorage     txStorage     = new InMemoryTxStorage();

            _stateDb = new StateDb();
            ISnapshotableDb codeDb      = new StateDb();
            IStateReader    stateReader = new StateReader(_stateDb, codeDb, LimboLogs.Instance);

            _stateProvider = new StateProvider(_stateDb, codeDb, LimboLogs.Instance);
            _stateProvider.CreateAccount(TestItem.AddressA, 1000.Ether());
            _stateProvider.CreateAccount(TestItem.AddressB, 1000.Ether());
            _stateProvider.CreateAccount(TestItem.AddressC, 1000.Ether());
            byte[] code     = Bytes.FromHexString("0xabcd");
            Keccak codeHash = Keccak.Compute(code);

            _stateProvider.UpdateCode(code);
            _stateProvider.UpdateCodeHash(TestItem.AddressA, codeHash, specProvider.GenesisSpec);

            IStorageProvider storageProvider = new StorageProvider(_stateDb, _stateProvider, LimboLogs.Instance);

            storageProvider.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef"));
            storageProvider.Commit();

            _stateProvider.Commit(specProvider.GenesisSpec);
            _stateProvider.CommitTree();

            ITxPool txPool = new TxPool.TxPool(txStorage, Timestamper.Default, ethereumEcdsa, specProvider, new TxPoolConfig(), _stateProvider, LimboLogs.Instance);

            IDb        blockDb     = new MemDb();
            IDb        headerDb    = new MemDb();
            IDb        blockInfoDb = new MemDb();
            IBlockTree blockTree   = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), specProvider, txPool, NullBloomStorage.Instance, LimboLogs.Instance);

            IReceiptStorage      receiptStorage = new InMemoryReceiptStorage();
            VirtualMachine       virtualMachine = new VirtualMachine(_stateProvider, storageProvider, new BlockhashProvider(blockTree, LimboLogs.Instance), specProvider, LimboLogs.Instance);
            TransactionProcessor txProcessor    = new TransactionProcessor(specProvider, _stateProvider, storageProvider, virtualMachine, LimboLogs.Instance);
            IBlockProcessor      blockProcessor = new BlockProcessor(specProvider, Always.Valid, new RewardCalculator(specProvider), txProcessor, _stateDb, codeDb, _stateProvider, storageProvider, txPool, receiptStorage, LimboLogs.Instance);

            IFilterStore   filterStore   = new FilterStore();
            IFilterManager filterManager = new FilterManager(filterStore, blockProcessor, txPool, LimboLogs.Instance);

            _blockchainBridge = new BlockchainBridge(stateReader, _stateProvider, storageProvider, blockTree, txPool, receiptStorage, filterStore, filterManager, NullWallet.Instance, txProcessor, ethereumEcdsa, NullBloomStorage.Instance, LimboLogs.Instance, false);

            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ethereumEcdsa, txPool, LimboLogs.Instance), LimboLogs.Instance, true);

            blockchainProcessor.Start();

            ManualResetEventSlim resetEvent = new ManualResetEventSlim(false);

            blockTree.NewHeadBlock += (s, e) =>
            {
                Console.WriteLine(e.Block.Header.Hash);
                if (e.Block.Number == 9)
                {
                    resetEvent.Set();
                }
            };

            var genesisBlockBuilder = Build.A.Block.Genesis.WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f"));

            if (auRa)
            {
                genesisBlockBuilder.WithAura(0, new byte[65]);
            }

            Block genesis = genesisBlockBuilder.TestObject;

            blockTree.SuggestBlock(genesis);

            Block previousBlock = genesis;

            for (int i = 1; i < 10; i++)
            {
                List <Transaction> transactions = new List <Transaction>();
                for (int j = 0; j < i; j++)
                {
                    transactions.Add(Build.A.Transaction.WithNonce((UInt256)j).SignedAndResolved().TestObject);
                }

                BlockBuilder builder = Build.A.Block.WithNumber(i).WithParent(previousBlock).WithTransactions(transactions.ToArray()).WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f"));
                if (auRa)
                {
                    builder.WithAura(i, i.ToByteArray());
                }

                Block block = builder.TestObject;
                blockTree.SuggestBlock(block);
                previousBlock = block;
            }

            IReceiptsRecovery receiptsRecovery = new ReceiptsRecovery();
            IReceiptFinder    receiptFinder    = new FullInfoReceiptFinder(receiptStorage, receiptsRecovery, blockTree);

            resetEvent.Wait(2000);
            _traceModule = new TraceModule(receiptFinder, new Tracer(_stateProvider, blockchainProcessor), _blockchainBridge);
            _blockTree   = blockTree;
        }
예제 #27
0
        protected virtual async Task <TestBlockchain> Build(ISpecProvider specProvider = null, UInt256?initialValues = null)
        {
            Timestamper    = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc));
            JsonSerializer = new EthereumJsonSerializer();
            SpecProvider   = specProvider ?? MainnetSpecProvider.Instance;
            EthereumEcdsa  = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance);
            ITxStorage txStorage = new InMemoryTxStorage();

            DbProvider = await TestMemDbProvider.InitAsync();

            State = new StateProvider(StateDb, CodeDb, LimboLogs.Instance);
            State.CreateAccount(TestItem.AddressA, (initialValues ?? 1000.Ether()));
            State.CreateAccount(TestItem.AddressB, (initialValues ?? 1000.Ether()));
            State.CreateAccount(TestItem.AddressC, (initialValues ?? 1000.Ether()));
            byte[] code     = Bytes.FromHexString("0xabcd");
            Keccak codeHash = Keccak.Compute(code);

            State.UpdateCode(code);
            State.UpdateCodeHash(TestItem.AddressA, codeHash, SpecProvider.GenesisSpec);

            Storage = new StorageProvider(StateDb, State, LimboLogs.Instance);
            Storage.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef"));
            Storage.Commit();

            State.Commit(SpecProvider.GenesisSpec);
            State.CommitTree();

            TxPool = new TxPool.TxPool(
                txStorage,
                EthereumEcdsa,
                SpecProvider,
                new TxPoolConfig(),
                new StateProvider(StateDb, CodeDb, LimboLogs.Instance),
                LimboLogs.Instance);

            IDb blockDb     = new MemDb();
            IDb headerDb    = new MemDb();
            IDb blockInfoDb = new MemDb();

            BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), SpecProvider, NullBloomStorage.Instance, LimboLogs.Instance);
            new OnChainTxWatcher(BlockTree, TxPool, SpecProvider, LimboLogs.Instance);

            ReceiptStorage = new InMemoryReceiptStorage();
            VirtualMachine virtualMachine = new VirtualMachine(State, Storage, new BlockhashProvider(BlockTree, LimboLogs.Instance), SpecProvider, LimboLogs.Instance);

            TxProcessor    = new TransactionProcessor(SpecProvider, State, Storage, virtualMachine, LimboLogs.Instance);
            BlockProcessor = CreateBlockProcessor();

            BlockchainProcessor chainProcessor = new BlockchainProcessor(BlockTree, BlockProcessor, new RecoverSignatures(EthereumEcdsa, TxPool, SpecProvider, LimboLogs.Instance), LimboLogs.Instance, Nethermind.Blockchain.Processing.BlockchainProcessor.Options.Default);

            BlockchainProcessor = chainProcessor;
            chainProcessor.Start();

            StateReader = new StateReader(StateDb, CodeDb, LimboLogs.Instance);
            TxPoolTxSource txPoolTxSource = CreateTxPoolTxSource();
            ISealer        sealer         = new NethDevSealEngine(TestItem.AddressD);

            BlockProducer = new TestBlockProducer(txPoolTxSource, chainProcessor, State, sealer, BlockTree, chainProcessor, Timestamper, LimboLogs.Instance);
            BlockProducer.Start();

            _resetEvent = new SemaphoreSlim(0);
            _suggestedBlockResetEvent = new ManualResetEvent(true);
            BlockTree.NewHeadBlock   += (s, e) =>
            {
                _resetEvent.Release(1);
            };
            BlockProducer.LastProducedBlockChanged += (s, e) =>
            {
                _suggestedBlockResetEvent.Set();
            };

            var genesis = GetGenesisBlock();

            BlockTree.SuggestBlock(genesis);
            await _resetEvent.WaitAsync();

            //if (!await _resetEvent.WaitAsync(1000))
            // {
            //     throw new InvalidOperationException("Failed to process genesis in 1s.");
            // }

            await AddBlocksOnStart();

            return(this);
        }
예제 #28
0
        protected async Task RunTest(LegacyBlockchainTest test, Stopwatch stopwatch = null)
        {
            TestContext.Write($"Running {test.Name} at {DateTime.UtcNow:HH:mm:ss.ffffff}");
            Assert.IsNull(test.LoadFailure, "test data loading failure");

            ISnapshotableDb stateDb = new StateDb();
            ISnapshotableDb codeDb  = new StateDb();
            IDb             traceDb = new MemDb();

            ISpecProvider specProvider;

            if (test.NetworkAfterTransition != null)
            {
                specProvider = new CustomSpecProvider(
                    (0, Frontier.Instance),
                    (1, test.Network),
                    (test.TransitionBlockNumber, test.NetworkAfterTransition));
            }
            else
            {
                specProvider = new CustomSpecProvider(
                    (0, Frontier.Instance), // TODO: this thing took a lot of time to find after it was removed!, genesis block is always initialized with Frontier
                    (1, test.Network));
            }

            if (specProvider.GenesisSpec != Frontier.Instance)
            {
                Assert.Fail("Expected genesis spec to be Frontier for blockchain tests");
            }

            DifficultyCalculator.Wrapped = new DifficultyCalculator(specProvider);
            IRewardCalculator rewardCalculator = new RewardCalculator(specProvider);

            IEthereumEcdsa     ecdsa             = new EthereumEcdsa(specProvider, _logManager);
            IStateProvider     stateProvider     = new StateProvider(stateDb, codeDb, _logManager);
            ITxPool            transactionPool   = new TxPool(NullTxStorage.Instance, new Timestamper(), ecdsa, specProvider, new TxPoolConfig(), stateProvider, _logManager);
            IReceiptStorage    receiptStorage    = NullReceiptStorage.Instance;
            var                blockInfoDb       = new MemDb();
            IBlockTree         blockTree         = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, transactionPool, _logManager);
            IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager);
            ITxValidator       txValidator       = new TxValidator(ChainId.MainNet);
            IHeaderValidator   headerValidator   = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
            IOmmersValidator   ommersValidator   = new OmmersValidator(blockTree, headerValidator, _logManager);
            IBlockValidator    blockValidator    = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, _logManager);
            IStorageProvider   storageProvider   = new StorageProvider(stateDb, stateProvider, _logManager);
            IVirtualMachine    virtualMachine    = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                specProvider,
                _logManager);

            IBlockProcessor blockProcessor = new BlockProcessor(
                specProvider,
                blockValidator,
                rewardCalculator,
                new TransactionProcessor(
                    specProvider,
                    stateProvider,
                    storageProvider,
                    virtualMachine,
                    _logManager),
                stateDb,
                codeDb,
                traceDb,
                stateProvider,
                storageProvider,
                transactionPool,
                receiptStorage,
                _logManager);

            IBlockchainProcessor blockchainProcessor = new BlockchainProcessor(
                blockTree,
                blockProcessor,
                new TxSignaturesRecoveryStep(ecdsa, NullTxPool.Instance, _logManager),
                _logManager,
                false,
                false);

            InitializeTestState(test, stateProvider, storageProvider, specProvider);

            List <(Block Block, string ExpectedException)> correctRlpsBlocks = new List <(Block, string)>();

            for (int i = 0; i < test.Blocks.Length; i++)
            {
                try
                {
                    TestBlockJson testBlockJson  = test.Blocks[i];
                    var           rlpContext     = Bytes.FromHexString(testBlockJson.Rlp).AsRlpStream();
                    Block         suggestedBlock = Rlp.Decode <Block>(rlpContext);
                    suggestedBlock.Header.SealEngineType = test.SealEngineUsed ? SealEngineType.Ethash : SealEngineType.None;

                    Assert.AreEqual(new Keccak(testBlockJson.BlockHeader.Hash), suggestedBlock.Header.Hash, "hash of the block");
                    for (int ommerIndex = 0; ommerIndex < suggestedBlock.Ommers.Length; ommerIndex++)
                    {
                        Assert.AreEqual(new Keccak(testBlockJson.UncleHeaders[ommerIndex].Hash), suggestedBlock.Ommers[ommerIndex].Hash, "hash of the ommer");
                    }

                    correctRlpsBlocks.Add((suggestedBlock, testBlockJson.ExpectedException));
                }
                catch (Exception)
                {
                    _logger?.Info($"Invalid RLP ({i})");
                }
            }

            if (correctRlpsBlocks.Count == 0)
            {
                Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), test.LastBlockHash);
                return;
            }

            if (test.GenesisRlp == null)
            {
                test.GenesisRlp = Rlp.Encode(new Block(JsonToBlockchainTest.Convert(test.GenesisBlockHeader)));
            }

            Block genesisBlock = Rlp.Decode <Block>(test.GenesisRlp.Bytes);

            Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), genesisBlock.Header.Hash, "genesis header hash");

            ManualResetEvent genesisProcessed = new ManualResetEvent(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 0)
                {
                    Assert.AreEqual(genesisBlock.Header.StateRoot, stateProvider.StateRoot, "genesis state root");
                    genesisProcessed.Set();
                }
            };

            blockchainProcessor.Start();
            blockTree.SuggestBlock(genesisBlock);

            genesisProcessed.WaitOne();

            for (int i = 0; i < correctRlpsBlocks.Count; i++)
            {
                stopwatch?.Start();
                try
                {
                    if (correctRlpsBlocks[i].ExpectedException != null)
                    {
                        _logger.Info($"Expecting block exception: {correctRlpsBlocks[i].ExpectedException}");
                    }

                    if (correctRlpsBlocks[i].Block.Hash == null)
                    {
                        throw new Exception($"null hash in {test.Name} block {i}");
                    }

                    // TODO: mimic the actual behaviour where block goes through validating sync manager?
                    if (!test.SealEngineUsed || blockValidator.ValidateSuggestedBlock(correctRlpsBlocks[i].Block))
                    {
                        blockTree.SuggestBlock(correctRlpsBlocks[i].Block);
                    }
                    else
                    {
                        Console.WriteLine("Invalid block");
                    }
                }
                catch (InvalidBlockException)
                {
                }
                catch (Exception ex)
                {
                    _logger?.Info(ex.ToString());
                }
            }

            await blockchainProcessor.StopAsync(true);

            stopwatch?.Stop();

            List <string> differences = RunAssertions(test, blockTree.RetrieveHeadBlock(), storageProvider, stateProvider);

//            if (differences.Any())
//            {
//                BlockTrace blockTrace = blockchainProcessor.TraceBlock(blockTree.BestSuggested.Hash);
//                _logger.Info(new UnforgivingJsonSerializer().Serialize(blockTrace, true));
//            }

            Assert.Zero(differences.Count, "differences");
        }
예제 #29
0
        private static async Task RunBenchmarkBlocks()
        {
            Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly);

            /* logging & instrumentation */
            _logManager = new NLogManager("perfTest.logs.txt", null);
            _logger     = _logManager.GetClassLogger();

            if (_logger.IsInfo)
            {
                _logger.Info("Deleting state DBs");
            }

            DeleteDb(FullStateDbPath);
            DeleteDb(FullCodeDbPath);
            DeleteDb(FullReceiptsDbPath);
            DeleteDb(FullPendingTxsDbPath);
            if (_logger.IsInfo)
            {
                _logger.Info("State DBs deleted");
            }

            /* load spec */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"chainspec", "ropsten.json"));

            _logger.Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllText(path));

            _logger.Info($"ChainSpec loaded");

            var specProvider = new ChainSpecBasedSpecProvider(chainSpec);
            IRewardCalculator rewardCalculator = new RewardCalculator(specProvider);

            var dbProvider   = new RocksDbProvider(DbBasePath, DbConfig.Default, _logManager, true, true);
            var stateDb      = dbProvider.StateDb;
            var codeDb       = dbProvider.CodeDb;
            var traceDb      = dbProvider.TraceDb;
            var blocksDb     = dbProvider.BlocksDb;
            var headersDb    = dbProvider.HeadersDb;
            var blockInfosDb = dbProvider.BlockInfosDb;
            var receiptsDb   = dbProvider.ReceiptsDb;

            /* state & storage */
            var stateProvider   = new StateProvider(stateDb, codeDb, _logManager);
            var storageProvider = new StorageProvider(stateDb, stateProvider, _logManager);

            var ethereumSigner = new EthereumEcdsa(specProvider, _logManager);

            var transactionPool = new TxPool(
                NullTxStorage.Instance,
                Timestamper.Default,
                ethereumSigner,
                specProvider,
                new TxPoolConfig(),
                stateProvider,
                _logManager);

            var blockInfoRepository = new ChainLevelInfoRepository(blockInfosDb);
            var blockTree           = new UnprocessedBlockTreeWrapper(new BlockTree(blocksDb, headersDb, blockInfosDb, blockInfoRepository, specProvider, transactionPool, _logManager));
            var receiptStorage      = new InMemoryReceiptStorage();

            IBlockDataRecoveryStep recoveryStep = new TxSignaturesRecoveryStep(ethereumSigner, transactionPool, _logManager);

            /* blockchain processing */
            IList <IAdditionalBlockProcessor> blockProcessors = new List <IAdditionalBlockProcessor>();
            var blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            var virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, _logManager);
            var processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, _logManager);

            ISealValidator sealValidator;

            if (specProvider.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                var difficultyCalculator = new DifficultyCalculator(specProvider);
                sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager));
            }
            else if (chainSpec.SealEngineType == SealEngineType.Clique)
            {
                var snapshotManager = new SnapshotManager(CliqueConfig.Default, blocksDb, blockTree, ethereumSigner, _logManager);
                sealValidator    = new CliqueSealValidator(CliqueConfig.Default, snapshotManager, _logManager);
                rewardCalculator = NoBlockRewards.Instance;
                recoveryStep     = new CompositeDataRecoveryStep(recoveryStep, new AuthorRecoveryStep(snapshotManager));
            }
            else if (chainSpec.SealEngineType == SealEngineType.AuRa)
            {
                var abiEncoder         = new AbiEncoder();
                var validatorProcessor = new AuRaAdditionalBlockProcessorFactory(dbProvider.StateDb, stateProvider, abiEncoder, processor, blockTree, receiptStorage, _logManager)
                                         .CreateValidatorProcessor(chainSpec.AuRa.Validators);

                sealValidator    = new AuRaSealValidator(chainSpec.AuRa, new AuRaStepCalculator(chainSpec.AuRa.StepDuration, new Timestamper()), validatorProcessor, ethereumSigner, _logManager);
                rewardCalculator = new AuRaRewardCalculator(chainSpec.AuRa, abiEncoder, processor);
                blockProcessors.Add(validatorProcessor);
            }
            else
            {
                throw new NotSupportedException();
            }

            /* store & validation */
            var headerValidator      = new HeaderValidator(blockTree, sealValidator, specProvider, _logManager);
            var ommersValidator      = new OmmersValidator(blockTree, headerValidator, _logManager);
            var transactionValidator = new TxValidator(chainSpec.ChainId);
            var blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, _logManager);

            /* blockchain processing */
            var blockProcessor      = new BlockProcessor(specProvider, blockValidator, rewardCalculator, processor, stateDb, codeDb, traceDb, stateProvider, storageProvider, transactionPool, receiptStorage, _logManager, blockProcessors);
            var blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, recoveryStep, _logManager, true, false);

            if (chainSpec.SealEngineType == SealEngineType.AuRa)
            {
                stateProvider.CreateAccount(Address.Zero, UInt256.Zero);
                storageProvider.Commit();
                stateProvider.Commit(Homestead.Instance);
                var finalizationManager = new AuRaBlockFinalizationManager(blockTree, blockInfoRepository, blockProcessor, blockProcessors.OfType <IAuRaValidator>().First(), _logManager);
            }

            foreach ((Address address, ChainSpecAllocation allocation) in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(address, allocation.Balance);
                if (allocation.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Code);
                    stateProvider.UpdateCodeHash(address, codeHash, specProvider.GenesisSpec);
                }

                if (allocation.Constructor != null)
                {
                    Transaction constructorTransaction = new Transaction(true)
                    {
                        SenderAddress = address,
                        Init          = allocation.Constructor,
                        GasLimit      = chainSpec.Genesis.GasLimit
                    };

                    processor.Execute(constructorTransaction, chainSpec.Genesis.Header, NullTxTracer.Instance);
                }
            }

            _logger.Info($"Allocations configured, committing...");

            stateProvider.Commit(specProvider.GenesisSpec);

            _logger.Info($"Finalizing genesis...");
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot;
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);

            if (chainSpec.Genesis.Hash != blockTree.Genesis.Hash)
            {
                throw new Exception("Unexpected genesis hash");
            }

            _logger.Info($"Starting benchmark processor...");
            /* start processing */
            BigInteger totalGas  = BigInteger.Zero;
            Stopwatch  stopwatch = new Stopwatch();
            Block      currentHead;
            long       maxMemory = 0;

            blockTree.NewHeadBlock += (sender, args) =>
            {
                currentHead = args.Block;
                if (currentHead.Number == 0)
                {
                    return;
                }

                maxMemory = Math.Max(maxMemory, GC.GetTotalMemory(false));
                totalGas += currentHead.GasUsed;
                if ((BigInteger)args.Block.Number % 10000 == 9999)
                {
                    stopwatch.Stop();
                    long       ms     = 1_000L * stopwatch.ElapsedTicks / Stopwatch.Frequency;
                    BigInteger number = args.Block.Number + 1;
                    _logger.Warn($"TOTAL after {number} (ms)       : " + ms);
                    _logger.Warn($"TOTAL after {number} blocks/s   : {(decimal) currentHead.Number / (ms / 1000m),5}");
                    _logger.Warn($"TOTAL after {number} Mgas/s     : {((decimal) totalGas / 1000000) / (ms / 1000m),5}");
                    _logger.Warn($"TOTAL after {number} max mem    : {maxMemory}");
                    _logger.Warn($"TOTAL after {number} GC (0/1/2) : {GC.CollectionCount(0)}/{GC.CollectionCount(1)}/{GC.CollectionCount(2)}");
                    _logger.Warn($"Is server GC {number}           : {System.Runtime.GCSettings.IsServerGC}");
                    _logger.Warn($"GC latency mode {number}        : {System.Runtime.GCSettings.LatencyMode}");

                    _logger.Warn($"TOTAL after {number} blocks DB reads      : {Store.Metrics.BlocksDbReads}");
                    _logger.Warn($"TOTAL after {number} blocks DB writes     : {Store.Metrics.BlocksDbWrites}");
                    _logger.Warn($"TOTAL after {number} infos DB reads       : {Store.Metrics.BlockInfosDbReads}");
                    _logger.Warn($"TOTAL after {number} infos DB writes      : {Store.Metrics.BlockInfosDbWrites}");
                    _logger.Warn($"TOTAL after {number} state tree reads     : {Store.Metrics.StateTreeReads}");
                    _logger.Warn($"TOTAL after {number} state tree writes    : {Store.Metrics.StateTreeWrites}");
                    _logger.Warn($"TOTAL after {number} state DB reads       : {Store.Metrics.StateDbReads}");
                    _logger.Warn($"TOTAL after {number} state DB writes      : {Store.Metrics.StateDbWrites}");
                    _logger.Warn($"TOTAL after {number} storage tree reads   : {Store.Metrics.StorageTreeReads}");
                    _logger.Warn($"TOTAL after {number} storage tree writes  : {Store.Metrics.StorageTreeWrites}");
                    _logger.Warn($"TOTAL after {number} tree node hash       : {Store.Metrics.TreeNodeHashCalculations}");
                    _logger.Warn($"TOTAL after {number} tree node RLP decode : {Store.Metrics.TreeNodeRlpDecodings}");
                    _logger.Warn($"TOTAL after {number} tree node RLP encode : {Store.Metrics.TreeNodeRlpEncodings}");
                    _logger.Warn($"TOTAL after {number} code DB reads        : {Store.Metrics.CodeDbReads}");
                    _logger.Warn($"TOTAL after {number} code DB writes       : {Store.Metrics.CodeDbWrites}");
                    _logger.Warn($"TOTAL after {number} receipts DB reads    : {Store.Metrics.ReceiptsDbReads}");
                    _logger.Warn($"TOTAL after {number} receipts DB writes   : {Store.Metrics.ReceiptsDbWrites}");
                    _logger.Warn($"TOTAL after {number} other DB reads       : {Store.Metrics.OtherDbReads}");
                    _logger.Warn($"TOTAL after {number} other DB writes      : {Store.Metrics.OtherDbWrites}");
                    _logger.Warn($"TOTAL after {number} EVM exceptions       : {Evm.Metrics.EvmExceptions}");
                    _logger.Warn($"TOTAL after {number} SLOAD opcodes        : {Evm.Metrics.SloadOpcode}");
                    _logger.Warn($"TOTAL after {number} SSTORE opcodes       : {Evm.Metrics.SstoreOpcode}");
                    _logger.Warn($"TOTAL after {number} EXP opcodes          : {Evm.Metrics.ModExpOpcode}");
                    _logger.Warn($"TOTAL after {number} BLOCKHASH opcodes    : {Evm.Metrics.BlockhashOpcode}");
                    _logger.Warn($"TOTAL after {number} EVM calls            : {Evm.Metrics.Calls}");
                    _logger.Warn($"TOTAL after {number} RIPEMD Precompiles   : {Evm.Metrics.Ripemd160Precompile}");
                    _logger.Warn($"TOTAL after {number} SHA256 Precompiles   : {Evm.Metrics.Sha256Precompile}");
                    // disk space
                    stopwatch.Start();
                }
            };

            bool isStarted = false;

            TaskCompletionSource <object> completionSource = new TaskCompletionSource <object>();

            blockTree.NewBestSuggestedBlock += (sender, args) =>
            {
                if (!isStarted)
                {
                    blockchainProcessor.Process(blockTree.FindBlock(blockTree.Genesis.Hash, BlockTreeLookupOptions.RequireCanonical), ProcessingOptions.None, NullBlockTracer.Instance);
                    stopwatch.Start();
                    blockchainProcessor.Start();
                    isStarted = true;
                }

                if (args.Block.Number == BlocksToLoad)
                {
                    completionSource.SetResult(null);
                }
            };

            await Task.WhenAny(completionSource.Task, blockTree.LoadBlocksFromDb(CancellationToken.None, 0, 10000, BlocksToLoad));

            await blockchainProcessor.StopAsync(true).ContinueWith(
                t =>
            {
                if (t.IsFaulted)
                {
                    _logger.Error("processing failed", t.Exception);
                    _logger.Error("inner", t.Exception.InnerException);
                    Console.ReadLine();
                }

                _logger.Info("Block processing completed.");
            });

            stopwatch.Stop();
            Console.ReadLine();
        }
예제 #30
0
        private Task InitBlockchain()
        {
            if (_api.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_api.ChainSpec));
            }
            if (_api.DbProvider == null)
            {
                throw new StepDependencyException(nameof(_api.DbProvider));
            }
            if (_api.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(_api.SpecProvider));
            }

            ILogger     logger     = _api.LogManager.GetClassLogger();
            IInitConfig initConfig = _api.Config <IInitConfig>();
            ISyncConfig syncConfig = _api.Config <ISyncConfig>();

            if (syncConfig.DownloadReceiptsInFastSync && !syncConfig.DownloadBodiesInFastSync)
            {
                logger.Warn($"{nameof(syncConfig.DownloadReceiptsInFastSync)} is selected but {nameof(syncConfig.DownloadBodiesInFastSync)} - enabling bodies to support receipts download.");
                syncConfig.DownloadBodiesInFastSync = true;
            }

            Account.AccountStartNonce = _api.ChainSpec.Parameters.AccountStartNonce;

            Signer signer = new Signer(_api.SpecProvider.ChainId, _api.OriginalSignerKey, _api.LogManager);

            _api.Signer      = signer;
            _api.SignerStore = signer;

            _api.StateProvider = new StateProvider(
                _api.DbProvider.StateDb,
                _api.DbProvider.CodeDb,
                _api.LogManager);

            _api.EthereumEcdsa = new EthereumEcdsa(_api.SpecProvider.ChainId, _api.LogManager);
            _api.TxPool        = new TxPool.TxPool(
                new PersistentTxStorage(_api.DbProvider.PendingTxsDb),
                Timestamper.Default,
                _api.EthereumEcdsa,
                _api.SpecProvider,
                _api.Config <ITxPoolConfig>(),
                _api.StateProvider,
                _api.LogManager);

            TxSealer standardSealer = new TxSealer(_api.Signer, _api.Timestamper);
            NonceReservingTxSealer nonceReservingTxSealer =
                new NonceReservingTxSealer(_api.Signer, _api.Timestamper, _api.TxPool);

            IVaultConfig vaultConfig = _api.Config <IVaultConfig>();

            if (!vaultConfig.Enabled)
            {
                _api.TxSender = new TxPoolSender(_api.TxPool, standardSealer, nonceReservingTxSealer);
            }
            else
            {
                IVaultService vaultService = new VaultService(vaultConfig, _api.LogManager);
                IVaultWallet  wallet       = new VaultWallet(vaultService, vaultConfig.VaultId, _api.LogManager);
                ITxSigner     vaultSigner  = new VaultTxSigner(wallet, _api.ChainSpec.ChainId);

                // change vault to provide, use sealer to set the gas price as well
                _api.TxSender = new VaultTxSender(vaultSigner, vaultConfig, _api.ChainSpec.ChainId);
            }

            IBloomConfig?bloomConfig = _api.Config <IBloomConfig>();

            IFileStoreFactory fileStoreFactory = initConfig.DiagnosticMode == DiagnosticMode.MemDb
                ? (IFileStoreFactory) new InMemoryDictionaryFileStoreFactory()
                : new FixedSizeFileStoreFactory(Path.Combine(initConfig.BaseDbPath, DbNames.Bloom), DbNames.Bloom, Bloom.ByteLength);

            _api.BloomStorage = bloomConfig.Index
                ? new BloomStorage(bloomConfig, _api.DbProvider.BloomDb, fileStoreFactory)
                : (IBloomStorage)NullBloomStorage.Instance;

            _api.DisposeStack.Push(_api.BloomStorage);

            _api.ChainLevelInfoRepository = new ChainLevelInfoRepository(_api.DbProvider.BlockInfosDb);

            _api.BlockTree = new BlockTree(
                _api.DbProvider.BlocksDb,
                _api.DbProvider.HeadersDb,
                _api.DbProvider.BlockInfosDb,
                _api.ChainLevelInfoRepository,
                _api.SpecProvider,
                _api.TxPool,
                _api.BloomStorage,
                _api.Config <ISyncConfig>(),
                _api.LogManager);

            // Init state if we need system calls before actual processing starts
            if (_api.BlockTree.Head != null)
            {
                _api.StateProvider.StateRoot = _api.BlockTree.Head.StateRoot;
            }

            _api.ReceiptStorage = initConfig.StoreReceipts ? (IReceiptStorage?)new PersistentReceiptStorage(_api.DbProvider.ReceiptsDb, _api.SpecProvider, new ReceiptsRecovery()) : NullReceiptStorage.Instance;
            _api.ReceiptFinder  = new FullInfoReceiptFinder(_api.ReceiptStorage, new ReceiptsRecovery(), _api.BlockTree);

            _api.RecoveryStep = new TxSignaturesRecoveryStep(_api.EthereumEcdsa, _api.TxPool, _api.LogManager);

            _api.StorageProvider = new StorageProvider(
                _api.DbProvider.StateDb,
                _api.StateProvider,
                _api.LogManager);

            // blockchain processing
            BlockhashProvider blockhashProvider = new BlockhashProvider(
                _api.BlockTree, _api.LogManager);

            VirtualMachine virtualMachine = new VirtualMachine(
                _api.StateProvider,
                _api.StorageProvider,
                blockhashProvider,
                _api.SpecProvider,
                _api.LogManager);

            _api.TransactionProcessor = new TransactionProcessor(
                _api.SpecProvider,
                _api.StateProvider,
                _api.StorageProvider,
                virtualMachine,
                _api.LogManager);

            InitSealEngine();
            if (_api.SealValidator == null)
            {
                throw new StepDependencyException(nameof(_api.SealValidator));
            }

            /* validation */
            _api.HeaderValidator = CreateHeaderValidator();

            OmmersValidator ommersValidator = new OmmersValidator(
                _api.BlockTree,
                _api.HeaderValidator,
                _api.LogManager);

            TxValidator txValidator = new TxValidator(_api.SpecProvider.ChainId);

            _api.BlockValidator = new BlockValidator(
                txValidator,
                _api.HeaderValidator,
                ommersValidator,
                _api.SpecProvider,
                _api.LogManager);

            ReadOnlyDbProvider readOnly    = new ReadOnlyDbProvider(_api.DbProvider, false);
            StateReader        stateReader = new StateReader(readOnly.StateDb, readOnly.CodeDb, _api.LogManager);

            _api.TxPoolInfoProvider = new TxPoolInfoProvider(stateReader, _api.TxPool);

            _api.MainBlockProcessor = CreateBlockProcessor();

            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(
                _api.BlockTree,
                _api.MainBlockProcessor,
                _api.RecoveryStep,
                _api.LogManager,
                new BlockchainProcessor.Options
            {
                AutoProcess            = !syncConfig.BeamSync,
                StoreReceiptsByDefault = initConfig.StoreReceipts,
            });

            _api.BlockProcessingQueue = blockchainProcessor;
            _api.BlockchainProcessor  = blockchainProcessor;

            if (syncConfig.BeamSync)
            {
                BeamBlockchainProcessor beamBlockchainProcessor = new BeamBlockchainProcessor(
                    new ReadOnlyDbProvider(_api.DbProvider, false),
                    _api.BlockTree,
                    _api.SpecProvider,
                    _api.LogManager,
                    _api.BlockValidator,
                    _api.RecoveryStep,
                    _api.RewardCalculatorSource !,
                    _api.BlockProcessingQueue,
                    _api.SyncModeSelector !);

                _api.DisposeStack.Push(beamBlockchainProcessor);
            }

            return(Task.CompletedTask);
        }