use of org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage in project besu by hyperledger.
the class BlockBroadcaster method propagate.
public void propagate(final Block block, final Difficulty totalDifficulty) {
blockPropagatedSubscribers.forEach(listener -> listener.accept(block, totalDifficulty));
final NewBlockMessage newBlockMessage = NewBlockMessage.create(block, totalDifficulty);
ethContext.getEthPeers().streamAvailablePeers().filter(ethPeer -> !ethPeer.hasSeenBlock(block.getHash())).forEach(ethPeer -> {
ethPeer.registerKnownBlock(block.getHash());
try {
ethPeer.send(newBlockMessage);
} catch (final PeerConnection.PeerNotConnected e) {
LOG.trace("Failed to broadcast new block to peer", e);
}
});
}
use of org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage in project besu by hyperledger.
the class EthProtocolManagerTest method newBlockMinedSendsNewBlockMessageToAllPeers.
@Test
public void newBlockMinedSendsNewBlockMessageToAllPeers() {
try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig())) {
// Define handler to validate response
final PeerSendHandler onSend = mock(PeerSendHandler.class);
final List<PeerConnection> peers = Lists.newArrayList();
final int PEER_COUNT = 5;
for (int i = 0; i < PEER_COUNT; i++) {
peers.add(setupPeer(ethManager, onSend));
}
final Hash chainHeadHash = blockchain.getChainHeadHash();
final Block minedBlock = new Block(blockchain.getBlockHeader(chainHeadHash).get(), blockchain.getBlockBody(chainHeadHash).get());
final Difficulty expectedTotalDifficulty = blockchain.getChainHead().getTotalDifficulty();
reset(onSend);
ethManager.blockMined(minedBlock);
final ArgumentCaptor<NewBlockMessage> messageSentCaptor = ArgumentCaptor.forClass(NewBlockMessage.class);
final ArgumentCaptor<PeerConnection> receivingPeerCaptor = ArgumentCaptor.forClass(PeerConnection.class);
final ArgumentCaptor<Capability> capabilityCaptor = ArgumentCaptor.forClass(Capability.class);
verify(onSend, times(PEER_COUNT)).exec(capabilityCaptor.capture(), messageSentCaptor.capture(), receivingPeerCaptor.capture());
// assert that all entries in capability param were Eth63
assertThat(capabilityCaptor.getAllValues().stream().distinct().collect(Collectors.toList())).isEqualTo(Collections.singletonList(EthProtocol.ETH63));
// assert that all messages transmitted contain the expected block & total difficulty.
final ProtocolSchedule protocolSchdeule = ProtocolScheduleFixture.MAINNET;
for (final NewBlockMessage msg : messageSentCaptor.getAllValues()) {
assertThat(msg.block(protocolSchdeule)).isEqualTo(minedBlock);
assertThat(msg.totalDifficulty(protocolSchdeule)).isEqualTo(expectedTotalDifficulty);
}
assertThat(receivingPeerCaptor.getAllValues()).containsAll(peers);
}
}
use of org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage in project besu by hyperledger.
the class AbstractBlockPropagationManagerTest method verifyBroadcastBlockInvocation.
@Test
public void verifyBroadcastBlockInvocation() {
blockchainUtil.importFirstBlocks(2);
final Block block = blockchainUtil.getBlock(2);
blockPropagationManager.start();
// Setup peer and messages
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
final Difficulty totalDifficulty = getFullBlockchain().getTotalDifficultyByHash(block.getHash()).get();
final NewBlockMessage newBlockMessage = NewBlockMessage.create(block, totalDifficulty);
// Broadcast message
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlockMessage);
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
peer.respondWhile(responder, peer::hasOutstandingRequests);
verify(blockBroadcaster, times(1)).propagate(block, totalDifficulty);
}
use of org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage in project besu by hyperledger.
the class AbstractBlockPropagationManagerTest method purgesOldBlocks.
@Test
public void purgesOldBlocks() {
final int oldBlocksToImport = 3;
syncConfig = SynchronizerConfiguration.builder().blockPropagationRange(-oldBlocksToImport, 5).build();
final BlockPropagationManager blockPropagationManager = new BlockPropagationManager(syncConfig, protocolSchedule, protocolContext, ethProtocolManager.ethContext(), syncState, pendingBlocksManager, metricsSystem, blockBroadcaster);
final BlockDataGenerator gen = new BlockDataGenerator();
// Import some blocks
blockchainUtil.importFirstBlocks(5);
// Set up test block next to head, that should eventually be purged
final Block blockToPurge = gen.block(BlockOptions.create().setBlockNumber(blockchain.getChainHeadBlockNumber()));
blockPropagationManager.start();
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
final NewBlockMessage blockAnnouncementMsg = NewBlockMessage.create(blockToPurge, Difficulty.ZERO);
// Broadcast
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, blockAnnouncementMsg);
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
peer.respondWhile(responder, peer::hasOutstandingRequests);
// Check that we pushed our block into the pending collection
assertThat(blockchain.contains(blockToPurge.getHash())).isFalse();
assertThat(pendingBlocksManager.contains(blockToPurge.getHash())).isTrue();
// Import blocks until we bury the target block far enough to be cleaned up
for (int i = 0; i < oldBlocksToImport; i++) {
blockchainUtil.importBlockAtIndex((int) blockchain.getChainHeadBlockNumber() + 1);
assertThat(blockchain.contains(blockToPurge.getHash())).isFalse();
assertThat(pendingBlocksManager.contains(blockToPurge.getHash())).isTrue();
}
// Import again to trigger cleanup
blockchainUtil.importBlockAtIndex((int) blockchain.getChainHeadBlockNumber() + 1);
assertThat(blockchain.contains(blockToPurge.getHash())).isFalse();
assertThat(pendingBlocksManager.contains(blockToPurge.getHash())).isFalse();
}
use of org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage in project besu by hyperledger.
the class AbstractBlockPropagationManagerTest method handlesDuplicateAnnouncements.
@Test
public void handlesDuplicateAnnouncements() {
final ProtocolSchedule stubProtocolSchedule = spy(protocolSchedule);
final ProtocolSpec stubProtocolSpec = spy(protocolSchedule.getByBlockNumber(2));
final BlockImporter stubBlockImporter = spy(stubProtocolSpec.getBlockImporter());
doReturn(stubProtocolSpec).when(stubProtocolSchedule).getByBlockNumber(anyLong());
doReturn(stubBlockImporter).when(stubProtocolSpec).getBlockImporter();
final BlockPropagationManager blockPropagationManager = new BlockPropagationManager(syncConfig, stubProtocolSchedule, protocolContext, ethProtocolManager.ethContext(), syncState, pendingBlocksManager, metricsSystem, blockBroadcaster);
blockchainUtil.importFirstBlocks(2);
final Block nextBlock = blockchainUtil.getBlock(2);
// Sanity check
assertThat(blockchain.contains(nextBlock.getHash())).isFalse();
blockPropagationManager.start();
// Setup peer and messages
final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0);
final NewBlockHashesMessage newBlockHash = NewBlockHashesMessage.create(Collections.singletonList(new NewBlockHashesMessage.NewBlockHash(nextBlock.getHash(), nextBlock.getHeader().getNumber())));
final NewBlockMessage newBlock = NewBlockMessage.create(nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get());
final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain());
// Broadcast first message
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock);
peer.respondWhile(responder, peer::hasOutstandingRequests);
// Broadcast duplicate
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlockHash);
peer.respondWhile(responder, peer::hasOutstandingRequests);
// Broadcast duplicate
EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock);
peer.respondWhile(responder, peer::hasOutstandingRequests);
assertThat(blockchain.contains(nextBlock.getHash())).isTrue();
verify(stubBlockImporter, times(1)).importBlock(eq(protocolContext), eq(nextBlock), any());
}
Aggregations