Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 401
ci: deploy operator with ansible#1382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
4172aa6d45921ff0777fbf98ccac3ebf89501ea554dbdf94ad17162dd44ac44f640339497cf0f405b611a12924fb1ac3030fb1117ba159ce23e37419816bef64242f3590bd7e1697986cdbd2d4e1b4b0488ca83aab51d4f077cccca4ea64ae399e1756f33773ada0e3879cb708dbb94e4722a4508b8b61e3471fdd02a272c66905dc46353445c27b7668eba851d37452c39ff1ea03215cef77fda7050956d8fdc4File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| - name: Foundry Setup | ||
| hosts: "{{ host }}" | ||
| tasks: | ||
| - name: Download Foundry | ||
| shell: | ||
| cmd: curl -L https://foundry.paradigm.xyz | bash | ||
| - name: Run Foundryup | ||
| shell: | ||
| cmd: /home/{{ ansible_user }}/.foundry/bin/foundryup |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| [global] | ||
| aligned_layer_deployment_config_file_path= | ||
| eigen_layer_deployment_config_file_path= | ||
| eth_rpc_url= | ||
| eth_rpc_url_fallback= | ||
| eth_ws_url= | ||
| eth_ws_url_fallback= | ||
| ecdsa_private_key_store_path= | ||
| ecdsa_private_key_store_password= | ||
| bls_private_key_store_path= | ||
| bls_private_key_store_password= | ||
| aggregator_rpc_server_ip_port_address= | ||
| operator_tracker_ip_port_address= | ||
| address= | ||
| metadata_url= | ||
| enable_metrics= | ||
| metrics_ip_port_address= | ||
| last_processed_batch_filepath= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| [global] | ||
| address= | ||
| metadata_url= | ||
| el_delegation_manager_address= | ||
| eth_rpc_url= | ||
| private_key_store_path= | ||
| private_key_store_password= | ||
| chain_id= | ||
| weth_address= | ||
| weth_strategy_address= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,47 +1,181 @@ | ||
| - import_playbook: setup.yaml | ||
| - import_playbook: go.yaml | ||
| - import_playbook: rust.yaml | ||
| - import_playbook: eigenlayer-cli.yaml | ||
| - name: Run setup playbook | ||
| ansible.builtin.import_playbook: setup.yaml | ||
| vars: | ||
| host: operator | ||
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For a future improvement: parametrize this variable so it's not repeated so much | ||
| - name: Run go playbook | ||
| ansible.builtin.import_playbook: go.yaml | ||
| vars: | ||
| host: operator | ||
| - name: Run rust playbook | ||
| ansible.builtin.import_playbook: rust.yaml | ||
| vars: | ||
| host: operator | ||
| - name: Run eigenlayer-cli playbook | ||
| ansible.builtin.import_playbook: eigenlayer-cli.yaml | ||
| vars: | ||
| host: operator | ||
| - hosts: aligned-holesky-operator-1 | ||
| become: true | ||
| - name: Run foundry playbook | ||
| ansible.builtin.import_playbook: foundry.yaml | ||
| vars: | ||
| user: "{{ user }}" | ||
| host: operator | ||
| - hosts: operator | ||
| tasks: | ||
| # Install required packages | ||
| - name: Update apt and install required system packages | ||
| become: true | ||
| apt: | ||
| pkg: | ||
| - pkg-config | ||
| - libssl-dev | ||
| - gcc | ||
| state: latest | ||
| update_cache: true | ||
| vars: | ||
| ansible_ssh_user: "{{ admin_user }}" | ||
| # Create directories for each service | ||
| - name: Create directories for each service if do not exist | ||
| - name: Create directory for the repository | ||
| ansible.builtin.file: | ||
| path: /home/{{ user }}/repos/{{ item }} | ||
| path: /home/{{ ansible_user }}/repos/operator | ||
| state: directory | ||
| mode: '0755' | ||
| become_user: "{{ user }}" | ||
| loop: | ||
| - operator | ||
| owner: '{{ ansible_user }}' | ||
| group: '{{ ansible_user }}' | ||
| # Clone Aligned repository for each service | ||
| - name: Clone Aligned repository | ||
| ansible.builtin.git: | ||
| repo: https://github.com/yetanotherco/aligned_layer.git | ||
| dest: /home/{{ user }}/repos/{{ item }}/aligned_layer | ||
| dest: /home/{{ ansible_user }}/repos/operator/aligned_layer | ||
| version: v0.10.2 | ||
| become_user: "{{ user }}" | ||
| loop: | ||
| - operator | ||
| recursive: false | ||
| - name: Build the Operator | ||
| make: | ||
| chdir: /home/{{ ansible_user }}/repos/operator/aligned_layer | ||
| target: build_operator | ||
| environment: | ||
| PATH: "{{ ansible_env.PATH }}:/usr/bin:/usr/local/go/bin:/home/{{ ansible_user }}/.cargo/bin" | ||
| - name: Copy ECDSA keystore to server | ||
| ansible.builtin.copy: | ||
| src: '{{ ecdsa_keystore_path }}' | ||
| dest: /home/{{ ansible_user }}/.keystores/operator.ecdsa | ||
| owner: '{{ ansible_user }}' | ||
| group: '{{ ansible_user }}' | ||
| - name: Copy BLS keystore to server | ||
| ansible.builtin.copy: | ||
| src: '{{ bls_keystore_path }}' | ||
| dest: /home/{{ ansible_user }}/.keystores/operator.bls | ||
| owner: '{{ ansible_user }}' | ||
| group: '{{ ansible_user }}' | ||
| - name: Create variables | ||
| set_fact: | ||
| weth_strategy_address: "{{ lookup('ini', 'weth_strategy_address', file='ini/config-register-operator.ini') }}" | ||
| address: "{{ lookup('ini', 'address', file='ini/config-register-operator.ini') }}" | ||
| eth_rpc_url: "{{ lookup('ini', 'eth_rpc_url', file='ini/config-register-operator.ini') }}" | ||
| - name: Check if Operator already staked wETH | ||
| ansible.builtin.command: "cast call {{ weth_strategy_address }} shares(address)(uint256) {{ address }} --rpc-url {{ eth_rpc_url }}" | ||
| register: operator_stake | ||
| environment: | ||
| PATH: "{{ ansible_env.PATH }}:/home/{{ ansible_user }}/.foundry/bin" | ||
| - name: Upload config file for register Operator | ||
| when: operator_stake.stdout == "0" | ||
| template: | ||
| src: operator/config-register-operator.yaml.j2 | ||
| dest: "/home/{{ ansible_user }}/config/config-register-operator.yaml" | ||
| vars: | ||
| address: "{{ lookup('ini', 'address', file='ini/config-register-operator.ini') }}" | ||
| metadata_url: "{{ lookup('ini', 'metadata_url', file='ini/config-register-operator.ini') }}" | ||
| el_delegation_manager_address: "{{ lookup('ini', 'el_delegation_manager_address', file='ini/config-register-operator.ini') }}" | ||
| eth_rpc_url: "{{ lookup('ini', 'eth_rpc_url', file='ini/config-register-operator.ini') }}" | ||
| private_key_store_path: "{{ lookup('ini', 'private_key_store_path', file='ini/config-register-operator.ini') }}" | ||
| chain_id: "{{ lookup('ini', 'chain_id', file='ini/config-register-operator.ini') }}" | ||
| - name: Register Operator in EigenLayer | ||
| when: operator_stake.stdout == "0" | ||
| shell: | ||
| cmd: echo "{{ lookup('ini', 'private_key_store_password', file='ini/config-register-operator.ini') }}" | eigenlayer operator register /home/{{ ansible_user }}/config/config-register-operator.yaml >> register.log 2>&1 | ||
| environment: | ||
| PATH: "{{ ansible_env.PATH }}:/home/{{ ansible_user }}/bin" | ||
| - name: Swap holETH for wETH | ||
| when: operator_stake.stdout == "0" | ||
| shell: | ||
| cmd: cast send --value 0.1ether {{ lookup('ini', 'weth_address', file='ini/config-register-operator.ini') }} --password {{ lookup('ini', 'private_key_store_password', file='ini/config-register-operator.ini') }} | ||
| environment: | ||
| PATH: "{{ ansible_env.PATH }}:/home/{{ ansible_user }}/.foundry/bin" | ||
| ETH_KEYSTORE: "{{ lookup('ini', 'private_key_store_path', file='ini/config-register-operator.ini') }}" | ||
| ETH_PASSWORD: "{{ lookup('ini', 'private_key_store_password', file='ini/config-register-operator.ini') }}" # It is not working idk why | ||
| ETH_RPC_URL: "{{ lookup('ini', 'eth_rpc_url', file='ini/config-register-operator.ini') }}" | ||
| - name: Upload config file for Operator | ||
| template: | ||
| src: config-files/config-operator.yaml.j2 | ||
| dest: "/home/{{ ansible_user }}/config/config-operator.yaml" | ||
| vars: | ||
| aligned_layer_deployment_config_file_path: "{{ lookup('ini', 'aligned_layer_deployment_config_file_path', file='ini/config-operator.ini') }}" | ||
| eigen_layer_deployment_config_file_path: "{{ lookup('ini', 'eigen_layer_deployment_config_file_path', file='ini/config-operator.ini') }}" | ||
| eth_rpc_url: "{{ lookup('ini', 'eth_rpc_url', file='ini/config-operator.ini') }}" | ||
| eth_rpc_url_fallback: "{{ lookup('ini', 'eth_rpc_url_fallback', file='ini/config-operator.ini') }}" | ||
| eth_ws_url: "{{ lookup('ini', 'eth_ws_url', file='ini/config-operator.ini') }}" | ||
| eth_ws_url_fallback: "{{ lookup('ini', 'eth_ws_url_fallback', file='ini/config-operator.ini') }}" | ||
| ecdsa_private_key_store_path: "{{ lookup('ini', 'ecdsa_private_key_store_path', file='ini/config-operator.ini') }}" | ||
| ecdsa_private_key_store_password: "{{ lookup('ini', 'ecdsa_private_key_store_password', file='ini/config-operator.ini') }}" | ||
| bls_private_key_store_path: "{{ lookup('ini', 'bls_private_key_store_path', file='ini/config-operator.ini') }}" | ||
| bls_private_key_store_password: "{{ lookup('ini', 'bls_private_key_store_password', file='ini/config-operator.ini') }}" | ||
| aggregator_rpc_server_ip_port_address: "{{ lookup('ini', 'aggregator_rpc_server_ip_port_address', file='ini/config-operator.ini') }}" | ||
| operator_tracker_ip_port_address: "{{ lookup('ini', 'operator_tracker_ip_port_address', file='ini/config-operator.ini') }}" | ||
| address: "{{ lookup('ini', 'address', file='ini/config-operator.ini') }}" | ||
| metadata_url: "{{ lookup('ini', 'metadata_url', file='ini/config-operator.ini') }}" | ||
| enable_metrics: "{{ lookup('ini', 'enable_metrics', file='ini/config-operator.ini') }}" | ||
| metrics_ip_port_address: "{{ lookup('ini', 'metrics_ip_port_address', file='ini/config-operator.ini') }}" | ||
| last_processed_batch_filepath: "{{ lookup('ini', 'last_processed_batch_filepath', file='ini/config-operator.ini') }}" | ||
| - name: Deposit into wETH strategy | ||
| when: operator_stake.stdout == "0" | ||
| make: | ||
| chdir: /home/{{ ansible_user }}/repos/operator/aligned_layer | ||
| target: operator_deposit_into_strategy | ||
| params: | ||
| CONFIG_FILE=/home/{{ ansible_user }}/config/config-operator.yaml | ||
| STRATEGY_ADDRESS={{ lookup('ini', 'weth_strategy_address', file='ini/config-register-operator.ini') }} | ||
| AMOUNT=100000000000000000 # 0.1ether | ||
| environment: | ||
| PATH: "{{ ansible_env.PATH }}:/usr/bin:/usr/local/go/bin" | ||
| - name: Allow access to tcp port 9092 from the VPN | ||
| become: true | ||
| ufw: | ||
| rule: allow | ||
| port: 9092 | ||
| proto: tcp | ||
| src: 100.0.0.0/24 | ||
| src: 100.0.0.0/24 | ||
| vars: | ||
| ansible_ssh_user: "{{ admin_user }}" | ||
| - name: Create systemd services directory | ||
| file: | ||
| path: "/home/{{ ansible_user }}/.config/systemd/user/" | ||
| state: directory | ||
| - name: Add service to systemd | ||
| template: | ||
| src: services/operator.service.j2 | ||
| dest: "/home/{{ ansible_user }}/.config/systemd/user/operator.service" | ||
| force: no | ||
| - name: Start Operator service | ||
| ansible.builtin.systemd_service: | ||
| name: operator | ||
| state: started | ||
| enabled: true | ||
| scope: user | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Common variables for all the services | ||
| # 'production' only prints info and above. 'development' also prints debug | ||
| environment: 'production' | ||
| aligned_layer_deployment_config_file_path: "{{ aligned_layer_deployment_config_file_path }}" | ||
| eigen_layer_deployment_config_file_path: "{{ eigen_layer_deployment_config_file_path }}" | ||
| eth_rpc_url: "{{ eth_rpc_url }}" | ||
| eth_rpc_url_fallback: "{{ eth_rpc_url_fallback }}" | ||
| eth_ws_url: "{{ eth_ws_url }}" | ||
| eth_ws_url_fallback: "{{ eth_ws_url_fallback }}" | ||
| eigen_metrics_ip_port_address: 'localhost:9090' | ||
| ## ECDSA Configurations | ||
| ecdsa: | ||
| private_key_store_path: "{{ ecdsa_private_key_store_path }}" | ||
| private_key_store_password: "{{ ecdsa_private_key_store_password }}" | ||
| ## BLS Configurations | ||
| bls: | ||
| private_key_store_path: "{{ bls_private_key_store_path }}" | ||
| private_key_store_password: "{{ bls_private_key_store_password }}" | ||
| ## Operator Configurations | ||
| operator: | ||
| aggregator_rpc_server_ip_port_address: "{{ aggregator_rpc_server_ip_port_address }}" | ||
| operator_tracker_ip_port_address: "{{ operator_tracker_ip_port_address }}" | ||
| address: "{{ address }}" | ||
| earnings_receiver_address: "{{ address }}" #Can be the same as the operator. | ||
| delegation_approver_address: '0x0000000000000000000000000000000000000000' | ||
| staker_opt_out_window_blocks: 0 | ||
| metadata_url: "{{ metadata_url }}" | ||
| enable_metrics: {{ enable_metrics }} | ||
| metrics_ip_port_address: "{{ metrics_ip_port_address }}" | ||
| max_batch_size: 268435456 # 256 MiB | ||
| last_processed_batch_filepath: "{{ last_processed_batch_filepath }}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Reference: https://github.com/Layr-Labs/eigenlayer-cli/blob/master/pkg/operator/config/operator-config-example.yaml | ||
| # All the below fields are required for successful operator registration. | ||
| # To learn more about operator fields | ||
| # https://github.com/Layr-Labs/eigenlayer-contracts/blob/92ccacc868785350973afc15e90a18dcd39fbc0b/src/contracts/interfaces/IDelegationManager.sol#L21: | ||
| operator: | ||
| # This is the standard Ethereum address format (ex: 0x6a8c0D554a694899041E52a91B4EC3Ff23d8aBD5) of your operator | ||
| # which is the ecdsa key you created or imported using EigenLayer CLI | ||
| address: {{ address }} | ||
| # This is the standard Ethereum address format (0x...) | ||
| # This is the address which operator will use to approve delegation requests from stakers. | ||
| # if set, this address must sign and approve new delegation from Stakers to this Operator | ||
| # For now, you can leave it with the default value for un-gated delegation requests | ||
| # Once we enable gated delegation requests, you can update this field with the address of the approver | ||
| delegation_approver_address: 0x0000000000000000000000000000000000000000 | ||
| # Please refer to this link for more details on this field https://github.com/Layr-Labs/eigenlayer-contracts/blob/92ccacc868785350973afc15e90a18dcd39fbc0b/src/contracts/interfaces/IDelegationManager.sol#L33: | ||
| # Please keep this field to 0, and it can be updated later using EigenLayer CLI | ||
| staker_opt_out_window_blocks: 0 | ||
| metadata_url: {{ metadata_url }} | ||
| # EigenLayer Delegation manager contract address | ||
| # For the testnet address, refer to here: https://github.com/layr-labs/eigenlayer-contracts/?tab=readme-ov-file#current-testnet-deployment | ||
| # For the mainnet address, refer to here: https://github.com/layr-labs/eigenlayer-contracts/?tab=readme-ov-file#current-mainnet-deployment | ||
| el_delegation_manager_address: {{ el_delegation_manager_address }} | ||
| # ETH RPC URL to the ethereum node you are using for on-chain operations | ||
| eth_rpc_url: {{ eth_rpc_url }} | ||
| # Signer Type to use | ||
| # Supported values: local_keystore, fireblocks, web3 | ||
| signer_type: local_keystore | ||
| # Full path to local ecdsa private key store file | ||
| private_key_store_path: {{ private_key_store_path }} | ||
| # Chain ID: 1 for mainnet, 17000 for holesky, 31337 for local | ||
| chain_id: {{ chain_id }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| [Unit] | ||
| Description=Operator | ||
| After=network.target | ||
| [Service] | ||
| Type=simple | ||
| WorkingDirectory=/home/{{ ansible_user }}/repos/operator/aligned_layer | ||
| ExecStart=/home/{{ ansible_user }}/repos/operator/aligned_layer/operator/build/aligned-operator start --config /home/{{ ansible_user }}/config/config-operator.yaml | ||
| Restart=always | ||
| RestartSec=1 | ||
| StartLimitBurst=100 | ||
| [Install] | ||
| WantedBy=multi-user.target |
Uh oh!
There was an error while loading. Please reload this page.