From 9a026d0fc21b0f6ef1d9247cb47f17d29d1b4e5a Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Tue, 17 Oct 2023 13:27:39 -0700 Subject: [PATCH] add batch key create utility (#35) * add batch key utility * fmt * fix lint * add util to read the generated folder * fix golint error * addressed comments * add command descriptions * add go install * add better descriptions * update readme * update readme * moved the readutil to crypto util * move types too * lint * password without symbols for testing * keep 3 test files --- Makefile | 2 +- cmd/egnkey/README.md | 29 +++ cmd/egnkey/generate.go | 208 ++++++++++++++++++ cmd/egnkey/main.go | 25 +++ crypto/utils/batch_key.go | 97 ++++++++ crypto/utils/batch_key_test.go | 57 +++++ .../test_data/bls_keys/keys/1.bls.key.json | 1 + .../test_data/bls_keys/keys/2.bls.key.json | 1 + .../test_data/bls_keys/keys/3.bls.key.json | 1 + crypto/utils/test_data/bls_keys/password.txt | 3 + .../test_data/bls_keys/private_key_hex.txt | 3 + .../ecdsa_keys/keys/1.ecdsa.key.json | 1 + .../ecdsa_keys/keys/2.ecdsa.key.json | 1 + .../ecdsa_keys/keys/3.ecdsa.key.json | 1 + .../utils/test_data/ecdsa_keys/password.txt | 3 + .../test_data/ecdsa_keys/private_key_hex.txt | 3 + crypto/utils/types.go | 7 + go.mod | 6 +- 18 files changed, 447 insertions(+), 2 deletions(-) create mode 100644 cmd/egnkey/README.md create mode 100644 cmd/egnkey/generate.go create mode 100644 cmd/egnkey/main.go create mode 100644 crypto/utils/batch_key.go create mode 100644 crypto/utils/batch_key_test.go create mode 100644 crypto/utils/test_data/bls_keys/keys/1.bls.key.json create mode 100644 crypto/utils/test_data/bls_keys/keys/2.bls.key.json create mode 100644 crypto/utils/test_data/bls_keys/keys/3.bls.key.json create mode 100644 crypto/utils/test_data/bls_keys/password.txt create mode 100644 crypto/utils/test_data/bls_keys/private_key_hex.txt create mode 100644 crypto/utils/test_data/ecdsa_keys/keys/1.ecdsa.key.json create mode 100644 crypto/utils/test_data/ecdsa_keys/keys/2.ecdsa.key.json create mode 100644 crypto/utils/test_data/ecdsa_keys/keys/3.ecdsa.key.json create mode 100644 crypto/utils/test_data/ecdsa_keys/password.txt create mode 100644 crypto/utils/test_data/ecdsa_keys/private_key_hex.txt create mode 100644 crypto/utils/types.go diff --git a/Makefile b/Makefile index 77a8dae7..f3c0ef96 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ GO_LINES_IGNORED_DIRS=contracts GO_PACKAGES=./chainio/... ./crypto/... ./logging/... \ - ./types/... ./utils/... ./signer/... + ./types/... ./utils/... ./signer/... ./cmd/... GO_FOLDERS=$(shell echo ${GO_PACKAGES} | sed -e "s/\.\///g" | sed -e "s/\/\.\.\.//g") help: @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/cmd/egnkey/README.md b/cmd/egnkey/README.md new file mode 100644 index 00000000..3bf56fe6 --- /dev/null +++ b/cmd/egnkey/README.md @@ -0,0 +1,29 @@ +## egnkey +This tool is used to manage keys for AVS development purpose + +Features: +- [Generate ecdsa or bls key in batches](#generate-ecdsa-or-bls-key-in-batches) + +### How to install +#### Install from source +```bash + go install github.com/Layr-Labs/eigensdk-go/cmd/egnkey@latest +``` + +#### Build from source +Navigate to [egnkey](../egnkey/) directory and run +```bash + go install +``` + +### Generate ecdsa or bls key in batches + +To create in a random folder +```bash + egnkey generate --key-type ecdsa --num-keys +``` + +To create in specific folder +```bash + egnkey generate --key-type ecdsa --num-keys --output-dir +``` \ No newline at end of file diff --git a/cmd/egnkey/generate.go b/cmd/egnkey/generate.go new file mode 100644 index 00000000..654156ae --- /dev/null +++ b/cmd/egnkey/generate.go @@ -0,0 +1,208 @@ +package main + +import ( + "encoding/hex" + "fmt" + "math/rand" + "os" + "path/filepath" + "time" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + + "github.com/Layr-Labs/eigensdk-go/crypto/ecdsa" + "github.com/ethereum/go-ethereum/crypto" + "github.com/google/uuid" + "github.com/urfave/cli/v2" +) + +const ( + DefaultKeyFolder = "keys" + + PasswordFile = "password.txt" + PrivateKeyHexFile = "private_key_hex.txt" +) + +var ( + KeyTypeFlag = &cli.StringFlag{ + Name: "key-type", + Usage: "key type to create (ecdsa or bls)", + Required: true, + } + NumKeysFlag = &cli.IntFlag{ + Name: "num-keys", + Usage: "number of keys to create", + Required: true, + DefaultText: "1", + } + OutputDirFlag = &cli.StringFlag{ + Name: "output-dir", + Usage: "folder to store keys", + Required: false, + } +) + +var commandGenerate = &cli.Command{ + Name: "generate", + Aliases: []string{"g"}, + Description: `Generate keys for testing purpose. +This command creates ecdsa or bls key pair for testing purposes. It generates +all the relevant files for reading and keys and decrypted it and also gets +you the private keys in plaintext. + +It creates the following artifacts based on arguments +- passwords.txt - contains all passwords to decrypt keys +- private_key_hex.txt - will create plaintext private keys +- keys/* - create all the encrypted json files in this folder +`, + Action: generate, + Flags: []cli.Flag{ + KeyTypeFlag, + NumKeysFlag, + OutputDirFlag, + }, +} + +func generate(c *cli.Context) error { + keyType := c.String(KeyTypeFlag.Name) + if keyType != "ecdsa" && keyType != "bls" { + return cli.Exit("Invalid key type", 1) + } + numKeys := c.Int(NumKeysFlag.Name) + if numKeys < 1 { + return cli.Exit("Invalid number of keys", 1) + } + + folder := c.String(OutputDirFlag.Name) + if folder == "" { + id, err := uuid.NewUUID() + if err != nil { + return cli.Exit("Failed to generate UUID", 1) + } + folder = id.String() + } + + _, err := os.Stat(folder) + if !os.IsNotExist(err) { + return cli.Exit("Folder already exists, choose a different folder or delete the existing folder", 1) + } + + err = os.MkdirAll(folder+"/"+DefaultKeyFolder, 0755) + if err != nil { + return err + } + + passwordFile, err := os.Create(filepath.Clean(folder + "/" + PasswordFile)) + if err != nil { + return err + } + privateKeyFile, err := os.Create(filepath.Clean(folder + "/" + PrivateKeyHexFile)) + if err != nil { + return err + } + + if keyType == "ecdsa" { + err := generateECDSAKeys(numKeys, folder, passwordFile, privateKeyFile) + if err != nil { + return err + } + } else if keyType == "bls" { + err := generateBlsKeys(numKeys, folder, passwordFile, privateKeyFile) + if err != nil { + return err + } + } else { + return cli.Exit("Invalid key type", 1) + } + + return nil +} + +func generateBlsKeys(numKeys int, path string, passwordFile, privateKeyFile *os.File) error { + for i := 0; i < numKeys; i++ { + key, err := bls.GenRandomBlsKeys() + if err != nil { + return err + } + + password := generateRandomPassword() + if err != nil { + return err + } + + privateKeyHex := key.PrivKey.String() + fileName := fmt.Sprintf("%d.bls.key.json", i+1) + err = key.SaveToFile(filepath.Clean(path+"/"+DefaultKeyFolder+"/"+fileName), password) + if err != nil { + return err + } + + _, err = passwordFile.WriteString(password + "\n") + if err != nil { + return err + } + + _, err = privateKeyFile.WriteString(privateKeyHex + "\n") + if err != nil { + return err + } + } + return nil +} + +func generateECDSAKeys(numKeys int, path string, passwordFile, privateKeyFile *os.File) error { + for i := 0; i < numKeys; i++ { + key, err := crypto.GenerateKey() + if err != nil { + return err + } + + password := generateRandomPassword() + if err != nil { + return err + } + + privateKeyHex := hex.EncodeToString(key.D.Bytes()) + fileName := fmt.Sprintf("%d.ecdsa.key.json", i+1) + err = ecdsa.WriteKey(filepath.Clean(path+"/"+DefaultKeyFolder+"/"+fileName), key, password) + if err != nil { + return err + } + + _, err = passwordFile.WriteString(password + "\n") + if err != nil { + return err + } + + _, err = privateKeyFile.WriteString("0x" + privateKeyHex + "\n") + if err != nil { + return err + } + } + return nil +} + +func generateRandomPassword() string { + // Seed the random number generator + random := rand.New(rand.NewSource(time.Now().UnixNano())) + + // Define character sets for the password + uppercaseLetters := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + lowercaseLetters := "abcdefghijklmnopqrstuvwxyz" + digits := "0123456789" + //specialSymbols := "!@#$%^&*()-_+=[]{}|;:,.<>?/\\" + + // Combine character sets into one + //allCharacters := uppercaseLetters + lowercaseLetters + digits + specialSymbols + allCharacters := uppercaseLetters + lowercaseLetters + digits + + // Length of the password you want + passwordLength := 20 + + // Generate the password + password := make([]byte, passwordLength) + for i := range password { + password[i] = allCharacters[random.Intn(len(allCharacters))] + } + return string(password) +} diff --git a/cmd/egnkey/main.go b/cmd/egnkey/main.go new file mode 100644 index 00000000..b9dd9da5 --- /dev/null +++ b/cmd/egnkey/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli/v2" +) + +func main() { + app := cli.NewApp() + app.Name = "egnkey" + app.Description = "Eigenlayer batch keys manager" + app.Commands = []*cli.Command{ + commandGenerate, + } + + app.Usage = "Used to manage batch keys for testing" + + if err := app.Run(os.Args); err != nil { + fmt.Println("Error: ", err) + os.Exit(1) + } + +} diff --git a/crypto/utils/batch_key.go b/crypto/utils/batch_key.go new file mode 100644 index 00000000..c8c8673d --- /dev/null +++ b/crypto/utils/batch_key.go @@ -0,0 +1,97 @@ +package utils + +import ( + "bufio" + "fmt" + "os" + "path/filepath" +) + +const ( + // TODO: move to a common constants file which + // can be used by utils and cmd + DefaultKeyFolder = "keys" + PasswordFile = "password.txt" + PrivateKeyHexFile = "private_key_hex.txt" +) + +// ReadBatchKeys reads the batch keys from the given folder +// and returns the list of BatchKey +// folder: folder where the keys are stored, relative to the current directory +func ReadBatchKeys(folder string, isECDSA bool) ([]BatchKey, error) { + var batchKey []BatchKey + absFolder, err := filepath.Abs(folder) + if err != nil { + return nil, err + } + + // read the private key file + privateKeyFile, err := os.Open(filepath.Clean(absFolder + "/" + PrivateKeyHexFile)) + if err != nil { + fmt.Println("Error opening the file:", err) + return nil, err + } + defer func(privateKeyFile *os.File) { + err := privateKeyFile.Close() + if err != nil { + _ = fmt.Errorf("error closing the file: %s", err) + return + } + }(privateKeyFile) + + // read the password file + passwordFile, err := os.Open(filepath.Clean(absFolder + "/" + PasswordFile)) + if err != nil { + fmt.Println("Error opening the file:", err) + return nil, err + } + defer func(passwordFile *os.File) { + err := passwordFile.Close() + if err != nil { + _ = fmt.Errorf("error closing the file: %s", err) + return + } + }(passwordFile) + + privateKeyScanner := bufio.NewScanner(privateKeyFile) + passwordScanner := bufio.NewScanner(passwordFile) + + // To create file names + fileCtr := 1 + keyType := "ecdsa" + if !isECDSA { + keyType = "bls" + } + for privateKeyScanner.Scan() && passwordScanner.Scan() { + privateKey := privateKeyScanner.Text() + password := passwordScanner.Text() + fileName := fmt.Sprintf("%d.%s.key.json", fileCtr, keyType) + filePath := fmt.Sprintf("%s/%s/%s", absFolder, DefaultKeyFolder, fileName) + // Since a last line with empty string is also read + // I need to break here + // TODO(madhur): remove empty string when it gets created + if privateKey == "" { + break + } + + bK := BatchKey{ + FilePath: filePath, + Password: password, + PrivateKey: privateKey, + } + batchKey = append(batchKey, bK) + fileCtr++ + } + + if err := privateKeyScanner.Err(); err != nil { + fmt.Println("Error reading privateKey file: ", err) + return nil, err + } + + if err := passwordScanner.Err(); err != nil { + fmt.Println("Error reading password file: ", err) + return nil, err + } + + return batchKey, nil +} diff --git a/crypto/utils/batch_key_test.go b/crypto/utils/batch_key_test.go new file mode 100644 index 00000000..82fce133 --- /dev/null +++ b/crypto/utils/batch_key_test.go @@ -0,0 +1,57 @@ +package utils + +import ( + "encoding/hex" + "fmt" + "testing" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/eigensdk-go/crypto/ecdsa" + "github.com/stretchr/testify/assert" +) + +func TestReadBatchKeys(t *testing.T) { + + var tests = []struct { + keyFolder string + isEcdsa bool + }{ + { + keyFolder: "test_data/bls_keys", + isEcdsa: false, + }, + { + keyFolder: "test_data/ecdsa_keys", + isEcdsa: true, + }, + } + + for _, test := range tests { + readKeys, err := ReadBatchKeys(test.keyFolder, test.isEcdsa) + if err != nil { + t.Errorf("Error reading batch keys: %s", err) + } + + if test.isEcdsa { + for _, key := range readKeys { + fmt.Printf("Valdiate ecdsa key: %s with password %s\n", key.FilePath, key.Password) + pk, err := ecdsa.ReadKey(key.FilePath, key.Password) + if err != nil { + assert.Fail(t, "Error reading ecdsa key") + break + } + assert.Equal(t, key.PrivateKey, "0x"+hex.EncodeToString(pk.D.Bytes())) + } + } else { + for _, key := range readKeys { + fmt.Printf("Valdiate bls key: %s with password %s\n", key.FilePath, key.Password) + pk, err := bls.ReadPrivateKeyFromFile(key.FilePath, key.Password) + if err != nil { + assert.Fail(t, "Error reading bls key") + break + } + assert.Equal(t, key.PrivateKey, pk.PrivKey.String()) + } + } + } +} diff --git a/crypto/utils/test_data/bls_keys/keys/1.bls.key.json b/crypto/utils/test_data/bls_keys/keys/1.bls.key.json new file mode 100644 index 00000000..72306d85 --- /dev/null +++ b/crypto/utils/test_data/bls_keys/keys/1.bls.key.json @@ -0,0 +1 @@ +{"pubKey":"E([19408553463882111916887171276012224475029133183214861480489485386352635269635,17418827901203159022109906145273000034647571131322064812191371351028964064220])","crypto":{"cipher":"aes-128-ctr","ciphertext":"f2e5a3df524234426297f84b80c3c69e008ca17960fa512845b250a5308a7a6c","cipherparams":{"iv":"64528130796bc7227f48b0b01030b4c2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"7ceca78a0011e3ab5dce8b4f562b0615f60d8642b841d751bc676fb7dc574938"},"mac":"f9e5050e1077e2558a66f82fad05259ebc9e81da6e5ef8025f34d8fbc7e6e8ac"}} \ No newline at end of file diff --git a/crypto/utils/test_data/bls_keys/keys/2.bls.key.json b/crypto/utils/test_data/bls_keys/keys/2.bls.key.json new file mode 100644 index 00000000..f061a9d5 --- /dev/null +++ b/crypto/utils/test_data/bls_keys/keys/2.bls.key.json @@ -0,0 +1 @@ +{"pubKey":"E([1611472477336575391907540595283981736749839435478357492584206660415845982634,17740534282163859696734712865013083642718796435843138137894885755851743300823])","crypto":{"cipher":"aes-128-ctr","ciphertext":"d6dd67cddc77447c63b3bba2a1ffb115af151a31c3a9811b40b7b3b965799402","cipherparams":{"iv":"bf935b67d026db7f0502a46b8e35bddd"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"85c1c9b32e1182b5d769cce7005b00f5c64eec2537636e8b2a3d125083bc8ef6"},"mac":"b398381ce566074af656237d71be1551254f8824221690b59dd9bcdbcb409055"}} \ No newline at end of file diff --git a/crypto/utils/test_data/bls_keys/keys/3.bls.key.json b/crypto/utils/test_data/bls_keys/keys/3.bls.key.json new file mode 100644 index 00000000..a71ecc03 --- /dev/null +++ b/crypto/utils/test_data/bls_keys/keys/3.bls.key.json @@ -0,0 +1 @@ +{"pubKey":"E([3336192159512049190945679273141887248666932624338963482128432381981287252980,15195175002875833468883745675063986308012687914999552116603423331534089122704])","crypto":{"cipher":"aes-128-ctr","ciphertext":"c7fc50d7cd8e324f8e27d4f14991dc821b6552496c5c0330506d239bd11f5fca","cipherparams":{"iv":"e9a0897abbd105b322ecaecee5acb344"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"1bb93fdaef6fe17cb50d1d7963f27efa025e09390b4718e56f51479b85937d78"},"mac":"4c28491d98ee0181d99277f011c2a396dbd29d8b6461fb3d802a0ba4317955ba"}} \ No newline at end of file diff --git a/crypto/utils/test_data/bls_keys/password.txt b/crypto/utils/test_data/bls_keys/password.txt new file mode 100644 index 00000000..17854791 --- /dev/null +++ b/crypto/utils/test_data/bls_keys/password.txt @@ -0,0 +1,3 @@ +fDUMDLmBROwlzzPXyIcy +2EVEUyHCrHZdfdo8lp29 +k1ZxvbBylq0lscHnrrJy diff --git a/crypto/utils/test_data/bls_keys/private_key_hex.txt b/crypto/utils/test_data/bls_keys/private_key_hex.txt new file mode 100644 index 00000000..11501e1d --- /dev/null +++ b/crypto/utils/test_data/bls_keys/private_key_hex.txt @@ -0,0 +1,3 @@ +2215338531151182997276243965065522514190247674553811942190946030173209230351 +5217984197168966461576865353015567761629607981429081178519583306084941850805 +16834990251706844646759019708813363710810183547292596296141001406129498851847 diff --git a/crypto/utils/test_data/ecdsa_keys/keys/1.ecdsa.key.json b/crypto/utils/test_data/ecdsa_keys/keys/1.ecdsa.key.json new file mode 100644 index 00000000..aa11e4c9 --- /dev/null +++ b/crypto/utils/test_data/ecdsa_keys/keys/1.ecdsa.key.json @@ -0,0 +1 @@ +{"address":"d5a0359da7b310917d7760385516b2426e86ab7f","crypto":{"cipher":"aes-128-ctr","ciphertext":"91a55f690a65c9b352a24783d1db851a7b2f826763ff979a877bb78ae63860eb","cipherparams":{"iv":"313c5db87ccef736f2844c218b0728c2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"64e28acc8270b64aa22fb6554a694657face2887ceb6cc209c607db11c4338d7"},"mac":"9087dd2b17322a7237505b368eac0462dd8c87637516cd80740fafe7d2f3ae5b"},"id":"96c2a806-cd73-4e95-8d65-e0933a3e7e1c","version":3} \ No newline at end of file diff --git a/crypto/utils/test_data/ecdsa_keys/keys/2.ecdsa.key.json b/crypto/utils/test_data/ecdsa_keys/keys/2.ecdsa.key.json new file mode 100644 index 00000000..aeedac52 --- /dev/null +++ b/crypto/utils/test_data/ecdsa_keys/keys/2.ecdsa.key.json @@ -0,0 +1 @@ +{"address":"9441540e8183d416f2dc1901ab2034600f17b65a","crypto":{"cipher":"aes-128-ctr","ciphertext":"f5eb7776cb577b05ac7762177e447f15c1adcfab57a39f757f3e4b92af6f661b","cipherparams":{"iv":"2b41e5cbb0bc3ca4c380071831f00ae4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e984d8a762013fd76e5a7c6df30de81a613899962a4c154f370259274b7e6b83"},"mac":"54b650442a628bdce4585d499f5bdf4e35c7cee81b90cdcbd89db4646f595aa2"},"id":"e8555893-d21a-48d7-98a6-06b7f07eba39","version":3} \ No newline at end of file diff --git a/crypto/utils/test_data/ecdsa_keys/keys/3.ecdsa.key.json b/crypto/utils/test_data/ecdsa_keys/keys/3.ecdsa.key.json new file mode 100644 index 00000000..96264e46 --- /dev/null +++ b/crypto/utils/test_data/ecdsa_keys/keys/3.ecdsa.key.json @@ -0,0 +1 @@ +{"address":"f270e0dd5a1cc34cda8fb991307604097e622002","crypto":{"cipher":"aes-128-ctr","ciphertext":"d382b45ad3a9b69fd5933a38d711996b5283bb0e6a71e6da09edeb6c4a23b069","cipherparams":{"iv":"cf764c9c72afcf5748131711f61c49d0"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"bbdbccf9058c71c63cd251a9d975454ecdbd5f7795329954867a607512492b0d"},"mac":"3c16f6528a7812c2da48ff2d251e4c830875f5fcff6694a81b908cabdb809a7c"},"id":"05b7b538-57c6-489c-bf34-fe25409e7bf4","version":3} \ No newline at end of file diff --git a/crypto/utils/test_data/ecdsa_keys/password.txt b/crypto/utils/test_data/ecdsa_keys/password.txt new file mode 100644 index 00000000..ecbaa84e --- /dev/null +++ b/crypto/utils/test_data/ecdsa_keys/password.txt @@ -0,0 +1,3 @@ +EnJuncq01CiVk9UbuBYl +isru1gvtykIavuk1Fg1Q +3bxTdXda0Kwvo8KC9GGT diff --git a/crypto/utils/test_data/ecdsa_keys/private_key_hex.txt b/crypto/utils/test_data/ecdsa_keys/private_key_hex.txt new file mode 100644 index 00000000..05491374 --- /dev/null +++ b/crypto/utils/test_data/ecdsa_keys/private_key_hex.txt @@ -0,0 +1,3 @@ +0xd1d51de8ce6bbaac0572e481268232898bfe46491766214c5738929dd557c552 +0x6374444d520f8ae51eee2683f4790644ee5f2d95ca4382fa78021e0460cb1663 +0xa2788f1c26c799b7e1ac32ababc0b598fc7e9c6fc3d319c461ae67ffb1ee57dd diff --git a/crypto/utils/types.go b/crypto/utils/types.go new file mode 100644 index 00000000..f61b2f24 --- /dev/null +++ b/crypto/utils/types.go @@ -0,0 +1,7 @@ +package utils + +type BatchKey struct { + PrivateKey string + FilePath string + Password string +} diff --git a/go.mod b/go.mod index c95a1f0f..4c294d38 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,10 @@ go 1.21 require ( github.com/consensys/gnark-crypto v0.12.0 github.com/ethereum/go-ethereum v1.12.2 + github.com/google/uuid v1.3.0 github.com/prometheus/client_golang v1.17.0 github.com/stretchr/testify v1.8.4 + github.com/urfave/cli/v2 v2.24.1 go.uber.org/mock v0.2.0 go.uber.org/zap v1.26.0 gopkg.in/yaml.v3 v3.0.1 @@ -19,6 +21,7 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/consensys/bavard v0.1.13 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect @@ -26,7 +29,6 @@ require ( github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/uuid v1.3.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/holiman/uint256 v1.2.3 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -35,9 +37,11 @@ require ( github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230810033253-352e893a4cad // indirect