Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display Currently-Used HTTP Connection to Eth1 Node via Healthz or an API Endpoint #9972

Closed
rauljordan opened this issue Dec 2, 2021 · 3 comments · Fixed by #10073
Closed
Labels
API Api related tasks Good First Issue Good for newcomers Help Wanted Extra attention is needed

Comments

@rauljordan
Copy link
Contributor

🚀 Feature Request

Description

Prysm allows users to specify a connection to an eth1 node using the --http-web3provider flag. Additionally, users can provide a fallback URL to connect to if the first one goes down. This is important functionality that is used by many stakers today. However, for more advanced users running cloud infrastructures or those developing user interfaces to Prysm, it would be nice to expose an API that shows the current eth1 connection information including the currently connected endpoint, the fallback providers, and whether or not there is an active error in the connections.

Describe the solution you'd like

Some API endpoint in the Prysm beacon node which returns the following data:

  • Currently connected endpoint
  • List of fallback provider URLs
  • Any connection error

This endpoint should go under proto/prysm/v1alpha1/node.proto

Describe alternatives you've considered

Today, the information about the currently connected endpoint is available in the prom metrics of the beacon node:

# HELP powchain_sync_eth1_connected Boolean indicating whether an eth1 endpoint is currently connected: 0=false, 1=true.
# TYPE powchain_sync_eth1_connected gauge
powchain_sync_eth1_connected 1
# HELP powchain_sync_eth1_fallback_configured Boolean recording whether a fallback eth1 endpoint was configured: 0=false, 1=true.
# TYPE powchain_sync_eth1_fallback_configured gauge
powchain_sync_eth1_fallback_configured 1
# HELP powchain_sync_eth1_fallback_connected Boolean indicating whether a fallback eth1 endpoint is currently connected: 0=false, 1=true.
# TYPE powchain_sync_eth1_fallback_connected gauge
powchain_sync_eth1_fallback_connected 0

but there is no way to see the list of fallback providers or the currently connected URL.

@michaelneuder
Copy link
Contributor

michaelneuder commented Jan 8, 2022

Hey Raul!

This is something I would like to take a swing at. I wanted to run my plan by you before diving too deep in case there is something obvious I am missing (highly likely).

This is how I am understanding the data flow of the URLs:

  1. The flags http-web3provider and fallback-web3provider are set and parsed into a slice of strings, which is passed into the beacon node options here.
  2. Inside the node constructor, registerPOWChainService() is called, which in turn passes these options into powchain.NewService here.
  3. The options get processed inside this function, and then set as the httpEndpoints in the config of the powchain service.
  4. The endpoints are then used by this service to download the chain data.

On the other end, we want to implement an RPC on the v1alpha1 node. From what I can tell:

  1. The proto/prysm/v1alpha1/node.proto RPCs are implemented in beacon-chain/rpc/prysm/v1alpha1/node/server.go using this Server type.
  2. This server is composed into the larger beacon chain RPC service as nodeServer here.

Given this, my plan to extract the HTTP endpoints and connection statuses out of the powchain service is as follows.

  1. Add two new methods to the powchain.Service struct. (a) a method to retrieve the list of http endpoints (the 0th being the default), (b) a method to check the connection status of a specific endpoint. This method will call dialETH1Nodes defined here, and assert that there is a nil error result.
  2. Add a new interface to the powchain package, that implements the two above functions. (using the interface to copy the pattern of ChainStartFetcher for example).
  3. In the nodev1alpha1.Server add a field for the interface defined in step 2.
  4. In beacon-chain/rpc/service.go, construct the nodev1alpha.Serverwith the interface from the powchain package (similar to what is done for the BlockFetcher here, which makes use of the Chain interface defined in powchain).

I know that was a bit verbose, but since there is a good bit of plumbing I was hoping to get an overall sense of if this is a reasonable approach or if you had anything you would do significantly differently!

Thanks in advance for taking a look!
Mike

@michaelneuder
Copy link
Contributor

FYI I wrote up a little proof-of-concept in michaelneuder#1. I need to add tests and clean up obviously, but I am going to pause here before getting to invested in this implementation in case the approach needs to be adjusted.

@rauljordan
Copy link
Contributor Author

michaelneuder#1

This is an excellent description that describes the code path perfectly. Your PR is great, as it accomplishes exactly what we wanted. I believe it is almost ready for a final review and merge into Prysm. Feel free to open a pull request. We use a build system called Bazel which can be a little difficult to deal with when adding new endpoints, but I can help fix those problems in your PR after you push

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Api related tasks Good First Issue Good for newcomers Help Wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants