public DelayBlockImprovementContext( Block currentBestBlock, IManualBlockProductionTrigger blockProductionTrigger, TimeSpan timeout, BlockHeader parentHeader, PayloadAttributes payloadAttributes, int delay) { _cancellationTokenSource = new CancellationTokenSource(timeout); CurrentBestBlock = currentBestBlock; ImprovementTask = BuildBlock(blockProductionTrigger, parentHeader, payloadAttributes, delay, _cancellationTokenSource.Token); }
public BlockImprovementContext( Block currentBestBlock, IManualBlockProductionTrigger blockProductionTrigger, TimeSpan timeout, BlockHeader parentHeader, PayloadAttributes payloadAttributes) { _cancellationTokenSource = new CancellationTokenSource(timeout); CurrentBestBlock = currentBestBlock; ImprovementTask = blockProductionTrigger .BuildBlock(parentHeader, _cancellationTokenSource.Token, NullBlockTracer.Instance, payloadAttributes) .ContinueWith(SetCurrentBestBlock, _cancellationTokenSource.Token); }
public BoostBlockImprovementContext( Block currentBestBlock, IManualBlockProductionTrigger blockProductionTrigger, TimeSpan timeout, BlockHeader parentHeader, PayloadAttributes payloadAttributes, IBoostRelay boostRelay, IStateReader stateReader) { _boostRelay = boostRelay; _stateReader = stateReader; _cancellationTokenSource = new CancellationTokenSource(timeout); CurrentBestBlock = currentBestBlock; ImprovementTask = StartImprovingBlock(blockProductionTrigger, parentHeader, payloadAttributes, _cancellationTokenSource.Token); }
private async Task <Block?> BuildBlock( IManualBlockProductionTrigger blockProductionTrigger, BlockHeader parentHeader, PayloadAttributes payloadAttributes, int delay, CancellationToken cancellationToken) { Block?block = await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, NullBlockTracer.Instance, payloadAttributes); await Task.Delay(delay, cancellationToken); if (block is not null) { CurrentBestBlock = block; } return(CurrentBestBlock); }
private async Task <Block?> StartImprovingBlock( IManualBlockProductionTrigger blockProductionTrigger, BlockHeader parentHeader, PayloadAttributes payloadAttributes, CancellationToken cancellationToken) { payloadAttributes = await _boostRelay.GetPayloadAttributes(payloadAttributes, cancellationToken); UInt256 balanceBefore = _stateReader.GetAccount(parentHeader.StateRoot !, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; Block? block = await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, NullBlockTracer.Instance, payloadAttributes); if (block is not null) { CurrentBestBlock = block; UInt256 balanceAfter = _stateReader.GetAccount(block.StateRoot !, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; await _boostRelay.SendPayload(new BoostExecutionPayloadV1 { Block = new ExecutionPayloadV1(block), Profit = balanceAfter - balanceBefore }, cancellationToken); } return(CurrentBestBlock); }
public IBlockImprovementContext StartBlockImprovementContext( Block currentBestBlock, BlockHeader parentHeader, PayloadAttributes payloadAttributes) => new BlockImprovementContext(currentBestBlock, _blockProductionTrigger, _timeout, parentHeader, payloadAttributes);
public async Task forkchoiceUpdatedV1_should_communicate_with_boost_relay() { MergeConfig mergeConfig = new() { Enabled = true, SecondsPerSlot = 1, TerminalTotalDifficulty = "0" }; using MergeTestBlockchain chain = await CreateBlockChain(mergeConfig); IBoostRelay boostRelay = Substitute.For <IBoostRelay>(); boostRelay.GetPayloadAttributes(Arg.Any <PayloadAttributes>(), Arg.Any <CancellationToken>()) .Returns(c => { PayloadAttributes payloadAttributes = c.Arg <PayloadAttributes>(); payloadAttributes.SuggestedFeeRecipient = TestItem.AddressA; payloadAttributes.PrevRandao = TestItem.KeccakA; payloadAttributes.Timestamp += 1; payloadAttributes.GasLimit = 10_000_000L; return(payloadAttributes); }); BoostBlockImprovementContextFactory improvementContextFactory = new(chain.BlockProductionTrigger, TimeSpan.FromSeconds(5), boostRelay, chain.StateReader); TimeSpan timePerSlot = TimeSpan.FromSeconds(10); chain.PayloadPreparationService = new PayloadPreparationService( chain.PostMergeBlockProducer !, improvementContextFactory, TimerFactory.Default, chain.LogManager, timePerSlot); IEngineRpcModule rpc = CreateEngineModule(chain); Keccak startingHead = chain.BlockTree.HeadHash; UInt256 timestamp = Timestamper.UnixTime.Seconds; Keccak random = Keccak.Zero; Address feeRecipient = Address.Zero; BoostExecutionPayloadV1?sentItem = null; boostRelay.When(b => b.SendPayload(Arg.Any <BoostExecutionPayloadV1>(), Arg.Any <CancellationToken>())) .Do(c => sentItem = c.Arg <BoostExecutionPayloadV1>()); ManualResetEvent wait = new(false); chain.PayloadPreparationService.BlockImproved += (_, _) => wait.Set(); string payloadId = rpc.engine_forkchoiceUpdatedV1(new ForkchoiceStateV1(startingHead, Keccak.Zero, startingHead), new PayloadAttributes { Timestamp = timestamp, SuggestedFeeRecipient = feeRecipient, PrevRandao = random }).Result.Data .PayloadId !; await wait.WaitOneAsync(100, CancellationToken.None); ResultWrapper <ExecutionPayloadV1?> response = await rpc.engine_getPayloadV1(Bytes.FromHexString(payloadId)); ExecutionPayloadV1 executionPayloadV1 = response.Data !; executionPayloadV1.FeeRecipient.Should().Be(TestItem.AddressA); executionPayloadV1.PrevRandao.Should().Be(TestItem.KeccakA); executionPayloadV1.GasLimit.Should().Be(10_000_000L); executionPayloadV1.Should().BeEquivalentTo(sentItem !.Block); sentItem.Profit.Should().Be(0); }
public Task <PayloadAttributes> GetPayloadAttributes(PayloadAttributes payloadAttributes, CancellationToken cancellationToken) => _httpClient.PostJsonAsync <PayloadAttributes>(GetUri(_relayUrl, GetPayloadAttributesPath), payloadAttributes, cancellationToken);