public async Task should_return_invalid_lvh_null_on_invalid_blocks_during_the_sync() { using MergeTestBlockchain chain = await CreateBlockChain(); IEngineRpcModule rpc = CreateEngineModule(chain); Keccak? startingHead = chain.BlockTree.HeadHash; BlockHeader parent = Build.A.BlockHeader .WithNumber(1) .WithHash(TestItem.KeccakA) .WithNonce(0) .WithDifficulty(0) .TestObject; Block block = Build.A.Block .WithNumber(2) .WithParent(parent) .WithNonce(0) .WithDifficulty(0) .WithAuthor(Address.Zero) .WithPostMergeFlag(true) .TestObject; ExecutionPayloadV1 startingNewPayload = new(block); await rpc.engine_newPayloadV1(startingNewPayload); ForkchoiceStateV1 forkchoiceStateV1 = new(block.Hash !, startingHead, startingHead); ResultWrapper <ForkchoiceUpdatedV1Result> forkchoiceUpdatedResult = await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); ExecutionPayloadV1[] requests = CreateBlockRequestBranch(startingNewPayload, TestItem.AddressD, 1); foreach (ExecutionPayloadV1 r in requests) { ResultWrapper <PayloadStatusV1> payloadStatus = await rpc.engine_newPayloadV1(r); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Syncing).ToUpper()); } ExecutionPayloadV1[] invalidRequests = CreateBlockRequestBranch(requests[0], TestItem.AddressD, 1); foreach (ExecutionPayloadV1 r in invalidRequests) { r.TryGetBlock(out Block? newBlock); newBlock !.Header.GasLimit = long.MaxValue; // incorrect gas limit newBlock.Header.Hash = newBlock.CalculateHash(); ResultWrapper <PayloadStatusV1> payloadStatus = await rpc.engine_newPayloadV1(new ExecutionPayloadV1(newBlock)); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Invalid).ToUpper()); payloadStatus.Data.LatestValidHash.Should().BeNull(); } }
public async Task newPayloadV1_can_insert_blocks_from_cache_when_syncing() { using MergeTestBlockchain chain = await CreateBlockChain(); IEngineRpcModule rpc = CreateEngineModule(chain); Keccak startingHead = chain.BlockTree.HeadHash; ExecutionPayloadV1 parentBlockRequest = new(Build.A.Block.WithNumber(2).TestObject); ExecutionPayloadV1[] requests = CreateBlockRequestBranch(parentBlockRequest, Address.Zero, 7); ResultWrapper <PayloadStatusV1> payloadStatus; foreach (ExecutionPayloadV1 r in requests) { payloadStatus = await rpc.engine_newPayloadV1(r); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Syncing).ToUpper()); chain.BeaconSync.IsBeaconSyncHeadersFinished().Should().BeTrue(); chain.BeaconSync.ShouldBeInBeaconHeaders().Should().BeFalse(); chain.BeaconPivot.BeaconPivotExists().Should().BeFalse(); } int pivotNum = 3; requests[pivotNum].TryGetBlock(out Block? pivotBlock); // initiate sync ForkchoiceStateV1 forkchoiceStateV1 = new(pivotBlock !.Hash, startingHead, startingHead); ResultWrapper <ForkchoiceUpdatedV1Result> forkchoiceUpdatedResult = await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); // trigger insertion of blocks in cache into block tree payloadStatus = await rpc.engine_newPayloadV1(requests[^ 1]);
public async Task forkChoiceUpdatedV1_unknown_block_initiates_syncing() { using MergeTestBlockchain chain = await CreateBlockChain(); IEngineRpcModule rpc = CreateEngineModule(chain); Keccak? startingHead = chain.BlockTree.HeadHash; BlockHeader parent = Build.A.BlockHeader .WithNumber(1) .WithHash(TestItem.KeccakA) .WithNonce(0) .WithDifficulty(0) .TestObject; Block block = Build.A.Block .WithNumber(2) .WithParent(parent) .WithNonce(0) .WithDifficulty(0) .WithAuthor(Address.Zero) .WithPostMergeFlag(true) .TestObject; await rpc.engine_newPayloadV1(new ExecutionPayloadV1(block)); // sync has not started yet chain.BeaconSync.IsBeaconSyncHeadersFinished().Should().BeTrue(); chain.BeaconSync.IsBeaconSyncFinished(block.Header).Should().BeTrue(); chain.BeaconSync.ShouldBeInBeaconHeaders().Should().BeFalse(); chain.BeaconPivot.BeaconPivotExists().Should().BeFalse(); BlockTreePointers pointers = new() { BestKnownNumber = 0, BestSuggestedHeader = chain.BlockTree.Genesis !, BestSuggestedBody = chain.BlockTree.FindBlock(0) !, BestKnownBeaconBlock = 0, LowestInsertedHeader = null, LowestInsertedBeaconHeader = null }; AssertBlockTreePointers(chain.BlockTree, pointers); ForkchoiceStateV1 forkchoiceStateV1 = new(block.Hash !, startingHead, startingHead); ResultWrapper <ForkchoiceUpdatedV1Result> forkchoiceUpdatedResult = await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); chain.BeaconSync.ShouldBeInBeaconHeaders().Should().BeTrue(); chain.BeaconSync.IsBeaconSyncHeadersFinished().Should().BeFalse(); chain.BeaconSync.IsBeaconSyncFinished(chain.BlockTree.FindBlock(block.Hash)?.Header).Should().BeFalse(); AssertBeaconPivotValues(chain.BeaconPivot, block.Header); pointers.LowestInsertedBeaconHeader = block.Header; pointers.BestKnownBeaconBlock = block.Number; pointers.LowestInsertedHeader = block.Header; AssertBlockTreePointers(chain.BlockTree, pointers); AssertExecutionStatusNotChangedV1(rpc, block.Hash !, startingHead, startingHead); }