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(); }
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); }
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()); }
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 }); }
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); }
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); }
// 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); }
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); } } }
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; }
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); }
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); }
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(); }
public BlockchainProcessorTests() { Processor = new BlockchainProcessor(MockProcessingStrategy.Object, MockBlockProcessor.Object); }
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); }
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); }
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"); }
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; }
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); }
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); }
// 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"); }
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; }
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); }
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"); }
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(); }
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); }