use of org.hyperledger.besu.ethereum.eth.messages.EthPV62 in project besu by hyperledger.
the class Istanbul99ProtocolManagerTest method respondToEth65GetHeadersUsingIstanbul99.
@Test
public void respondToEth65GetHeadersUsingIstanbul99() throws ExecutionException, InterruptedException, TimeoutException {
final CompletableFuture<Void> done = new CompletableFuture<>();
final EthScheduler ethScheduler = new DeterministicEthScheduler(() -> false);
EthPeers peers = new EthPeers(Istanbul99Protocol.NAME, TestClock.fixed(), new NoOpMetricsSystem(), 25);
EthMessages messages = new EthMessages();
final BigInteger networkId = BigInteger.ONE;
try (final EthProtocolManager ethManager = new Istanbul99ProtocolManager(blockchain, networkId, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig(), peers, messages, new EthContext(peers, messages, ethScheduler), Collections.emptyList(), false, ethScheduler)) {
final long startBlock = blockchain.getChainHeadBlockNumber() + 1;
final int blockCount = 5;
final MessageData messageData = GetBlockHeadersMessage.create(startBlock, blockCount, 0, false);
final PeerSendHandler onSend = (cap, message, conn) -> {
if (message.getCode() == EthPV62.STATUS) {
// Ignore status message
return;
}
assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_HEADERS);
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers.size()).isEqualTo(0);
done.complete(null);
};
final PeerConnection peer = setupPeer(ethManager, onSend);
ethManager.processMessage(Istanbul99Protocol.ISTANBUL99, new DefaultMessage(peer, messageData));
done.get(10, TimeUnit.SECONDS);
}
}
use of org.hyperledger.besu.ethereum.eth.messages.EthPV62 in project besu by hyperledger.
the class DownloadHeaderSequenceTaskTest method failsWhenPeerReturnsOnlySubsetOfHeaders.
@Test
public void failsWhenPeerReturnsOnlySubsetOfHeaders() {
final RespondingEthPeer respondingPeer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager);
// Execute task and wait for response
final BlockHeader referenceHeader = blockchain.getChainHeadHeader();
final EthTask<List<BlockHeader>> task = DownloadHeaderSequenceTask.endingAtHeader(protocolSchedule, protocolContext, ethContext, referenceHeader, 10, maxRetries, validationPolicy, metricsSystem);
final CompletableFuture<List<BlockHeader>> future = task.run();
// Filter response to include only reference header and previous header
final RespondingEthPeer.Responder fullResponder = RespondingEthPeer.blockchainResponder(blockchain);
final RespondingEthPeer.Responder responder = (cap, message) -> {
final Optional<MessageData> fullResponse = fullResponder.respond(cap, message);
if (!fullResponse.isPresent() || message.getCode() != EthPV62.GET_BLOCK_HEADERS) {
return fullResponse;
}
final BlockHeadersMessage headersMessage = BlockHeadersMessage.readFrom(fullResponse.get());
// Filter for a subset of headers
final List<BlockHeader> headerSubset = headersMessage.getHeaders(protocolSchedule).stream().filter(h -> h.getNumber() >= referenceHeader.getNumber() - 1L).collect(Collectors.toList());
return Optional.of(BlockHeadersMessage.create(headerSubset));
};
respondingPeer.respondTimes(responder, 100);
assertThat(future.isDone()).isTrue();
assertThat(future.isCompletedExceptionally()).isTrue();
assertThatThrownBy(future::get).hasCauseInstanceOf(MaxRetriesReachedException.class);
}
use of org.hyperledger.besu.ethereum.eth.messages.EthPV62 in project besu by hyperledger.
the class EthProtocolManager method processMessage.
@Override
public void processMessage(final Capability cap, final Message message) {
checkArgument(getSupportedCapabilities().contains(cap), "Unsupported capability passed to processMessage(): " + cap);
final MessageData messageData = message.getData();
final int code = messageData.getCode();
LOG.trace("Process message {}, {}", cap, code);
final EthPeer ethPeer = ethPeers.peer(message.getConnection());
if (ethPeer == null) {
LOG.debug("Ignoring message received from unknown peer connection: {}", message.getConnection());
return;
}
if (messageData.getSize() > 10 * 1_000_000) /*10MB*/
{
LOG.debug("Received message over 10MB. Disconnecting from {}", ethPeer);
ethPeer.disconnect(DisconnectReason.BREACH_OF_PROTOCOL);
return;
}
// Handle STATUS processing
if (code == EthPV62.STATUS) {
handleStatusMessage(ethPeer, messageData);
return;
} else if (!ethPeer.statusHasBeenReceived()) {
// Peers are required to send status messages before any other message type
LOG.debug("{} requires a Status ({}) message to be sent first. Instead, received message {}. Disconnecting from {}.", this.getClass().getSimpleName(), EthPV62.STATUS, code, ethPeer);
ethPeer.disconnect(DisconnectReason.BREACH_OF_PROTOCOL);
return;
}
final EthMessage ethMessage = new EthMessage(ethPeer, messageData);
if (!ethPeer.validateReceivedMessage(ethMessage, getSupportedProtocol())) {
LOG.debug("Unsolicited message received from, disconnecting: {}", ethPeer);
ethPeer.disconnect(DisconnectReason.BREACH_OF_PROTOCOL);
return;
}
if (isFinalized() && (code == EthPV62.NEW_BLOCK || code == EthPV62.NEW_BLOCK_HASHES)) {
LOG.debug("disconnecting peer for sending new blocks after transition to PoS");
ethPeer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
}
// This will handle responses
ethPeers.dispatchMessage(ethPeer, ethMessage, getSupportedProtocol());
// This will handle requests
Optional<MessageData> maybeResponseData = Optional.empty();
try {
if (EthProtocol.isEth66Compatible(cap) && EthProtocol.requestIdCompatible(code)) {
final Map.Entry<BigInteger, MessageData> requestIdAndEthMessage = ethMessage.getData().unwrapMessageData();
maybeResponseData = ethMessages.dispatch(new EthMessage(ethPeer, requestIdAndEthMessage.getValue())).map(responseData -> responseData.wrapMessageData(requestIdAndEthMessage.getKey()));
} else {
maybeResponseData = ethMessages.dispatch(ethMessage);
}
} catch (final RLPException e) {
LOG.debug("Received malformed message {} , disconnecting: {}", messageData.getData(), ethPeer, e);
ethPeer.disconnect(DisconnectMessage.DisconnectReason.BREACH_OF_PROTOCOL);
}
maybeResponseData.ifPresent(responseData -> {
try {
ethPeer.send(responseData, getSupportedProtocol());
} catch (final PeerNotConnected missingPeerException) {
// Peer disconnected before we could respond - nothing to do
}
});
}
use of org.hyperledger.besu.ethereum.eth.messages.EthPV62 in project besu by hyperledger.
the class EthProtocolManagerTest method respondToGetHeaders.
@Test
public void respondToGetHeaders() throws ExecutionException, InterruptedException {
final CompletableFuture<Void> done = new CompletableFuture<>();
try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig())) {
final long startBlock = 5L;
final int blockCount = 5;
final MessageData messageData = GetBlockHeadersMessage.create(startBlock, blockCount, 0, false);
final PeerSendHandler onSend = (cap, message, conn) -> {
if (message.getCode() == EthPV62.STATUS) {
// Ignore status message
return;
}
assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_HEADERS);
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(blockCount);
for (int i = 0; i < blockCount; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i);
}
done.complete(null);
};
final PeerConnection peer = setupPeer(ethManager, onSend);
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, messageData));
done.get();
}
}
use of org.hyperledger.besu.ethereum.eth.messages.EthPV62 in project besu by hyperledger.
the class EthProtocolManagerTest method respondToGetHeadersWithinLimits.
@Test
public void respondToGetHeadersWithinLimits() throws ExecutionException, InterruptedException {
final CompletableFuture<Void> done = new CompletableFuture<>();
final int limit = 5;
try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, new EthProtocolConfiguration(limit, limit, limit, limit, limit, false))) {
final long startBlock = 5L;
final int blockCount = 10;
final MessageData messageData = GetBlockHeadersMessage.create(startBlock, blockCount, 0, false);
final PeerSendHandler onSend = (cap, message, conn) -> {
if (message.getCode() == EthPV62.STATUS) {
// Ignore status message
return;
}
assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_HEADERS);
final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message);
final List<BlockHeader> headers = Lists.newArrayList(headersMsg.getHeaders(protocolSchedule));
assertThat(headers).hasSize(limit);
for (int i = 0; i < limit; i++) {
assertThat(headers.get(i).getNumber()).isEqualTo(startBlock + i);
}
done.complete(null);
};
final PeerConnection peer = setupPeer(ethManager, onSend);
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, messageData));
done.get();
}
}
Aggregations