$ make build
$ make full-test
$ make lint-prepare
$ make lint
$ ./bin/ssvnode version
We split an eth2 BLS validator key into shares via Shamir-Secret-Sharing(SSS) to be used between the SSV nodes.
# Extract Private keys from mnemonic (optional, skip if you have the public/private keys )
$ ./bin/ssvnode export-keys --mnemonic="<mnemonic>" --index={keyIndex}
# Generate threshold keys
$ ./bin/ssvnode create-threshold --count <number of ssv nodes> --private-key <privateKey>
To generate an operator key, you can use ./bin/ssvnode generate-operator-keys
. This command can generate the key in three distinct ways:
- Raw format
- Encrypted format as keystore.json
- Convert an existing key to encrypted keystore.json format
IMPORTANT: The raw format is NOT recommended for production use, as it can expose sensitive data. Use the encrypted format for added security.
Option 1: Raw Operator Key Generation: This is the default mode of operation and does not require any additional parameters.
$ ./bin/ssvnode generate-operator-keys
This will generate an operator key in raw format.
Option 2: Encrypted Operator Key Generation as keystore.json:
To generate an operator key in encrypted format, use the --password-file
option followed by your password file.
$ ./bin/ssvnode generate-operator-keys --password-file=path/to/your/file
Please replace path/to/your/file
with your password file. This will generate an operator key in encrypted format.
Option 3: Convert an Existing Key to keystore.json:
To convert an existing key to keystore.json format, use both the --password-file
and --operator-key-file
options.
$ ./bin/ssvnode generate-operator-keys --password-file=path/to/your/password/file --operator-key-file=path/to/your/existing/key/file
Please replace path/to/your/password/file
with your password file and path/to/your/existing/key/file
with your existing key file. This will convert the existing key to a keystore.json file as an encrypted private key.
Keep your password safe as it will be required to decrypt the operator key for use.
Config files are located in ./config
directory:
Specifies general configuration regards the current node.
Example yaml - config.yaml
The operator private key can be provided in the config.yaml
file in two different ways:
-
As a base64-encoded private key:
OperatorPrivateKey: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBbCtQT05ocUxpMDRtMUVpMlVjV0NEbzVaRE5SNzVaamF3cTZ1elFnTkFwb0E5aUxNClJ0ZzU2SHF3d0x3NnpIYWVVZmRHMlRNQm5sL0YwQW54MWFtd2RUcGRLcEIvbDNjRnpHWXl2Z3FZaVFpaDYxalYKNU1IV1JqTG9NWjFiQUJLWmJ5OGZaYnYvRi9oQVVNditRZ3EyMWw2SDVMeUF1UEhqSDhoczJGS0RDWUxWelRhdgpXWGYremRQdGZMdExoSURTd3lvYnQrS0pJTHlabjR1Mzl0M1E2WFFSSjNWNHBXOVNHNGw4TUJVMmVSRDgvV3lRCmVrb3dQUm1CSUw0dVhQU01oR3EzQUhTdWxVYnFYZ1R4TFBnTWxUYkNvWXFvU00wYXIvME9XOWpPV3AvSGllMW4KSTRFTC9VRXhpV2dhV0kwTENYTTZ6Z0NLdzI4cE1SNDgzTnBmQVFJREFRQUJBb0lCQUZkWUdnSkUyNUFkUGZqLwpZMUM4cW1DaWZSVUNyOGpGVUs5NWNtM1hQbHdMb1pmcFJOMU1oR2hxL1crb0RvdjdmbW1XTURqQXV5S080cHNTCnpPM1lhZS9Qd3pteDVKMStSV2hZTUwvV0tnZExYb21QQ1ZsR0dtazk1d1o0L1phYUczK3pjbk8zV3ljMmpBMnEKY1NrYkxpOHlKeVZqUFFhZG1zVnhKUjUwdklQZnhUWmYxQkVSbjBUa2sybmhkWlZkWmxFS3VWN3NLY2FTRkFtWAp2eElKazFjUzZWN2xFTk1iazlITXpwbjkxYm1vK3JITEd0R1dsZHN6dXRTTHcxNXE3N3ZyZm0xZ29rdE9YUlFqCmNCU3RIZGVkdEJYUE1EYnMyS3V1WFVYR3JZeWtKZUkwb1hLNjIzU0JRcmlSa0wxQ2cydCtZdEVWd1RhWWtOakgKcmZYTWlFRUNnWUVBeFpCY1NSYzQ0amhFLzV6VDBZVERuangyVEV4c2pHL3VvY2ZPRWRSUHVKTEJuL3VTNXRhNAoxTlZMcDBSTnFGYlNxNHppbHByS1F1ZU1US0VoSlJjMWxwZ2M1MzhyT2srYkZXM1lJUlJweldzWHQxNnNOdXdLCnRlSGFNTUNrbkxpRTNWMEgva1BXOGlkZkVoRkJTTkhFWXEzZHdzMGpDL0c5SzRSWk9WRTVrUWtDZ1lFQXhORDcKdU00MUZVeUF2S29lcHJsVE9lY3YyMy93QWhESDZ4MkMxUnZPTUhaV0Rwdjd5VXZ2YlZLRXhkNmE5bUxkZ3ZsbApEWlo3TWorZTFzVUlJQXdsMUdVU1MrcDVFUzNtRll3K0pZY3lBUDN1TVRkQ0Y4cXpScGdWOEhTUFhWS0NYWXh1CjZ5UzN5WUljRlpTSHJNQmlqcTVTUjNWNUpMZVYxTytubHRnSmREa0NnWUVBd3oxYzFpYUs0cFQxS3g3Uy9aV1UKdEVYUUtxckVBeTJDeUlKcWxaZ1ppTEFQaFlqYXJpRzQyeXhHN1hCRXhuMjNDQzNjcHpVbGVXVFdjOHd3c3pUeQprbmFVNmZuMHdGVjNUNEFVUE95dGVvSEJHRWdKTE9XcjEvN3czNGtocEhkOVpqM1A3bWtnZklLSUk1VEZ6YTd2Cnd3MUx3SDExaXhKRS9rSjI0bnZ3eGZFQ2dZQUw0N0FCSnZ2UDhKSXFVNENNZzgrQ1JQUUFKNGRoS0pCYkpLbzkKbzNOZVBCZlF4QjErdUlhYkxRdjJSQTlLYVFpR20vZzl6T1JlVWJlUHM5RmMxajhHeUtCRlU4SENodXBLVFBHSQpKTldoZDdXRzVaYXBoMFl6TW9iSXd0SFNTbVN6c0FNWFUxMkMzOGhBaVh0MHRSNS9EZ3JNWkUxUUtZTDBuUkdiCnJDdE9DUUtCZ0FJL0dtd2tUcHlVNHBNWEFsRWU0UXFuZjVoS09vMXp3NHJXTTBQaGFXRnRlZzJ1aUR2ODNHYXMKbUxOMkx0NGcyb0dYZDM5RGFZazFsdG5taU1ScUJBTG5JdUhSMjFiR1pMQ3RCWUtUMllNRDRBUlRyd0I4bzJiSQpMQlFwN3FLRC9BVzZhbkVYT1hLbE9zT01vZG5QZjUyS3o2STZMMXpyVmhlVWlXc2NBancxCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
This private key can be generated using the CLI command
./bin/ssvnode generate-operator-keys
. However, this method merely encodes the private key, it doesn't provide additional encryption. For a more secure approach, it's recommended to use an encrypted keystore file with a password. -
As an Encrypted Keystore file:
KeyStore: PrivateKeyFile: /path/to/your/file PasswordFile: /path/to/your/file
In this approach, the private key is not only encoded but also encrypted, adding an extra layer of security. To generate the encrypted keystore file, run the
./bin/ssvnode generate-operator-keys
command with the--password-file=path/to/your/file
flag. Replacepath/to/your/file
with password file path. This command will generate an encrypted keystore file that can be used securely in theconfig.yaml
file. It's a more secure approach because the private key is not only encoded but also encrypted, adding an extra layer of security.
This section details the steps to run a local network of operator nodes.
In order to run a local environment, install the following:
- git
- go (1.20)
- docker
- make
- yq
$ git clone https://github.com/bloxapp/ssv.git
$ make build
By using this script, developers can simulate a real SSV environment, run multiple nodes, and start those nodes performing duties with the passed validator's keystore. This is incredibly beneficial for debugging, testing functionalities, or preparing for deployment in a live setting. It provides a realistic but controlled environment where developers can observe the interaction of multiple nodes in the SSV network.
The script simplifies configuration by automatically generating YAML files for each operator and an 'events.yaml' file. The 'events.yaml' emulates a 'happy flow' scenario, which includes the registration of four operators and one validator
-
Download the latest executable version (v1.0.0 or later) from ssv-keys.
- After downloading, follow these steps to provide the necessary permissions to the executable.
-
Generate a local configuration using the provided script.
- Execute the script by typing the following command in your terminal:
./generate_local_config.sh $OP_SIZE $KS_PATH $KS_PASSWORD $OA $NONCE $SSV_KEYS_PATH
- Please replace each variable with the following details:
OP_SIZE
: Number of operators to create [3f+1]. (e.g., 4 or 7 or 10, etc.)KS_PATH
: Path to your keystore.json file (e.g., ./keystore-m_12381_3600_0_0_0-1639058279.json).KS_PASSWORD
: Your keystore password (e.g., 12345678).OA
: Owner address (e.g., 0x1234567890123456789012345678901234567890).NONCE
: Nonce (e.g., 0).SSV_KEYS_PATH
: Path to ssv-keys executable [optional]. The default path is ./bin/ssv-keys-mac.
- Execute the script by typing the following command in your terminal:
-
Move the generated .yaml files to the
./config
directory. -
Update the config.yaml file to include the local events path:
LocalEventsPath: ./config/events.yaml
-
Add "mdns" under the p2p configuration in the config.yaml file:
p2p: Discovery: mdns
-
To enable debugging for all components, add the debug services line in the config.yaml file:
global: DebugServices: ssv/.*
-
Finally, build and run 4 local nodes with this command:
docker-compose up --build ssv-node-1 ssv-node-2 ssv-node-3 ssv-node-4
These steps offer a detailed manual alternative to the script. They provide a step-by-step guide for setting up a local SSV environment, generating the necessary keys, creating and configuring YAML files, and building and running multiple SSV nodes. They are beneficial for those who prefer more control over the setup process or need to understand it in greater detail.
-
Generate 4 operator keys. You can refer to the Generating an Operator Key section for guidance.
-
Create 4 .yaml files (
share1.yaml
,share2.yaml
,share3.yaml
,share4.yaml
) with the corresponding configurations, based on the provided template file.- Save these files in the
./config
directory.
- Save these files in the
-
Populate the
OperatorPrivateKey
field in theshare[1..4].yaml
files with the operator private keys that you generated in step 1. -
Generate share keys using the 4 operator public keys generated in step 1. You can do this using ssv-keys.
-
Create an
events.yaml
file based on the provided template file. Follow the validator registration happy flow example for proper configuration.- Populate the operator registration events with the data generated in step 4.
- Populate the validator registration event with the data generated in step 4.
-
Place the
events.yaml
file in the./config
directory (./config/events.yaml
). -
Add the local events path to the config.yaml file:
LocalEventsPath: ./config/events.yaml
-
If you want to debug all components, add debug services to the config.yaml file:
global: DebugServices: ssv/.*
-
Add the discovery "mdns" under the p2p section in the config.yaml file:
p2p: Discovery: mdns
-
Finally, build and run 4 local nodes with the following command:
docker-compose up --build ssv-node-1 ssv-node-2 ssv-node-3 ssv-node-4
Run a local network using docker
$ make docker-all
$ make docker-debug
In order to spin up local prometheus and grafana use:
$ make docker-monitor
For a grafana dashboard, use the SSV Operator dashboard as explained in monitoring/README.md#grafana
Please make sure your contributions adhere to our coding guidelines:
- Code must adhere to the official Go formatting guidelines (i.e. uses gofmt).
- Code must be documented adhering to the official Go commentary guidelines.
- Pull requests need to be based on and opened against the
stage
branch, and its commits should be squashed on merge.