From 9901e516ebc0bd4d4a4248ac0ff322de919fa3ea Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Mon, 16 Oct 2023 22:38:17 -0700 Subject: [PATCH 1/4] add keys relative to home folder --- cli/operator/keys/create.go | 41 +++++++++++++++++++------------- cli/operator/keys/create_test.go | 12 +++++++--- cli/operator/keys/import_test.go | 14 +++++++---- cli/operator/keys/list.go | 20 ++++++++++------ 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/cli/operator/keys/create.go b/cli/operator/keys/create.go index 8a29b6dc..df32f6fa 100644 --- a/cli/operator/keys/create.go +++ b/cli/operator/keys/create.go @@ -22,7 +22,7 @@ import ( ) const ( - OperatorKeyFolder = "operator_keys" + OperatorKeyFolder = ".eigenlayer/operator_keys" KeyTypeECDSA = "ecdsa" KeyTypeBLS = "bls" @@ -116,9 +116,13 @@ This command will create keys in ./operator_keys/ location func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insecure bool) error { // TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109 - basePath, _ := os.Getwd() + homePath, err := os.UserHomeDir() + if err != nil { + return err + } keyFileName := keyName + ".bls.key.json" - if checkIfKeyExists(keyFileName) { + fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeyFolder, keyFileName)) + if checkIfKeyExists(fileLoc) { return errors.New("key name already exists. Please choose a different name") } password, err := p.InputHiddenString("Enter password to encrypt the bls private key:", "", @@ -133,7 +137,7 @@ func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insec return err } - err = keyPair.SaveToFile(OperatorKeyFolder+"/"+keyFileName, password) + err = keyPair.SaveToFile(fileLoc, password) if err != nil { return err } @@ -142,15 +146,19 @@ func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insec fmt.Println("Please backup the above private key in safe place.") fmt.Println() fmt.Println("BLS Pub key: " + keyPair.PubKey.String()) - fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + keyFileName) + fmt.Println("Key location: " + fileLoc) return nil } func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.PrivateKey, insecure bool) error { // TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109 - basePath, _ := os.Getwd() + homePath, err := os.UserHomeDir() + if err != nil { + return err + } keyFileName := keyName + ".ecdsa.key.json" - if checkIfKeyExists(keyFileName) { + fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeyFolder, keyFileName)) + if checkIfKeyExists(fileLoc) { return errors.New("key name already exists. Please choose a different name") } @@ -166,7 +174,7 @@ func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.Private return err } - err = WriteEncryptedECDSAPrivateKeyToPath(keyFileName, privateKey, password) + err = WriteEncryptedECDSAPrivateKeyToPath(fileLoc, privateKey, password) if err != nil { return err } @@ -176,7 +184,7 @@ func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.Private fmt.Println("ECDSA Private Key (Hex): ", privateKeyHex) fmt.Println("Please backup the above private key hex in safe place.") fmt.Println() - fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + keyFileName) + fmt.Println("Key location: " + fileLoc) publicKey := privateKey.Public() publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) if !ok { @@ -189,7 +197,7 @@ func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.Private return nil } -func WriteEncryptedECDSAPrivateKeyToPath(keyName string, privateKey *ecdsa.PrivateKey, password string) error { +func WriteEncryptedECDSAPrivateKeyToPath(fileLoc string, privateKey *ecdsa.PrivateKey, password string) error { UUID, err := uuid.NewRandom() if err != nil { return err @@ -205,15 +213,16 @@ func WriteEncryptedECDSAPrivateKeyToPath(keyName string, privateKey *ecdsa.Priva return err } - return writeBytesToFile(keyName, encryptedBytes) + return writeBytesToFile(fileLoc, encryptedBytes) } -func writeBytesToFile(keyName string, data []byte) error { - err := os.Mkdir(OperatorKeyFolder, 0o755) +func writeBytesToFile(fileLoc string, data []byte) error { + filepath.Dir(fileLoc) + err := os.Mkdir(filepath.Dir(fileLoc), 0o755) if err != nil && !os.IsExist(err) { return err } - file, err := os.Create(filepath.Clean(OperatorKeyFolder + "/" + keyName)) + file, err := os.Create(fileLoc) if err != nil { fmt.Println("file create error") return err @@ -233,8 +242,8 @@ func writeBytesToFile(keyName string, data []byte) error { return err } -func checkIfKeyExists(keyName string) bool { - _, err := os.Stat(OperatorKeyFolder + "/" + keyName) +func checkIfKeyExists(fileLoc string) bool { + _, err := os.Stat(fileLoc) return !os.IsNotExist(err) } diff --git a/cli/operator/keys/create_test.go b/cli/operator/keys/create_test.go index 04f719dc..bbe0871a 100644 --- a/cli/operator/keys/create_test.go +++ b/cli/operator/keys/create_test.go @@ -3,6 +3,7 @@ package keys import ( "fmt" "os" + "path/filepath" "testing" prompterMock "github.com/NethermindEth/eigenlayer/cli/prompter/mocks" @@ -11,6 +12,11 @@ import ( ) func TestCreateCmd(t *testing.T) { + homePath, err := os.UserHomeDir() + if err != nil { + t.Fatal(err) + } + tests := []struct { name string args []string @@ -66,7 +72,7 @@ func TestCreateCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: OperatorKeyFolder + "/test.ecdsa.key.json", + keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.ecdsa.key.json"), }, { name: "valid bls key creation", @@ -75,13 +81,13 @@ func TestCreateCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: OperatorKeyFolder + "/test.bls.key.json", + keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.bls.key.json"), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Cleanup(func() { - _ = os.RemoveAll(OperatorKeyFolder) + _ = os.Remove(tt.keyPath) }) controller := gomock.NewController(t) p := prompterMock.NewMockPrompter(controller) diff --git a/cli/operator/keys/import_test.go b/cli/operator/keys/import_test.go index 73764146..679cfaa4 100644 --- a/cli/operator/keys/import_test.go +++ b/cli/operator/keys/import_test.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" "os" + "path/filepath" "strings" "testing" @@ -15,6 +16,11 @@ import ( ) func TestImportCmd(t *testing.T) { + homePath, err := os.UserHomeDir() + if err != nil { + t.Fatal(err) + } + tests := []struct { name string args []string @@ -86,7 +92,7 @@ func TestImportCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: OperatorKeyFolder + "/test.ecdsa.key.json", + keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.ecdsa.key.json"), }, { name: "valid ecdsa key import with 0x prefix", @@ -95,7 +101,7 @@ func TestImportCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: OperatorKeyFolder + "/test.ecdsa.key.json", + keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.ecdsa.key.json"), }, { name: "valid bls key import", @@ -104,13 +110,13 @@ func TestImportCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: OperatorKeyFolder + "/test.bls.key.json", + keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.bls.key.json"), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Cleanup(func() { - _ = os.RemoveAll(OperatorKeyFolder) + _ = os.Remove(tt.keyPath) }) controller := gomock.NewController(t) p := prompterMock.NewMockPrompter(controller) diff --git a/cli/operator/keys/list.go b/cli/operator/keys/list.go index a5b37ed3..4c71043f 100644 --- a/cli/operator/keys/list.go +++ b/cli/operator/keys/list.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "os" + "path/filepath" "strings" "github.com/NethermindEth/eigenlayer/cli/prompter" @@ -22,13 +23,16 @@ func ListCmd(p prompter.Prompter) *cobra.Command { It will only list keys created in the default folder (./operator_keys/) `, RunE: func(cmd *cobra.Command, args []string) error { - files, err := os.ReadDir(OperatorKeyFolder + "/") + homePath, err := os.UserHomeDir() + if err != nil { + return err + } + keyStorePath := filepath.Clean(filepath.Join(homePath, OperatorKeyFolder)) + files, err := os.ReadDir(keyStorePath) if err != nil { return err } - // TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109 - basePath, _ := os.Getwd() for _, file := range files { keySplits := strings.Split(file.Name(), ".") fileName := keySplits[0] @@ -37,22 +41,24 @@ func ListCmd(p prompter.Prompter) *cobra.Command { switch keyType { case KeyTypeECDSA: fmt.Println("Key Type: ECDSA") - address, err := GetAddress(OperatorKeyFolder + "/" + file.Name()) + keyFilePath := filepath.Join(keyStorePath, file.Name()) + address, err := GetAddress(filepath.Clean(keyFilePath)) if err != nil { return err } fmt.Println("Address: 0x" + address) - fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + file.Name()) + fmt.Println("Key location: " + keyFilePath) fmt.Println("====================================================================================") fmt.Println() case KeyTypeBLS: fmt.Println("Key Type: BLS") - pubKey, err := GetPubKey(OperatorKeyFolder + "/" + file.Name()) + keyFilePath := filepath.Join(keyStorePath, file.Name()) + pubKey, err := GetPubKey(filepath.Clean(keyFilePath)) if err != nil { return err } fmt.Println("Public Key: " + pubKey) - fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + file.Name()) + fmt.Println("Key location: " + keyFilePath) fmt.Println("====================================================================================") fmt.Println() } From 58665db1f5db679a98ec173c176d739564fef930 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Mon, 16 Oct 2023 22:41:13 -0700 Subject: [PATCH 2/4] some fixes --- cli/operator/keys/create.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cli/operator/keys/create.go b/cli/operator/keys/create.go index df32f6fa..bf3d3bc6 100644 --- a/cli/operator/keys/create.go +++ b/cli/operator/keys/create.go @@ -88,7 +88,6 @@ This command will create keys in ./operator_keys/ location }, RunE: func(cmd *cobra.Command, args []string) error { keyName := args[0] - switch keyType { case KeyTypeECDSA: privateKey, err := crypto.GenerateKey() @@ -115,7 +114,6 @@ This command will create keys in ./operator_keys/ location } func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insecure bool) error { - // TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109 homePath, err := os.UserHomeDir() if err != nil { return err @@ -151,7 +149,6 @@ func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insec } func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.PrivateKey, insecure bool) error { - // TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109 homePath, err := os.UserHomeDir() if err != nil { return err @@ -217,7 +214,6 @@ func WriteEncryptedECDSAPrivateKeyToPath(fileLoc string, privateKey *ecdsa.Priva } func writeBytesToFile(fileLoc string, data []byte) error { - filepath.Dir(fileLoc) err := os.Mkdir(filepath.Dir(fileLoc), 0o755) if err != nil && !os.IsExist(err) { return err From f4973f8d13c89059f7972804ee2fb1c179a436d3 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Mon, 16 Oct 2023 22:50:35 -0700 Subject: [PATCH 3/4] mkdirall --- cli/operator/keys/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/operator/keys/create.go b/cli/operator/keys/create.go index bf3d3bc6..5f419fb4 100644 --- a/cli/operator/keys/create.go +++ b/cli/operator/keys/create.go @@ -214,7 +214,7 @@ func WriteEncryptedECDSAPrivateKeyToPath(fileLoc string, privateKey *ecdsa.Priva } func writeBytesToFile(fileLoc string, data []byte) error { - err := os.Mkdir(filepath.Dir(fileLoc), 0o755) + err := os.MkdirAll(filepath.Dir(fileLoc), 0o755) if err != nil && !os.IsExist(err) { return err } From 6f5f4e325b0f3169dcc0d88e9ec09e47a601a0b7 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Tue, 17 Oct 2023 09:54:00 -0700 Subject: [PATCH 4/4] addressed comments --- CHANGELOG.md | 2 +- cli/operator/keys/create.go | 6 +++--- cli/operator/keys/create_test.go | 4 ++-- cli/operator/keys/import_test.go | 6 +++--- cli/operator/keys/list.go | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0932d8ad..9e5a0f74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Pull plugin image if does not exist locally ([#101](https://github.com/NethermindEth/eigenlayer/pull/101)) - +- Updated keystore folder relative to user's HOME directory ([#118](https://github.com/NethermindEth/eigenlayer/pull/118)) ## [v0.2.0] - 2023-10-10 ### Added diff --git a/cli/operator/keys/create.go b/cli/operator/keys/create.go index 5f419fb4..498e3593 100644 --- a/cli/operator/keys/create.go +++ b/cli/operator/keys/create.go @@ -22,7 +22,7 @@ import ( ) const ( - OperatorKeyFolder = ".eigenlayer/operator_keys" + OperatorKeystoreSubFolder = ".eigenlayer/operator_keys" KeyTypeECDSA = "ecdsa" KeyTypeBLS = "bls" @@ -119,7 +119,7 @@ func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insec return err } keyFileName := keyName + ".bls.key.json" - fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeyFolder, keyFileName)) + fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeystoreSubFolder, keyFileName)) if checkIfKeyExists(fileLoc) { return errors.New("key name already exists. Please choose a different name") } @@ -154,7 +154,7 @@ func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.Private return err } keyFileName := keyName + ".ecdsa.key.json" - fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeyFolder, keyFileName)) + fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeystoreSubFolder, keyFileName)) if checkIfKeyExists(fileLoc) { return errors.New("key name already exists. Please choose a different name") } diff --git a/cli/operator/keys/create_test.go b/cli/operator/keys/create_test.go index bbe0871a..76bf2e1a 100644 --- a/cli/operator/keys/create_test.go +++ b/cli/operator/keys/create_test.go @@ -72,7 +72,7 @@ func TestCreateCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.ecdsa.key.json"), + keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.ecdsa.key.json"), }, { name: "valid bls key creation", @@ -81,7 +81,7 @@ func TestCreateCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.bls.key.json"), + keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.bls.key.json"), }, } for _, tt := range tests { diff --git a/cli/operator/keys/import_test.go b/cli/operator/keys/import_test.go index 679cfaa4..d2d808c8 100644 --- a/cli/operator/keys/import_test.go +++ b/cli/operator/keys/import_test.go @@ -92,7 +92,7 @@ func TestImportCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.ecdsa.key.json"), + keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.ecdsa.key.json"), }, { name: "valid ecdsa key import with 0x prefix", @@ -101,7 +101,7 @@ func TestImportCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.ecdsa.key.json"), + keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.ecdsa.key.json"), }, { name: "valid bls key import", @@ -110,7 +110,7 @@ func TestImportCmd(t *testing.T) { promptMock: func(p *prompterMock.MockPrompter) { p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil) }, - keyPath: filepath.Clean(homePath + "/" + OperatorKeyFolder + "/test.bls.key.json"), + keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.bls.key.json"), }, } for _, tt := range tests { diff --git a/cli/operator/keys/list.go b/cli/operator/keys/list.go index 4c71043f..cd68471e 100644 --- a/cli/operator/keys/list.go +++ b/cli/operator/keys/list.go @@ -27,7 +27,7 @@ func ListCmd(p prompter.Prompter) *cobra.Command { if err != nil { return err } - keyStorePath := filepath.Clean(filepath.Join(homePath, OperatorKeyFolder)) + keyStorePath := filepath.Clean(filepath.Join(homePath, OperatorKeystoreSubFolder)) files, err := os.ReadDir(keyStorePath) if err != nil { return err