Search in sources :

Example 1 with PeerDisconnectedException

use of tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException in project teku by ConsenSys.

the class RpcResponseCallback method completeWithUnexpectedError.

@Override
public void completeWithUnexpectedError(final Throwable error) {
    if (error instanceof PeerDisconnectedException) {
        LOG.trace("Not sending RPC response as peer has already disconnected");
        // But close the stream just to be completely sure we don't leak any resources.
        rpcStream.closeAbruptly().reportExceptions();
    } else {
        completeWithErrorResponse(new ServerErrorException());
    }
}
Also used : ServerErrorException(tech.pegasys.teku.networking.eth2.rpc.core.RpcException.ServerErrorException) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException)

Example 2 with PeerDisconnectedException

use of tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException in project teku by ConsenSys.

the class SyncSourceBatchTest method requestMoreBlocks_shouldResetAndSelectNewPeerAfterDisconnection.

@Test
void requestMoreBlocks_shouldResetAndSelectNewPeerAfterDisconnection() {
    final Runnable callback = mock(Runnable.class);
    final Batch batch = createBatch(70, 50);
    batch.requestMoreBlocks(callback);
    // First request returns some data, so the batch isn't in initial state
    final StubSyncSource firstSyncSource = getSyncSource(batch);
    firstSyncSource.receiveBlocks(dataStructureUtil.randomSignedBeaconBlock(72));
    verify(callback).run();
    batch.markFirstBlockConfirmed();
    batch.markAsContested();
    // Second request should go to the same source
    batch.requestMoreBlocks(callback);
    firstSyncSource.assertRequestedBlocks(73, 47);
    assertThatBatch(batch).isNotEmpty();
    // But this requests fails
    firstSyncSource.failRequest(new PeerDisconnectedException());
    // The request is complete, so should call the callback
    verify(callback, times(2)).run();
    // And the batch should be back in initial state
    assertThatBatch(batch).isEmpty();
    assertThatBatch(batch).isNotContested();
    assertThatBatch(batch).hasUnconfirmedFirstBlock();
    // Third request selects a new peer to request data from
    batch.requestMoreBlocks(callback);
    assertThat(syncSources.get(batch)).hasSize(2);
    final StubSyncSource secondSyncSource = getSyncSource(batch);
    assertThat(secondSyncSource).isNotSameAs(firstSyncSource);
    secondSyncSource.assertRequestedBlocks(70, 50);
}
Also used : BatchAssert.assertThatBatch(tech.pegasys.teku.beacon.sync.forward.multipeer.batches.BatchAssert.assertThatBatch) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException) StubSyncSource(tech.pegasys.teku.networking.eth2.peers.StubSyncSource) Test(org.junit.jupiter.api.Test)

Example 3 with PeerDisconnectedException

use of tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException in project teku by ConsenSys.

the class RpcHandler method sendRequest.

public SafeFuture<RpcStreamController<TOutgoingHandler>> sendRequest(Connection connection, TRequest request, TRespHandler responseHandler) {
    final Bytes initialPayload;
    try {
        initialPayload = rpcMethod.encodeRequest(request);
    } catch (Exception e) {
        return SafeFuture.failedFuture(e);
    }
    Interruptor closeInterruptor = SafeFuture.createInterruptor(connection.closeFuture(), PeerDisconnectedException::new);
    Interruptor timeoutInterruptor = SafeFuture.createInterruptor(asyncRunner.getDelayedFuture(TIMEOUT), () -> new StreamTimeoutException("Timed out waiting to initialize stream for protocol(s): " + String.join(",", rpcMethod.getIds())));
    return SafeFuture.notInterrupted(closeInterruptor).thenApply(__ -> connection.muxerSession().createStream(this)).thenWaitFor(StreamPromise::getStream).orInterrupt(closeInterruptor, timeoutInterruptor).thenCompose(streamPromise -> {
        final SafeFuture<String> protocolIdFuture = SafeFuture.of(streamPromise.getStream().thenCompose(Stream::getProtocol));
        // waiting for controller, writing initial payload or interrupt
        return SafeFuture.of(streamPromise.getController()).<String, RpcStreamController<TOutgoingHandler>>thenCombine(protocolIdFuture, (controller, protocolId) -> {
            final TOutgoingHandler handler = rpcMethod.createOutgoingRequestHandler(protocolId, request, responseHandler);
            controller.setOutgoingRequestHandler(handler);
            return controller;
        }).orInterrupt(closeInterruptor, timeoutInterruptor).thenWaitFor(controller -> controller.getRpcStream().writeBytes(initialPayload)).orInterrupt(closeInterruptor, timeoutInterruptor).whenException(err -> closeStreamAbruptly(streamPromise.getStream().join()));
    }).catchAndRethrow(err -> {
        if (ExceptionUtil.getCause(err, ConnectionClosedException.class).isPresent()) {
            throw new PeerDisconnectedException(err);
        }
    });
}
Also used : SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) Bytes(org.apache.tuweni.bytes.Bytes) Interruptor(tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor) RemoteWriteClosed(io.libp2p.etc.util.netty.mux.RemoteWriteClosed) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) LibP2PNodeId(tech.pegasys.teku.networking.p2p.libp2p.LibP2PNodeId) ByteBuf(io.netty.buffer.ByteBuf) RpcResponseHandler(tech.pegasys.teku.networking.p2p.rpc.RpcResponseHandler) Controller(tech.pegasys.teku.networking.p2p.libp2p.rpc.RpcHandler.Controller) P2PChannel(io.libp2p.core.P2PChannel) Duration(java.time.Duration) StreamPromise(io.libp2p.core.StreamPromise) ProtocolBinding(io.libp2p.core.multistream.ProtocolBinding) ProtocolDescriptor(io.libp2p.core.multistream.ProtocolDescriptor) RpcStream(tech.pegasys.teku.networking.p2p.rpc.RpcStream) AsyncRunner(tech.pegasys.teku.infrastructure.async.AsyncRunner) Connection(io.libp2p.core.Connection) Stream(io.libp2p.core.Stream) Throwables(com.google.common.base.Throwables) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException) RpcRequestHandler(tech.pegasys.teku.networking.p2p.rpc.RpcRequestHandler) FutureUtil.ignoreFuture(tech.pegasys.teku.infrastructure.async.FutureUtil.ignoreFuture) Consumer(java.util.function.Consumer) RpcMethod(tech.pegasys.teku.networking.p2p.rpc.RpcMethod) StreamClosedException(tech.pegasys.teku.networking.p2p.rpc.StreamClosedException) ExceptionUtil(tech.pegasys.teku.infrastructure.exceptions.ExceptionUtil) StreamTimeoutException(tech.pegasys.teku.networking.p2p.rpc.StreamTimeoutException) Logger(org.apache.logging.log4j.Logger) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) NotNull(org.jetbrains.annotations.NotNull) LogManager(org.apache.logging.log4j.LogManager) NodeId(tech.pegasys.teku.networking.p2p.peer.NodeId) ConnectionClosedException(io.libp2p.core.ConnectionClosedException) RpcStreamController(tech.pegasys.teku.networking.p2p.rpc.RpcStreamController) Bytes(org.apache.tuweni.bytes.Bytes) Interruptor(tech.pegasys.teku.infrastructure.async.SafeFuture.Interruptor) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) ConnectionClosedException(io.libp2p.core.ConnectionClosedException) RpcStream(tech.pegasys.teku.networking.p2p.rpc.RpcStream) Stream(io.libp2p.core.Stream) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException) PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException) StreamClosedException(tech.pegasys.teku.networking.p2p.rpc.StreamClosedException) StreamTimeoutException(tech.pegasys.teku.networking.p2p.rpc.StreamTimeoutException) ConnectionClosedException(io.libp2p.core.ConnectionClosedException) StreamTimeoutException(tech.pegasys.teku.networking.p2p.rpc.StreamTimeoutException)

Example 4 with PeerDisconnectedException

use of tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException in project teku by ConsenSys.

the class PeerRequiredLocalMessageHandler method onIncomingMessage.

@Override
public void onIncomingMessage(final String protocolId, final Optional<Eth2Peer> maybePeer, final I message, final ResponseCallback<O> callback) {
    maybePeer.ifPresentOrElse(peer -> onIncomingMessage(protocolId, peer, message, callback), () -> {
        LOG.trace("Ignoring message of type {} because peer has disconnected", message.getClass());
        callback.completeWithUnexpectedError(new PeerDisconnectedException());
    });
}
Also used : PeerDisconnectedException(tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException)

Aggregations

PeerDisconnectedException (tech.pegasys.teku.networking.p2p.peer.PeerDisconnectedException)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Throwables (com.google.common.base.Throwables)1 Connection (io.libp2p.core.Connection)1 ConnectionClosedException (io.libp2p.core.ConnectionClosedException)1 P2PChannel (io.libp2p.core.P2PChannel)1 Stream (io.libp2p.core.Stream)1 StreamPromise (io.libp2p.core.StreamPromise)1 ProtocolBinding (io.libp2p.core.multistream.ProtocolBinding)1 ProtocolDescriptor (io.libp2p.core.multistream.ProtocolDescriptor)1 RemoteWriteClosed (io.libp2p.etc.util.netty.mux.RemoteWriteClosed)1 ByteBuf (io.netty.buffer.ByteBuf)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 SimpleChannelInboundHandler (io.netty.channel.SimpleChannelInboundHandler)1 Duration (java.time.Duration)1 Optional (java.util.Optional)1 Consumer (java.util.function.Consumer)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 Bytes (org.apache.tuweni.bytes.Bytes)1