Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,39 @@ public async Task NewPayloadV4_reject_payload_with_bad_authorization_list_rlp()
Assert.That(response.Data.Status, Is.EqualTo("INVALID"));
}

[Test]
public async Task NewPayloadV4_reject_payload_with_bad_execution_requests()
{
ExecutionRequestsProcessorMock executionRequestsProcessorMock = new();
using MergeTestBlockchain chain = await CreateBlockchain(Prague.Instance, null, null, null, executionRequestsProcessorMock);
IEngineRpcModule rpc = CreateEngineModule(chain);
Hash256 lastHash = (await ProduceBranchV4(rpc, chain, 10, CreateParentBlockRequestOnHead(chain.BlockTree), true, withRequests: true))
.LastOrDefault()?.BlockHash ?? Keccak.Zero;

Block TestBlock = Build.A.Block.WithNumber(chain.BlockTree.Head!.Number + 1).TestObject;
ExecutionPayloadV3 executionPayload = ExecutionPayloadV3.Create(TestBlock);

// must reject if execution requests types are not in ascending order
var response = await rpc.engine_newPayloadV4(
executionPayload,
[],
TestBlock.ParentBeaconBlockRoot,
executionRequests: [Bytes.FromHexString("0x0001"), Bytes.FromHexString("0x0101"), Bytes.FromHexString("0x0101")]
);

Assert.That(response.ErrorCode, Is.EqualTo(ErrorCodes.InvalidParams));

//must reject if one of the execution requests size is <= 1 byte
response = await rpc.engine_newPayloadV4(
executionPayload,
[],
TestBlock.ParentBeaconBlockRoot,
executionRequests: [Bytes.FromHexString("0x0001"), Bytes.FromHexString("0x01"), Bytes.FromHexString("0x0101")]
);

Assert.That(response.ErrorCode, Is.EqualTo(ErrorCodes.InvalidParams));
}

[TestCase(30)]
public async Task can_progress_chain_one_by_one_v4(int count)
{
Expand Down Expand Up @@ -247,7 +280,7 @@ private async Task<IReadOnlyList<ExecutionPayload>> ProduceBranchV4(IEngineRpcMo
ExecutionPayloadV3? getPayloadResult = await BuildAndGetPayloadOnBranchV4(rpc, chain, parentHeader,
parentBlock.Timestamp + 12,
random ?? TestItem.KeccakA, Address.Zero);
PayloadStatusV1 payloadStatusResponse = (await rpc.engine_newPayloadV4(getPayloadResult, [], Keccak.Zero, executionRequests: withRequests ? ExecutionRequestsProcessorMock.Requests : new byte[][] { [], [], [] })).Data;
PayloadStatusV1 payloadStatusResponse = (await rpc.engine_newPayloadV4(getPayloadResult, [], Keccak.Zero, executionRequests: withRequests ? ExecutionRequestsProcessorMock.Requests : new byte[][] { })).Data;
payloadStatusResponse.Status.Should().Be(PayloadStatus.Valid);
if (setHead)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,23 @@ public ValidationResult ValidateParams(IReleaseSpec spec, int version, out strin
if (ExecutionRequests.Length > ExecutionRequestExtensions.MaxRequestsCount)
{
error = $"Execution requests must have less than {ExecutionRequestExtensions.MaxRequestsCount} items";
return ValidationResult.Invalid;
return ValidationResult.Fail;
}

// verification of the requests
for (int i = 0; i < ExecutionRequests.Length; i++)
{
if (ExecutionRequests[i] == null || ExecutionRequests[i].Length <= 1)
{
error = "Execution request data must be longer than 1 byte";
return ValidationResult.Fail;
}

if (i > 0 && ExecutionRequests[i][0] <= ExecutionRequests[i - 1][0])
{
error = "Execution requests must not contain duplicates and be ordered by request_type in ascending order";
return ValidationResult.Fail;
}
}

}
Expand Down