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);
 }
コード例 #2
0
 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);
 }
コード例 #3
0
 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);
        }
コード例 #5
0
    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);
    }
コード例 #6
0
 public IBlockImprovementContext StartBlockImprovementContext(
     Block currentBestBlock,
     BlockHeader parentHeader,
     PayloadAttributes payloadAttributes) =>
 new BlockImprovementContext(currentBestBlock, _blockProductionTrigger, _timeout, parentHeader, payloadAttributes);
コード例 #7
0
    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);
    }
コード例 #8
0
 public Task <PayloadAttributes> GetPayloadAttributes(PayloadAttributes payloadAttributes, CancellationToken cancellationToken) =>
 _httpClient.PostJsonAsync <PayloadAttributes>(GetUri(_relayUrl, GetPayloadAttributesPath), payloadAttributes, cancellationToken);