internal ITxHub CreateTxPool() { var validator = new TxValidator(TxPoolConfig.Default, _chainService, _logger); return(new TxHub(_transactionManager, _transactionReceiptManager, _chainService, _signatureVerifier, _refBlockValidator)); // return new TxPool(_logger, new NewTxHub(_transactionManager, _chainService, _signatureVerifier, _refBlockValidator)); }
public void Test() { IBlockTree blockchain = Substitute.For <IBlockTree>(); HeaderValidator headerValidator = new HeaderValidator(blockchain, NullSealEngine.Instance, null, null); OmmersValidator ommersValidator = new OmmersValidator(blockchain, headerValidator, null); TxValidator txValidator = new TxValidator(ChainId.MainNet); BlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, ommersValidator, RopstenSpecProvider.Instance, null); }
public void No_chain_id_tx_is_valid() { byte[] sigData = new byte[65]; sigData[31] = 1; // correct r sigData[63] = 1; // correct s Signature signature = new Signature(sigData); var tx = Build.A.Transaction.WithSignature(signature).TestObject; TxValidator txValidator = new TxValidator(1); txValidator.IsWellFormed(tx, MuirGlacier.Instance).Should().BeTrue(); }
private void RunTest(TransactionTest test, IReleaseSpec spec) { //TestContext.CurrentContext.Test.Properties.Set("Category", test.Network); // no longer public ValidTransactionTest validTest = test as ValidTransactionTest; Nethermind.Core.Transaction transaction; try { Rlp rlp = new Rlp(Bytes.FromHexString(test.Rlp)); transaction = Rlp.Decode <Nethermind.Core.Transaction>(rlp); } catch (Exception) { if (validTest == null) { return; } throw; } bool useChainId = transaction.Signature.V > 28; TxValidator validator = new TxValidator(useChainId ? ChainId.MainNet : 0); if (validTest != null) { Assert.AreEqual(validTest.Value, transaction.Value, "value"); Assert.AreEqual(validTest.Data, transaction.Data ?? transaction.Init, "data"); Assert.AreEqual(validTest.GasLimit, transaction.GasLimit, "gasLimit"); Assert.AreEqual(validTest.GasPrice, transaction.GasPrice, "gasPrice"); Assert.AreEqual(validTest.Nonce, transaction.Nonce, "nonce"); Assert.AreEqual(validTest.To, transaction.To, "to"); Assert.True(validator.IsWellFormed(transaction, spec)); Signature expectedSignature = new Signature(validTest.R, validTest.S, validTest.V); Assert.AreEqual(expectedSignature, transaction.Signature, "signature"); // if(useChainId && spec.IsEip155Enabled) // IEthereumEcdsa ecdsa = new EthereumEcdsa(new SingleReleaseSpecProvider(spec, useChainId ? (int)ChainId.MainNet : 0), NullLogManager.Instance); bool verified = ecdsa.Verify( validTest.Sender, transaction, 0); Assert.True(verified); } else { Assert.False(validator.IsWellFormed(transaction, spec)); } }
public void Bad_chain_id_is_not_valid() { byte[] sigData = new byte[65]; sigData[31] = 1; // correct r sigData[63] = 1; // correct s sigData[64] = 39; Signature signature = new Signature(sigData); Transaction tx = Build.A.Transaction.WithSignature(signature).TestObject; TxValidator txValidator = new TxValidator(1); txValidator.IsWellFormed(tx, MuirGlacier.Instance).Should().BeFalse(); }
public void Zero_s_is_not_valid() { byte[] sigData = new byte[65]; sigData[31] = 1; // correct r // s is zero Signature signature = new Signature(sigData); var tx = Build.A.Transaction.WithSignature(signature).TestObject; TxValidator txValidator = new TxValidator(1); txValidator.IsWellFormed(tx, MuirGlacier.Instance).Should().BeFalse(); }
public void When_more_uncles_than_allowed_returns_false() { TxValidator txValidator = new TxValidator(ChainId.MainNet); ReleaseSpec releaseSpec = new ReleaseSpec(); releaseSpec.MaximumUncleCount = 0; ISpecProvider specProvider = new CustomSpecProvider((0, releaseSpec)); BlockValidator blockValidator = new BlockValidator(txValidator, AlwaysValidHeaderValidator.Instance, AlwaysValidOmmersValidator.Instance, specProvider, LimboLogs.Instance); bool noiseRemoved = blockValidator.ValidateSuggestedBlock(Build.A.Block.TestObject); Assert.True(noiseRemoved); bool result = blockValidator.ValidateSuggestedBlock(Build.A.Block.WithOmmers(Build.A.BlockHeader.TestObject).TestObject); Assert.False(result); }
public bool Chain_Id_required_for_non_legacy_transactions_after_Berlin(TxType txType) { byte[] sigData = new byte[65]; sigData[31] = 1; // correct r sigData[63] = 1; // correct s sigData[64] = 38; Signature signature = new Signature(sigData); Transaction tx = Build.A.Transaction .WithType(txType > TxType.AccessList ? TxType.Legacy : txType) .WithAccessList(txType == TxType.AccessList ? new AccessList(new Dictionary <Address, IReadOnlySet <UInt256> >()) : null) .WithSignature(signature).TestObject; tx.Type = txType; TxValidator txValidator = new TxValidator(ChainId.Mainnet); return(txValidator.IsWellFormed(tx, Berlin.Instance)); }
public static bool IsValid(Block block) { if (block.Index == 0) { Console.WriteLine("Genesis block is always valid"); return(true); } foreach (var tx in block.Txs) { if (!TxValidator.ValidateTransaction(tx)) { Console.WriteLine("Transaction is not valid"); Console.WriteLine(JsonConvert.SerializeObject(tx)); return(false); } } return(true); }
public void Before_eip_155_has_to_have_valid_chain_id_unless_overridden(bool validateChainId) { byte[] sigData = new byte[65]; sigData[31] = 1; // correct r sigData[63] = 1; // correct s sigData[64] = 41; Signature signature = new Signature(sigData); var tx = Build.A.Transaction.WithSignature(signature).TestObject; IReleaseSpec releaseSpec = Substitute.For <IReleaseSpec>(); releaseSpec.IsEip155Enabled.Returns(false); releaseSpec.ValidateChainId.Returns(validateChainId); TxValidator txValidator = new TxValidator(1); txValidator.IsWellFormed(tx, releaseSpec).Should().Be(!validateChainId); }
public bool Before_eip_2930_has_to_be_legacy_tx(TxType txType, bool eip2930) { byte[] sigData = new byte[65]; sigData[31] = 1; // correct r sigData[63] = 1; // correct s sigData[64] = 38; Signature signature = new Signature(sigData); Transaction tx = Build.A.Transaction .WithType(txType > TxType.AccessList ? TxType.Legacy : txType) .WithChainId(ChainId.Mainnet) .WithAccessList(txType == TxType.AccessList ? new AccessList(new Dictionary <Address, IReadOnlySet <UInt256> >()) : null) .WithSignature(signature).TestObject; tx.Type = txType; TxValidator txValidator = new TxValidator(1); return(txValidator.IsWellFormed(tx, eip2930 ? Berlin.Instance : MuirGlacier.Instance)); }
public bool Before_eip_1559_has_to_be_legacy_or_access_list_tx(TxType txType, bool eip2930, bool eip1559) { byte[] sigData = new byte[65]; sigData[31] = 1; // correct r sigData[63] = 1; // correct s sigData[64] = 38; Signature signature = new Signature(sigData); Transaction tx = Build.A.Transaction .WithType(txType) .WithChainId(ChainId.Mainnet) .WithAccessList(txType == TxType.AccessList || txType == TxType.EIP1559 ? new AccessList(new Dictionary <Address, IReadOnlySet <UInt256> >()) : null) .WithSignature(signature).TestObject; tx.Type = txType; TxValidator txValidator = new TxValidator(1); IReleaseSpec releaseSpec = new ReleaseSpec() { IsEip2930Enabled = eip2930, IsEip1559Enabled = eip1559 }; return(txValidator.IsWellFormed(tx, releaseSpec)); }
// 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 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); }
new protected async Task StartRunners(IConfigProvider configProvider) { InitRlp(); _configProvider = configProvider; _initConfig = _configProvider.GetConfig <IInitConfig>(); _logManager = new NLogManager(_initConfig.LogFileName, _initConfig.LogDirectory); _logger = _logManager.GetClassLogger(); _networkHelper = new NetworkHelper(_logger); SetupKeyStore(); LoadChainSpec(); IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>(); _dbProvider = new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts); var stateProvider = new StateProvider( _dbProvider.StateDb, _dbProvider.CodeDb, _logManager); _stateProvider = stateProvider; /* blockchain processing */ if (_chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId) { _specProvider = RopstenSpecProvider.Instance; } else if (_chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId) { _specProvider = MainNetSpecProvider.Instance; } else if (_chainSpec.ChainId == RinkebySpecProvider.Instance.ChainId) { _specProvider = RinkebySpecProvider.Instance; } else if (_chainSpec.ChainId == GoerliSpecProvider.Instance.ChainId) { _specProvider = GoerliSpecProvider.Instance; } else { _specProvider = new SingleReleaseSpecProvider(Latest.Release, _chainSpec.ChainId); } _ethereumEcdsa = new EthereumEcdsa(_specProvider, _logManager); _txPool = new TxPool( new PersistentTransactionStorage(_dbProvider.PendingTxsDb, _specProvider), new PendingTransactionThresholdValidator(_initConfig.ObsoletePendingTransactionInterval, _initConfig.RemovePendingTransactionInterval), new Timestamp(), _ethereumEcdsa, _specProvider, _logManager, _initConfig.RemovePendingTransactionInterval, _initConfig.PeerNotificationThreshold); _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _specProvider); _blockTree = new BlockTree( _dbProvider.BlocksDb, _dbProvider.HeadersDb, _dbProvider.BlockInfosDb, _specProvider, _txPool, _logManager); _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _txPool, _logManager); CliqueConfig cliqueConfig = null; _snapshotManager = null; switch (_chainSpec.SealEngineType) { case SealEngineType.None: _sealer = NullSealEngine.Instance; _sealValidator = NullSealEngine.Instance; _rewardCalculator = NoBlockRewards.Instance; break; case SealEngineType.Clique: _rewardCalculator = NoBlockRewards.Instance; cliqueConfig = new CliqueConfig(); cliqueConfig.BlockPeriod = _chainSpec.Clique.Period; cliqueConfig.Epoch = _chainSpec.Clique.Epoch; _snapshotManager = new SnapshotManager(cliqueConfig, _dbProvider.BlocksDb, _blockTree, _ethereumEcdsa, _logManager); _sealValidator = new CliqueSealValidator(cliqueConfig, _snapshotManager, _logManager); _recoveryStep = new CompositeDataRecoveryStep(_recoveryStep, new AuthorRecoveryStep(_snapshotManager)); if (_initConfig.IsMining) { _sealer = new CliqueSealer(new BasicWallet(_nodeKey), cliqueConfig, _snapshotManager, _nodeKey.Address, _logManager); } else { _sealer = NullSealEngine.Instance; } break; case SealEngineType.NethDev: _sealer = NullSealEngine.Instance; _sealValidator = NullSealEngine.Instance; _rewardCalculator = NoBlockRewards.Instance; break; case SealEngineType.Ethash: _rewardCalculator = new RewardCalculator(_specProvider); var difficultyCalculator = new DifficultyCalculator(_specProvider); if (_initConfig.IsMining) { _sealer = new EthashSealer(new Ethash(_logManager), _logManager); } else { _sealer = NullSealEngine.Instance; } _sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager)); break; default: throw new NotSupportedException($"Seal engine type {_chainSpec.SealEngineType} is not supported in Nethermind"); } _headerValidator = new HeaderValidator( _blockTree, _sealValidator, _specProvider, _logManager); var ommersValidator = new OmmersValidator( _blockTree, _headerValidator, _logManager); var storageProvider = new StorageProvider( _dbProvider.StateDb, stateProvider, _logManager); var txValidator = new TxValidator(_specProvider.ChainId); _blockValidator = new BlockValidator( txValidator, _headerValidator, ommersValidator, _specProvider, _logManager); var blockhashProvider = new BlockhashProvider( _blockTree, _logManager); var virtualMachine = new VirtualMachine( stateProvider, storageProvider, blockhashProvider, _logManager); var transactionProcessor = new TransactionProcessor( _specProvider, stateProvider, storageProvider, virtualMachine, _logManager); _blockProcessor = new BlockProcessor( _specProvider, _blockValidator, _rewardCalculator, transactionProcessor, _dbProvider.StateDb, _dbProvider.CodeDb, _dbProvider.TraceDb, stateProvider, storageProvider, _txPool, _receiptStorage, _configProvider.GetConfig <ISyncConfig>(), _logManager); _blockchainProcessor = new BlockchainProcessor( _blockTree, _blockProcessor, _recoveryStep, _logManager, _initConfig.StoreReceipts, _initConfig.StoreTraces); string chainFile = Path.Join(Path.GetDirectoryName(_initConfig.ChainSpecPath), "chain.rlp"); if (!File.Exists(chainFile)) { _logger.Info($"Chain file does not exist: {chainFile}, skipping"); return; } var chainFileContent = File.ReadAllBytes(chainFile); var context = new Rlp.DecoderContext(chainFileContent); var blocks = new List <Block>(); while (context.ReadNumberOfItemsRemaining() > 0) { context.PeekNextItem(); blocks.Add(Rlp.Decode <Block>(context)); } for (int i = 0; i < blocks.Count; i++) { ProcessBlock(blocks[i]); } }
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; } Account.AccountStartNonce = _context.ChainSpec.Parameters.AccountStartNonce; _context.Signer = new Signer(_context.SpecProvider.ChainId, _context.OriginalSignerKey); _context.StateProvider = new StateProvider( _context.DbProvider.StateDb, _context.DbProvider.CodeDb, _context.LogManager); _context.EthereumEcdsa = new EthereumEcdsa(_context.SpecProvider.ChainId, _context.LogManager); _context.TxPool = new TxPool.TxPool( new PersistentTxStorage(_context.DbProvider.PendingTxsDb), Timestamper.Default, _context.EthereumEcdsa, _context.SpecProvider, _context.Config <ITxPoolConfig>(), _context.StateProvider, _context.LogManager); var bloomConfig = _context.Config <IBloomConfig>(); var fileStoreFactory = initConfig.DiagnosticMode == DiagnosticMode.MemDb ? (IFileStoreFactory) new InMemoryDictionaryFileStoreFactory() : new FixedSizeFileStoreFactory(Path.Combine(initConfig.BaseDbPath, DbNames.Bloom), DbNames.Bloom, Bloom.ByteLength); _context.BloomStorage = bloomConfig.Index ? new BloomStorage(bloomConfig, _context.DbProvider.BloomDb, fileStoreFactory) : (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.ReceiptStorage = initConfig.StoreReceipts ? (IReceiptStorage?)new PersistentReceiptStorage(_context.DbProvider.ReceiptsDb, _context.SpecProvider, new ReceiptsRecovery()) : NullReceiptStorage.Instance; _context.ReceiptFinder = new FullInfoReceiptFinder(_context.ReceiptStorage, new ReceiptsRecovery(), _context.BlockTree); _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 = CreateHeaderValidator(); 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); ReadOnlyDbProvider readOnly = new ReadOnlyDbProvider(_context.DbProvider, false); StateReader stateReader = new StateReader(readOnly.StateDb, readOnly.CodeDb, _context.LogManager); _context.TxPoolInfoProvider = new TxPoolInfoProvider(stateReader, _context.TxPool); _context.MainBlockProcessor = CreateBlockProcessor(); BlockchainProcessor blockchainProcessor = new BlockchainProcessor( _context.BlockTree, _context.MainBlockProcessor, _context.RecoveryStep, _context.LogManager, new BlockchainProcessor.Options { AutoProcess = !syncConfig.BeamSync, StoreReceiptsByDefault = initConfig.StoreReceipts, RunGethTracer = initConfig.DiagnosticMode == DiagnosticMode.GethTrace, RunParityTracer = initConfig.DiagnosticMode == DiagnosticMode.ParityTrace, }); _context.BlockProcessingQueue = blockchainProcessor; _context.BlockchainProcessor = blockchainProcessor; if (syncConfig.BeamSync) { BeamBlockchainProcessor beamBlockchainProcessor = new BeamBlockchainProcessor( new ReadOnlyDbProvider(_context.DbProvider, false), _context.BlockTree, _context.SpecProvider, _context.LogManager, _context.BlockValidator, _context.RecoveryStep, _context.RewardCalculatorSource, _context.BlockProcessingQueue, _context.BlockchainProcessor, _context.SyncModeSelector); _context.DisposeStack.Push(beamBlockchainProcessor); } ThisNodeInfo.AddInfo("Mem est trie :", $"{LruCache<Keccak, byte[]>.CalculateMemorySize(52 + 320, Trie.MemoryAllowance.TrieNodeCacheSize) / 1024 / 1024}MB".PadLeft(8)); return(Task.CompletedTask); }
private async Task InitBlockchain() { _specProvider = new ChainSpecBasedSpecProvider(_chainSpec); Account.AccountStartNonce = _chainSpec.Parameters.AccountStartNonce; /* sync */ IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>(); _syncConfig = _configProvider.GetConfig <ISyncConfig>(); foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties()) { if (_logger.IsDebug) { _logger.Debug($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}"); } } _dbProvider = HiveEnabled ? (IDbProvider) new MemDbProvider() : new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts || _syncConfig.DownloadReceiptsInFastSync); // IDbProvider debugRecorder = new RocksDbProvider(Path.Combine(_initConfig.BaseDbPath, "debug"), dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts); // _dbProvider = new RpcDbProvider(_jsonSerializer, new BasicJsonRpcClient(KnownRpcUris.Localhost, _jsonSerializer, _logManager), _logManager, debugRecorder); // IDbProvider debugReader = new ReadOnlyDbProvider(new RocksDbProvider(Path.Combine(_initConfig.BaseDbPath, "debug"), dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts), false); // _dbProvider = debugReader; _stateProvider = new StateProvider( _dbProvider.StateDb, _dbProvider.CodeDb, _logManager); _ethereumEcdsa = new EthereumEcdsa(_specProvider, _logManager); _txPool = new TxPool( new PersistentTxStorage(_dbProvider.PendingTxsDb, _specProvider), Timestamper.Default, _ethereumEcdsa, _specProvider, _txPoolConfig, _stateProvider, _logManager); var _rc7FixDb = _initConfig.EnableRc7Fix ? _dbProvider.HeadersDb : NullDb.Instance; _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _rc7FixDb, _specProvider, _logManager); _blockTree = new BlockTree( _dbProvider.BlocksDb, _dbProvider.HeadersDb, _dbProvider.BlockInfosDb, _specProvider, _txPool, _syncConfig, _logManager); _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _txPool, _logManager); _snapshotManager = null; _storageProvider = new StorageProvider( _dbProvider.StateDb, _stateProvider, _logManager); IList <IAdditionalBlockProcessor> blockPreProcessors = new List <IAdditionalBlockProcessor>(); // blockchain processing var blockhashProvider = new BlockhashProvider( _blockTree, _logManager); var virtualMachine = new VirtualMachine( _stateProvider, _storageProvider, blockhashProvider, _specProvider, _logManager); _transactionProcessor = new TransactionProcessor( _specProvider, _stateProvider, _storageProvider, virtualMachine, _logManager); InitSealEngine(blockPreProcessors); /* validation */ _headerValidator = new HeaderValidator( _blockTree, _sealValidator, _specProvider, _logManager); var ommersValidator = new OmmersValidator( _blockTree, _headerValidator, _logManager); var txValidator = new TxValidator(_specProvider.ChainId); _blockValidator = new BlockValidator( txValidator, _headerValidator, ommersValidator, _specProvider, _logManager); _txPoolInfoProvider = new TxPoolInfoProvider(_stateProvider, _txPool); _blockProcessor = new BlockProcessor( _specProvider, _blockValidator, _rewardCalculator, _transactionProcessor, _dbProvider.StateDb, _dbProvider.CodeDb, _dbProvider.TraceDb, _stateProvider, _storageProvider, _txPool, _receiptStorage, _logManager, blockPreProcessors); _blockchainProcessor = new BlockchainProcessor( _blockTree, _blockProcessor, _recoveryStep, _logManager, _initConfig.StoreReceipts, _initConfig.StoreTraces); // create shared objects between discovery and peer manager IStatsConfig statsConfig = _configProvider.GetConfig <IStatsConfig>(); _nodeStatsManager = new NodeStatsManager(statsConfig, _logManager); InitBlockProducers(); _blockchainProcessor.Start(); LoadGenesisBlock(string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash)); if (_initConfig.ProcessingEnabled) { #pragma warning disable 4014 RunBlockTreeInitTasks(); #pragma warning restore 4014 } else { if (_logger.IsWarn) { _logger.Warn($"Shutting down the blockchain processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false"); } await _blockchainProcessor.StopAsync(); } if (HiveEnabled) { await InitHive(); } var producers = new List <IProducer>(); var kafkaConfig = _configProvider.GetConfig <IKafkaConfig>(); if (kafkaConfig.Enabled) { var kafkaProducer = await PrepareKafkaProducer(_blockTree, _configProvider.GetConfig <IKafkaConfig>()); producers.Add(kafkaProducer); } var grpcConfig = _configProvider.GetConfig <IGrpcConfig>(); if (grpcConfig.Enabled && grpcConfig.ProducerEnabled) { var grpcProducer = new GrpcProducer(_grpcServer); producers.Add(grpcProducer); } ISubscription subscription; if (producers.Any()) { subscription = new Subscription(producers, _blockProcessor, _logManager); } else { subscription = new EmptySubscription(); } _disposeStack.Push(subscription); await InitializeNetwork(); }
protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) { TestContext.Write($"Running {test.Name} at {DateTime.UtcNow:HH:mm:ss.ffffff}"); Assert.IsNull(test.LoadFailure, "test data loading failure"); IDb stateDb = new MemDb(); IDb codeDb = new MemDb(); ISpecProvider specProvider = new CustomSpecProvider(1, (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.Fork)); if (specProvider.GenesisSpec != Frontier.Instance) { Assert.Fail("Expected genesis spec to be Frontier for blockchain tests"); } TrieStore trieStore = new(stateDb, _logManager); StateProvider stateProvider = new (trieStore, codeDb, _logManager); IBlockhashProvider blockhashProvider = new TestBlockhashProvider(); IStorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, _logManager); IVirtualMachine virtualMachine = new VirtualMachine( blockhashProvider, specProvider, _logManager); TransactionProcessor transactionProcessor = new( specProvider, stateProvider, storageProvider, virtualMachine, _logManager); InitializeTestState(test, stateProvider, storageProvider, specProvider); BlockHeader header = new(test.PreviousHash, Keccak.OfAnEmptySequenceRlp, test.CurrentCoinbase, test.CurrentDifficulty, test.CurrentNumber, test.CurrentGasLimit, test.CurrentTimestamp, new byte[0]); header.BaseFeePerGas = test.Fork.IsEip1559Enabled ? test.CurrentBaseFee ?? _defaultBaseFeeForStateTest : UInt256.Zero; header.StateRoot = test.PostHash; header.Hash = header.CalculateHash(); Stopwatch stopwatch = Stopwatch.StartNew(); var txValidator = new TxValidator((MainnetSpecProvider.Instance.ChainId)); var spec = specProvider.GetSpec(test.CurrentNumber); if (test.Transaction.ChainId == null) { test.Transaction.ChainId = MainnetSpecProvider.Instance.ChainId; } bool isValid = txValidator.IsWellFormed(test.Transaction, spec); if (isValid) { transactionProcessor.Execute(test.Transaction, header, txTracer); } stopwatch.Stop(); stateProvider.Commit(specProvider.GenesisSpec); stateProvider.CommitTree(1); // '@winsvega added a 0-wei reward to the miner , so we had to add that into the state test execution phase. He needed it for retesteth.' if (!stateProvider.AccountExists(test.CurrentCoinbase)) { stateProvider.CreateAccount(test.CurrentCoinbase, 0); } stateProvider.RecalculateStateRoot(); List <string> differences = RunAssertions(test, stateProvider); EthereumTestResult testResult = new(test.Name, test.ForkName, differences.Count == 0); testResult.TimeInMs = (int)stopwatch.Elapsed.TotalMilliseconds; testResult.StateRoot = stateProvider.StateRoot; // Assert.Zero(differences.Count, "differences"); return(testResult); }
public void Chain_id_has_to_be_non_negative() { Assert.Throws <ArgumentException>(() => _ = new TxValidator(-1)); }
private async Task InitializeNetwork( IReceiptStorage receiptStorage, ISealValidator sealValidator, TxValidator txValidator) { ISyncConfig syncConfig = _configProvider.GetConfig <ISyncConfig>(); _syncPeerPool = new EthSyncPeerPool(_blockTree, _nodeStatsManager, syncConfig, _logManager); NodeDataFeed feed = new NodeDataFeed(_dbProvider.CodeDb, _dbProvider.StateDb, _logManager); NodeDataDownloader nodeDataDownloader = new NodeDataDownloader(_syncPeerPool, feed, _logManager); _synchronizer = new Synchronizer(_blockTree, _blockValidator, _sealValidator, _syncPeerPool, syncConfig, nodeDataDownloader, _logManager); _syncServer = new SyncServer( _dbProvider.StateDb, _dbProvider.CodeDb, _blockTree, _receiptStorage, sealValidator, _syncPeerPool, _synchronizer, _logManager); InitDiscovery(); await InitPeer().ContinueWith(initPeerTask => { if (initPeerTask.IsFaulted) { _logger.Error("Unable to init the peer manager.", initPeerTask.Exception); } }); ; await StartSync().ContinueWith(initNetTask => { if (initNetTask.IsFaulted) { _logger.Error("Unable to start the synchronizer.", initNetTask.Exception); } }); await StartDiscovery().ContinueWith(initDiscoveryTask => { if (initDiscoveryTask.IsFaulted) { _logger.Error("Unable to start the discovery protocol.", initDiscoveryTask.Exception); } }); try { StartPeer(); } catch (Exception e) { _logger.Error("Unable to start the peer manager.", e); } ; if (_logger.IsInfo) { _logger.Info($"Ethereum : tcp://{_enode.IpAddress}:{_enode.P2PPort}"); } if (_logger.IsInfo) { _logger.Info($"Version : {ClientVersion.Description}"); } if (_logger.IsInfo) { _logger.Info($"This node : {_enode.Info}"); } if (_logger.IsInfo) { _logger.Info($"Node address : {_enode.Address} (do not use as an account)"); } }
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 Task InitBlockchain() { InitBlockTraceDumper(); (IApiWithStores getApi, IApiWithBlockchain setApi) = _api.ForBlockchain; if (getApi.ChainSpec == null) { throw new StepDependencyException(nameof(getApi.ChainSpec)); } if (getApi.DbProvider == null) { throw new StepDependencyException(nameof(getApi.DbProvider)); } if (getApi.SpecProvider == null) { throw new StepDependencyException(nameof(getApi.SpecProvider)); } if (getApi.BlockTree == null) { throw new StepDependencyException(nameof(getApi.BlockTree)); } _logger = getApi.LogManager.GetClassLogger(); IInitConfig initConfig = getApi.Config <IInitConfig>(); ISyncConfig syncConfig = getApi.Config <ISyncConfig>(); IPruningConfig pruningConfig = getApi.Config <IPruningConfig>(); IMiningConfig miningConfig = getApi.Config <IMiningConfig>(); 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 = getApi.ChainSpec.Parameters.AccountStartNonce; IWitnessCollector witnessCollector; if (syncConfig.WitnessProtocolEnabled) { WitnessCollector witnessCollectorImpl = new(getApi.DbProvider.WitnessDb, _api.LogManager); witnessCollector = setApi.WitnessCollector = witnessCollectorImpl; setApi.WitnessRepository = witnessCollectorImpl.WithPruning(getApi.BlockTree !, getApi.LogManager); } else { witnessCollector = setApi.WitnessCollector = NullWitnessCollector.Instance; setApi.WitnessRepository = NullWitnessCollector.Instance; } CachingStore cachedStateDb = getApi.DbProvider.StateDb .Cached(Trie.MemoryAllowance.TrieNodeCacheCount); setApi.MainStateDbWithCache = cachedStateDb; IKeyValueStore codeDb = getApi.DbProvider.CodeDb .WitnessedBy(witnessCollector); TrieStore trieStore; IKeyValueStoreWithBatching stateWitnessedBy = setApi.MainStateDbWithCache.WitnessedBy(witnessCollector); if (pruningConfig.Mode.IsMemory()) { IPersistenceStrategy persistenceStrategy = Persist.IfBlockOlderThan(pruningConfig.PersistenceInterval); // TODO: this should be based on time if (pruningConfig.Mode.IsFull()) { PruningTriggerPersistenceStrategy triggerPersistenceStrategy = new((IFullPruningDb)getApi.DbProvider !.StateDb, getApi.BlockTree !, getApi.LogManager); getApi.DisposeStack.Push(triggerPersistenceStrategy); persistenceStrategy = persistenceStrategy.Or(triggerPersistenceStrategy); } setApi.TrieStore = trieStore = new TrieStore( stateWitnessedBy, Prune.WhenCacheReaches(pruningConfig.CacheMb.MB()), // TODO: memory hint should define this persistenceStrategy, getApi.LogManager); if (pruningConfig.Mode.IsFull()) { IFullPruningDb fullPruningDb = (IFullPruningDb)getApi.DbProvider !.StateDb; fullPruningDb.PruningStarted += (_, args) => { cachedStateDb.PersistCache(args.Context); trieStore.PersistCache(args.Context, args.Context.CancellationTokenSource.Token); }; } } else { setApi.TrieStore = trieStore = new TrieStore( stateWitnessedBy, No.Pruning, Persist.EveryBlock, getApi.LogManager); } TrieStoreBoundaryWatcher trieStoreBoundaryWatcher = new(trieStore, _api.BlockTree !, _api.LogManager); getApi.DisposeStack.Push(trieStoreBoundaryWatcher); getApi.DisposeStack.Push(trieStore); ITrieStore readOnlyTrieStore = setApi.ReadOnlyTrieStore = trieStore.AsReadOnly(cachedStateDb); IStateProvider stateProvider = setApi.StateProvider = new StateProvider( trieStore, codeDb, getApi.LogManager); ReadOnlyDbProvider readOnly = new(getApi.DbProvider, false); IStateReader stateReader = setApi.StateReader = new StateReader(readOnlyTrieStore, readOnly.GetDb <IDb>(DbNames.Code), getApi.LogManager); setApi.TransactionComparerProvider = new TransactionComparerProvider(getApi.SpecProvider !, getApi.BlockTree.AsReadOnly()); setApi.ChainHeadStateProvider = new ChainHeadReadOnlyStateProvider(getApi.BlockTree, stateReader); Account.AccountStartNonce = getApi.ChainSpec.Parameters.AccountStartNonce; stateProvider.StateRoot = getApi.BlockTree !.Head?.StateRoot ?? Keccak.EmptyTreeHash; if (_api.Config <IInitConfig>().DiagnosticMode == DiagnosticMode.VerifyTrie) { Task.Run(() => { try { _logger !.Info("Collecting trie stats and verifying that no nodes are missing..."); TrieStats stats = stateProvider.CollectStats(getApi.DbProvider.CodeDb, _api.LogManager); _logger.Info($"Starting from {getApi.BlockTree.Head?.Number} {getApi.BlockTree.Head?.StateRoot}{Environment.NewLine}" + stats); } catch (Exception ex) { _logger !.Error(ex.ToString()); } }); } // Init state if we need system calls before actual processing starts if (getApi.BlockTree !.Head?.StateRoot != null) { stateProvider.StateRoot = getApi.BlockTree.Head.StateRoot; } TxValidator txValidator = setApi.TxValidator = new TxValidator(getApi.SpecProvider.ChainId); ITxPool txPool = _api.TxPool = CreateTxPool(); ReceiptCanonicalityMonitor receiptCanonicalityMonitor = new(getApi.BlockTree, getApi.ReceiptStorage, _api.LogManager); getApi.DisposeStack.Push(receiptCanonicalityMonitor); _api.ReceiptMonitor = receiptCanonicalityMonitor; _api.BlockPreprocessor.AddFirst( new RecoverSignatures(getApi.EthereumEcdsa, txPool, getApi.SpecProvider, getApi.LogManager)); IStorageProvider storageProvider = setApi.StorageProvider = new StorageProvider( trieStore, stateProvider, getApi.LogManager); // blockchain processing BlockhashProvider blockhashProvider = new ( getApi.BlockTree, getApi.LogManager); VirtualMachine virtualMachine = new ( blockhashProvider, getApi.SpecProvider, getApi.LogManager); WorldState worldState = new (stateProvider, storageProvider); _api.TransactionProcessor = new TransactionProcessor( getApi.SpecProvider, worldState, virtualMachine, getApi.LogManager); InitSealEngine(); if (_api.SealValidator == null) { throw new StepDependencyException(nameof(_api.SealValidator)); } setApi.HeaderValidator = CreateHeaderValidator(); IHeaderValidator?headerValidator = setApi.HeaderValidator; IUnclesValidator unclesValidator = setApi.UnclesValidator = new UnclesValidator( getApi.BlockTree, headerValidator, getApi.LogManager); setApi.BlockValidator = new BlockValidator( txValidator, headerValidator, unclesValidator, getApi.SpecProvider, getApi.LogManager); IChainHeadInfoProvider chainHeadInfoProvider = new ChainHeadInfoProvider(getApi.SpecProvider, getApi.BlockTree, stateReader); setApi.TxPoolInfoProvider = new TxPoolInfoProvider(chainHeadInfoProvider.AccountStateProvider, txPool); setApi.GasPriceOracle = new GasPriceOracle(getApi.BlockTree, getApi.SpecProvider, _api.LogManager, miningConfig.MinGasPrice); IBlockProcessor mainBlockProcessor = setApi.MainBlockProcessor = CreateBlockProcessor(); BlockchainProcessor blockchainProcessor = new( getApi.BlockTree, mainBlockProcessor, _api.BlockPreprocessor, stateReader, getApi.LogManager, new BlockchainProcessor.Options { StoreReceiptsByDefault = initConfig.StoreReceipts, DumpOptions = initConfig.AutoDump }); setApi.BlockProcessingQueue = blockchainProcessor; setApi.BlockchainProcessor = blockchainProcessor; setApi.EthSyncingInfo = new EthSyncingInfo(getApi.BlockTree); // TODO: can take the tx sender from plugin here maybe ITxSigner txSigner = new WalletTxSigner(getApi.Wallet, getApi.SpecProvider.ChainId); TxSealer standardSealer = new(txSigner, getApi.Timestamper); NonceReservingTxSealer nonceReservingTxSealer = new(txSigner, getApi.Timestamper, txPool); setApi.TxSender = new TxPoolSender(txPool, nonceReservingTxSealer, standardSealer); // TODO: possibly hide it (but need to confirm that NDM does not really need it) IFilterStore filterStore = setApi.FilterStore = new FilterStore(); setApi.FilterManager = new FilterManager(filterStore, mainBlockProcessor, txPool, getApi.LogManager); setApi.HealthHintService = CreateHealthHintService(); setApi.BlockProductionPolicy = new BlockProductionPolicy(miningConfig); InitializeFullPruning(pruningConfig, initConfig, _api, stateReader); return(Task.CompletedTask); }
private async Task InitBlockchain() { _specProvider = new ChainSpecBasedSpecProvider(_chainSpec); Account.AccountStartNonce = _chainSpec.Parameters.AccountStartNonce; /* sync */ IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>(); _syncConfig = _configProvider.GetConfig <ISyncConfig>(); foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties()) { if (_logger.IsDebug) { _logger.Debug($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}"); } } _dbProvider = HiveEnabled ? (IDbProvider) new MemDbProvider() : new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts || _syncConfig.DownloadReceiptsInFastSync); _ethereumEcdsa = new EthereumEcdsa(_specProvider, _logManager); _txPool = new TxPool( new PersistentTxStorage(_dbProvider.PendingTxsDb, _specProvider), Timestamp.Default, _ethereumEcdsa, _specProvider, _txPoolConfig, _logManager); var _rc7FixDb = _initConfig.EnableRc7Fix ? _dbProvider.HeadersDb : NullDb.Instance; _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _rc7FixDb, _specProvider, _logManager); // IDbProvider debugRecorder = new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig); // _dbProvider = new RpcDbProvider(_jsonSerializer, new BasicJsonRpcClient(KnownRpcUris.NethVm1, _jsonSerializer, _logManager), _logManager, debugRecorder); // IDbProvider debugReader = new ReadOnlyDbProvider(new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig)); // _dbProvider = debugReader; _blockTree = new BlockTree( _dbProvider.BlocksDb, _dbProvider.HeadersDb, _dbProvider.BlockInfosDb, _specProvider, _txPool, _syncConfig, _logManager); _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _txPool, _logManager); CliqueConfig cliqueConfig = null; _snapshotManager = null; switch (_chainSpec.SealEngineType) { case SealEngineType.None: _sealer = NullSealEngine.Instance; _sealValidator = NullSealEngine.Instance; _rewardCalculator = NoBlockRewards.Instance; break; case SealEngineType.Clique: _rewardCalculator = NoBlockRewards.Instance; cliqueConfig = new CliqueConfig(); cliqueConfig.BlockPeriod = _chainSpec.Clique.Period; cliqueConfig.Epoch = _chainSpec.Clique.Epoch; _snapshotManager = new SnapshotManager(cliqueConfig, _dbProvider.BlocksDb, _blockTree, _ethereumEcdsa, _logManager); _sealValidator = new CliqueSealValidator(cliqueConfig, _snapshotManager, _logManager); _recoveryStep = new CompositeDataRecoveryStep(_recoveryStep, new AuthorRecoveryStep(_snapshotManager)); if (_initConfig.IsMining) { _sealer = new CliqueSealer(new BasicWallet(_nodeKey), cliqueConfig, _snapshotManager, _nodeKey.Address, _logManager); } else { _sealer = NullSealEngine.Instance; } break; case SealEngineType.NethDev: _sealer = NullSealEngine.Instance; _sealValidator = NullSealEngine.Instance; _rewardCalculator = NoBlockRewards.Instance; break; case SealEngineType.Ethash: _rewardCalculator = new RewardCalculator(_specProvider); var difficultyCalculator = new DifficultyCalculator(_specProvider); if (_initConfig.IsMining) { _sealer = new EthashSealer(new Ethash(_logManager), _logManager); } else { _sealer = NullSealEngine.Instance; } _sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager)); break; default: throw new NotSupportedException($"Seal engine type {_chainSpec.SealEngineType} is not supported in Nethermind"); } /* validation */ _headerValidator = new HeaderValidator( _blockTree, _sealValidator, _specProvider, _logManager); var ommersValidator = new OmmersValidator( _blockTree, _headerValidator, _logManager); var txValidator = new TxValidator(_specProvider.ChainId); _blockValidator = new BlockValidator( txValidator, _headerValidator, ommersValidator, _specProvider, _logManager); var stateProvider = new StateProvider( _dbProvider.StateDb, _dbProvider.CodeDb, _logManager); _stateProvider = stateProvider; var storageProvider = new StorageProvider( _dbProvider.StateDb, stateProvider, _logManager); _txPoolInfoProvider = new TxPoolInfoProvider(stateProvider); _transactionPoolInfoProvider = new TxPoolInfoProvider(stateProvider); /* blockchain processing */ var blockhashProvider = new BlockhashProvider( _blockTree, _logManager); var virtualMachine = new VirtualMachine( stateProvider, storageProvider, blockhashProvider, _logManager); var transactionProcessor = new TransactionProcessor( _specProvider, stateProvider, storageProvider, virtualMachine, _logManager); _blockProcessor = new BlockProcessor( _specProvider, _blockValidator, _rewardCalculator, transactionProcessor, _dbProvider.StateDb, _dbProvider.CodeDb, _dbProvider.TraceDb, stateProvider, storageProvider, _txPool, _receiptStorage, _logManager); _blockchainProcessor = new BlockchainProcessor( _blockTree, _blockProcessor, _recoveryStep, _logManager, _initConfig.StoreReceipts, _initConfig.StoreTraces); // create shared objects between discovery and peer manager IStatsConfig statsConfig = _configProvider.GetConfig <IStatsConfig>(); _nodeStatsManager = new NodeStatsManager(statsConfig, _logManager); if (_initConfig.IsMining) { IReadOnlyDbProvider minerDbProvider = new ReadOnlyDbProvider(_dbProvider, false); AlternativeChain producerChain = new AlternativeChain(_blockTree, _blockValidator, _rewardCalculator, _specProvider, minerDbProvider, _recoveryStep, _logManager, _txPool, _receiptStorage); switch (_chainSpec.SealEngineType) { case SealEngineType.Clique: { if (_logger.IsWarn) { _logger.Warn("Starting Clique block producer & sealer"); } _blockProducer = new CliqueBlockProducer(_txPool, producerChain.Processor, _blockTree, _timestamp, _cryptoRandom, producerChain.StateProvider, _snapshotManager, (CliqueSealer)_sealer, _nodeKey.Address, cliqueConfig, _logManager); break; } case SealEngineType.NethDev: { if (_logger.IsWarn) { _logger.Warn("Starting Dev block producer & sealer"); } _blockProducer = new DevBlockProducer(_txPool, producerChain.Processor, _blockTree, _timestamp, _logManager); break; } default: throw new NotSupportedException($"Mining in {_chainSpec.SealEngineType} mode is not supported"); } _blockProducer.Start(); } _blockchainProcessor.Start(); LoadGenesisBlock(_chainSpec, string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash), _blockTree, stateProvider, _specProvider); if (_initConfig.ProcessingEnabled) { #pragma warning disable 4014 LoadBlocksFromDb(); #pragma warning restore 4014 } else { if (_logger.IsWarn) { _logger.Warn($"Shutting down the blockchain processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false"); } await _blockchainProcessor.StopAsync(); } if (HiveEnabled) { await InitHive(); } if (HiveEnabled) { await InitHive(); } var producers = new List <IProducer>(); if (_initConfig.PubSubEnabled) { var kafkaProducer = await PrepareKafkaProducer(_blockTree, _configProvider.GetConfig <IKafkaConfig>()); producers.Add(kafkaProducer); } var grpcClientConfig = _configProvider.GetConfig <IGrpcClientConfig>(); if (grpcClientConfig.Enabled) { var grpcProducer = new GrpcProducer(_grpcClient, _logManager); producers.Add(grpcProducer); } ISubscription subscription; if (producers.Any()) { subscription = new Subscription(producers, _blockProcessor, _logManager); } else { subscription = new EmptySubscription(); } _disposeStack.Push(subscription); _dataBridge = new DataBridge(subscription, _receiptStorage, _blockTree, _logManager); _dataBridge.Start(); await InitializeNetwork(); }
protected async Task <EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?stopwatch = null) { TestContext.Write($"Running {test.Name} at {DateTime.UtcNow:HH:mm:ss.ffffff}"); Assert.IsNull(test.LoadFailure, "test data loading failure"); IDb stateDb = new MemDb(); IDb codeDb = new MemDb(); ISpecProvider specProvider; if (test.NetworkAfterTransition != null) { specProvider = new CustomSpecProvider(1, (0, Frontier.Instance), (1, test.Network), (test.TransitionBlockNumber, test.NetworkAfterTransition)); } else { specProvider = new CustomSpecProvider(1, (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"); } bool isNetworkAfterTransitionLondon = test.NetworkAfterTransition == London.Instance; HeaderDecoder.Eip1559TransitionBlock = isNetworkAfterTransitionLondon ? test.TransitionBlockNumber : long.MaxValue; DifficultyCalculator.Wrapped = new EthashDifficultyCalculator(specProvider); IRewardCalculator rewardCalculator = new RewardCalculator(specProvider); IEthereumEcdsa ecdsa = new EthereumEcdsa(specProvider.ChainId, _logManager); TrieStore trieStore = new(stateDb, _logManager); IStateProvider stateProvider = new StateProvider(trieStore, codeDb, _logManager); MemDb blockInfoDb = new MemDb(); IBlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, _logManager); ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree); IStateReader stateReader = new StateReader(trieStore, codeDb, _logManager); IChainHeadInfoProvider chainHeadInfoProvider = new ChainHeadInfoProvider(specProvider, blockTree, stateReader); ITxPool transactionPool = new TxPool(ecdsa, chainHeadInfoProvider, new TxPoolConfig(), new TxValidator(specProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer()); IReceiptStorage receiptStorage = NullReceiptStorage.Instance; IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager); ITxValidator txValidator = new TxValidator(ChainId.Mainnet); IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager); IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager); IBlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, unclesValidator, specProvider, _logManager); IStorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, _logManager); IVirtualMachine virtualMachine = new VirtualMachine( blockhashProvider, specProvider, _logManager); IBlockProcessor blockProcessor = new BlockProcessor( specProvider, blockValidator, rewardCalculator, new BlockProcessor.BlockValidationTransactionsExecutor( new TransactionProcessor( specProvider, stateProvider, storageProvider, virtualMachine, _logManager), stateProvider), stateProvider, storageProvider, receiptStorage, NullWitnessCollector.Instance, _logManager); IBlockchainProcessor blockchainProcessor = new BlockchainProcessor( blockTree, blockProcessor, new RecoverSignatures(ecdsa, NullTxPool.Instance, specProvider, _logManager), _logManager, BlockchainProcessor.Options.NoReceipts); InitializeTestState(test, stateProvider, storageProvider, specProvider); List <(Block Block, string ExpectedException)> correctRlp = new(); 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 uncleIndex = 0; uncleIndex < suggestedBlock.Uncles.Length; uncleIndex++) { Assert.AreEqual(new Keccak(testBlockJson.UncleHeaders[uncleIndex].Hash), suggestedBlock.Uncles[uncleIndex].Hash, "hash of the uncle"); } correctRlp.Add((suggestedBlock, testBlockJson.ExpectedException)); } catch (Exception) { _logger?.Info($"Invalid RLP ({i})"); } } if (correctRlp.Count == 0) { EthereumTestResult result; if (test.GenesisBlockHeader is null) { result = new EthereumTestResult(test.Name, "Genesis block header missing in the test spec."); } else if (!new Keccak(test.GenesisBlockHeader.Hash).Equals(test.LastBlockHash)) { result = new EthereumTestResult(test.Name, "Genesis hash mismatch"); } else { result = new EthereumTestResult(test.Name, null, true); } return(result); } if (test.GenesisRlp == null) { test.GenesisRlp = Rlp.Encode(new Block(JsonToEthereumTest.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(false); blockTree.NewHeadBlock += (_, 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 < correctRlp.Count; i++) { stopwatch?.Start(); try { if (correctRlp[i].ExpectedException != null) { _logger.Info($"Expecting block exception: {correctRlp[i].ExpectedException}"); } if (correctRlp[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(correctRlp[i].Block)) { blockTree.SuggestBlock(correctRlp[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"); return(new EthereumTestResult ( test.Name, null, differences.Count == 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); }
protected virtual Task InitBlockchain() { var(_get, _set) = _api.ForBlockchain; if (_get.ChainSpec == null) { throw new StepDependencyException(nameof(_get.ChainSpec)); } if (_get.DbProvider == null) { throw new StepDependencyException(nameof(_get.DbProvider)); } if (_get.SpecProvider == null) { throw new StepDependencyException(nameof(_get.SpecProvider)); } ILogger logger = _get.LogManager.GetClassLogger(); IInitConfig initConfig = _get.Config <IInitConfig>(); ISyncConfig syncConfig = _get.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 = _get.ChainSpec.Parameters.AccountStartNonce; var stateProvider = _set.StateProvider = new StateProvider( _get.DbProvider.StateDb, _get.DbProvider.CodeDb, _get.LogManager); ReadOnlyDbProvider readOnly = new ReadOnlyDbProvider(_api.DbProvider, false); var stateReader = _set.StateReader = new StateReader(readOnly.StateDb, readOnly.CodeDb, _api.LogManager); _set.ChainHeadStateProvider = new ChainHeadReadOnlyStateProvider(_get.BlockTree, stateReader); PersistentTxStorage txStorage = new PersistentTxStorage(_get.DbProvider.PendingTxsDb); // Init state if we need system calls before actual processing starts if (_get.BlockTree !.Head != null) { stateProvider.StateRoot = _get.BlockTree.Head.StateRoot; } var txPool = _api.TxPool = CreateTxPool(txStorage); var onChainTxWatcher = new OnChainTxWatcher(_get.BlockTree, txPool, _get.SpecProvider, _api.LogManager); _get.DisposeStack.Push(onChainTxWatcher); _api.BlockPreprocessor.AddFirst( new RecoverSignatures(_get.EthereumEcdsa, txPool, _get.SpecProvider, _get.LogManager)); var storageProvider = _set.StorageProvider = new StorageProvider( _get.DbProvider.StateDb, stateProvider, _get.LogManager); // blockchain processing BlockhashProvider blockhashProvider = new BlockhashProvider( _get.BlockTree, _get.LogManager); VirtualMachine virtualMachine = new VirtualMachine( stateProvider, storageProvider, blockhashProvider, _get.SpecProvider, _get.LogManager); _api.TransactionProcessor = new TransactionProcessor( _get.SpecProvider, stateProvider, storageProvider, virtualMachine, _get.LogManager); InitSealEngine(); if (_api.SealValidator == null) { throw new StepDependencyException(nameof(_api.SealValidator)); } /* validation */ var headerValidator = _set.HeaderValidator = CreateHeaderValidator(); OmmersValidator ommersValidator = new OmmersValidator( _get.BlockTree, headerValidator, _get.LogManager); TxValidator txValidator = new TxValidator(_get.SpecProvider.ChainId); var blockValidator = _set.BlockValidator = new BlockValidator( txValidator, headerValidator, ommersValidator, _get.SpecProvider, _get.LogManager); _set.TxPoolInfoProvider = new TxPoolInfoProvider(_api.StateReader, _api.TxPool); var mainBlockProcessor = _set.MainBlockProcessor = CreateBlockProcessor(); BlockchainProcessor blockchainProcessor = new BlockchainProcessor( _get.BlockTree, mainBlockProcessor, _api.BlockPreprocessor, _get.LogManager, new BlockchainProcessor.Options { AutoProcess = !syncConfig.BeamSync, StoreReceiptsByDefault = initConfig.StoreReceipts, }); _set.BlockProcessingQueue = blockchainProcessor; _set.BlockchainProcessor = blockchainProcessor; if (syncConfig.BeamSync) { BeamBlockchainProcessor beamBlockchainProcessor = new BeamBlockchainProcessor( new ReadOnlyDbProvider(_api.DbProvider, false), _get.BlockTree, _get.SpecProvider, _get.LogManager, blockValidator, _api.BlockPreprocessor, _api.RewardCalculatorSource !, // TODO: does it work with AuRa? blockchainProcessor, _get.SyncModeSelector !); _api.DisposeStack.Push(beamBlockchainProcessor); } // TODO: can take the tx sender from plugin here maybe ITxSigner txSigner = new WalletTxSigner(_get.Wallet, _get.SpecProvider.ChainId); TxSealer standardSealer = new TxSealer(txSigner, _get.Timestamper); NonceReservingTxSealer nonceReservingTxSealer = new NonceReservingTxSealer(txSigner, _get.Timestamper, txPool); _set.TxSender = new TxPoolSender(txPool, nonceReservingTxSealer, standardSealer); // TODO: possibly hide it (but need to confirm that NDM does not really need it) var filterStore = _set.FilterStore = new FilterStore(); _set.FilterManager = new FilterManager(filterStore, mainBlockProcessor, txPool, _get.LogManager); return(Task.CompletedTask); }
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"); }
private async Task InitBlockchain() { /* spec */ if (_chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId) { _specProvider = RopstenSpecProvider.Instance; } else if (_chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId) { _specProvider = MainNetSpecProvider.Instance; } else if (_chainSpec.ChainId == RinkebySpecProvider.Instance.ChainId) { _specProvider = RinkebySpecProvider.Instance; } else if (_chainSpec.ChainId == GoerliSpecProvider.Instance.ChainId) { _specProvider = GoerliSpecProvider.Instance; } else if (_chainSpec.ChainId == SturebySpecProvider.Instance.ChainId) { _specProvider = SturebySpecProvider.Instance; } else { _specProvider = new SingleReleaseSpecProvider(LatestRelease.Instance, _chainSpec.ChainId); } /* sync */ IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>(); foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties()) { if (_logger.IsDebug) { _logger.Debug($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}"); } } _dbProvider = HiveEnabled ? (IDbProvider) new MemDbProvider() : new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts); _ethereumEcdsa = new EthereumEcdsa(_specProvider, _logManager); _txPool = new TxPool( new PersistentTransactionStorage(_dbProvider.PendingTxsDb, _specProvider), new PendingTransactionThresholdValidator(_initConfig.ObsoletePendingTransactionInterval, _initConfig.RemovePendingTransactionInterval), new Timestamp(), _ethereumEcdsa, _specProvider, _logManager, _initConfig.RemovePendingTransactionInterval, _initConfig.PeerNotificationThreshold); _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _specProvider); // IDbProvider debugRecorder = new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig); // _dbProvider = new RpcDbProvider(_jsonSerializer, new BasicJsonRpcClient(KnownRpcUris.NethVm1, _jsonSerializer, _logManager), _logManager, debugRecorder); // IDbProvider debugReader = new ReadOnlyDbProvider(new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig)); // _dbProvider = debugReader; _blockTree = new BlockTree( _dbProvider.BlocksDb, _dbProvider.HeadersDb, _dbProvider.BlockInfosDb, _specProvider, _txPool, _logManager); _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _txPool, _logManager); CliqueConfig cliqueConfig = null; _snapshotManager = null; switch (_chainSpec.SealEngineType) { case SealEngineType.None: _sealer = NullSealEngine.Instance; _sealValidator = NullSealEngine.Instance; _rewardCalculator = NoBlockRewards.Instance; break; case SealEngineType.Clique: _rewardCalculator = NoBlockRewards.Instance; cliqueConfig = new CliqueConfig(); cliqueConfig.BlockPeriod = _chainSpec.CliquePeriod; cliqueConfig.Epoch = _chainSpec.CliqueEpoch; _snapshotManager = new SnapshotManager(cliqueConfig, _dbProvider.BlocksDb, _blockTree, _ethereumEcdsa, _logManager); _sealValidator = new CliqueSealValidator(cliqueConfig, _snapshotManager, _logManager); _recoveryStep = new CompositeDataRecoveryStep(_recoveryStep, new AuthorRecoveryStep(_snapshotManager)); if (_initConfig.IsMining) { _sealer = new CliqueSealer(new BasicWallet(_nodeKey), cliqueConfig, _snapshotManager, _nodeKey.Address, _logManager); } else { _sealer = NullSealEngine.Instance; } break; case SealEngineType.NethDev: _sealer = NullSealEngine.Instance; _sealValidator = NullSealEngine.Instance; _rewardCalculator = NoBlockRewards.Instance; break; case SealEngineType.Ethash: _rewardCalculator = new RewardCalculator(_specProvider); var difficultyCalculator = new DifficultyCalculator(_specProvider); if (_initConfig.IsMining) { _sealer = new EthashSealer(new Ethash(_logManager), _logManager); } else { _sealer = NullSealEngine.Instance; } _sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager)); break; default: throw new NotSupportedException($"Seal engine type {_chainSpec.SealEngineType} is not supported in Nethermind"); } /* validation */ _headerValidator = new HeaderValidator( _blockTree, _sealValidator, _specProvider, _logManager); var ommersValidator = new OmmersValidator( _blockTree, _headerValidator, _logManager); var txValidator = new TxValidator(_specProvider.ChainId); _blockValidator = new BlockValidator( txValidator, _headerValidator, ommersValidator, _specProvider, _logManager); var stateProvider = new StateProvider( _dbProvider.StateDb, _dbProvider.CodeDb, _logManager); _stateProvider = stateProvider; var storageProvider = new StorageProvider( _dbProvider.StateDb, stateProvider, _logManager); _transactionPoolInfoProvider = new TxPoolInfoProvider(stateProvider); /* blockchain processing */ var blockhashProvider = new BlockhashProvider( _blockTree, _logManager); var virtualMachine = new VirtualMachine( stateProvider, storageProvider, blockhashProvider, _logManager); var transactionProcessor = new TransactionProcessor( _specProvider, stateProvider, storageProvider, virtualMachine, _logManager); _blockProcessor = new BlockProcessor( _specProvider, _blockValidator, _rewardCalculator, transactionProcessor, _dbProvider.StateDb, _dbProvider.CodeDb, _dbProvider.TraceDb, stateProvider, storageProvider, _txPool, _receiptStorage, _configProvider.GetConfig <ISyncConfig>(), _logManager); _blockchainProcessor = new BlockchainProcessor( _blockTree, _blockProcessor, _recoveryStep, _logManager, _initConfig.StoreReceipts, _initConfig.StoreTraces); // create shared objects between discovery and peer manager IStatsConfig statsConfig = _configProvider.GetConfig <IStatsConfig>(); _nodeStatsManager = new NodeStatsManager(statsConfig, _logManager); if (_initConfig.IsMining) { IReadOnlyDbProvider minerDbProvider = new ReadOnlyDbProvider(_dbProvider, false); AlternativeChain producerChain = new AlternativeChain(_blockTree, _blockValidator, _rewardCalculator, _specProvider, minerDbProvider, _recoveryStep, _logManager, _txPool, _receiptStorage); switch (_chainSpec.SealEngineType) { case SealEngineType.Clique: { if (_logger.IsWarn) { _logger.Warn("Starting Clique block producer & sealer"); } _blockProducer = new CliqueBlockProducer(_txPool, producerChain.Processor, _blockTree, _timestamp, _cryptoRandom, producerChain.StateProvider, _snapshotManager, (CliqueSealer)_sealer, _nodeKey.Address, cliqueConfig, _logManager); break; } case SealEngineType.NethDev: { if (_logger.IsWarn) { _logger.Warn("Starting Dev block producer & sealer"); } _blockProducer = new DevBlockProducer(_txPool, producerChain.Processor, _blockTree, _timestamp, _logManager); break; } default: throw new NotSupportedException($"Mining in {_chainSpec.SealEngineType} mode is not supported"); } _blockProducer.Start(); } if (!HiveEnabled) { _blockchainProcessor.Start(); LoadGenesisBlock(_chainSpec, string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash), _blockTree, stateProvider, _specProvider); if (_initConfig.ProcessingEnabled) { #pragma warning disable 4014 LoadBlocksFromDb(); #pragma warning restore 4014 } else { if (_logger.IsWarn) { _logger.Warn($"Shutting down the blockchain processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false"); } await _blockchainProcessor.StopAsync(); } } await InitializeNetwork( _receiptStorage, _sealValidator, txValidator); }