Search in sources :

Example 1 with StatusMessage

use of org.hyperledger.besu.ethereum.eth.messages.StatusMessage in project besu by hyperledger.

the class EthProtocolManager method handleStatusMessage.

private void handleStatusMessage(final EthPeer peer, final MessageData data) {
    final StatusMessage status = StatusMessage.readFrom(data);
    try {
        if (!status.networkId().equals(networkId)) {
            LOG.debug("{} has mismatched network id: {}", peer, status.networkId());
            peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
        } else if (!forkIdManager.peerCheck(status.forkId()) && status.protocolVersion() > 63) {
            LOG.debug("{} has matching network id ({}), but non-matching fork id: {}", peer, networkId, status.forkId());
            peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
        } else if (forkIdManager.peerCheck(status.genesisHash())) {
            LOG.debug("{} has matching network id ({}), but non-matching genesis hash: {}", peer, networkId, status.genesisHash());
            peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
        } else if (isFinalized()) {
            long lockStamp = this.powTerminalDifficultyLock.readLock();
            try {
                if (this.powTerminalDifficulty.isPresent() && status.totalDifficulty().greaterThan(this.powTerminalDifficulty.get())) {
                    LOG.debug("Disconnecting peer with difficulty {}, likely still on PoW chain", status.totalDifficulty());
                    peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
                }
            } finally {
                this.powTerminalDifficultyLock.unlockRead(lockStamp);
            }
        } else {
            LOG.debug("Received status message from {}: {}", peer, status);
            peer.registerStatusReceived(status.bestHash(), status.totalDifficulty(), status.protocolVersion());
        }
    } catch (final RLPException e) {
        LOG.debug("Unable to parse status message.", e);
        // Parsing errors can happen when clients broadcast network ids outside the int range,
        // So just disconnect with "subprotocol" error rather than "breach of protocol".
        peer.disconnect(DisconnectReason.SUBPROTOCOL_TRIGGERED);
    }
}
Also used : RLPException(org.hyperledger.besu.ethereum.rlp.RLPException) StatusMessage(org.hyperledger.besu.ethereum.eth.messages.StatusMessage)

Example 2 with StatusMessage

use of org.hyperledger.besu.ethereum.eth.messages.StatusMessage in project besu by hyperledger.

the class EthProtocolManagerTest method disconnectOnWrongGenesisHash.

@Test
public void disconnectOnWrongGenesisHash() {
    try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig())) {
        final MessageData messageData = BlockHeadersMessage.create(Collections.singletonList(blockchain.getBlockHeader(1).get()));
        final MockPeerConnection peer = setupPeerWithoutStatusExchange(ethManager, (cap, msg, conn) -> {
        });
        // Send status message with wrong chain
        final StatusMessage statusMessage = StatusMessage.create(EthProtocol.EthVersion.V63, BigInteger.ONE, blockchain.getChainHead().getTotalDifficulty(), gen.hash(), blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
        ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, statusMessage));
        ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, messageData));
        assertThat(peer.isDisconnected()).isTrue();
    }
}
Also used : DefaultMessage(org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage) MessageData(org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData) StatusMessage(org.hyperledger.besu.ethereum.eth.messages.StatusMessage) Test(org.junit.Test)

Example 3 with StatusMessage

use of org.hyperledger.besu.ethereum.eth.messages.StatusMessage in project besu by hyperledger.

the class EthProtocolManagerTest method disconnectPoWPeersAfterTransition.

@Test
public void disconnectPoWPeersAfterTransition() {
    try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig())) {
        final MockPeerConnection workPeer = setupPeer(ethManager, (cap, msg, conn) -> {
        });
        final MockPeerConnection stakePeer = setupPeer(ethManager, (cap, msg, conn) -> {
        });
        final StatusMessage workPeerStatus = StatusMessage.create(EthProtocol.EthVersion.V63, BigInteger.ONE, blockchain.getChainHead().getTotalDifficulty().add(20), blockchain.getChainHeadHash(), blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
        final StatusMessage stakePeerStatus = StatusMessage.create(EthProtocol.EthVersion.V63, BigInteger.ONE, blockchain.getChainHead().getTotalDifficulty(), blockchain.getChainHeadHash(), blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
        ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(workPeer, workPeerStatus));
        ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(stakePeer, stakePeerStatus));
        ethManager.onCrossingMergeBoundary(true, Optional.of(blockchain.getChainHead().getTotalDifficulty()));
        ethManager.onNewForkchoiceMessage(Hash.EMPTY, Optional.of(Hash.hash(Bytes.of(1))), Hash.EMPTY);
        ethManager.onNewForkchoiceMessage(Hash.EMPTY, Optional.of(Hash.hash(Bytes.of(2))), Hash.EMPTY);
        assertThat(workPeer.isDisconnected()).isTrue();
        assertThat(workPeer.getDisconnectReason()).isPresent();
        assertThat(workPeer.getDisconnectReason()).get().isEqualTo(DisconnectReason.SUBPROTOCOL_TRIGGERED);
        assertThat(stakePeer.isDisconnected()).isFalse();
    }
}
Also used : DefaultMessage(org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage) StatusMessage(org.hyperledger.besu.ethereum.eth.messages.StatusMessage) Test(org.junit.Test)

Example 4 with StatusMessage

use of org.hyperledger.besu.ethereum.eth.messages.StatusMessage in project besu by hyperledger.

the class EthProtocolManagerTest method shouldSuccessfullyRespondToGetHeadersRequestLessThanZero.

@Test
public void shouldSuccessfullyRespondToGetHeadersRequestLessThanZero() throws ExecutionException, InterruptedException {
    final Block genesisBlock = gen.genesisBlock();
    final MutableBlockchain blockchain = createInMemoryBlockchain(genesisBlock);
    final BlockDataGenerator.BlockOptions options = new BlockDataGenerator.BlockOptions().setBlockNumber(1L).setParentHash(blockchain.getBlockHashByNumber(0L).get());
    final Block block = gen.block(options);
    final List<TransactionReceipt> receipts = gen.receipts(block);
    blockchain.appendBlock(block, receipts);
    final CompletableFuture<Void> done = new CompletableFuture<>();
    try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create(blockchain, () -> false, protocolContext.getWorldStateArchive(), transactionPool, EthProtocolConfiguration.defaultConfig())) {
        final long startBlock = 1L;
        final int requestedBlockCount = 13;
        final int receivedBlockCount = 2;
        final MessageData messageData = GetBlockHeadersMessage.create(startBlock, requestedBlockCount, 0, true);
        final MockPeerConnection.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(receivedBlockCount);
            for (int i = 0; i < receivedBlockCount; i++) {
                assertThat(headers.get(i).getNumber()).isEqualTo(receivedBlockCount - 1 - i);
            }
            done.complete(null);
        };
        final Set<Capability> caps = new HashSet<>(Collections.singletonList(EthProtocol.ETH63));
        final MockPeerConnection peer = new MockPeerConnection(caps, onSend);
        ethManager.handleNewConnection(peer);
        final StatusMessage statusMessage = StatusMessage.create(EthProtocol.EthVersion.V63, BigInteger.ONE, blockchain.getChainHead().getTotalDifficulty(), blockchain.getChainHeadHash(), blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
        ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, statusMessage));
        ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, messageData));
        done.get();
    }
}
Also used : TransactionsMessage(org.hyperledger.besu.ethereum.eth.messages.TransactionsMessage) Arrays(java.util.Arrays) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) RawMessage(org.hyperledger.besu.ethereum.p2p.rlpx.wire.RawMessage) DefaultMessage(org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage) Mockito.verifyNoInteractions(org.mockito.Mockito.verifyNoInteractions) BlockDataGenerator(org.hyperledger.besu.ethereum.core.BlockDataGenerator) ReceiptsMessage(org.hyperledger.besu.ethereum.eth.messages.ReceiptsMessage) BlockchainSetupUtil(org.hyperledger.besu.ethereum.core.BlockchainSetupUtil) DataStorageFormat(org.hyperledger.besu.ethereum.worldstate.DataStorageFormat) TransactionReceipt(org.hyperledger.besu.ethereum.core.TransactionReceipt) BigInteger(java.math.BigInteger) Block(org.hyperledger.besu.ethereum.core.Block) GetNodeDataMessage(org.hyperledger.besu.ethereum.eth.messages.GetNodeDataMessage) ConditionFactory(org.awaitility.core.ConditionFactory) Difficulty(org.hyperledger.besu.ethereum.core.Difficulty) EthProtocolConfiguration(org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration) Blockchain(org.hyperledger.besu.ethereum.chain.Blockchain) Set(java.util.Set) MiningParameters(org.hyperledger.besu.ethereum.core.MiningParameters) Collectors(java.util.stream.Collectors) BlockBodiesMessage(org.hyperledger.besu.ethereum.eth.messages.BlockBodiesMessage) BlockHeadersMessage(org.hyperledger.besu.ethereum.eth.messages.BlockHeadersMessage) ConditionTimeoutException(org.awaitility.core.ConditionTimeoutException) List(java.util.List) TransactionPoolConfiguration(org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration) ProtocolScheduleFixture(org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture) Optional(java.util.Optional) Capability(org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability) MetricsSystem(org.hyperledger.besu.plugin.services.MetricsSystem) MutableBlockchain(org.hyperledger.besu.ethereum.chain.MutableBlockchain) TransactionPoolFactory(org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory) Awaitility(org.awaitility.Awaitility) Mockito.mock(org.mockito.Mockito.mock) Hash(org.hyperledger.besu.datatypes.Hash) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) StatusMessage(org.hyperledger.besu.ethereum.eth.messages.StatusMessage) EthPV62(org.hyperledger.besu.ethereum.eth.messages.EthPV62) PeerSendHandler(org.hyperledger.besu.ethereum.eth.manager.MockPeerConnection.PeerSendHandler) SyncState(org.hyperledger.besu.ethereum.eth.sync.state.SyncState) BeforeClass(org.junit.BeforeClass) CompletableFuture(java.util.concurrent.CompletableFuture) NoOpMetricsSystem(org.hyperledger.besu.metrics.noop.NoOpMetricsSystem) Bytes(org.apache.tuweni.bytes.Bytes) EthProtocol(org.hyperledger.besu.ethereum.eth.EthProtocol) ArrayList(java.util.ArrayList) NodeDataMessage(org.hyperledger.besu.ethereum.eth.messages.NodeDataMessage) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) HashSet(java.util.HashSet) InMemoryKeyValueStorageProvider.createInMemoryBlockchain(org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain) GetBlockHeadersMessage(org.hyperledger.besu.ethereum.eth.messages.GetBlockHeadersMessage) Lists(com.google.common.collect.Lists) ArgumentCaptor(org.mockito.ArgumentCaptor) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) PeerConnection(org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection) WorldStateArchive(org.hyperledger.besu.ethereum.worldstate.WorldStateArchive) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Wei(org.hyperledger.besu.datatypes.Wei) DisconnectReason(org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason) ExecutorService(java.util.concurrent.ExecutorService) GetReceiptsMessage(org.hyperledger.besu.ethereum.eth.messages.GetReceiptsMessage) TransactionPool(org.hyperledger.besu.ethereum.eth.transactions.TransactionPool) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) NewBlockMessage(org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) MessageData(org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData) GetBlockBodiesMessage(org.hyperledger.besu.ethereum.eth.messages.GetBlockBodiesMessage) ProtocolContext(org.hyperledger.besu.ethereum.ProtocolContext) BlockBody(org.hyperledger.besu.ethereum.core.BlockBody) EthPV63(org.hyperledger.besu.ethereum.eth.messages.EthPV63) Mockito.reset(org.mockito.Mockito.reset) Transaction(org.hyperledger.besu.ethereum.core.Transaction) Collections(java.util.Collections) TestClock(org.hyperledger.besu.testutil.TestClock) DefaultMessage(org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage) Capability(org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability) MessageData(org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData) PeerSendHandler(org.hyperledger.besu.ethereum.eth.manager.MockPeerConnection.PeerSendHandler) TransactionReceipt(org.hyperledger.besu.ethereum.core.TransactionReceipt) BlockDataGenerator(org.hyperledger.besu.ethereum.core.BlockDataGenerator) StatusMessage(org.hyperledger.besu.ethereum.eth.messages.StatusMessage) CompletableFuture(java.util.concurrent.CompletableFuture) Block(org.hyperledger.besu.ethereum.core.Block) MutableBlockchain(org.hyperledger.besu.ethereum.chain.MutableBlockchain) List(java.util.List) ArrayList(java.util.ArrayList) BlockHeadersMessage(org.hyperledger.besu.ethereum.eth.messages.BlockHeadersMessage) GetBlockHeadersMessage(org.hyperledger.besu.ethereum.eth.messages.GetBlockHeadersMessage) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 5 with StatusMessage

use of org.hyperledger.besu.ethereum.eth.messages.StatusMessage in project besu by hyperledger.

the class EthProtocolManagerTest method setupPeer.

private MockPeerConnection setupPeer(final EthProtocolManager ethManager, final PeerSendHandler onSend) {
    final MockPeerConnection peer = setupPeerWithoutStatusExchange(ethManager, onSend);
    final StatusMessage statusMessage = StatusMessage.create(EthProtocol.EthVersion.V63, BigInteger.ONE, blockchain.getChainHead().getTotalDifficulty(), blockchain.getChainHeadHash(), blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash());
    ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, statusMessage));
    return peer;
}
Also used : DefaultMessage(org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage) StatusMessage(org.hyperledger.besu.ethereum.eth.messages.StatusMessage)

Aggregations

StatusMessage (org.hyperledger.besu.ethereum.eth.messages.StatusMessage)9 DefaultMessage (org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage)7 Test (org.junit.Test)5 MessageData (org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData)3 Lists (com.google.common.collect.Lists)1 BigInteger (java.math.BigInteger)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Optional (java.util.Optional)1 Set (java.util.Set)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ExecutionException (java.util.concurrent.ExecutionException)1 ExecutorService (java.util.concurrent.ExecutorService)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1 TimeUnit (java.util.concurrent.TimeUnit)1 Collectors (java.util.stream.Collectors)1 Bytes (org.apache.tuweni.bytes.Bytes)1