mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-25 08:05:17 +00:00
173 lines
3.8 KiB
Go
173 lines
3.8 KiB
Go
package cmd
|
||
|
||
import (
|
||
"bytes"
|
||
"crypto/tls"
|
||
"encoding/hex"
|
||
"fmt"
|
||
"os"
|
||
"strings"
|
||
|
||
"github.com/cloudflare/circl/sign/ed448"
|
||
"github.com/multiformats/go-multiaddr"
|
||
mn "github.com/multiformats/go-multiaddr/net"
|
||
"github.com/spf13/cobra"
|
||
"golang.org/x/crypto/sha3"
|
||
"google.golang.org/grpc"
|
||
"google.golang.org/grpc/credentials"
|
||
"google.golang.org/grpc/credentials/insecure"
|
||
"source.quilibrium.com/quilibrium/monorepo/node/config"
|
||
)
|
||
|
||
var configDirectory string
|
||
var signatureCheck bool = true
|
||
var NodeConfig *config.Config
|
||
var simulateFail bool
|
||
var LightNode bool = false
|
||
var DryRun bool = false
|
||
|
||
var rootCmd = &cobra.Command{
|
||
Use: "qclient",
|
||
Short: "Quilibrium RPC Client",
|
||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||
if signatureCheck {
|
||
ex, err := os.Executable()
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
b, err := os.ReadFile(ex)
|
||
if err != nil {
|
||
fmt.Println(
|
||
"Error encountered during signature check – are you running this " +
|
||
"from source? (use --signature-check=false)",
|
||
)
|
||
panic(err)
|
||
}
|
||
|
||
checksum := sha3.Sum256(b)
|
||
digest, err := os.ReadFile(ex + ".dgst")
|
||
if err != nil {
|
||
fmt.Println("Digest file not found")
|
||
os.Exit(1)
|
||
}
|
||
|
||
parts := strings.Split(string(digest), " ")
|
||
if len(parts) != 2 {
|
||
fmt.Println("Invalid digest file format")
|
||
os.Exit(1)
|
||
}
|
||
|
||
digestBytes, err := hex.DecodeString(parts[1][:64])
|
||
if err != nil {
|
||
fmt.Println("Invalid digest file format")
|
||
os.Exit(1)
|
||
}
|
||
|
||
if !bytes.Equal(checksum[:], digestBytes) {
|
||
fmt.Println("Invalid digest for node")
|
||
os.Exit(1)
|
||
}
|
||
|
||
count := 0
|
||
|
||
for i := 1; i <= len(config.Signatories); i++ {
|
||
signatureFile := fmt.Sprintf(ex+".dgst.sig.%d", i)
|
||
sig, err := os.ReadFile(signatureFile)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
|
||
pubkey, _ := hex.DecodeString(config.Signatories[i-1])
|
||
if !ed448.Verify(pubkey, digest, sig, "") {
|
||
fmt.Printf("Failed signature check for signatory #%d\n", i)
|
||
os.Exit(1)
|
||
}
|
||
count++
|
||
}
|
||
|
||
if count < len(config.Signatories)/2+len(config.Signatories)%2 {
|
||
fmt.Printf("Quorum on signatures not met")
|
||
os.Exit(1)
|
||
}
|
||
|
||
fmt.Println("Signature check passed")
|
||
} else {
|
||
fmt.Println("Signature check bypassed, be sure you know what you're doing")
|
||
}
|
||
|
||
_, err := os.Stat(configDirectory)
|
||
if os.IsNotExist(err) {
|
||
fmt.Printf("config directory doesn't exist: %s\n", configDirectory)
|
||
os.Exit(1)
|
||
}
|
||
|
||
NodeConfig, err = config.LoadConfig(configDirectory, "", false)
|
||
if err != nil {
|
||
fmt.Printf("invalid config directory: %s\n", configDirectory)
|
||
os.Exit(1)
|
||
}
|
||
|
||
if NodeConfig.ListenGRPCMultiaddr == "" {
|
||
fmt.Println("gRPC not enabled, using light node")
|
||
LightNode = true
|
||
}
|
||
},
|
||
}
|
||
|
||
func Execute() {
|
||
err := rootCmd.Execute()
|
||
if err != nil {
|
||
os.Exit(1)
|
||
}
|
||
}
|
||
|
||
func GetGRPCClient() (*grpc.ClientConn, error) {
|
||
addr := "rpc.quilibrium.com:8337"
|
||
credentials := credentials.NewTLS(&tls.Config{InsecureSkipVerify: false})
|
||
if !LightNode {
|
||
ma, err := multiaddr.NewMultiaddr(NodeConfig.ListenGRPCMultiaddr)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
_, addr, err = mn.DialArgs(ma)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
credentials = insecure.NewCredentials()
|
||
}
|
||
|
||
return grpc.Dial(
|
||
addr,
|
||
grpc.WithTransportCredentials(
|
||
credentials,
|
||
),
|
||
grpc.WithDefaultCallOptions(
|
||
grpc.MaxCallSendMsgSize(600*1024*1024),
|
||
grpc.MaxCallRecvMsgSize(600*1024*1024),
|
||
),
|
||
)
|
||
}
|
||
|
||
func init() {
|
||
rootCmd.PersistentFlags().StringVar(
|
||
&configDirectory,
|
||
"config",
|
||
".config/",
|
||
"config directory (default is .config/)",
|
||
)
|
||
rootCmd.PersistentFlags().BoolVar(
|
||
&DryRun,
|
||
"dry-run",
|
||
false,
|
||
"runs the command (if applicable) without actually mutating state (printing effect output)",
|
||
)
|
||
rootCmd.PersistentFlags().BoolVar(
|
||
&signatureCheck,
|
||
"signature-check",
|
||
true,
|
||
"bypass signature check (not recommended for binaries)",
|
||
)
|
||
}
|