Search in sources :

Example 1 with ResponseCallback

use of tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback in project teku by ConsenSys.

the class BeaconBlocksByRangeMessageHandler method onIncomingMessage.

@Override
public void onIncomingMessage(final String protocolId, final Eth2Peer peer, final BeaconBlocksByRangeRequestMessage message, final ResponseCallback<SignedBeaconBlock> callback) {
    LOG.trace("Peer {} requested {} BeaconBlocks starting at slot {} with step {}", peer.getId(), message.getCount(), message.getStartSlot(), message.getStep());
    if (message.getStep().compareTo(ONE) < 0) {
        callback.completeWithErrorResponse(new RpcException(INVALID_REQUEST_CODE, "Step must be greater than zero"));
        return;
    }
    if (message.getCount().compareTo(UInt64.valueOf(MAX_REQUEST_BLOCKS)) > 0) {
        callback.completeWithErrorResponse(new RpcException(INVALID_REQUEST_CODE, "Only a maximum of " + MAX_REQUEST_BLOCKS + " blocks can be requested per request"));
        return;
    }
    if (!peer.wantToMakeRequest() || !peer.wantToReceiveObjects(callback, maxRequestSize.min(message.getCount()).longValue())) {
        return;
    }
    sendMatchingBlocks(message, callback).finish(callback::completeSuccessfully, error -> {
        final Throwable rootCause = Throwables.getRootCause(error);
        if (rootCause instanceof RpcException) {
            // Keep full context
            LOG.trace("Rejecting beacon blocks by range request", error);
            callback.completeWithErrorResponse((RpcException) rootCause);
        } else {
            if (rootCause instanceof StreamClosedException || rootCause instanceof ClosedChannelException) {
                LOG.trace("Stream closed while sending requested blocks", error);
            } else {
                LOG.error("Failed to process blocks by range request", error);
            }
            callback.completeWithUnexpectedError(error);
        }
    });
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) RpcException(tech.pegasys.teku.networking.eth2.rpc.core.RpcException) StreamClosedException(tech.pegasys.teku.networking.p2p.rpc.StreamClosedException)

Example 2 with ResponseCallback

use of tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback in project teku by ConsenSys.

the class BeaconBlocksByRangeMessageHandler method sendMatchingBlocks.

private SafeFuture<?> sendMatchingBlocks(final BeaconBlocksByRangeRequestMessage message, final ResponseCallback<SignedBeaconBlock> callback) {
    final UInt64 count = maxRequestSize.min(message.getCount());
    final UInt64 endSlot = message.getStartSlot().plus(message.getStep().times(count)).minus(ONE);
    return combinedChainDataClient.getEarliestAvailableBlockSlot().thenCompose(earliestSlot -> {
        if (earliestSlot.map(s -> s.isGreaterThan(message.getStartSlot())).orElse(true)) {
            // We're missing the first block so return an error
            return SafeFuture.failedFuture(new RpcException.ResourceUnavailableException("Requested historical blocks are currently unavailable"));
        }
        final UInt64 headBlockSlot = combinedChainDataClient.getChainHead().map(MinimalBeaconBlockSummary::getSlot).orElse(ZERO);
        final NavigableMap<UInt64, Bytes32> hotRoots;
        if (combinedChainDataClient.isFinalized(endSlot)) {
            // All blocks are finalized so skip scanning the protoarray
            hotRoots = new TreeMap<>();
        } else {
            hotRoots = combinedChainDataClient.getAncestorRoots(message.getStartSlot(), message.getStep(), count);
        }
        // Don't send anything past the last slot found in protoarray to ensure blocks are
        // consistent
        // If we didn't find any blocks in protoarray, every block in the range must be
        // finalized
        // so we don't need to worry about inconsistent blocks
        final UInt64 headSlot = hotRoots.isEmpty() ? headBlockSlot : hotRoots.lastKey();
        return sendNextBlock(new RequestState(message.getStartSlot(), message.getStep(), count, headSlot, hotRoots, callback)).toVoid();
    });
}
Also used : CombinedChainDataClient(tech.pegasys.teku.storage.client.CombinedChainDataClient) RpcException(tech.pegasys.teku.networking.eth2.rpc.core.RpcException) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) MinimalBeaconBlockSummary(tech.pegasys.teku.spec.datastructures.blocks.MinimalBeaconBlockSummary) SafeFuture.completedFuture(tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture) ONE(tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE) ResponseCallback(tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback) MAX_REQUEST_BLOCKS(tech.pegasys.teku.spec.config.Constants.MAX_REQUEST_BLOCKS) BeaconBlocksByRangeRequestMessage(tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BeaconBlocksByRangeRequestMessage) Eth2Peer(tech.pegasys.teku.networking.eth2.peers.Eth2Peer) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) ZERO(tech.pegasys.teku.infrastructure.unsigned.UInt64.ZERO) Spec(tech.pegasys.teku.spec.Spec) SignedBeaconBlock(tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock) Bytes32(org.apache.tuweni.bytes.Bytes32) InvalidRpcMethodVersion(tech.pegasys.teku.networking.eth2.rpc.core.RpcException.InvalidRpcMethodVersion) PeerRequiredLocalMessageHandler(tech.pegasys.teku.networking.eth2.rpc.core.PeerRequiredLocalMessageHandler) ClosedChannelException(java.nio.channels.ClosedChannelException) Throwables(com.google.common.base.Throwables) NavigableMap(java.util.NavigableMap) INVALID_REQUEST_CODE(tech.pegasys.teku.networking.eth2.rpc.core.RpcResponseStatus.INVALID_REQUEST_CODE) StreamClosedException(tech.pegasys.teku.networking.p2p.rpc.StreamClosedException) TreeMap(java.util.TreeMap) BeaconChainMethodIds(tech.pegasys.teku.networking.eth2.rpc.beaconchain.BeaconChainMethodIds) Optional(java.util.Optional) LogManager(org.apache.logging.log4j.LogManager) SpecMilestone(tech.pegasys.teku.spec.SpecMilestone) RpcException(tech.pegasys.teku.networking.eth2.rpc.core.RpcException) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Bytes32(org.apache.tuweni.bytes.Bytes32)

Example 3 with ResponseCallback

use of tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback in project teku by ConsenSys.

the class BeaconBlocksByRootMessageHandler method onIncomingMessage.

@Override
public void onIncomingMessage(final String protocolId, final Eth2Peer peer, final BeaconBlocksByRootRequestMessage message, final ResponseCallback<SignedBeaconBlock> callback) {
    LOG.trace("Peer {} requested BeaconBlocks with roots: {}", peer.getId(), message);
    if (storageClient.getStore() != null) {
        SafeFuture<Void> future = SafeFuture.COMPLETE;
        if (!peer.wantToMakeRequest() || !peer.wantToReceiveObjects(callback, message.size())) {
            peer.disconnectCleanly(DisconnectReason.RATE_LIMITING).reportExceptions();
            return;
        }
        for (SszBytes32 blockRoot : message) {
            future = future.thenCompose(__ -> storageClient.getStore().retrieveSignedBlock(blockRoot.get()).thenCompose(block -> {
                final Optional<RpcException> validationResult = block.flatMap(b -> validateResponse(protocolId, b));
                if (validationResult.isPresent()) {
                    return SafeFuture.failedFuture(validationResult.get());
                }
                return block.map(callback::respond).orElse(SafeFuture.COMPLETE);
            }));
        }
        future.finish(callback::completeSuccessfully, err -> handleError(callback, err));
    } else {
        callback.completeSuccessfully();
    }
}
Also used : PeerRequiredLocalMessageHandler(tech.pegasys.teku.networking.eth2.rpc.core.PeerRequiredLocalMessageHandler) BeaconBlocksByRootRequestMessage(tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BeaconBlocksByRootRequestMessage) RpcException(tech.pegasys.teku.networking.eth2.rpc.core.RpcException) ClosedChannelException(java.nio.channels.ClosedChannelException) Throwables(com.google.common.base.Throwables) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) SszBytes32(tech.pegasys.teku.infrastructure.ssz.primitive.SszBytes32) ResponseCallback(tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback) DisconnectReason(tech.pegasys.teku.networking.p2p.peer.DisconnectReason) StreamClosedException(tech.pegasys.teku.networking.p2p.rpc.StreamClosedException) BeaconChainMethodIds(tech.pegasys.teku.networking.eth2.rpc.beaconchain.BeaconChainMethodIds) RecentChainData(tech.pegasys.teku.storage.client.RecentChainData) Eth2Peer(tech.pegasys.teku.networking.eth2.peers.Eth2Peer) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Spec(tech.pegasys.teku.spec.Spec) SignedBeaconBlock(tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock) LogManager(org.apache.logging.log4j.LogManager) InvalidRpcMethodVersion(tech.pegasys.teku.networking.eth2.rpc.core.RpcException.InvalidRpcMethodVersion) SpecMilestone(tech.pegasys.teku.spec.SpecMilestone) SszBytes32(tech.pegasys.teku.infrastructure.ssz.primitive.SszBytes32) RpcException(tech.pegasys.teku.networking.eth2.rpc.core.RpcException)

Example 4 with ResponseCallback

use of tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback in project teku by ConsenSys.

the class StatusMessageHandler method onIncomingMessage.

@Override
public void onIncomingMessage(final String protocolId, final Eth2Peer peer, final StatusMessage message, final ResponseCallback<StatusMessage> callback) {
    LOG.trace("Peer {} sent status {}", peer.getId(), message);
    if (!peer.wantToMakeRequest()) {
        return;
    }
    final PeerStatus status = PeerStatus.fromStatusMessage(message);
    peer.updateStatus(status);
    final Optional<StatusMessage> localStatus = statusMessageFactory.createStatusMessage();
    if (localStatus.isPresent()) {
        callback.respondAndCompleteSuccessfully(localStatus.get());
    } else {
        LOG.warn("Node is not ready to receive p2p traffic. Responding to incoming status message with an error.");
        callback.completeWithErrorResponse(NODE_NOT_READY);
    }
}
Also used : PeerStatus(tech.pegasys.teku.networking.eth2.peers.PeerStatus) StatusMessage(tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.StatusMessage)

Example 5 with ResponseCallback

use of tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback in project teku by ConsenSys.

the class DefaultEth2Peer method wantToReceiveObjects.

@Override
public boolean wantToReceiveObjects(final ResponseCallback<SignedBeaconBlock> callback, final long objectCount) {
    if (blockRequestTracker.wantToRequestObjects(objectCount) == 0L) {
        LOG.debug("Peer {} disconnected due to block rate limits", getId());
        callback.completeWithErrorResponse(new RpcException(INVALID_REQUEST_CODE, "Peer has been rate limited"));
        disconnectCleanly(DisconnectReason.RATE_LIMITING).reportExceptions();
        return false;
    }
    return true;
}
Also used : RpcException(tech.pegasys.teku.networking.eth2.rpc.core.RpcException)

Aggregations

RpcException (tech.pegasys.teku.networking.eth2.rpc.core.RpcException)4 ClosedChannelException (java.nio.channels.ClosedChannelException)3 StreamClosedException (tech.pegasys.teku.networking.p2p.rpc.StreamClosedException)3 Throwables (com.google.common.base.Throwables)2 Optional (java.util.Optional)2 LogManager (org.apache.logging.log4j.LogManager)2 SafeFuture (tech.pegasys.teku.infrastructure.async.SafeFuture)2 Eth2Peer (tech.pegasys.teku.networking.eth2.peers.Eth2Peer)2 BeaconChainMethodIds (tech.pegasys.teku.networking.eth2.rpc.beaconchain.BeaconChainMethodIds)2 PeerRequiredLocalMessageHandler (tech.pegasys.teku.networking.eth2.rpc.core.PeerRequiredLocalMessageHandler)2 ResponseCallback (tech.pegasys.teku.networking.eth2.rpc.core.ResponseCallback)2 InvalidRpcMethodVersion (tech.pegasys.teku.networking.eth2.rpc.core.RpcException.InvalidRpcMethodVersion)2 Spec (tech.pegasys.teku.spec.Spec)2 SpecMilestone (tech.pegasys.teku.spec.SpecMilestone)2 SignedBeaconBlock (tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 NavigableMap (java.util.NavigableMap)1 TreeMap (java.util.TreeMap)1 Bytes32 (org.apache.tuweni.bytes.Bytes32)1 SafeFuture.completedFuture (tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture)1