public async Task forkchoiceUpdatedV1_should_ignore_gas_limit([Values(false, true)] bool relay) { MergeConfig mergeConfig = new() { Enabled = true, SecondsPerSlot = 1, TerminalTotalDifficulty = "0" }; using MergeTestBlockchain chain = await CreateBlockChain(mergeConfig); IBlockImprovementContextFactory improvementContextFactory; if (relay) { IBoostRelay boostRelay = Substitute.For <IBoostRelay>(); boostRelay.GetPayloadAttributes(Arg.Any <PayloadAttributes>(), Arg.Any <CancellationToken>()) .Returns(c => c.Arg <PayloadAttributes>()); improvementContextFactory = new BoostBlockImprovementContextFactory(chain.BlockProductionTrigger, TimeSpan.FromSeconds(5), boostRelay, chain.StateReader); } else { improvementContextFactory = new BlockImprovementContextFactory(chain.BlockProductionTrigger, TimeSpan.FromSeconds(5)); } 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; string payloadId = rpc.engine_forkchoiceUpdatedV1(new ForkchoiceStateV1(startingHead, Keccak.Zero, startingHead), new PayloadAttributes { Timestamp = timestamp, SuggestedFeeRecipient = feeRecipient, PrevRandao = random, GasLimit = 10_000_000L }).Result.Data .PayloadId !; ResultWrapper <ExecutionPayloadV1?> response = await rpc.engine_getPayloadV1(Bytes.FromHexString(payloadId)); ExecutionPayloadV1 executionPayloadV1 = response.Data !; executionPayloadV1.GasLimit.Should().Be(4_000_000L); }
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 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); }