diff --git a/cmd/chain.go b/cmd/chain.go new file mode 100644 index 0000000..e3a8c67 --- /dev/null +++ b/cmd/chain.go @@ -0,0 +1,32 @@ +// Copyright © 2020 Weald Technology Trading +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "github.com/spf13/cobra" +) + +// chainCmd represents the chain command +var chainCmd = &cobra.Command{ + Use: "chain", + Short: "Obtain information about an Ethereum 2 chain", + Long: "Obtain information about an Ethereum 2 chain", +} + +func init() { + RootCmd.AddCommand(chainCmd) +} + +func chainFlags(cmd *cobra.Command) { +} diff --git a/cmd/chaininfo.go b/cmd/chaininfo.go new file mode 100644 index 0000000..989049f --- /dev/null +++ b/cmd/chaininfo.go @@ -0,0 +1,68 @@ +// Copyright © 2020 Weald Technology Trading +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + "os" + "time" + + "github.com/spf13/cobra" + "github.com/wealdtech/ethdo/grpc" +) + +var chainInfoCmd = &cobra.Command{ + Use: "info", + Short: "Obtain information about a chain", + Long: `Obtain information about a chain. For example: + + ethdo chain info + +In quiet mode this will return 0 if the chain information can be obtained, otherwise 1.`, + Run: func(cmd *cobra.Command, args []string) { + err := connect() + errCheck(err, "Failed to obtain connection to Ethereum 2 beacon chain node") + config, err := grpc.FetchChainConfig(eth2GRPCConn) + errCheck(err, "Failed to obtain beacon chain configuration") + + genesisTime, err := grpc.FetchGenesis(eth2GRPCConn) + errCheck(err, "Failed to obtain genesis time") + + if quiet { + os.Exit(_exit_success) + } + + fmt.Printf("Genesis time:\t\t%s\n", genesisTime.Format(time.UnixDate)) + slot := timestampToSlot(genesisTime.Unix(), time.Now().Unix(), config["SecondsPerSlot"].(uint64)) + fmt.Printf("Current slot:\t\t%d\n", slot) + fmt.Printf("Current epoch:\t\t%d\n", slot/int64(config["SlotsPerEpoch"].(uint64))) + outputIf(verbose, fmt.Sprintf("Genesis timestamp:\t%v", genesisTime.Unix())) + outputIf(verbose, fmt.Sprintf("Seconds per slot:\t%v", config["SecondsPerSlot"].(uint64))) + outputIf(verbose, fmt.Sprintf("Slots per epoch:\t%v", config["SlotsPerEpoch"].(uint64))) + + os.Exit(_exit_success) + }, +} + +func init() { + chainCmd.AddCommand(chainInfoCmd) + chainFlags(chainInfoCmd) +} + +func timestampToSlot(genesis int64, timestamp int64, secondsPerSlot uint64) int64 { + if timestamp < genesis { + return 0 + } + return (timestamp - genesis) / int64(secondsPerSlot) +}