Skip to content

Commit e0e91d0

Browse files
committed
Add cli utility for serializing NetworkState at a given slot
1 parent f4d1ec3 commit e0e91d0

2 files changed

Lines changed: 106 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
cli
2+
*.json

shared/services/state/cli/cli.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"flag"
6+
"fmt"
7+
"os"
8+
9+
"github.com/ethereum/go-ethereum/common"
10+
"github.com/ethereum/go-ethereum/ethclient"
11+
"github.com/rocket-pool/rocketpool-go/rocketpool"
12+
"github.com/rocket-pool/smartnode/shared/services/beacon/client"
13+
"github.com/rocket-pool/smartnode/shared/services/config"
14+
"github.com/rocket-pool/smartnode/shared/services/state"
15+
cfgtypes "github.com/rocket-pool/smartnode/shared/types/config"
16+
)
17+
18+
// A basic CLI tool which can be used to serialize NetworkState objects to files
19+
// for future use.
20+
// Accepts arguments for a beacon node URL, an execution node URL, and a slot number
21+
// to get the state for.
22+
23+
var bnFlag = flag.String("b", "http://localhost:5052", "The beacon node URL")
24+
var elFlag = flag.String("e", "http://localhost:8545", "The execution node URL")
25+
var slotFlag = flag.Uint64("slot", 0, "The slot number to get the state for")
26+
var networkFlag = flag.String("network", "mainnet", "The network to get the state for, i.e. 'mainnet' or 'holesky'")
27+
var prettyFlag = flag.Bool("p", false, "Pretty print the output")
28+
29+
var validateFlag = flag.Bool("validate", false, "Validate the json from stdin can be unmarshalled into a NetworkState")
30+
31+
func validate() {
32+
decoder := json.NewDecoder(os.Stdin)
33+
networkState := state.NetworkState{}
34+
err := decoder.Decode(&networkState)
35+
if err != nil {
36+
fmt.Fprintf(os.Stderr, "Error decoding network state: %v\n", err)
37+
os.Exit(1)
38+
}
39+
fmt.Fprintf(os.Stderr, "Network state validated\n")
40+
}
41+
42+
func main() {
43+
flag.Parse()
44+
45+
if *validateFlag {
46+
validate()
47+
return
48+
}
49+
50+
sn := config.NewSmartnodeConfig(nil)
51+
switch *networkFlag {
52+
case "mainnet":
53+
sn.Network.Value = cfgtypes.Network_Mainnet
54+
case "holesky":
55+
sn.Network.Value = cfgtypes.Network_Holesky
56+
default:
57+
fmt.Fprintf(os.Stderr, "Invalid network: %s\n", *networkFlag)
58+
fmt.Fprintf(os.Stderr, "Valid networks are: mainnet, holesky\n")
59+
os.Exit(1)
60+
}
61+
62+
ec, err := ethclient.Dial(*elFlag)
63+
if err != nil {
64+
fmt.Fprintf(os.Stderr, "Error connecting to execution node: %v\n", err)
65+
os.Exit(1)
66+
}
67+
68+
contracts := sn.GetStateManagerContracts()
69+
fmt.Fprintf(os.Stderr, "Contracts: %+v\n", contracts)
70+
71+
rocketStorage := sn.GetStorageAddress()
72+
73+
rp, err := rocketpool.NewRocketPool(ec, common.HexToAddress(rocketStorage))
74+
if err != nil {
75+
fmt.Fprintf(os.Stderr, "Error creating rocketpool: %v\n", err)
76+
os.Exit(1)
77+
}
78+
bc := client.NewStandardHttpClient(*bnFlag)
79+
sm := state.NewNetworkStateManager(rp, contracts, bc, nil)
80+
81+
var networkState *state.NetworkState
82+
83+
if *slotFlag == 0 {
84+
fmt.Fprintf(os.Stderr, "Slot number not provided, defaulting to head slot.\n")
85+
networkState, err = sm.GetHeadState()
86+
} else {
87+
networkState, err = sm.GetStateForSlot(*slotFlag)
88+
}
89+
if err != nil {
90+
fmt.Fprintf(os.Stderr, "Error getting network state: %v\n", err)
91+
os.Exit(1)
92+
}
93+
94+
fmt.Fprintf(os.Stderr, "Network state fetched, outputting to stdout\n")
95+
encoder := json.NewEncoder(os.Stdout)
96+
if *prettyFlag {
97+
encoder.SetIndent("", " ")
98+
}
99+
err = encoder.Encode(networkState)
100+
if err != nil {
101+
fmt.Fprintf(os.Stderr, "Error encoding network state: %v\n", err)
102+
os.Exit(1)
103+
}
104+
}

0 commit comments

Comments
 (0)