use of org.hyperledger.besu.ethereum.eth.messages.BlockBodiesMessage in project besu by hyperledger.
the class EthProtocolManagerTest method respondToGetBodiesPartial.
@Test
public void respondToGetBodiesPartial() throws ExecutionException, InterruptedException {
final CompletableFuture<Void> done = new CompletableFuture<>();
try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig())) {
// Setup blocks query
final long expectedBlockNumber = blockchain.getChainHeadBlockNumber() - 1;
final BlockHeader header = blockchain.getBlockHeader(expectedBlockNumber).get();
final BlockBody body = blockchain.getBlockBody(header.getHash()).get();
final Block expectedBlock = new Block(header, body);
final List<Hash> hashes = Arrays.asList(gen.hash(), expectedBlock.getHash(), gen.hash());
final MessageData messageData = GetBlockBodiesMessage.create(hashes);
// Define handler to validate response
final PeerSendHandler onSend = (cap, message, conn) -> {
if (message.getCode() == EthPV62.STATUS) {
// Ignore status message
return;
}
assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_BODIES);
final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message);
final List<BlockBody> bodies = Lists.newArrayList(blocksMessage.bodies(protocolSchedule));
assertThat(bodies).hasSize(1);
assertThat(expectedBlock.getBody()).isEqualTo(bodies.get(0));
done.complete(null);
};
// Run test
final PeerConnection peer = setupPeer(ethManager, onSend);
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, messageData));
done.get();
}
}
use of org.hyperledger.besu.ethereum.eth.messages.BlockBodiesMessage in project besu by hyperledger.
the class EthProtocolManagerTest method respondToGetBodies.
@Test
public void respondToGetBodies() throws ExecutionException, InterruptedException {
final CompletableFuture<Void> done = new CompletableFuture<>();
try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig())) {
// Setup blocks query
final long startBlock = blockchain.getChainHeadBlockNumber() - 5;
final int blockCount = 2;
final Block[] expectedBlocks = new Block[blockCount];
for (int i = 0; i < blockCount; i++) {
final BlockHeader header = blockchain.getBlockHeader(startBlock + i).get();
final BlockBody body = blockchain.getBlockBody(header.getHash()).get();
expectedBlocks[i] = new Block(header, body);
}
final List<Hash> hashes = Arrays.stream(expectedBlocks).map(Block::getHash).collect(Collectors.toList());
final MessageData messageData = GetBlockBodiesMessage.create(hashes);
// Define handler to validate response
final PeerSendHandler onSend = (cap, message, conn) -> {
if (message.getCode() == EthPV62.STATUS) {
// Ignore status message
return;
}
assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_BODIES);
final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message);
final List<BlockBody> bodies = Lists.newArrayList(blocksMessage.bodies(protocolSchedule));
assertThat(bodies).hasSize(blockCount);
for (int i = 0; i < blockCount; i++) {
assertThat(expectedBlocks[i].getBody()).isEqualTo(bodies.get(i));
}
done.complete(null);
};
// Run test
final PeerConnection peer = setupPeer(ethManager, onSend);
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, messageData));
done.get();
}
}
use of org.hyperledger.besu.ethereum.eth.messages.BlockBodiesMessage in project besu by hyperledger.
the class GetBodiesFromPeerTask method processResponse.
@Override
protected Optional<List<Block>> processResponse(final boolean streamClosed, final MessageData message, final EthPeer peer) {
if (streamClosed) {
// All outstanding requests have been responded to and we still haven't found the response
// we wanted. It must have been empty or contain data that didn't match.
peer.recordUselessResponse("bodies");
return Optional.of(Collections.emptyList());
}
final BlockBodiesMessage bodiesMessage = BlockBodiesMessage.readFrom(message);
final List<BlockBody> bodies = bodiesMessage.bodies(protocolSchedule);
if (bodies.size() == 0) {
// Message contains no data - nothing to do
LOG.debug("Message contains no data. Peer: {}", peer);
return Optional.empty();
} else if (bodies.size() > headers.size()) {
// Message doesn't match our request - nothing to do
LOG.debug("Message doesn't match our request. Peer: {}", peer);
return Optional.empty();
}
final List<Block> blocks = new ArrayList<>();
for (final BlockBody body : bodies) {
final List<BlockHeader> headers = bodyToHeaders.get(new BodyIdentifier(body));
if (headers == null) {
// This message contains unrelated bodies - exit
LOG.debug("This message contains unrelated bodies. Peer: {}", peer);
return Optional.empty();
}
headers.forEach(h -> blocks.add(new Block(h, body)));
// Clear processed headers
headers.clear();
}
return Optional.of(blocks);
}
use of org.hyperledger.besu.ethereum.eth.messages.BlockBodiesMessage in project besu by hyperledger.
the class EthProtocolManagerTest method respondToGetBodiesWithinLimits.
@Test
public void respondToGetBodiesWithinLimits() 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))) {
// Setup blocks query
final int blockCount = 10;
final long startBlock = blockchain.getChainHeadBlockNumber() - blockCount;
final Block[] expectedBlocks = new Block[blockCount];
for (int i = 0; i < blockCount; i++) {
final BlockHeader header = blockchain.getBlockHeader(startBlock + i).get();
final BlockBody body = blockchain.getBlockBody(header.getHash()).get();
expectedBlocks[i] = new Block(header, body);
}
final List<Hash> hashes = Arrays.stream(expectedBlocks).map(Block::getHash).collect(Collectors.toList());
final MessageData messageData = GetBlockBodiesMessage.create(hashes);
// Define handler to validate response
final PeerSendHandler onSend = (cap, message, conn) -> {
if (message.getCode() == EthPV62.STATUS) {
// Ignore status message
return;
}
assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_BODIES);
final BlockBodiesMessage blocksMessage = BlockBodiesMessage.readFrom(message);
final List<BlockBody> bodies = Lists.newArrayList(blocksMessage.bodies(protocolSchedule));
assertThat(bodies).hasSize(limit);
for (int i = 0; i < limit; i++) {
assertThat(expectedBlocks[i].getBody()).isEqualTo(bodies.get(i));
}
done.complete(null);
};
// Run test
final PeerConnection peer = setupPeer(ethManager, onSend);
ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, messageData));
done.get();
}
}
Aggregations