Skip to content

Commit 60fdedd

Browse files
committed
Merge remote-tracking branch 'origin/main' into SD_utilize
2 parents ee4830d + e914eb6 commit 60fdedd

File tree

18 files changed

+542
-12
lines changed

18 files changed

+542
-12
lines changed

.github/workflows/go.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ jobs:
2020
with:
2121
go-version: 1.19
2222

23+
- name: Test with the Go CLI
24+
run: go test ./...
25+
2326
- name: Golangci
2427
uses: golangci/golangci-lint-action@v3
2528
with:

shared/services/bc-manager.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ func (m *BeaconClientManager) GetSyncStatus() (beacon.SyncStatus, error) {
134134
return result.(beacon.SyncStatus), nil
135135
}
136136

137+
func (m *BeaconClientManager) GetNodeVersion() (beacon.NodeVersion, error) {
138+
result, err := m.runFunction1(func(client beacon.Client) (interface{}, error) {
139+
return client.GetNodeVersion()
140+
})
141+
if err != nil {
142+
return beacon.NodeVersion{}, err
143+
}
144+
return result.(beacon.NodeVersion), nil
145+
}
146+
137147
// Get the Beacon configuration
138148
func (m *BeaconClientManager) GetEth2Config() (beacon.Eth2Config, error) {
139149
result, err := m.runFunction1(func(client beacon.Client) (interface{}, error) {

shared/services/beacon/client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ type AttestationInfo struct {
9797
CommitteeIndex uint64
9898
}
9999

100+
type NodeVersion struct {
101+
Version string
102+
}
103+
100104
// Beacon client type
101105
type BeaconClientType int
102106

@@ -133,6 +137,7 @@ const (
133137
type Client interface {
134138
GetClientType() (BeaconClientType, error)
135139
GetSyncStatus() (SyncStatus, error)
140+
GetNodeVersion() (NodeVersion, error)
136141
GetEth2Config() (Eth2Config, error)
137142
GetEth2DepositContract() (Eth2DepositContract, error)
138143
GetAttestations(blockId string) ([]AttestationInfo, bool, error)

shared/services/beacon/client/std-http-client.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const (
4848
RequestContentType = "application/json"
4949

5050
RequestSyncStatusPath = "/eth/v1/node/syncing"
51+
RequestNodeVersionPath = "/eth/v1/node/version"
5152
RequestEth2ConfigPath = "/eth/v1/config/spec"
5253
RequestEth2DepositContractMethod = "/eth/v1/config/deposit_contract"
5354
RequestGenesisPath = "/eth/v1/beacon/genesis"
@@ -107,6 +108,17 @@ func (c *StandardHttpClient) GetSyncStatus() (beacon.SyncStatus, error) {
107108

108109
}
109110

111+
func (c *StandardHttpClient) GetNodeVersion() (beacon.NodeVersion, error) {
112+
nodeVersion, err := c.getNodeVersion()
113+
if err != nil {
114+
return beacon.NodeVersion{}, err
115+
}
116+
117+
return beacon.NodeVersion{
118+
Version: nodeVersion.Data.Version,
119+
}, nil
120+
}
121+
110122
// Get the eth2 config
111123
func (c *StandardHttpClient) GetEth2Config() (beacon.Eth2Config, error) {
112124

@@ -572,6 +584,21 @@ func (c *StandardHttpClient) getSyncStatus() (SyncStatusResponse, error) {
572584
return syncStatus, nil
573585
}
574586

587+
func (c *StandardHttpClient) getNodeVersion() (NodeVersionResponse, error) {
588+
responseBody, status, err := c.getRequest(RequestNodeVersionPath)
589+
if err != nil {
590+
return NodeVersionResponse{}, fmt.Errorf("Could not get node sync status: %w", err)
591+
}
592+
if status != http.StatusOK {
593+
return NodeVersionResponse{}, fmt.Errorf("Could not get node sync status: HTTP status %d; response body: '%s'", status, string(responseBody))
594+
}
595+
var nodeVersion NodeVersionResponse
596+
if err := json.Unmarshal(responseBody, &nodeVersion); err != nil {
597+
return NodeVersionResponse{}, fmt.Errorf("Could not decode node sync status: %w", err)
598+
}
599+
return nodeVersion, nil
600+
}
601+
575602
// Get the eth2 config
576603
func (c *StandardHttpClient) getEth2Config() (Eth2ConfigResponse, error) {
577604
responseBody, status, err := c.getRequest(RequestEth2ConfigPath)

shared/services/beacon/client/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ type SyncStatusResponse struct {
4646
SyncDistance uinteger `json:"sync_distance"`
4747
} `json:"data"`
4848
}
49+
50+
type NodeVersionResponse struct {
51+
Data struct {
52+
Version string `json:"version"`
53+
} `json:"data"`
54+
}
55+
4956
type Eth2ConfigResponse struct {
5057
Data struct {
5158
SecondsPerSlot uinteger `json:"SECONDS_PER_SLOT"`

shared/services/config/stadernode-config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ func (cfg *StaderNodeConfig) GetMerkleProofApi() string {
324324
return cfg.baseStaderBackendUrl[cfg.Network.Value.(config.Network)] + "/merklesForElRewards/proofs/%s"
325325
}
326326

327+
func (cfg *StaderNodeConfig) GetNodeDiversityApi() string {
328+
return cfg.baseStaderBackendUrl[cfg.Network.Value.(config.Network)] + "/saveNodeDiversity"
329+
}
330+
327331
func (cfg *StaderNodeConfig) GetTxWatchUrl() string {
328332
return cfg.txWatchUrl[cfg.Network.Value.(config.Network)]
329333
}

shared/services/ec-manager.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ package services
2121

2222
import (
2323
"context"
24+
"encoding/json"
2425
"fmt"
26+
"io"
2527
"math"
2628
"math/big"
2729
"strings"
@@ -36,6 +38,7 @@ import (
3638
"github.com/stader-labs/stader-node/shared/types/api"
3739
cfgtypes "github.com/stader-labs/stader-node/shared/types/config"
3840
"github.com/stader-labs/stader-node/shared/utils/log"
41+
"github.com/stader-labs/stader-node/shared/utils/net"
3942
)
4043

4144
// This is a proxy for multiple ETH clients, providing natural fallback support if one of them fails.
@@ -520,3 +523,51 @@ func (p *ExecutionClientManager) runFunction(function ecFunction) (interface{},
520523
func (p *ExecutionClientManager) isDisconnected(err error) bool {
521524
return strings.Contains(err.Error(), "dial tcp")
522525
}
526+
527+
func (p *ExecutionClientManager) Version() (string, error) {
528+
if !p.primaryReady && !p.fallbackReady {
529+
return "", fmt.Errorf("EC not ready")
530+
}
531+
532+
var url string
533+
534+
if p.primaryReady {
535+
url = p.primaryEcUrl
536+
} else {
537+
url = p.fallbackEcUrl
538+
}
539+
540+
payload := struct {
541+
Jsonrpc string `json:"jsonrpc"`
542+
Method string `json:"method"`
543+
Params []string `json:"params"`
544+
Id int64 `json:"id"`
545+
}{
546+
Jsonrpc: "2.0",
547+
Method: "web3_clientVersion",
548+
Params: []string{},
549+
Id: 1,
550+
}
551+
552+
res, err := net.MakePostRequest(url, payload)
553+
if err != nil {
554+
return "", err
555+
}
556+
defer res.Body.Close()
557+
558+
body, err := io.ReadAll(res.Body)
559+
if err != nil {
560+
return "", err
561+
}
562+
563+
response := struct {
564+
Result string `json:"result"`
565+
}{}
566+
567+
err = json.Unmarshal(body, &response)
568+
if err != nil {
569+
return "", err
570+
}
571+
572+
return response.Result, nil
573+
}

shared/services/gas/gas.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func handleEtherscanGasPrices(gasSuggestion etherscan.GasFeeSuggestion, priority
184184

185185
desiredPriceFloat, err := strconv.ParseFloat(desiredPrice, 64)
186186
if err != nil {
187-
fmt.Println("Not a valid gas price (%s), try again.", err.Error())
187+
fmt.Printf("Not a valid gas price (%s), try again.\n", err.Error())
188188
continue
189189
}
190190
if desiredPriceFloat <= 0 {

shared/services/requirements.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ func waitBeaconClientSynced(c *cli.Context, verbose bool, timeout int64) (bool,
499499
// Check sync status
500500
if syncStatus.Syncing {
501501
if verbose {
502-
log.Println("Eth 2.0 node syncing: %.2f%%\n", syncStatus.Progress*100)
502+
log.Printf("Eth 2.0 node syncing: %.2f%%\n", syncStatus.Progress*100)
503503
}
504504
} else {
505505
return true, nil

shared/services/stader/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func (c *Client) UpdatePrometheusConfiguration(settings map[string]string) error
298298
}
299299
err = os.Chmod(prometheusConfigPath, 0664)
300300
if err != nil {
301-
return fmt.Errorf("Could not set Prometheus config file permissions: %w", shellescape.Quote(prometheusConfigPath), err)
301+
return fmt.Errorf("Could not set Prometheus config file permissions: %s: %w", shellescape.Quote(prometheusConfigPath), err)
302302
}
303303

304304
return nil

shared/services/wallet/node.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package wallet
2222
import (
2323
"context"
2424
"crypto/ecdsa"
25+
"encoding/hex"
2526
"errors"
2627
"fmt"
2728
"math/big"
@@ -186,3 +187,29 @@ func (w *Wallet) getNodeDerivedKey(index uint) (*hdkeychain.ExtendedKey, string,
186187
return key, derivationPath, nil
187188

188189
}
190+
191+
// Get the node hex encoding public key
192+
func (w *Wallet) GetNodePubkey() (string, error) {
193+
194+
// Check wallet is initialized
195+
if !w.IsInitialized() {
196+
return "", errors.New("Wallet is not initialized")
197+
}
198+
199+
// Get private key
200+
privateKey, _, err := w.getNodePrivateKey()
201+
if err != nil {
202+
return "", err
203+
}
204+
205+
// Get public key
206+
publicKey := privateKey.Public()
207+
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
208+
if !ok {
209+
return "", errors.New("Could not get node public key")
210+
}
211+
212+
publickeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
213+
214+
return hex.EncodeToString(publickeyBytes), nil
215+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package stader_backend
2+
3+
type NodeDiversityRequest struct {
4+
Signature string `json:"signature"`
5+
Message *NodeDiversity `json:"message"`
6+
}
7+
8+
type NodeDiversity struct {
9+
ExecutionClient string `json:"executionClient"`
10+
ConsensusClient string `json:"consensusClient"`
11+
ValidatorClient string `json:"validatorClient"`
12+
TotalNonTerminalKeys uint64 `json:"totalNonTerminalKeys"`
13+
NodeAddress string `json:"nodeAddress"`
14+
NodePublicKey string `json:"nodePublicKey"`
15+
Relays string `json:"relays"`
16+
}
17+
18+
type NodeDiversityResponseType struct {
19+
Success bool `json:"success"`
20+
Error string `json:"error"`
21+
}

shared/utils/stader/node-diversity.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package stader
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
"github.com/stader-labs/stader-node/shared/services"
8+
stader_backend "github.com/stader-labs/stader-node/shared/types/stader-backend"
9+
"github.com/stader-labs/stader-node/shared/utils/net"
10+
"github.com/urfave/cli"
11+
)
12+
13+
func SendNodeDiversityResponseType(
14+
c *cli.Context,
15+
request *stader_backend.NodeDiversityRequest,
16+
) (*stader_backend.NodeDiversityResponseType, error) {
17+
config, err := services.GetConfig(c)
18+
if err != nil {
19+
return nil, err
20+
}
21+
22+
res, err := net.MakePostRequest(config.StaderNode.GetNodeDiversityApi(), request)
23+
if err != nil {
24+
return nil, fmt.Errorf("request to GetNodeDiversityApi %w", err)
25+
}
26+
defer res.Body.Close()
27+
28+
var resp stader_backend.NodeDiversityResponseType
29+
err = json.NewDecoder(res.Body).Decode(&resp)
30+
31+
if err != nil {
32+
return nil, fmt.Errorf("decode NodeDiversityResponseType %w", err)
33+
}
34+
35+
return &resp, nil
36+
37+
}

stader-cli/node/claim-sp-rewards.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func ClaimSpRewards(c *cli.Context) error {
7474

7575
fmt.Println("Following are the unclaimed cycles, Please enter in a comma separated string the cycles you want to claim rewards for:")
7676

77-
fmt.Printf("%-18s%-14.30s%-14.10s%-10s\n", "Cycle Number", "Cycle Date", "ETH Rewards", "SD Rewards")
77+
fmt.Printf("\n%-18s%-14.30s%-14.10s%-10s\n", "Cycle Number", "Cycle Date", "ETH Rewards", "SD Rewards")
7878
cyclesToClaim := map[int64]bool{}
7979
for {
8080
for _, cycleInfo := range detailedCyclesInfo.DetailedCyclesInfo {

stader-cli/service/service.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -684,8 +684,8 @@ func startService(
684684
fmt.Printf("%sWarning: couldn't verify that the validator container can be safely restarted:\n\t%s\n", colorYellow, err.Error())
685685
fmt.Println("If you are changing to a different ETH2 client, it may resubmit an attestation you have already submitted.")
686686
fmt.Println("This will slash your validator!")
687-
fmt.Println("To prevent slashing, you must wait 15 minutes from the time you stopped the clients before starting them again.\n")
688-
fmt.Println("**If you did NOT change clients, you can safely ignore this warning.**\n")
687+
fmt.Println("To prevent slashing, you must wait 15 minutes from the time you stopped the clients before starting them again.")
688+
fmt.Println("**If you did NOT change clients, you can safely ignore this warning.**")
689689
if !cliutils.Confirm(fmt.Sprintf("Press y when you understand the above warning, have waited, and are ready to start Stader:%s", colorReset)) {
690690
fmt.Println("Cancelled.")
691691
return nil
@@ -914,7 +914,7 @@ func pruneExecutionClient(c *cli.Context) error {
914914
}
915915

916916
fmt.Println("This will shut down your main execution client and prune its database, freeing up disk space.")
917-
fmt.Println("Once pruning is complete, your execution client will restart automatically.\n")
917+
fmt.Println("Once pruning is complete, your execution client will restart automatically.")
918918

919919
if selectedEc == cfgtypes.ExecutionClient_Geth {
920920
if cfg.UseFallbackClients.Value == false {
@@ -1488,7 +1488,7 @@ func exportEcData(c *cli.Context, targetDir string) error {
14881488

14891489
fmt.Println("This will export your execution client's chain data to an external directory, such as a portable hard drive.")
14901490
fmt.Println("If your execution client is running, it will be shut down.")
1491-
fmt.Println("Once the export is complete, your execution client will restart automatically.\n")
1491+
fmt.Println("Once the export is complete, your execution client will restart automatically.")
14921492

14931493
// Get the container prefix
14941494
prefix, err := getContainerPrefix(staderClient)
@@ -1606,7 +1606,7 @@ func importEcData(c *cli.Context, sourceDir string) error {
16061606

16071607
fmt.Println("This will import execution layer chain data that you previously exported into your execution client.")
16081608
fmt.Println("If your execution client is running, it will be shut down.")
1609-
fmt.Println("Once the import is complete, your execution client will restart automatically.\n")
1609+
fmt.Println("Once the import is complete, your execution client will restart automatically.")
16101610

16111611
// Get the volume to import into
16121612
executionContainerName := prefix + ExecutionContainerSuffix

stader-cli/wallet/export.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ func exportWallet(c *cli.Context) error {
5151
// Check if stdout is interactive
5252
stat, err := os.Stdout.Stat()
5353
if err != nil {
54-
fmt.Fprintf(os.Stderr, "An error occured while determining whether or not the output is a tty: %w\n"+
55-
"Use \"stader-cli --secure-session wallet export\" to bypass.\n", err)
54+
fmt.Fprintf(os.Stderr, "An error occured while determining whether or not the output is a tty: %s\n"+
55+
"Use \"stader-cli --secure-session wallet export\" to bypass.\n", err.Error())
5656
os.Exit(1)
5757
}
5858

0 commit comments

Comments
 (0)