diff --git a/README.md b/README.md index 56f8f34..6643316 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CLI APP +# Lagrange CLI This CLI app provides the functionalities needed to run the a Lagrange Attestation Node. @@ -25,7 +25,9 @@ For a full breakdown of the architecture, please refer to the below two document ## Running a Lagrange Client Node -For the purpose of demonstrating how to run a Lagrange Attestation Node, we've created a Lagrange Holesky Network. The below commands will allow a developer to run a node and attest to the state of `Optimism` and `Base` chains. +The below commands will allow a developer to run a node and attest to the state of `Optimism` and `Base` chains. We are operating on two networks: + - Holesky Testnet + - Mainnet ### Chains @@ -46,32 +48,32 @@ For the purpose of demonstrating how to run a Lagrange Attestation Node, we've c 1. Golang -```bash -sudo apt-get update -sudo apt-get -y upgrade -wget https://go.dev/dl/go1.21.9.linux-amd64.tar.gz -sudo tar -xvf go1.21.9.linux-amd64.tar.gz -C /usr/local -echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.profile -export GOROOT=/usr/local/go -source ~/.profile -go version -``` + ```bash + sudo apt-get update + sudo apt-get -y upgrade + wget https://go.dev/dl/go1.21.9.linux-amd64.tar.gz + sudo tar -xvf go1.21.9.linux-amd64.tar.gz -C /usr/local + echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.profile + export GOROOT=/usr/local/go + source ~/.profile + go version + ``` 2. Docker and Docker Compose -```bash -sudo apt-get update -sudo install -m 0755 -d /etc/apt/keyrings -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg -sudo chmod a+r /etc/apt/keyrings/docker.gpg -echo "deb [arch=\"$(dpkg --print-architecture)\" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null -sudo apt-get update -sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin make gcc -echo '{ "log-opts": { "max-size": "10m", "max-file": "100" } }' | sudo tee /etc/docker/daemon.json -sudo usermod -aG docker $USER -newgrp docker -sudo systemctl restart docker -``` + ```bash + sudo apt-get update + sudo install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg + sudo chmod a+r /etc/apt/keyrings/docker.gpg + echo "deb [arch=\"$(dpkg --print-architecture)\" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + sudo apt-get update + sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin make gcc + echo '{ "log-opts": { "max-size": "10m", "max-file": "100" } }' | sudo tee /etc/docker/daemon.json + sudo usermod -aG docker $USER + newgrp docker + sudo systemctl restart docker + ``` ## Steps @@ -79,123 +81,144 @@ sudo systemctl restart docker 2. Clone the [Lagrange CLI repository](https://github.com/Lagrange-Labs/client-cli) to your machine. -```bash -git clone https://github.com/Lagrange-Labs/client-cli.git -``` + ```bash + git clone https://github.com/Lagrange-Labs/client-cli.git + ``` 3. Set environment variables and download dependencies. -```bash -export CGO_CFLAGS="-O -D__BLST_PORTABLE__" -export CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" -cd client-cli -go mod download -``` + ```bash + export CGO_CFLAGS="-O -D__BLST_PORTABLE__" + export CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" + cd client-cli + go mod download + ``` 4. Create a go binary. -```bash -sudo apt install make gcc + ```bash + sudo apt install make gcc -make build -``` + make build + ``` -5. Update `EthereumRPCURL` in `config_.toml` file. +5. Create a configuration file for the CLI. Please refer to `config.toml` for the configuration file. -- Mainnet: `EthereumRPCURL` is the RPC endpoint for ETH mainnet. -- Holesky: `EthereumRPCURL` is the RPC endpoint for ETH holesky. + - `EthereumRPCURL`: Ethereum mainnet RPC endpoint for mainnet, and Holesky RPC endpoint for testnet. + - `L1RPCEndpoint`: Ethereum mainnet RPC endpoint for both mainnet and Holesky testnet. + - `BeaconURL`: Beacon mainnet RPC endpoint for both mainnet and Holesky testnet. + - `L2RPCEndpoint`: Rollup (`Optimism` or `Base`) chain's mainnet RPC endpoint for both mainnet and Holesky testnet. -Currently, we only support the `BN254` curve for the `BLSScheme`. + > NOTE: Currently, we only support the `BN254` curve for the `BLSScheme`. -6. Run the following command to register your operator to Lagrange State Committees AVS. +### Commands -```bash -# Holesky Testnet -./dist/lagrange-cli run -c ./config_holesky.toml +- Generate Keystore: generates a new key pair for the given key type and password, and saves it in the keystore file. The key type can be either `ecdsa` or `bls`. + ```bash + lagrange-cli generate-keystore -t -p -# Mainnet -./dist/lagrange-cli run -c ./config_mainnet.toml -``` + # i.e. ./dist/lagrange-cli generate-keystore -t ecdsa -p password + ``` +- Import Keystore: imports a key pair from the given private key and saves it in the keystore file. The key type can be either `ecdsa` or `bls`. -- Enter `g` in the prompt to start the registration. + ```bash + lagrange-cli import-keystore -t -p -k -- Each Lagrange Attestation Node requires a BLS key pair to participate in the committee. Generate the BLS key pairs or insert your own keys in the prompt. + # i.e. ./dist/lagrange-cli import-keystore -t bls -p password -k 0x1234567890abcdef... + ``` +- Export Keystore: exports a private key from the keystore file for the given key type and password. -> NOTE: If you plan to run one node each for Optimism and Base, then you only need to generate one BLS key pair and use it for both of them. + ```bash + lagrange-cli export-keystore -t -p -f -- Prompt: "Do you want to add a new BLS Key Pair?" - Enter `y` if you want to add a BLS key pair -- Prompt: "Do you want to generate a new Key Pair?" - Enter `y` if you want the CLI to randomly generate a key pair or enter your own BLS private key. Please reach out to the Lagrange team if you get an error: `Failed to save BLS Key Pair` + # i.e. ./dist/lagrange-cli export-keystore -t ecdsa -p password -f ~/.lagrange/keystore/bls_.key + ``` -> NOTE: If you want to generate only one BLS key pair, press `n` when the CLI again prompts "Do you want to add a new BLS Key Pair?". +- Register Operator: registers an operator to the Lagrange State Committee. The network name can be either `mainnet` or `holesky`. The BLS key and Signer address are referenced from the config file. -- Please re-run this step to add more BLS key pairs if you want to run more nodes. + ```bash + lagrange-cli register-operator -c -n -- Each EigenLayer operator that participates into Lagrange State Committees AVS needs to generate one signer ECDSA private key. Please reach out to the Lagrange team if you get an error: `Failed to save ECDSA Key Pair` + # i.e. ./dist/lagrange-cli register-operator -c ./config.toml -n mainnet + ``` +- Deregsiter Operator: deregisters an operator from the Lagrange State Committee. The network name can be either `mainnet` or `holesky`. - > NOTE: This signer ECDSA key is only used to verify the identity and signature. It is not used in governance and/or asset flow. + ```bash + lagrange-cli deregister-operator -c -n - - Enter `y` in the prompt for CLI to randomly generate a signer private key if you haven't already created it before. + # i.e. ./dist/lagrange-cli deregister-operator -c ./config.toml -n mainnet + ``` -- Enter `y` to register to Lagrange State Committee if you haven't already registered. +- Update BLS Public Key: updates the BLS public key for the operator at the given index. The network name can be either `mainnet` or `holesky`. New BLS key is referenced from the config file. - - Enter ECDSA key of your EigenLayer operator to complete registration. + ```bash + lagrange-cli update-bls-pub-key -c -n -i -> NOTE: Please take a backup of your BLS and ECDSA key pairs. They are located at `~/.lagrange/keystore`. + # i.e. ./dist/lagrange-cli update-bls-pub-key -c ./config.toml -n mainnet -i 0 + ``` -7. Upon completion of the registration process, subscribe to the chain that you want to run the Lagrange Attestation Node. +- Update Signer Address: updates the signer address for the operator. The network name can be either `mainnet` or `holesky`. New signer address is referenced from the config file. -- Enter `s` in the prompt to start the subscription process. + ```bash + lagrange-cli update-signer-address -c -n -- Enter EigenLayer operator ECDSA key. + # i.e. ./dist/lagrange-cli update-signer-address -c ./config.toml -n mainnet + ``` -- Enter CHAIN_ID to subscribe to that chain ([Chain ids](#chains) like `10` or `8453`). +- Add BLS Public Key: adds a new BLS public key for the operator. The network name can be either `mainnet` or `holesky`. New BLS key is referenced from the config file. -> NOTE: Each Operator can be subscribed to multiple chains. + ```bash + lagrange-cli add-bls-pub-key -c -n -8. Generate config for your Lagrange Attestation Node which will be used to deploy the container. + # i.e. ./dist/lagrange-cli add-bls-pub-key -c ./config.toml -n mainnet + ``` -- Enter `c` in the prompt to start generating the config. +- Remove BLS Public Key: removes the BLS public key for the operator at the given index. The network name can be either `mainnet` or `holesky`. -- Enter the operator address. + ```bash + lagrange-cli remove-bls-pub-key -c -n -i -- Enter the chain name which you want to run the Lagrange Attestation Node ([Chain name](#chains) like `optimism` or `base`). + # i.e. ./dist/lagrange-cli remove-bls-pub-key -c ./config.toml -n mainnet -i 0 + ``` -- Enter L1 RPC endpoint, which will be ETH mainnet endpoint for both holesky and mainnet networks of State Committees AVS. +- Subscribe Chain: subscribes the operator to the given chain. The network name can be either `mainnet` or `holesky`. The chain name can be either `optimism` or `base`. -- Enter L2 RPC endpoint, which will be the rollup chain's mainnet endpoint for both holesky and mainnet networks of State Committees AVS. + ```bash + lagrange-cli subscribe-chain -c -n -r -- Enter the Beacon RPC endpoint, which is used to fetch blobs data. This is mainnet endpoint for both holesky and mainnet networks of State Committees AVS + # i.e. ./dist/lagrange-cli subscribe-chain -c ./config.toml -n mainnet -r optimism + ``` -- Enter gRPC URL. +- Unsubscribe Chain: unsubscribes the operator from the given chain. The network name can be either `mainnet` or `holesky`. The chain name can be either `optimism` or `base`. - - Mainnet - - Optimism: `34.202.191.166:9090` - - Base: `34.193.82.90:9090` - - Holesky Testnet - - Optimism: `44.210.11.64:9090` - - Base: `3.209.124.237:9090` + ```bash + lagrange-cli unsubscribe-chain -c -n -r -- Select and enter index of the key pair from the list of available BLS key pairs (registered in step #6). + # i.e. ./dist/lagrange-cli unsubscribe-chain -c ./config.toml -n mainnet -r optimism + ``` -> NOTE: We recommend using trusted providers like Alchemy, Quicknode, Infura if you don't run your own node. For the Beacon RPC endpoint, you should check if the given RPC provider supports the Beacon RPC API like `/eth/v1/beacon/genesis`. Quicknode supports this API. +- Generate Config: generates a client config file. The network name can be either `mainnet` or `holesky`. The chain name can be either `optimism` or `base`. The L1 RPC endpoint is the Ethereum mainnet RPC endpoint for both mainnet and Holesky testnet. The L2 (`Optimism` or `Base`) RPC endpoint is the rollup chain's mainnet RPC endpoint for both mainnet and Holesky testnet. The Beacon RPC endpoint is the Beacon mainnet RPC endpoint for both mainnet and Holesky testnet. -9. Deploy and run the Lagrange Attestation Node. + ```bash + lagrange-cli generate-config -c -n -r -- Enter `r` in the prompt. + # i.e. ./dist/lagrange-cli generate-config -c ./config.toml -n mainnet -r optimism + ``` -- Select index of the config file from the list of available configs to deploy the docker container. +- Deploy Node: creates a docker-compose file and deploys the docker container for the attestation node. The network name can be either `mainnet` or `holesky`. -10. Repeat `config` and `run` commands to deploy more attestation nodes. If you subscribe to `k` chains and you have `n` BLS key-pairs then there will be `n*k` containers running. + ```bash + lagrange-cli deploy -c -i -11. The operator can unsubscribe from chain/s. + # i.e. ./dist/lagrange-cli deploy -c ~/.lagrange/config/client_mainnet_optimism_.toml -i lagrangelabs/lagrange-node:v0.3.13 + ``` -- Enter `u` in the prompt. +> NOTE: Please take a backup of your BLS and ECDSA key pairs. They are located at `~/.lagrange/keystore/_.key`. -- Enter ECDSA key of your EigenLayer operator +> NOTE: We recommend using trusted providers like Alchemy, Quicknode, Infura if you don't run your own node. For the Beacon RPC endpoint, you should check if the given RPC provider supports the Beacon RPC API like `/eth/v1/beacon/genesis`. Quicknode supports this API. -- Enter CHAIN_ID to unsubscribe from the chain ([Chain ids](#chains)). - - Prompt: "Do you want to unsubscribe another chain?" - Enter `y` if you want to unsubscribe from more chain/s and enter CHAIN_ID again. +> NOTE: You can check client config files in the `~/.lagrange/config/client___.toml` and docker-compose files in the `~/.lagrange/docker-compose___.yml`. ### Post-Deployment @@ -216,10 +239,6 @@ cd $HOME/.lagrange && docker compose -f down --remove-orph ``` -> NOTE: If you are seeing this error message `time= level=error msg=failed to join the network: failed to join the network: pc error: code = Unknown desc = the operator is not a committee member`, please check if you are using a correct BLS key pair that you created in the `register` step because the node won't be able to join the committee with incorrect BLS keys. If you are using correct BLS keys then it means that the given attestation node setup is successful and it will start attesting from the next epoch. The current epoch period of the state committee rotation is 24 hours for Holesky testnet. - -> NOTE: You can check docker-compose files in the `~/.lagrange` directory and client configs in the `~/.lagrange/config` directory. The files are named as `docker-compose--.yml` and `client__.toml` respectively. - - If you experience the rpc provider issue, it can be due to the rate limit of the provider. You can control the `ConcurrentFetchers` in the `config.toml` file to manage the rate limit. - If you face any issues while running the Lagrange Attestation Node, please reach out to the Lagrange Labs team on Telegram. diff --git a/cmd/main.go b/cmd/main.go index 27dd675..4e77593 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -22,7 +22,6 @@ const ( flagKeyPath = "key-path" flagNetwork = "network" flagChain = "chain" - flagRollupRPC = "rollup-rpc" flagDockerImage = "docker-image" flagKeyIndex = "key-index" ) @@ -70,12 +69,6 @@ var ( Usage: "Chain `NAME` (optimism/base)", Aliases: []string{"r"}, } - rollupRPCFlag = &cli.StringFlag{ - Name: flagRollupRPC, - Value: "", - Usage: "Rollup RPC `URL`", - Aliases: []string{"u"}, - } dockerImageFlag = &cli.StringFlag{ Name: flagDockerImage, Value: "lagrangelabs/lagrange-node:v0.3.13", @@ -218,7 +211,6 @@ func main() { configFileFlag, networkFlag, chainFlag, - rollupRPCFlag, }, Action: generateConfig, }, @@ -496,7 +488,7 @@ func generateConfig(c *cli.Context) error { clientCfg.ChainName = chain clientCfg.ServerGrpcURL = config.NetworkConfigs[network].GRPCServerURLs[chain] clientCfg.L1RPCEndpoint = cfg.L1RPCEndpoint - clientCfg.L2RPCEndpoint = c.String(flagRollupRPC) + clientCfg.L2RPCEndpoint = cfg.L2RPCEndpoint clientCfg.BeaconURL = cfg.BeaconURL clientCfg.BatchInbox = config.ChainBatchConfigs[chain].BatchInbox clientCfg.BatchSender = config.ChainBatchConfigs[chain].BatchSender diff --git a/config.toml b/config.toml index e4cb2b7..3cfaa4c 100644 --- a/config.toml +++ b/config.toml @@ -7,5 +7,6 @@ BLSKeystorePasswordPath = "--- BLS Keystore Password Path ---" EthereumRPCURL = "--- Ethereum RPC URL (mainnet / holesky) ---" L1RPCEndpoint = "--- L1 RPC Endpoint (mainnet) ---" BeaconURL = "--- Beacon Endpoint (mainnet) ---" +L2RPCEndpoint = "--- L2 RPC Endpoint (optimism / base) ---" BLSCurve = "BN254" ConcurrentFetchers = 8 \ No newline at end of file diff --git a/config/config.go b/config/config.go index 2beea57..cb465eb 100644 --- a/config/config.go +++ b/config/config.go @@ -34,6 +34,7 @@ type CLIConfig struct { EthereumRPCURL string `mapstructure:"EthereumRPCURL"` L1RPCEndpoint string `mapstructure:"L1RPCEndpoint"` BeaconURL string `mapstructure:"BeaconURL"` + L2RPCEndpoint string `mapstructure:"L2RPCEndpoint"` BLSCurve string `mapstructure:"BLSCurve"` ConcurrentFetchers int `mapstructure:"ConcurrentFetchers"` }