diff --git a/cmd/generateNodeKeys.go b/cmd/generateNodeKeys.go index 6538a1f1..eb5e881c 100644 --- a/cmd/generateNodeKeys.go +++ b/cmd/generateNodeKeys.go @@ -10,27 +10,50 @@ import ( "github.com/spf13/cobra" ) +func generateKeySet(numberOfKeys int) (privateKeys []*PrivateKeySet, publicKeys []*PublicKeySet, err error) { + for i := 1; i <= numberOfKeys; i++ { + blsKey, err := bls.NewSignKey() + if err != nil { + return nil, nil, err + } + ecdsa, err := crypto.GenerateKey() + if err != nil { + return nil, nil, err + } + + privateKeys = append(privateKeys, &PrivateKeySet{ + BlsHexPrivateKey: hexutil.Encode(blsKey.Bytes()), + EcdsaHexPrivateKey: hexutil.Encode(crypto.FromECDSA(ecdsa)), + }) + + publicKeys = append(publicKeys, &PublicKeySet{ + BlsHexPublicKey: hexutil.Encode(consensus.BlsKeyToPublicKey(blsKey.MustVerKey()).PublicKey), + EcdsaHexPublicKey: hexutil.Encode(consensus.EcdsaToPublicKey(&ecdsa.PublicKey).PublicKey), + }) + } + + return privateKeys, publicKeys, err +} + // generateNodeKeysCmd represents the generateNodeKeys command var generateNodeKeysCmd = &cobra.Command{ Use: "generate-node-keys", Short: "Generate a new set of node keys", Long: ``, Run: func(cmd *cobra.Command, args []string) { - blsKey, err := bls.NewSignKey() - if err != nil { - panic("error generating bls") - } - ecdsa, err := crypto.GenerateKey() + privateKeys, publicKeys, err := generateKeySet(1) + if err != nil { - panic("error generating ecdsa") + panic(err) } fmt.Printf( "bls: '%v'\nbls public: '%v'\necdsa: '%v'\necdsa public: '%v'\n", - hexutil.Encode(blsKey.Bytes()), - hexutil.Encode(consensus.BlsKeyToPublicKey(blsKey.MustVerKey()).PublicKey), - hexutil.Encode(crypto.FromECDSA(ecdsa)), - hexutil.Encode(consensus.EcdsaToPublicKey(&ecdsa.PublicKey).PublicKey)) + privateKeys[0].BlsHexPrivateKey, + publicKeys[0].BlsHexPublicKey, + privateKeys[0].EcdsaHexPrivateKey, + publicKeys[0].EcdsaHexPublicKey, + ) }, } diff --git a/cmd/root.go b/cmd/root.go index 4f42fd3a..42865249 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,6 +24,18 @@ import ( ) var cfgFile string +var bootstrapPublicKeysFile string +var bootstrapPublicKeys []*PublicKeySet + +type PublicKeySet struct { + BlsHexPublicKey string `json:"blsHexPublicKey,omitempty"` + EcdsaHexPublicKey string `json:"ecdsaHexPublicKey,omitempty"` +} + +type PrivateKeySet struct { + BlsHexPrivateKey string `json:"blsHexPrivateKey,omitempty"` + EcdsaHexPrivateKey string `json:"ecdsaHexPrivateKey,omitempty"` +} // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ @@ -35,6 +47,16 @@ examples and usage of using your application. For example: Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.`, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + if bootstrapPublicKeysFile != "" { + var err error + bootstrapPublicKeys, err = loadPublicKeyFile(bootstrapPublicKeysFile) + if err != nil { + panic("Error loading public keys file") + } + } + }, + // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, diff --git a/cmd/rpcserver.go b/cmd/rpcserver.go index 64d3cca5..f488db6e 100644 --- a/cmd/rpcserver.go +++ b/cmd/rpcserver.go @@ -15,6 +15,7 @@ var ( tls bool certFile string keyFile string + localNetworkNodeCount int ) func loadPrivateKeyFile(path string) ([]*PrivateKeySet, error) { @@ -54,7 +55,20 @@ var rpcServerCmd = &cobra.Command{ Use: "rpc-server", Short: "Launches a Tupelo RPC Server", Run: func(cmd *cobra.Command, args []string) { - privateKeys, _ := loadPrivateKeyFile(bootstrapPrivateKeysFile) + var privateKeys []*PrivateKeySet + + if localNetworkNodeCount > 0 { + var err error + var publicKeys []*PublicKeySet + privateKeys, publicKeys, err = generateKeySet(localNetworkNodeCount) + if err != nil { + panic("Can't generate node keys") + } + bootstrapPublicKeys = publicKeys + } else { + privateKeys, _ = loadPrivateKeyFile(bootstrapPrivateKeysFile) + } + signers := make([]*signer.GossipedSigner, len(privateKeys)) for i, keys := range privateKeys { signers[i] = setupGossipNode(keys.EcdsaHexPrivateKey, keys.BlsHexPrivateKey) @@ -74,6 +88,7 @@ func init() { rootCmd.AddCommand(rpcServerCmd) rpcServerCmd.Flags().StringVarP(&bootstrapPublicKeysFile, "bootstrap-keys", "k", "", "which public keys to bootstrap the notary groups with") rpcServerCmd.Flags().StringVarP(&bootstrapPrivateKeysFile, "bootstrap-private-keys", "s", "", "which private keys to bootstrap the notary groups with") + rpcServerCmd.Flags().IntVarP(&localNetworkNodeCount, "local-network", "l", 0, "Run local network with randomly generated keys, specifying number of nodes as argument. Mutually exlusive with bootstrap-*") rpcServerCmd.Flags().BoolVarP(&tls, "tls", "t", false, "Encrypt connections with TLS/SSL") rpcServerCmd.Flags().StringVarP(&certFile, "tls-cert", "C", "", "TLS certificate file") rpcServerCmd.Flags().StringVarP(&keyFile, "tls-key", "K", "", "TLS private key file") diff --git a/cmd/testnode.go b/cmd/testnode.go index 08ab4eee..e4f13e54 100644 --- a/cmd/testnode.go +++ b/cmd/testnode.go @@ -40,21 +40,10 @@ import ( ) var ( - BlsSignKeys []*bls.SignKey - EcdsaKeys []*ecdsa.PrivateKey - bootstrapPublicKeysFile string + BlsSignKeys []*bls.SignKey + EcdsaKeys []*ecdsa.PrivateKey ) -type PublicKeySet struct { - BlsHexPublicKey string `json:"blsHexPublicKey,omitempty"` - EcdsaHexPublicKey string `json:"ecdsaHexPublicKey,omitempty"` -} - -type PrivateKeySet struct { - BlsHexPrivateKey string `json:"blsHexPrivateKey,omitempty"` - EcdsaHexPrivateKey string `json:"ecdsaHexPrivateKey,omitempty"` -} - func expandHomePath(path string) (string, error) { currentUser, err := user.Current() if err != nil { @@ -100,14 +89,8 @@ func loadPublicKeyFile(path string) ([]*PublicKeySet, error) { return jsonLoadedKeys, nil } -func bootstrapMembers(path string) (members []*consensus.RemoteNode) { - jsonLoadedKeys, err := loadPublicKeyFile(path) - if err != nil { - fmt.Printf("Error loading key file: %v", err) - return nil - } - - for _, keySet := range jsonLoadedKeys { +func bootstrapMembers(keys []*PublicKeySet) (members []*consensus.RemoteNode) { + for _, keySet := range keys { blsPubKey := consensus.PublicKey{ PublicKey: hexutil.MustDecode(keySet.BlsHexPublicKey), Type: consensus.KeyTypeBLSGroupSig, @@ -143,7 +126,7 @@ func setupNotaryGroup(storageAdapter storage.Storage) *consensus.NotaryGroup { nodeStore := nodestore.NewStorageBasedStore(storageAdapter) group := consensus.NewNotaryGroup("hardcodedprivatekeysareunsafe", nodeStore) if group.IsGenesis() { - testNetMembers := bootstrapMembers(bootstrapPublicKeysFile) + testNetMembers := bootstrapMembers(bootstrapPublicKeys) log.Debug("Creating gensis state", "nodes", len(testNetMembers)) group.CreateGenesisState(group.RoundAt(time.Now()), testNetMembers...) } diff --git a/cmd/workflowtest.go b/cmd/workflowtest.go index 2d775250..60988fd5 100644 --- a/cmd/workflowtest.go +++ b/cmd/workflowtest.go @@ -19,7 +19,7 @@ func smokeTestNetwork() (bool, string) { nodeStore := nodestore.NewStorageBasedStore(storage.NewMemStorage()) group := consensus.NewNotaryGroup("hardcodedprivatekeysareunsafe", nodeStore) if group.IsGenesis() { - testNetMembers := bootstrapMembers(bootstrapPublicKeysFile) + testNetMembers := bootstrapMembers(bootstrapPublicKeys) group.CreateGenesisState(group.RoundAt(time.Now()), testNetMembers...) }