protected virtual TxPool.TxPool CreateTxPool(PersistentTxStorage txStorage) => new TxPool.TxPool( txStorage, _api.EthereumEcdsa, new ChainHeadSpecProvider(_api.SpecProvider, _api.BlockTree), _api.Config <ITxPoolConfig>(), _api.ChainHeadStateProvider, _api.TxValidator, _api.LogManager, CreateTxPoolTxComparer());
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); }