Example #1
0
        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();
        }
Example #2
0
        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)");
            }
        }
Example #3
0
        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();
        }