Search in sources :

Example 1 with NewBlockMessage

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);
        }
    });
}
Also used : Difficulty(org.hyperledger.besu.ethereum.core.Difficulty) Logger(org.slf4j.Logger) PeerConnection(org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection) NewBlockMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage) LoggerFactory(org.slf4j.LoggerFactory) EthContext(org.hyperledger.besu.ethereum.eth.manager.EthContext) Block(org.hyperledger.besu.ethereum.core.Block) Subscribers(org.hyperledger.besu.util.Subscribers) NewBlockMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage) PeerConnection(org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection)

Example 2 with NewBlockMessage

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);
    }
}
Also used : NewBlockMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage) PeerConnection(org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection) Capability(org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability) Difficulty(org.hyperledger.besu.ethereum.core.Difficulty) Hash(org.hyperledger.besu.datatypes.Hash) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) Block(org.hyperledger.besu.ethereum.core.Block) PeerSendHandler(org.hyperledger.besu.ethereum.eth.manager.MockPeerConnection.PeerSendHandler) Test(org.junit.Test)

Example 3 with NewBlockMessage

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);
}
Also used : NewBlockMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage) Difficulty(org.hyperledger.besu.ethereum.core.Difficulty) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Block(org.hyperledger.besu.ethereum.core.Block) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Example 4 with NewBlockMessage

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();
}
Also used : NewBlockMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Block(org.hyperledger.besu.ethereum.core.Block) BlockDataGenerator(org.hyperledger.besu.ethereum.core.BlockDataGenerator) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Example 5 with NewBlockMessage

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());
}
Also used : NewBlockMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage) ProtocolSpec(org.hyperledger.besu.ethereum.mainnet.ProtocolSpec) RespondingEthPeer(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer) Block(org.hyperledger.besu.ethereum.core.Block) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) BlockImporter(org.hyperledger.besu.ethereum.core.BlockImporter) NewBlockHashesMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockHashesMessage) Responder(org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder) Test(org.junit.Test)

Aggregations

Block (org.hyperledger.besu.ethereum.core.Block)16 NewBlockMessage (org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage)16 Test (org.junit.Test)14 RespondingEthPeer (org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer)11 Responder (org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer.Responder)11 Difficulty (org.hyperledger.besu.ethereum.core.Difficulty)5 EthContext (org.hyperledger.besu.ethereum.eth.manager.EthContext)3 NewBlockHashesMessage (org.hyperledger.besu.ethereum.eth.messages.NewBlockHashesMessage)3 ProtocolSchedule (org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule)3 BlockDataGenerator (org.hyperledger.besu.ethereum.core.BlockDataGenerator)2 BlockImporter (org.hyperledger.besu.ethereum.core.BlockImporter)2 EthPeer (org.hyperledger.besu.ethereum.eth.manager.EthPeer)2 EthPeers (org.hyperledger.besu.ethereum.eth.manager.EthPeers)2 ProtocolSpec (org.hyperledger.besu.ethereum.mainnet.ProtocolSpec)2 PeerConnection (org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection)2 Bytes (org.apache.tuweni.bytes.Bytes)1 Hash (org.hyperledger.besu.datatypes.Hash)1 Blockchain (org.hyperledger.besu.ethereum.chain.Blockchain)1 PeerSendHandler (org.hyperledger.besu.ethereum.eth.manager.MockPeerConnection.PeerSendHandler)1 Capability (org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability)1