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

Node diver metrics #186

Merged
merged 21 commits into from
Feb 16, 2024
Merged
10 changes: 10 additions & 0 deletions shared/services/bc-manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ func (m *BeaconClientManager) GetSyncStatus() (beacon.SyncStatus, error) {
return result.(beacon.SyncStatus), nil
}

func (m *BeaconClientManager) GetNodeVersion() (beacon.NodeVersion, error) {
result, err := m.runFunction1(func(client beacon.Client) (interface{}, error) {
return client.GetNodeVersion()
})
if err != nil {
return beacon.NodeVersion{}, err
}
return result.(beacon.NodeVersion), nil
}

// Get the Beacon configuration
func (m *BeaconClientManager) GetEth2Config() (beacon.Eth2Config, error) {
result, err := m.runFunction1(func(client beacon.Client) (interface{}, error) {
Expand Down
5 changes: 5 additions & 0 deletions shared/services/beacon/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ type AttestationInfo struct {
CommitteeIndex uint64
}

type NodeVersion struct {
Version string
}

// Beacon client type
type BeaconClientType int

Expand Down Expand Up @@ -133,6 +137,7 @@ const (
type Client interface {
GetClientType() (BeaconClientType, error)
GetSyncStatus() (SyncStatus, error)
GetNodeVersion() (NodeVersion, error)
GetEth2Config() (Eth2Config, error)
GetEth2DepositContract() (Eth2DepositContract, error)
GetAttestations(blockId string) ([]AttestationInfo, bool, error)
Expand Down
27 changes: 27 additions & 0 deletions shared/services/beacon/client/std-http-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
RequestContentType = "application/json"

RequestSyncStatusPath = "/eth/v1/node/syncing"
RequestNodeVersionPath = "/eth/v1/node/version"
RequestEth2ConfigPath = "/eth/v1/config/spec"
RequestEth2DepositContractMethod = "/eth/v1/config/deposit_contract"
RequestGenesisPath = "/eth/v1/beacon/genesis"
Expand Down Expand Up @@ -107,6 +108,17 @@

}

func (c *StandardHttpClient) GetNodeVersion() (beacon.NodeVersion, error) {
nodeVersion, err := c.getNodeVersion()
if err != nil {
return beacon.NodeVersion{}, err
}

return beacon.NodeVersion{
Version: nodeVersion.Data.Version,
}, nil
}

// Get the eth2 config
func (c *StandardHttpClient) GetEth2Config() (beacon.Eth2Config, error) {

Expand Down Expand Up @@ -572,6 +584,21 @@
return syncStatus, nil
}

func (c *StandardHttpClient) getNodeVersion() (NodeVersionResponse, error) {
responseBody, status, err := c.getRequest(RequestNodeVersionPath)
if err != nil {
return NodeVersionResponse{}, fmt.Errorf("Could not get node sync status: %w", err)
}
if status != http.StatusOK {

Check failure on line 592 in shared/services/beacon/client/std-http-client.go

View workflow job for this annotation

GitHub Actions / build

if statements should only be cuddled with assignments (wsl)
return NodeVersionResponse{}, fmt.Errorf("Could not get node sync status: HTTP status %d; response body: '%s'", status, string(responseBody))
}
var nodeVersion NodeVersionResponse

Check failure on line 595 in shared/services/beacon/client/std-http-client.go

View workflow job for this annotation

GitHub Actions / build

declarations should never be cuddled (wsl)
if err := json.Unmarshal(responseBody, &nodeVersion); err != nil {

Check failure on line 596 in shared/services/beacon/client/std-http-client.go

View workflow job for this annotation

GitHub Actions / build

only one cuddle assignment allowed before if statement (wsl)
batphonghan marked this conversation as resolved.
Show resolved Hide resolved
return NodeVersionResponse{}, fmt.Errorf("Could not decode node sync status: %w", err)
}
return nodeVersion, nil
}

// Get the eth2 config
func (c *StandardHttpClient) getEth2Config() (Eth2ConfigResponse, error) {
responseBody, status, err := c.getRequest(RequestEth2ConfigPath)
Expand Down
7 changes: 7 additions & 0 deletions shared/services/beacon/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ type SyncStatusResponse struct {
SyncDistance uinteger `json:"sync_distance"`
} `json:"data"`
}

type NodeVersionResponse struct {
Data struct {
Version string `json:"version"`
} `json:"data"`
}

type Eth2ConfigResponse struct {
Data struct {
SecondsPerSlot uinteger `json:"SECONDS_PER_SLOT"`
Expand Down
4 changes: 4 additions & 0 deletions shared/services/config/stadernode-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@
return cfg.baseStaderBackendUrl[cfg.Network.Value.(config.Network)] + "/merklesForElRewards/proofs/%s"
}

func (cfg *StaderNodeConfig) GetNodeDiversityApi() string {

Check warning on line 327 in shared/services/config/stadernode-config.go

View workflow job for this annotation

GitHub Actions / build

var-naming: method GetNodeDiversityApi should be GetNodeDiversityAPI (revive)
return cfg.baseStaderBackendUrl[cfg.Network.Value.(config.Network)] + "/nodeDiversity"
}

func (cfg *StaderNodeConfig) GetTxWatchUrl() string {
return cfg.txWatchUrl[cfg.Network.Value.(config.Network)]
}
Expand Down
51 changes: 51 additions & 0 deletions shared/services/ec-manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@

import (
"context"
"encoding/json"
"fmt"
"io"
"math"
"math/big"
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -520,3 +523,51 @@
func (p *ExecutionClientManager) isDisconnected(err error) bool {
return strings.Contains(err.Error(), "dial tcp")
}

func (p *ExecutionClientManager) Version() (string, error) {
if !p.primaryReady && !p.fallbackReady {
return "", fmt.Errorf("EC not ready")
}

var url string

if p.primaryReady {

Check failure on line 534 in shared/services/ec-manager.go

View workflow job for this annotation

GitHub Actions / build

dupBranchBody: both branches in if statement have same body (gocritic)
url = p.primaryEcUrl
} else {
url = p.primaryEcUrl
batphonghan marked this conversation as resolved.
Show resolved Hide resolved
}

method := "POST"

payload := strings.NewReader(`{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}`)

client := &http.Client{}
req, err := http.NewRequest(method, url, payload)

if err != nil {
return "", err
}
req.Header.Add("Content-Type", "application/json")

res, err := client.Do(req)
if err != nil {
batphonghan marked this conversation as resolved.
Show resolved Hide resolved
return "", err
}
defer res.Body.Close()

body, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}

response := struct {
Result string `json:"result"`
}{}

err = json.Unmarshal(body, &response)
if err != nil {
return "", err
}

return response.Result, nil
}
27 changes: 27 additions & 0 deletions shared/services/wallet/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import (
"context"
"crypto/ecdsa"
"encoding/hex"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -186,3 +187,29 @@
return key, derivationPath, nil

}

// Get the node hex encoding public key
func (w *Wallet) GetNodePubkey() (string, error) {

Check failure on line 192 in shared/services/wallet/node.go

View workflow job for this annotation

GitHub Actions / build

unnecessary leading newline (whitespace)

// Check wallet is initialized
if !w.IsInitialized() {
return "", errors.New("Wallet is not initialized")
}

// Get private key
privateKey, _, err := w.getNodePrivateKey()
if err != nil {
return "", err
}

// Get public key
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return "", errors.New("Could not get node public key")
}

publickeyBytes := crypto.FromECDSAPub(publicKeyECDSA)

return hex.EncodeToString(publickeyBytes), nil
}
19 changes: 19 additions & 0 deletions shared/types/stader-backend/node-diversity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package stader_backend

Check warning on line 1 in shared/types/stader-backend/node-diversity.go

View workflow job for this annotation

GitHub Actions / build

var-naming: don't use an underscore in package name (revive)

type NodeDiversityRequest struct {
Signature string `json:"signature"`
Message *NodeDiversity `json:"message"`
}

type NodeDiversity struct {
ExecutionClient string `json:"executionClient"`
ConsensusClient string `json:"consensusClient"`
NodeAddress string `json:"nodeAddress"`
NodePublicKey string `json:"nodePublicKey"`
Relays string `json:"relays"`
}

type NodeDiversityResponseType struct {
Success bool `json:"success"`
Error string `json:"error"`
}
37 changes: 37 additions & 0 deletions shared/utils/stader/node-diversity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package stader

import (
"encoding/json"
"fmt"

"github.com/stader-labs/stader-node/shared/services"
stader_backend "github.com/stader-labs/stader-node/shared/types/stader-backend"
"github.com/stader-labs/stader-node/shared/utils/net"
"github.com/urfave/cli"
)

func SendNodeDiversityResponseType(
c *cli.Context,
request *stader_backend.NodeDiversityRequest,
) (*stader_backend.NodeDiversityResponseType, error) {
config, err := services.GetConfig(c)
if err != nil {
return nil, err
}

res, err := net.MakePostRequest(config.StaderNode.GetNodeDiversityApi(), request)
if err != nil {
return nil, fmt.Errorf("request to GetNodeDiversityApi %w", err)
}
defer res.Body.Close()

var resp stader_backend.NodeDiversityResponseType
err = json.NewDecoder(res.Body).Decode(&resp)

if err != nil {
return nil, fmt.Errorf("decode NodeDiversityResponseType %w", err)
}

return &resp, nil

Check failure on line 36 in shared/utils/stader/node-diversity.go

View workflow job for this annotation

GitHub Actions / build

unnecessary trailing newline (whitespace)
}
4 changes: 2 additions & 2 deletions stader-cli/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,8 @@ func startService(
fmt.Printf("%sWarning: couldn't verify that the validator container can be safely restarted:\n\t%s\n", colorYellow, err.Error())
fmt.Println("If you are changing to a different ETH2 client, it may resubmit an attestation you have already submitted.")
fmt.Println("This will slash your validator!")
fmt.Println("To prevent slashing, you must wait 15 minutes from the time you stopped the clients before starting them again.\n")
fmt.Println("**If you did NOT change clients, you can safely ignore this warning.**\n")
fmt.Println("To prevent slashing, you must wait 15 minutes from the time you stopped the clients before starting them again.")
fmt.Println("**If you did NOT change clients, you can safely ignore this warning.**")
if !cliutils.Confirm(fmt.Sprintf("Press y when you understand the above warning, have waited, and are ready to start Stader:%s", colorReset)) {
fmt.Println("Cancelled.")
return nil
Expand Down
Loading
Loading