pokt-network / poktroll

The official Shannon upgrade implementation of the Pocket Network Protocol implemented using Rollkit.dev
MIT License
15 stars 7 forks source link

[RelayMiner] Add an ability to test RelayMiner configuration without application #447

Open okdas opened 3 months ago

okdas commented 3 months ago

Objective

The current Morse mainnet client has a feature to send relays without application signature. We should add this functionality to RelayMiner: an ability to send relay through a supplier without providing meta information (session, signature, etc.) so operators can verify their RelayMiner configuration.

Origin Document

Requests from the community:

First mentioned in internal communication.

In the current Morse client, the feature is enabled by adding --simulateRelay argument. In our implementation, we can consider adding this to the relayminer config file.

Goals

General deliverables


Creator: @okdas

Olshansk commented 3 months ago

@okdas to provide a link to pocket-core and an example of how it works on Morse.

okdas commented 3 months ago

In pocket-core guidelines, we recommend node runners to start the process with --simulateRelay prior to staking, so they can test before going live. That way, they would avoid being ignored by the gateway (or getting jailed/slashed - though I don't think this is functionality is turned on).

This argument then adds a new http route where the relay simulation request can be sent to. For example, this is how I used to do that:

Fuse

curl -X POST \
--data '{"relay_network_id":"0005","payload":{"data":"{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":0}","method":"POST","path":"","headers":{}}}' \
http://localhost:8081/v1/client/sim

xdai

curl -X POST \
--data '{"relay_network_id":"0027","payload":{"data":"{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":0}","method":"POST","path":"","headers":{}}}' \
http://localhost:8081/v1/client/sim

I think we have an opportunity to make this functionality more user-friendly and still secure at the same time. The simplest way to implement I think would be to add some sort of "password" or a token that can be passed via HTTP header.

eddyzags commented 1 week ago

Hey folks!

I've been considering integrating the capability to test the connection between the Relay Server and the suppliers' endpoints to increase confidence in the Relay Miner configuration for operators. Based on what is already implemented in Morse, the discussion around the topic, and this issue, I've come up with two use cases for operators:

  1. As an operator, I want to ensure the suppliers' backend URL is routable.
  2. As an operator, I want to forward a request to the supplier backend URL and then assert the response.

Use case 1

We can add a safeguard at the startup process to ensure every supplier's backend URLs are reachable (before starting the relay servers). This safeguard logic will be responsible for dialing every supplier's backend URL to test the connectivity. Then, we could expose this capability as an endpoint (/ping) for synchronous verifications (e.g., Livesness probe in Kubernetes).

Use case 2

We can set up an authenticated endpoint (/services/{service_id}/forward) whose responsibility would be to forward raw requests from the Relay Server to the service ID (more precisely, service node or data node) without providing meta information (like Session, Signature). As we plan to have service nodes that support different transport layers (TCP, UPD, QUICK ect...), we could delegate the responsibility of defining the actual logic to forward a request to the Relay Server.

We could also make this feature configurable through the Relay Miner's configuration:

    forward:
      enabled: true
      auth-token: <token>

Questions

I am still grasping the code, but I would like your input. Thanks 🙏🏾

(I've just linked a draft PR so you can get a better idea of what I am proposing)

red-0ne commented 5 days ago

@eddyzags Thank you for your contribution. You've correctly identified the use cases, and the proposed solution aligns with our goals.

Let me address your questions:

There isn't a one-to-one relationship between RelayServer and ServiceId. Here's why:

  1. The ServiceId is already included in the RelayRequest, which is sufficient for routing requests to the appropriate BackendService.
  2. RelayServers don't need to handle service-specific logic. Their main functions are:
    1. Receiving a RelayRequest
    2. Unpacking and forwarding the RelayRequest.Payload to the BackendService
    3. Packaging the response into a RelayResponse
  3. Multiple RelayServers are intended to improve communication between Gateway/Application and RelayMiner while maintaining backward compatibility (e.g., supporting QUIC while still accommodating gateways using HTTP/1.1).

Regarding your comment about the Server Config Hydrator: It actually does allow for multiple servers, but we should clarify this in the comments. We're ensuring unique URLs/listen addresses for starting RelayServers, while allowing services to specify which server type to use. There's potential for further refactoring in this area.

Thank you for submitting the PR. I'll examine it and respond with comments before EOW.