示例#1
0
        public async Task Init(INethermindApi nethermindApi)
        {
            _api            = nethermindApi;
            _txPool         = _api.TxPool;
            _blockProcessor = _api.MainBlockProcessor;

            _config = _api.Config <IDslConfig>();
            if (_config.Enabled)
            {
                _logger = _api.LogManager.GetClassLogger();
                if (_logger.IsInfo)
                {
                    _logger.Info("Initializing DSL plugin ...");
                }

                var dslScript = await LoadDSLScript();

                var inputStream = new AntlrInputStream(dslScript);
                var lexer       = new DslGrammarLexer(inputStream);
                var tokens      = new CommonTokenStream(lexer);
                var parser      = new DslGrammarParser(tokens);
                parser.BuildParseTree = true;
                IParseTree tree = parser.init();

                _listener                   = new ParseTreeListener();
                _listener.OnEnterInit       = OnInitEntry;
                _listener.OnEnterExpression = OnExpressionEntry;
                _listener.OnEnterCondition  = OnConditionEntry;
                _listener.OnExitInit        = BuildPipeline;
                ParseTreeWalker.Default.Walk(_listener, tree);

                if (_logger.IsInfo)
                {
                    _logger.Info("DSL plugin initialized.");
                }
            }
        }
示例#2
0
        public async Task Init(INethermindApi api)
        {
            _vaultConfig = api.Config <IVaultConfig>();
            _api         = api;
            _logger      = api.LogManager.GetClassLogger();
            if (_vaultConfig.Enabled)
            {
                _vaultService = new VaultService(_vaultConfig, _api.LogManager);

                var passwordProvider = new FilePasswordProvider(a => _vaultConfig.VaultKeyFile.GetApplicationResourcePath())
                                       .OrReadFromConsole("Provide passsphrase to unlock Vault");
                var vaultKeyStoreFacade = new VaultKeyStoreFacade(passwordProvider);
                _vaultSealingHelper = new VaultSealingHelper(vaultKeyStoreFacade, _vaultConfig, _logger);
                await _vaultSealingHelper.Unseal();


                IVaultWallet wallet      = new VaultWallet(_vaultService, _vaultConfig.VaultId, _api.LogManager);
                ITxSigner    vaultSigner = new VaultTxSigner(wallet, _api.ChainSpec.ChainId);

                // TODO: change vault to provide, use sealer to set the gas price as well
                // TODO: need to verify the timing of initializations so the TxSender replacement works fine
                _api.TxSender = new VaultTxSender(vaultSigner, _vaultConfig, (int)_api.ChainSpec.ChainId);
            }
        }
示例#3
0
        public virtual async Task Execute(CancellationToken cancellationToken)
        {
            if (_api.BlockTree == null)
            {
                throw new StepDependencyException(nameof(_api.BlockTree));
            }
            if (_api.ReceiptFinder == null)
            {
                throw new StepDependencyException(nameof(_api.ReceiptFinder));
            }
            if (_api.BloomStorage == null)
            {
                throw new StepDependencyException(nameof(_api.BloomStorage));
            }
            if (_api.LogManager == null)
            {
                throw new StepDependencyException(nameof(_api.LogManager));
            }

            IJsonRpcConfig jsonRpcConfig = _api.Config <IJsonRpcConfig>();

            if (!jsonRpcConfig.Enabled)
            {
                return;
            }

            if (_api.RpcModuleProvider == null)
            {
                throw new StepDependencyException(nameof(_api.RpcModuleProvider));
            }
            if (_api.FileSystem == null)
            {
                throw new StepDependencyException(nameof(_api.FileSystem));
            }
            if (_api.TxPool == null)
            {
                throw new StepDependencyException(nameof(_api.TxPool));
            }
            if (_api.Wallet == null)
            {
                throw new StepDependencyException(nameof(_api.Wallet));
            }
            if (_api.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(_api.SpecProvider));
            }
            if (_api.TxSender == null)
            {
                throw new StepDependencyException(nameof(_api.TxSender));
            }
            if (_api.StateReader == null)
            {
                throw new StepDependencyException(nameof(_api.StateReader));
            }
            if (_api.PeerManager == null)
            {
                throw new StepDependencyException(nameof(_api.PeerManager));
            }

            if (jsonRpcConfig.Enabled)
            {
                _api.RpcModuleProvider = new RpcModuleProvider(_api.FileSystem, jsonRpcConfig, _api.LogManager);
            }
            else
            {
                _api.RpcModuleProvider ??= NullModuleProvider.Instance;
            }

            // the following line needs to be called in order to make sure that the CLI library is referenced from runner and built alongside
            ILogger logger = _api.LogManager.GetClassLogger();

            IInitConfig    initConfig    = _api.Config <IInitConfig>();
            IJsonRpcConfig rpcConfig     = _api.Config <IJsonRpcConfig>();
            INetworkConfig networkConfig = _api.Config <INetworkConfig>();

            // lets add threads to support parallel eth_getLogs
            ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads);
            ThreadPool.SetMinThreads(workerThreads + Environment.ProcessorCount, completionPortThreads + Environment.ProcessorCount);

            EthModuleFactory ethModuleFactory = new(
                _api.TxPool,
                _api.TxSender,
                _api.Wallet,
                _api.BlockTree,
                _api.Config <IJsonRpcConfig>(),
                _api.LogManager,
                _api.StateReader,
                _api);

            _api.RpcModuleProvider.RegisterBounded(ethModuleFactory, rpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, rpcConfig.Timeout);

            if (_api.DbProvider == null)
            {
                throw new StepDependencyException(nameof(_api.DbProvider));
            }
            if (_api.BlockPreprocessor == null)
            {
                throw new StepDependencyException(nameof(_api.BlockPreprocessor));
            }
            if (_api.BlockValidator == null)
            {
                throw new StepDependencyException(nameof(_api.BlockValidator));
            }
            if (_api.RewardCalculatorSource == null)
            {
                throw new StepDependencyException(nameof(_api.RewardCalculatorSource));
            }

            ProofModuleFactory proofModuleFactory = new(_api.DbProvider, _api.BlockTree, _api.ReadOnlyTrieStore, _api.BlockPreprocessor, _api.ReceiptFinder, _api.SpecProvider, _api.LogManager);

            _api.RpcModuleProvider.RegisterBounded(proofModuleFactory, 2, rpcConfig.Timeout);

            DebugModuleFactory debugModuleFactory = new(
                _api.DbProvider,
                _api.BlockTree,
                rpcConfig,
                _api.BlockValidator,
                _api.BlockPreprocessor,
                _api.RewardCalculatorSource,
                _api.ReceiptStorage,
                new ReceiptMigration(_api),
                _api.ReadOnlyTrieStore,
                _api.ConfigProvider,
                _api.SpecProvider,
                _api.LogManager);

            _api.RpcModuleProvider.RegisterBoundedByCpuCount(debugModuleFactory, rpcConfig.Timeout);

            TraceModuleFactory traceModuleFactory = new(
                _api.DbProvider,
                _api.BlockTree,
                _api.ReadOnlyTrieStore,
                rpcConfig,
                _api.BlockPreprocessor,
                _api.RewardCalculatorSource,
                _api.ReceiptStorage,
                _api.SpecProvider,
                _api.LogManager);

            _api.RpcModuleProvider.RegisterBoundedByCpuCount(traceModuleFactory, rpcConfig.Timeout);

            if (_api.EthereumEcdsa == null)
            {
                throw new StepDependencyException(nameof(_api.EthereumEcdsa));
            }
            if (_api.Wallet == null)
            {
                throw new StepDependencyException(nameof(_api.Wallet));
            }

            PersonalRpcModule personalRpcModule = new(
                _api.EthereumEcdsa,
                _api.Wallet,
                _api.KeyStore);

            _api.RpcModuleProvider.RegisterSingle <IPersonalRpcModule>(personalRpcModule);

            if (_api.PeerManager == null)
            {
                throw new StepDependencyException(nameof(_api.PeerManager));
            }
            if (_api.StaticNodesManager == null)
            {
                throw new StepDependencyException(nameof(_api.StaticNodesManager));
            }
            if (_api.Enode == null)
            {
                throw new StepDependencyException(nameof(_api.Enode));
            }

            AdminRpcModule adminRpcModule = new(
                _api.BlockTree,
                networkConfig,
                _api.PeerManager,
                _api.StaticNodesManager,
                _api.Enode,
                initConfig.BaseDbPath);

            _api.RpcModuleProvider.RegisterSingle <IAdminRpcModule>(adminRpcModule);

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

            TxPoolRpcModule txPoolRpcModule = new(_api.BlockTree, _api.TxPoolInfoProvider, _api.LogManager);

            _api.RpcModuleProvider.RegisterSingle <ITxPoolRpcModule>(txPoolRpcModule);

            if (_api.SyncServer == null)
            {
                throw new StepDependencyException(nameof(_api.SyncServer));
            }
            if (_api.EngineSignerStore == null)
            {
                throw new StepDependencyException(nameof(_api.EngineSignerStore));
            }

            NetRpcModule netRpcModule = new(_api.LogManager, new NetBridge(_api.Enode, _api.SyncServer));

            _api.RpcModuleProvider.RegisterSingle <INetRpcModule>(netRpcModule);

            ParityRpcModule parityRpcModule = new(
                _api.EthereumEcdsa,
                _api.TxPool,
                _api.BlockTree,
                _api.ReceiptFinder,
                _api.Enode,
                _api.EngineSignerStore,
                _api.KeyStore,
                _api.LogManager,
                _api.PeerManager);

            _api.RpcModuleProvider.RegisterSingle <IParityRpcModule>(parityRpcModule);

            SubscriptionFactory subscriptionFactory = new(
                _api.LogManager,
                _api.BlockTree,
                _api.TxPool,
                _api.ReceiptStorage,
                _api.FilterStore);

            SubscriptionManager subscriptionManager = new(subscriptionFactory, _api.LogManager);

            SubscribeRpcModule subscribeRpcModule = new(subscriptionManager);

            _api.RpcModuleProvider.RegisterSingle <ISubscribeRpcModule>(subscribeRpcModule);

            Web3RpcModule web3RpcModule = new(_api.LogManager);

            _api.RpcModuleProvider.RegisterSingle <IWeb3RpcModule>(web3RpcModule);

            EvmRpcModule evmRpcModule = new(_api.ManualBlockProductionTrigger);

            _api.RpcModuleProvider.RegisterSingle <IEvmRpcModule>(evmRpcModule);

            foreach (INethermindPlugin plugin in _api.Plugins)
            {
                await plugin.InitRpcModules();
            }

            if (logger.IsDebug)
            {
                logger.Debug($"RPC modules  : {string.Join(", ", _api.RpcModuleProvider.Enabled.OrderBy(x => x))}");
            }
            ThisNodeInfo.AddInfo("RPC modules  :", $"{string.Join(", ", _api.RpcModuleProvider.Enabled.OrderBy(x => x))}");
        }
示例#4
0
 public StartBlockProducerAuRa(AuRaNethermindApi api)
 {
     _api        = api;
     _auraConfig = NethermindApi.Config <IAuraConfig>();
 }
示例#5
0
        public async Task Execute(CancellationToken cancellationToken)
        {
            IJsonRpcConfig jsonRpcConfig = _api.Config <IJsonRpcConfig>();
            ILogger        logger        = _api.LogManager.GetClassLogger();

            if (jsonRpcConfig.Enabled)
            {
                IInitConfig           initConfig           = _api.Config <IInitConfig>();
                IJsonRpcUrlCollection jsonRpcUrlCollection = new JsonRpcUrlCollection(_api.LogManager, jsonRpcConfig, initConfig.WebSocketsEnabled);

                JsonRpcLocalStats jsonRpcLocalStats = new(
                    _api.Timestamper,
                    jsonRpcConfig,
                    _api.LogManager);

                IRpcModuleProvider rpcModuleProvider = _api.RpcModuleProvider !;
                JsonRpcService     jsonRpcService    = new(rpcModuleProvider, _api.LogManager, jsonRpcConfig);

                IJsonSerializer    jsonSerializer = CreateJsonSerializer(jsonRpcService);
                IRpcAuthentication auth           = jsonRpcConfig.UnsecureDevNoRpcAuthentication || !jsonRpcUrlCollection.Values.Any(u => u.IsAuthenticated)
                    ? NoAuthentication.Instance
                    : MicrosoftJwtAuthentication.CreateFromFileOrGenerate(jsonRpcConfig.JwtSecretFile, _api.Timestamper, logger);


                JsonRpcProcessor jsonRpcProcessor = new(
                    jsonRpcService,
                    jsonSerializer,
                    jsonRpcConfig,
                    _api.FileSystem,
                    _api.LogManager);


                if (initConfig.WebSocketsEnabled)
                {
                    JsonRpcWebSocketsModule webSocketsModule = new(
                        jsonRpcProcessor,
                        jsonRpcService,
                        jsonRpcLocalStats,
                        _api.LogManager,
                        jsonSerializer,
                        jsonRpcUrlCollection,
                        auth);

                    _api.WebSocketsManager !.AddModule(webSocketsModule, true);
                }

                Bootstrap.Instance.JsonRpcService        = jsonRpcService;
                Bootstrap.Instance.LogManager            = _api.LogManager;
                Bootstrap.Instance.JsonSerializer        = jsonSerializer;
                Bootstrap.Instance.JsonRpcLocalStats     = jsonRpcLocalStats;
                Bootstrap.Instance.JsonRpcAuthentication = auth;

                JsonRpcRunner?jsonRpcRunner = new(
                    jsonRpcProcessor,
                    jsonRpcUrlCollection,
                    _api.WebSocketsManager !,
                    _api.ConfigProvider,
                    auth,
                    _api.LogManager,
                    _api);

                await jsonRpcRunner.Start(cancellationToken).ContinueWith(x =>
                {
                    if (x.IsFaulted && logger.IsError)
                    {
                        logger.Error("Error during jsonRpc runner start", x.Exception);
                    }
                }, cancellationToken);

                JsonRpcIpcRunner jsonIpcRunner = new(jsonRpcProcessor, jsonRpcService, _api.ConfigProvider,
                                                     _api.LogManager, jsonRpcLocalStats, jsonSerializer, _api.FileSystem);
                jsonIpcRunner.Start(cancellationToken);

#pragma warning disable 4014
                _api.DisposeStack.Push(
                    new Reactive.AnonymousDisposable(() => jsonRpcRunner.StopAsync())); // do not await
                _api.DisposeStack.Push(jsonIpcRunner);                                  // do not await
#pragma warning restore 4014
            }
            else
            {
                if (logger.IsInfo)
                {
                    logger.Info("Json RPC is disabled");
                }
            }
        }
示例#6
0
        private Task InitBlockchain()
        {
            BlockTraceDumper.Converters.AddRange(DebugModuleFactory.Converters);
            BlockTraceDumper.Converters.AddRange(TraceModuleFactory.Converters);

            var(getApi, 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));
            }

            _logger = getApi.LogManager.GetClassLogger();
            IInitConfig    initConfig    = getApi.Config <IInitConfig>();
            ISyncConfig    syncConfig    = getApi.Config <ISyncConfig>();
            IPruningConfig pruningConfig = getApi.Config <IPruningConfig>();

            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 = setApi.WitnessCollector = syncConfig.WitnessProtocolEnabled
                ? new WitnessCollector(getApi.DbProvider.WitnessDb, _api.LogManager)
                                                                           .WithPruning(getApi.BlockTree !, getApi.LogManager)
                : NullWitnessCollector.Instance;

            IKeyValueStoreWithBatching cachedStateDb = getApi.DbProvider.StateDb
                                                       .Cached(Trie.MemoryAllowance.TrieNodeCacheCount);

            setApi.MainStateDbWithCache = cachedStateDb;
            IKeyValueStore codeDb = getApi.DbProvider.CodeDb
                                    .WitnessedBy(witnessCollector);

            TrieStore trieStore;

            if (pruningConfig.Enabled)
            {
                setApi.TrieStore = trieStore = new TrieStore(
                    setApi.MainStateDbWithCache.WitnessedBy(witnessCollector),
                    Prune.WhenCacheReaches(pruningConfig.CacheMb.MB()),          // TODO: memory hint should define this
                    Persist.IfBlockOlderThan(pruningConfig.PersistenceInterval), // TODO: this should be based on time
                    getApi.LogManager);
            }
            else
            {
                setApi.TrieStore = trieStore = new TrieStore(
                    setApi.MainStateDbWithCache.WitnessedBy(witnessCollector),
                    No.Pruning,
                    Persist.EveryBlock,
                    getApi.LogManager);
            }

            getApi.DisposeStack.Push(trieStore);
            trieStore.ReorgBoundaryReached += ReorgBoundaryReached;
            ITrieStore readOnlyTrieStore = setApi.ReadOnlyTrieStore = trieStore.AsReadOnly(cachedStateDb);

            IStateProvider stateProvider = setApi.StateProvider = new StateProvider(
                trieStore,
                codeDb,
                getApi.LogManager);

            ReadOnlyDbProvider readOnly = new(getApi.DbProvider, false);

            PersistentTxStorage txStorage   = new(getApi.DbProvider.PendingTxsDb);
            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)
            {
                _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);
            }

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

            var txValidator = setApi.TxValidator = new TxValidator(getApi.SpecProvider.ChainId);

            ITxPool txPool = _api.TxPool = CreateTxPool(txStorage);

            OnChainTxWatcher onChainTxWatcher = new(getApi.BlockTree, txPool, getApi.SpecProvider, _api.LogManager);

            getApi.DisposeStack.Push(onChainTxWatcher);

            ReceiptCanonicalityMonitor receiptCanonicalityMonitor = new(getApi.BlockTree, getApi.ReceiptStorage, _api.LogManager);

            getApi.DisposeStack.Push(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 BlockhashProvider(
                getApi.BlockTree, getApi.LogManager);

            VirtualMachine virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                getApi.SpecProvider,
                getApi.LogManager);

            _api.TransactionProcessor = new TransactionProcessor(
                getApi.SpecProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                getApi.LogManager);

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

            /* validation */
            var headerValidator = setApi.HeaderValidator = CreateHeaderValidator();

            OmmersValidator ommersValidator = new(
                getApi.BlockTree,
                headerValidator,
                getApi.LogManager);

            var blockValidator = setApi.BlockValidator = new BlockValidator(
                txValidator,
                headerValidator,
                ommersValidator,
                getApi.SpecProvider,
                getApi.LogManager);

            setApi.TxPoolInfoProvider = new TxPoolInfoProvider(stateReader, txPool);
            var mainBlockProcessor = setApi.MainBlockProcessor = CreateBlockProcessor();

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

            setApi.BlockProcessingQueue = blockchainProcessor;
            setApi.BlockchainProcessor  = blockchainProcessor;

            if (syncConfig.BeamSync)
            {
                BeamBlockchainProcessor beamBlockchainProcessor = new(
                    new ReadOnlyDbProvider(_api.DbProvider, false),
                    getApi.BlockTree,
                    getApi.SpecProvider,
                    getApi.LogManager,
                    blockValidator,
                    _api.BlockPreprocessor,
                    _api.RewardCalculatorSource !, // TODO: does it work with AuRa?
                    blockchainProcessor,
                    getApi.SyncModeSelector !);

                _api.DisposeStack.Push(beamBlockchainProcessor);
            }

            // 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)
            var filterStore = setApi.FilterStore = new FilterStore();

            setApi.FilterManager     = new FilterManager(filterStore, mainBlockProcessor, txPool, getApi.LogManager);
            setApi.HealthHintService = CreateHealthHintService();
            return(Task.CompletedTask);
        }
        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);
        }
        public Task Init(INethermindApi nethermindApi)
        {
            _nethermindApi            = nethermindApi ?? throw new ArgumentNullException(nameof(nethermindApi));
            _accountAbstractionConfig = _nethermindApi.Config <IAccountAbstractionConfig>();
            _logger = _nethermindApi.LogManager.GetClassLogger();

            if (_accountAbstractionConfig.Enabled)
            {
                // Increasing number of priority peers in network config by AaPriorityPeersMaxCount.
                // Be careful if there is another plugin with priority peers - they won't be distinguished in SyncPeerPool.
                _nethermindApi.Config <INetworkConfig>().PriorityPeersMaxCount += _accountAbstractionConfig.AaPriorityPeersMaxCount;
                IList <string> entryPointContractAddressesString = _accountAbstractionConfig.GetEntryPointAddresses().ToList();
                foreach (string addressString in entryPointContractAddressesString)
                {
                    bool parsed = Address.TryParse(
                        addressString,
                        out Address? entryPointContractAddress);
                    if (!parsed)
                    {
                        if (_logger.IsError)
                        {
                            _logger.Error("Account Abstraction Plugin: EntryPoint contract address could not be parsed");
                        }
                    }
                    else
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Parsed EntryPoint address: {entryPointContractAddress}");
                        }
                        _entryPointContractAddresses.Add(entryPointContractAddress !);
                    }
                }

                IList <string> whitelistedPaymastersString = _accountAbstractionConfig.GetWhitelistedPaymasters().ToList();
                foreach (string addressString in whitelistedPaymastersString)
                {
                    bool parsed = Address.TryParse(
                        addressString,
                        out Address? whitelistedPaymaster);
                    if (!parsed)
                    {
                        if (_logger.IsError)
                        {
                            _logger.Error("Account Abstraction Plugin: Whitelisted Paymaster address could not be parsed");
                        }
                    }
                    else
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Parsed Whitelisted Paymaster address: {whitelistedPaymaster}");
                        }
                        _whitelistedPaymasters.Add(whitelistedPaymaster !);
                    }
                }

                _entryPointContractAbi = LoadEntryPointContract();
            }

            if (Enabled)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("  Account Abstraction Plugin: User Operation Mining Enabled");
                }
            }
            else
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("  Account Abstraction Plugin: User Operation Mining Disabled");
                }
            }

            return(Task.CompletedTask);
        }
示例#9
0
        public async Task Execute(CancellationToken cancellationToken)
        {
            IJsonRpcConfig jsonRpcConfig = _api.Config <IJsonRpcConfig>();
            ILogger        logger        = _api.LogManager.GetClassLogger();

            if (jsonRpcConfig.Enabled)
            {
                IInitConfig       initConfig        = _api.Config <IInitConfig>();
                JsonRpcLocalStats jsonRpcLocalStats = new JsonRpcLocalStats(
                    _api.Timestamper,
                    jsonRpcConfig,
                    _api.LogManager);

                JsonRpcService jsonRpcService = new JsonRpcService(_api.RpcModuleProvider, _api.LogManager);

                JsonRpcProcessor jsonRpcProcessor = new JsonRpcProcessor(
                    jsonRpcService,
                    _api.EthereumJsonSerializer,
                    jsonRpcConfig,
                    _api.FileSystem,
                    _api.LogManager);

                if (initConfig.WebSocketsEnabled)
                {
                    // TODO: I do not like passing both service and processor to any of the types
                    JsonRpcWebSocketsModule?webSocketsModule = new JsonRpcWebSocketsModule(
                        jsonRpcProcessor,
                        jsonRpcService,
                        _api.EthereumJsonSerializer,
                        jsonRpcLocalStats);

                    _api.WebSocketsManager !.AddModule(webSocketsModule, true);
                }

                Bootstrap.Instance.JsonRpcService    = jsonRpcService;
                Bootstrap.Instance.LogManager        = _api.LogManager;
                Bootstrap.Instance.JsonSerializer    = _api.EthereumJsonSerializer;
                Bootstrap.Instance.JsonRpcLocalStats = jsonRpcLocalStats;
                var jsonRpcRunner = new JsonRpcRunner(
                    jsonRpcProcessor,
                    _api.WebSocketsManager,
                    _api.ConfigProvider,
                    _api.LogManager,
                    _api);

                await jsonRpcRunner.Start(cancellationToken).ContinueWith(x =>
                {
                    if (x.IsFaulted && logger.IsError)
                    {
                        logger.Error("Error during jsonRpc runner start", x.Exception);
                    }
                });

                _api.DisposeStack.Push(Disposable.Create(() => jsonRpcRunner.StopAsync())); // do not await
            }
            else
            {
                if (logger.IsInfo)
                {
                    logger.Info("Json RPC is disabled");
                }
            }
        }
        public Task Init(INethermindApi nethermindApi)
        {
            _nethermindApi            = nethermindApi ?? throw new ArgumentNullException(nameof(nethermindApi));
            _accountAbstractionConfig = _nethermindApi.Config <IAccountAbstractionConfig>();
            _logger = _nethermindApi.LogManager.GetClassLogger();

            if (_accountAbstractionConfig.Enabled)
            {
                bool parsed = Address.TryParse(
                    _accountAbstractionConfig.EntryPointContractAddress,
                    out Address? entryPointContractAddress);
                if (!parsed)
                {
                    if (_logger.IsError)
                    {
                        _logger.Error("Account Abstraction Plugin: EntryPoint contract address could not be parsed");
                    }
                }
                else
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Parsed EntryPoint Address: {entryPointContractAddress}");
                    }
                    _entryPointContractAddress = entryPointContractAddress !;
                }

                bool parsedCreate2Factory = Address.TryParse(
                    _accountAbstractionConfig.Create2FactoryAddress,
                    out Address? create2FactoryAddress);
                if (!parsedCreate2Factory)
                {
                    if (_logger.IsError)
                    {
                        _logger.Error("Account Abstraction Plugin: Create2Factory contract address could not be parsed");
                    }
                }
                else
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Parsed Create2Factory Address: {create2FactoryAddress}");
                    }
                    _create2FactoryAddress = create2FactoryAddress !;
                }

                _entryPointContractAbi = LoadEntryPointContract();
            }

            if (Enabled)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("  Account Abstraction Plugin: User Operation Mining Enabled");
                }
            }
            else
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("  Account Abstraction Plugin: User Operation Mining Disabled");
                }
            }

            return(Task.CompletedTask);
        }