-
Notifications
You must be signed in to change notification settings - Fork 166
/
check_machine_account.go
116 lines (96 loc) · 3.51 KB
/
check_machine_account.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package cmd
import (
"context"
"fmt"
"path/filepath"
"time"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
sdk "github.com/onflow/flow-go-sdk"
client "github.com/onflow/flow-go-sdk/access/grpc"
"github.com/onflow/flow-go/cmd"
"github.com/onflow/flow-go/cmd/util/cmd/common"
model "github.com/onflow/flow-go/model/bootstrap"
"github.com/onflow/flow-go/module/epochs"
)
var (
flagAccessAPIAddress string
)
var checkMachineAccountCmd = &cobra.Command{
Use: "check-machine-account",
Short: "checks a machine account configuration",
Run: checkMachineAccountRun,
}
func init() {
rootCmd.AddCommand(checkMachineAccountCmd)
checkMachineAccountCmd.Flags().StringVar(&flagAccessAPIAddress, "access-address", "", "network address of an Access Node")
cmd.MarkFlagRequired(checkMachineAccountCmd, "access-address")
}
func checkMachineAccountRun(_ *cobra.Command, _ []string) {
// read nodeID written to boostrap dir by `bootstrap key`
nodeID, err := readNodeID()
if err != nil {
log.Fatal().Err(err).Msg("could not read node id")
}
// read the private node information - used to get the role
var nodeInfoPriv model.NodeInfoPriv
err = common.ReadJSON(filepath.Join(flagOutdir, fmt.Sprintf(model.PathNodeInfoPriv, nodeID)), &nodeInfoPriv)
if err != nil {
log.Fatal().Err(err).Msg("failed to read json")
}
// read the machine account info file
machineAccountInfo := readMachineAccountInfo(nodeID)
machineAccountPrivKey, err := machineAccountInfo.PrivateKey()
if err != nil {
log.Fatal().Err(err).Msg("could not decode machine account private key")
}
// print public machine account info
log.Debug().
Str("machine_account_address", machineAccountInfo.Address).
Str("machine_account_pub_key", fmt.Sprintf("%x", encodedRuntimeAccountPubKey(machineAccountPrivKey))).
Uint("key_index", machineAccountInfo.KeyIndex).
Str("signing_algo", machineAccountInfo.SigningAlgorithm.String()).
Str("hash_algo", machineAccountInfo.HashAlgorithm.String()).
Msg("read machine account info from disk")
flowClient, err := client.NewClient(
flagAccessAPIAddress,
client.WithGRPCDialOptions(
grpc.WithTransportCredentials(insecure.NewCredentials()),
),
)
if err != nil {
log.Fatal().Err(err).Msgf("could not connect to access API at address %s", flagAccessAPIAddress)
}
// retrieve the on-chain machine account info
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
onChainAccount, err := flowClient.GetAccount(ctx, sdk.HexToAddress(machineAccountInfo.Address))
if err != nil {
log.Fatal().Err(err).Msg("could not read account")
}
// check the local machine account config with the on-chain account
// this will log non-critical warnings, and return an error for critical problems
err = epochs.CheckMachineAccountInfo(
log,
epochs.DefaultMachineAccountValidatorConfig(),
nodeInfoPriv.Role,
machineAccountInfo,
onChainAccount,
)
if err != nil {
log.Error().Err(err).Msg("⚠️ machine account is misconfigured")
return
}
log.Info().Msg("🤖 machine account is configured correctly")
}
// readMachineAccountInfo reads the machine account info from disk
func readMachineAccountInfo(nodeID string) model.NodeMachineAccountInfo {
var machineAccountInfo model.NodeMachineAccountInfo
path := filepath.Join(flagOutdir, fmt.Sprintf(model.PathNodeMachineAccountInfoPriv, nodeID))
err := common.ReadJSON(path, &machineAccountInfo)
if err != nil {
log.Fatal().Err(err).Msg("failed to read json")
}
return machineAccountInfo
}