### Question:
BeaconBlocksByRangeMessageHandler extends PeerRequiredLocalMessageHandler<BeaconBlocksByRangeRequestMessage, SignedBeaconBlock> { @Override public void onIncomingMessage( final Eth2Peer peer, final BeaconBlocksByRangeRequestMessage message, final ResponseCallback<SignedBeaconBlock> callback) { LOG.trace( "Peer {} requested {} BeaconBlocks starting at slot {} with step {}", peer.getId(), message.getCount(), message.getStartSlot(), message.getStep()); if (message.getStep().compareTo(ONE) < 0) { callback.completeWithErrorResponse( new RpcException(INVALID_REQUEST_CODE, "Step must be greater than zero")); return; } if (message.getCount().compareTo(UInt64.valueOf(MAX_REQUEST_BLOCKS)) > 0) { callback.completeWithErrorResponse( new RpcException( INVALID_REQUEST_CODE, "Only a maximum of " + MAX_REQUEST_BLOCKS + " blocks can be requested per request")); return; } if (!peer.wantToMakeRequest() || !peer.wantToReceiveObjects( callback, maxRequestSize.min(message.getCount()).longValue())) { return; } sendMatchingBlocks(message, callback) .finish( callback::completeSuccessfully, error -> { final Throwable rootCause = Throwables.getRootCause(error); if (rootCause instanceof RpcException) { LOG.trace("Rejecting beacon blocks by range request", error); callback.completeWithErrorResponse((RpcException) rootCause); } else { if (rootCause instanceof StreamClosedException || rootCause instanceof ClosedChannelException) { LOG.trace("Stream closed while sending requested blocks", error); } else { LOG.error("Failed to process blocks by range request", error); } callback.completeWithUnexpectedError(error); } }); } BeaconBlocksByRangeMessageHandler(
      final CombinedChainDataClient combinedChainDataClient, final UInt64 maxRequestSize); @Override void onIncomingMessage(
      final Eth2Peer peer,
      final BeaconBlocksByRangeRequestMessage message,
      final ResponseCallback<SignedBeaconBlock> callback);  }### Answer:
@Test public void shouldStopAtBestSlot() { final int startBlock = 15; final UInt64 count = UInt64.valueOf(MAX_REQUEST_BLOCKS); final int skip = 5; final SignedBeaconBlock headBlock = BLOCKS.get(5); withCanonicalHeadBlock(headBlock); withAncestorRoots(startBlock, MAX_REQUEST_SIZE.intValue(), skip, hotBlocks()); handler.onIncomingMessage( peer, new BeaconBlocksByRangeRequestMessage( UInt64.valueOf(startBlock), count, UInt64.valueOf(skip)), listener); verifyNoBlocksReturned(); verify(combinedChainDataClient, never()).getBlockAtSlotExact(any(), any()); }
@Test public void shouldRejectRequestWhenStepIsZero() { final int startBlock = 15; final UInt64 count = UInt64.valueOf(MAX_REQUEST_BLOCKS); final int skip = 0; final SignedBeaconBlock headBlock = BLOCKS.get(5); withCanonicalHeadBlock(headBlock); handler.onIncomingMessage( peer, new BeaconBlocksByRangeRequestMessage( UInt64.valueOf(startBlock), count, UInt64.valueOf(skip)), listener); verify(listener) .completeWithErrorResponse( new RpcException(INVALID_REQUEST_CODE, "Step must be greater than zero")); verifyNoMoreInteractions(listener); verifyNoMoreInteractions(combinedChainDataClient); }
@Test void shouldLimitNumberOfBlocksReturned() { final int startBlock = 1; final UInt64 count = MAX_REQUEST_SIZE.plus(ONE); final int skip = 1; final SignedBeaconBlock headBlock = BLOCKS.get(10); withCanonicalHeadBlock(headBlock); withAncestorRoots( startBlock, MAX_REQUEST_SIZE.intValue(), skip, hotBlocks(1, 2, 3, 6, 7, 8, 9)); handler.onIncomingMessage( peer, new BeaconBlocksByRangeRequestMessage( UInt64.valueOf(startBlock), count, UInt64.valueOf(skip)), listener); verifyBlocksReturned(1, 2, 3, 6, 7, 8); }