public Task <IBlockProducer> InitBlockProducer(IConsensusPlugin consensusPlugin) { if (!Enabled) { throw new InvalidOperationException("Account Abstraction plugin is disabled"); } UInt256 minerBalance = _nethermindApi.StateProvider !.GetBalance(_nethermindApi.EngineSigner !.Address); if (minerBalance < 1.Ether()) { if (_logger.IsWarn) { _logger.Warn( $"Account Abstraction Plugin: Miner ({_nethermindApi.EngineSigner!.Address}) Ether balance low - {minerBalance / 1.Ether()} Ether < 1 Ether. Increasing balance is recommended"); } else { if (_logger.IsInfo) { _logger.Info( $"Account Abstraction Plugin: Miner ({_nethermindApi.EngineSigner!.Address}) Ether balance adequate - {minerBalance / 1.Ether()} Ether"); } } } IManualBlockProductionTrigger trigger = new BuildBlocksWhenRequested(); return(consensusPlugin.InitBlockProducer(trigger, UserOperationTxSource)); }
private async Task <MevBlockProducer.MevBlockProducerInfo> CreateProducer( IConsensusPlugin consensusPlugin, int bundleLimit = 0, ITxSource?additionalTxSource = null) { bool BundleLimitTriggerCondition(BlockProductionEventArgs e) { // TODO: why we are checking parent and not the currently produced block...? BlockHeader?parent = _nethermindApi.BlockTree !.GetProducedBlockParent(e.ParentHeader); if (parent is not null) { IEnumerable <MevBundle> bundles = BundlePool.GetBundles(parent, _nethermindApi.Timestamper); return(bundles.Count() >= bundleLimit); } return(false); } IManualBlockProductionTrigger manualTrigger = new BuildBlocksWhenRequested(); IBlockProductionTrigger trigger = manualTrigger; if (bundleLimit != 0) { trigger = new TriggerWithCondition(manualTrigger, BundleLimitTriggerCondition); } IBlockProducer producer = await consensusPlugin.InitBlockProducer(trigger, additionalTxSource); return(new MevBlockProducer.MevBlockProducerInfo(producer, manualTrigger, new BeneficiaryTracer())); }
public void Manual_trigger_works() { bool triggered = false; BuildBlocksWhenRequested trigger = new BuildBlocksWhenRequested(); trigger.TriggerBlockProduction += (s, e) => triggered = true; trigger.BuildBlock(); triggered.Should().BeTrue(); }
public Context() { MainBlockProductionTrigger = new BuildBlocksWhenRequested(); BlockProcessingQueue = Substitute.For <IBlockProcessingQueue>(); BlockTree = Substitute.For <IBlockTree>(); Trigger = new BuildBlocksOnlyWhenNotProcessing(MainBlockProductionTrigger, BlockProcessingQueue, BlockTree, LimboLogs.Instance, false); DefaultBlock = Build.A.Block.TestObject; Trigger.TriggerBlockProduction += OnTriggerBlockProduction; }
public void Does_not_trigger_when_empty(int txCount, bool shouldTrigger) { var pool = Substitute.For <ITxPool>(); pool.GetPendingTransactions().Returns(new Transaction[txCount]); bool triggered = false; BuildBlocksWhenRequested trigger = new BuildBlocksWhenRequested(); IBlockProductionTrigger withCondition = trigger.IfPoolIsNotEmpty(pool); withCondition.TriggerBlockProduction += (s, e) => triggered = true; trigger.BuildBlock(); triggered.Should().Be(shouldTrigger); }
public void On_pending_trigger_works() { int triggered = 0; BuildBlocksWhenRequested trigger1 = new BuildBlocksWhenRequested(); BuildBlocksWhenRequested trigger2 = new BuildBlocksWhenRequested(); IBlockProductionTrigger composite = trigger1.Or(trigger2); composite.TriggerBlockProduction += (s, e) => triggered++; trigger1.BuildBlock(); trigger2.BuildBlock(); trigger1.BuildBlock(); trigger2.BuildBlock(); triggered.Should().Be(4); }
public Task <IBlockProducer> InitBlockProducer(IConsensusPlugin consensusPlugin) { if (!Enabled) { throw new InvalidOperationException("Account Abstraction plugin is disabled"); } // init all relevant objects if not already initted foreach (Address entryPoint in _entryPointContractAddresses) { UserOperationPool(entryPoint); UserOperationSimulator(entryPoint); UserOperationTxBuilder(entryPoint); } _nethermindApi.BlockProducerEnvFactory.TransactionsExecutorFactory = new AABlockProducerTransactionsExecutorFactory( _nethermindApi.SpecProvider !, _nethermindApi.LogManager !, _nethermindApi.EngineSigner !, _entryPointContractAddresses.ToArray()); UInt256 minerBalance = _nethermindApi.ChainHeadStateProvider !.GetBalance(_nethermindApi.EngineSigner !.Address); if (minerBalance < 1.Ether()) { if (_logger.IsWarn) { _logger.Warn( $"Account Abstraction Plugin: Miner ({_nethermindApi.EngineSigner!.Address}) Ether balance low - {minerBalance / 1.Ether()} Ether < 1 Ether. Increasing balance is recommended"); } else { if (_logger.IsInfo) { _logger.Info( $"Account Abstraction Plugin: Miner ({_nethermindApi.EngineSigner!.Address}) Ether balance adequate - {minerBalance / 1.Ether()} Ether"); } } } IManualBlockProductionTrigger trigger = new BuildBlocksWhenRequested(); return(consensusPlugin.InitBlockProducer(trigger, UserOperationTxSource)); }
protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider) { MiningConfig miningConfig = new() { MinGasPrice = UInt256.One }; SpecProvider.UpdateMergeTransitionInfo(1, 0); BlockProducerEnvFactory blockProducerEnvFactory = new( DbProvider, BlockTree, ReadOnlyTrieStore, SpecProvider, BlockValidator, NoBlockRewards.Instance, ReceiptStorage, BlockPreprocessorStep, TxPool, transactionComparerProvider, miningConfig, LogManager) { TransactionsExecutorFactory = new MevBlockProducerTransactionsExecutorFactory(SpecProvider, LogManager) }; PostMergeBlockProducer CreatePostMergeBlockProducer(IBlockProductionTrigger blockProductionTrigger, ITxSource?txSource = null) { BlockProducerEnv blockProducerEnv = blockProducerEnvFactory.Create(txSource); return(new PostMergeBlockProducerFactory(SpecProvider, SealEngine, Timestamper, miningConfig, LogManager).Create( blockProducerEnv, blockProductionTrigger, txSource)); } MevBlockProducer.MevBlockProducerInfo CreateProducer(int bundleLimit = 0, ITxSource?additionalTxSource = null) { // TODO: this could be simplified a lot of the parent was not retrieved, not sure why do we need the parent here bool BundleLimitTriggerCondition(BlockProductionEventArgs e) { // TODO: why do we need this parent? later we use only the current block number BlockHeader?parent = BlockTree.GetProducedBlockParent(e.ParentHeader); if (parent is not null) { // ToDo resolved conflict parent.Timestamp? IEnumerable <MevBundle> bundles = BundlePool.GetBundles(parent.Number + 1, parent.Timestamp); return(bundles.Count() >= bundleLimit); } return(false); } IManualBlockProductionTrigger manualTrigger = new BuildBlocksWhenRequested(); IBlockProductionTrigger trigger = manualTrigger; if (bundleLimit != 0) { trigger = new TriggerWithCondition(manualTrigger, BundleLimitTriggerCondition); } IBlockProducer producer = CreatePostMergeBlockProducer(trigger, additionalTxSource); return(new MevBlockProducer.MevBlockProducerInfo(producer, manualTrigger, new BeneficiaryTracer())); } int megabundleProducerCount = _relayAddresses.Any() ? 1 : 0; List <MevBlockProducer.MevBlockProducerInfo> blockProducers = new(_maxMergedBundles + megabundleProducerCount + 1); // Add non-mev block MevBlockProducer.MevBlockProducerInfo standardProducer = CreateProducer(); blockProducers.Add(standardProducer); // Try blocks with all bundle numbers <= maxMergedBundles for (int bundleLimit = 1; bundleLimit <= _maxMergedBundles; bundleLimit++) { BundleSelector bundleSelector = new(BundlePool, bundleLimit); BundleTxSource bundleTxSource = new(bundleSelector, Timestamper); MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(bundleLimit, bundleTxSource); blockProducers.Add(bundleProducer); } if (megabundleProducerCount > 0) { MegabundleSelector megabundleSelector = new(BundlePool); BundleTxSource megabundleTxSource = new(megabundleSelector, Timestamper); MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(0, megabundleTxSource); blockProducers.Add(bundleProducer); } MevBlockProducer blockProducer = new MevBlockProducer(BlockProductionTrigger, LogManager, blockProducers.ToArray()); blockProducer.BlockProduced += OnBlockProduced; return(blockProducer); }
protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider) { MiningConfig miningConfig = new() { MinGasPrice = UInt256.One }; BlockProducerEnvFactory blockProducerEnvFactory = new( DbProvider, BlockTree, ReadOnlyTrieStore, SpecProvider, BlockValidator, NoBlockRewards.Instance, ReceiptStorage, BlockPreprocessorStep, TxPool, transactionComparerProvider, miningConfig, LogManager) { TransactionsExecutorFactory = new MevBlockProducerTransactionsExecutorFactory(SpecProvider, LogManager) }; Eth2BlockProducer CreateEth2BlockProducer(IBlockProductionTrigger blockProductionTrigger, ITxSource?txSource = null) => new Eth2TestBlockProducerFactory(GasLimitCalculator, txSource).Create( blockProducerEnvFactory, BlockTree, blockProductionTrigger, SpecProvider, Signer, Timestamper, miningConfig, LogManager); MevBlockProducer.MevBlockProducerInfo CreateProducer(int bundleLimit = 0, ITxSource?additionalTxSource = null) { bool BundleLimitTriggerCondition(BlockProductionEventArgs e) { BlockHeader?parent = BlockTree.GetProducedBlockParent(e.ParentHeader); if (parent is not null) { IEnumerable <MevBundle> bundles = BundlePool.GetBundles(parent, Timestamper); return(bundles.Count() >= bundleLimit); } return(false); } IManualBlockProductionTrigger manualTrigger = new BuildBlocksWhenRequested(); IBlockProductionTrigger trigger = manualTrigger; if (bundleLimit != 0) { trigger = new TriggerWithCondition(manualTrigger, BundleLimitTriggerCondition); } IBlockProducer producer = CreateEth2BlockProducer(trigger, additionalTxSource); return(new MevBlockProducer.MevBlockProducerInfo(producer, manualTrigger, new BeneficiaryTracer())); } int megabundleProducerCount = _relayAddresses.Any() ? 1 : 0; List <MevBlockProducer.MevBlockProducerInfo> blockProducers = new(_maxMergedBundles + megabundleProducerCount + 1); // Add non-mev block MevBlockProducer.MevBlockProducerInfo standardProducer = CreateProducer(); blockProducers.Add(standardProducer); // Try blocks with all bundle numbers <= maxMergedBundles for (int bundleLimit = 1; bundleLimit <= _maxMergedBundles; bundleLimit++) { BundleSelector bundleSelector = new(BundlePool, bundleLimit); BundleTxSource bundleTxSource = new(bundleSelector, Timestamper); MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(bundleLimit, bundleTxSource); blockProducers.Add(bundleProducer); } if (megabundleProducerCount > 0) { MegabundleSelector megabundleSelector = new(BundlePool); BundleTxSource megabundleTxSource = new(megabundleSelector, Timestamper); MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(0, megabundleTxSource); blockProducers.Add(bundleProducer); } return(new MevBlockProducer(BlockProductionTrigger, LogManager, blockProducers.ToArray())); }
public void Test() { ISpecProvider specProvider = MainnetSpecProvider.Instance; DbProvider dbProvider = new DbProvider(DbModeHint.Mem); dbProvider.RegisterDb(DbNames.BlockInfos, new MemDb()); dbProvider.RegisterDb(DbNames.Blocks, new MemDb()); dbProvider.RegisterDb(DbNames.Headers, new MemDb()); dbProvider.RegisterDb(DbNames.State, new MemDb()); dbProvider.RegisterDb(DbNames.Code, new MemDb()); BlockTree blockTree = new BlockTree( dbProvider, new ChainLevelInfoRepository(dbProvider), specProvider, NullBloomStorage.Instance, LimboLogs.Instance); TrieStore trieStore = new TrieStore( dbProvider.RegisteredDbs[DbNames.State], NoPruning.Instance, Archive.Instance, LimboLogs.Instance); StateProvider stateProvider = new StateProvider( trieStore, dbProvider.RegisteredDbs[DbNames.Code], LimboLogs.Instance); StorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, LimboLogs.Instance); BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance); VirtualMachine virtualMachine = new VirtualMachine( stateProvider, storageProvider, blockhashProvider, specProvider, LimboLogs.Instance); TransactionProcessor txProcessor = new TransactionProcessor( specProvider, stateProvider, storageProvider, virtualMachine, LimboLogs.Instance); BlockProcessor blockProcessor = new BlockProcessor( specProvider, Always.Valid, NoBlockRewards.Instance, txProcessor, stateProvider, storageProvider, NullTxPool.Instance, NullReceiptStorage.Instance, NullWitnessCollector.Instance, LimboLogs.Instance); BlockchainProcessor blockchainProcessor = new BlockchainProcessor( blockTree, blockProcessor, NullRecoveryStep.Instance, LimboLogs.Instance, BlockchainProcessor.Options.Default); BuildBlocksWhenRequested trigger = new BuildBlocksWhenRequested(); var timestamper = new ManualTimestamper(); DevBlockProducer devBlockProducer = new DevBlockProducer( EmptyTxSource.Instance, blockchainProcessor, stateProvider, blockTree, blockchainProcessor, trigger, timestamper, specProvider, new MiningConfig { Enabled = true }, LimboLogs.Instance); blockchainProcessor.Start(); devBlockProducer.Start(); AutoResetEvent autoResetEvent = new AutoResetEvent(false); blockTree.NewHeadBlock += (s, e) => autoResetEvent.Set(); blockTree.SuggestBlock(Build.A.Block.Genesis.TestObject); autoResetEvent.WaitOne(1000).Should().BeTrue("genesis"); trigger.BuildBlock(); autoResetEvent.WaitOne(1000).Should().BeTrue("1"); blockTree.Head.Number.Should().Be(1); }