diff --git a/README.md b/README.md index e43adb91..4577ca6f 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ A collection of reusable ansible components used by the EthPandaOps team. - [ethstats](roles/ethstats) - [goomy](roles/goomy) - [mev_boost](roles/mev_boost) +- [mev_relay](roles/mev_relay) - [powfaucet](roles/powfaucet) - [xatu_sentry](roles/xatu_sentry) diff --git a/roles/mev_boost/defaults/main.yml b/roles/mev_boost/defaults/main.yml index 067284ba..7be9e19d 100644 --- a/roles/mev_boost/defaults/main.yml +++ b/roles/mev_boost/defaults/main.yml @@ -1,23 +1,24 @@ mev_boost_user: mev_boost mev_boost_cleanup: false # when set to "true" it will remove the container(s) - +mev_boost_docker_network_name: shared +mev_boost_docker_networks: + - name: "{{ mev_boost_docker_network_name }}" ################################################################################ ## ## mev_boost container configuration ## ################################################################################ -mev_boost_container_name: mev_boost +mev_boost_container_name: mev-boost mev_boost_container_image: flashbots/mev-boost:1.5.0 mev_boost_container_env: {} mev_boost_server_port: 18550 mev_boost_container_ports: - "127.0.0.1:{{ mev_boost_server_port }}:{{ mev_boost_server_port }}" - mev_boost_container_stop_timeout: "300" -mev_boost_container_networks: [] +mev_boost_container_networks: "{{ mev_boost_docker_networks }}" mev_boost_container_volumes: [] mev_boost_container_command: - - --addr=0.0.0.0:{{ mev_boost_server_port }} + - -relay-check mev_boost_container_command_extra_args: [] diff --git a/roles/mev_boost/tasks/setup.yaml b/roles/mev_boost/tasks/setup.yaml index 97b02aae..5923da74 100644 --- a/roles/mev_boost/tasks/setup.yaml +++ b/roles/mev_boost/tasks/setup.yaml @@ -3,6 +3,12 @@ name: "{{ mev_boost_user }}" register: mev_boost_user_meta +- name: Setup docker network + ansible.builtin.include_role: + name: ethpandaops.general.docker_network + vars: + docker_network_name: "{{ mev_boost_docker_network_name }}" + - name: Run mev_boost container community.docker.docker_container: name: "{{ mev_boost_container_name }}" diff --git a/roles/mev_flood/README.md b/roles/mev_flood/README.md new file mode 100644 index 00000000..9a31b63c --- /dev/null +++ b/roles/mev_flood/README.md @@ -0,0 +1,38 @@ +# ethpandaops.general.mev_flood + +This role will run [mev_flood](https://github.com/flashbots/mev-flood) within a docker container. + +## Requirements + +You'll need docker on the target system. Make sure to install it upfront. + +## Role Variables + +Default variables are defined in [defaults/main.yaml](defaults/main.yaml) + +## Dependencies + +You'll need docker to run this role. One way of installing docker could be via ansible galaxy with the following dependencies set within `requirements.yaml`: + +```yaml +roles: +- src: geerlingguy.docker + version: latest +- src: geerlingguy.pip + version: latest +``` + +## Example Playbook + +Your playbook could look like this: + +```yaml +- hosts: localhost + become: true + roles: + - role: geerlingguy.docker + - role: geerlingguy.pip + pip_install_packages: + - name: docker + - role: ethpandaops.general.mev_flood +``` diff --git a/roles/mev_flood/defaults/main.yml b/roles/mev_flood/defaults/main.yml new file mode 100644 index 00000000..506855e5 --- /dev/null +++ b/roles/mev_flood/defaults/main.yml @@ -0,0 +1,51 @@ +mev_flood_user: mev_flood +mev_flood_cleanup: false # when set to "true" it will remove the container(s) + +mev_flood_datadir: "/data/mev_flood" + +mev_flood_docker_network_name: shared +mev_flood_docker_networks: + - name: "{{ mev_flood_docker_network_name }}" + +################################################################################ +## +## mev_flood container configuration +## Deploy smart contracts and provision liquidity on UniV2 pairs. +## +################################################################################ +mev_flood_container_name: mev-flood +mev_flood_container_image: flashbots/mev-flood:latest +mev_flood_container_env: {} +mev_flood_container_ports: [] +mev_flood_container_stop_timeout: "300" +mev_flood_container_networks: "{{ mev_flood_docker_networks }}" +mev_flood_container_volumes: + - "{{ mev_flood_datadir }}:/app/cli/deployments" + - /etc/passwd:/etc/passwd:ro +mev_flood_container_command: + - init + - --saveFile=local.json + +mev_flood_container_command_extra_args: [] +################################################################################ +## +## mev_flood container configuration +## Send a constant stream of UniV2 swaps. +## +################################################################################ + +mev_flood_spam_container_name: mev-flood-spam +mev_flood_spam_container_image: flashbots/mev-flood:latest +mev_flood_spam_container_env: {} +mev_flood_spam_container_ports: [] +mev_flood_spam_container_stop_timeout: "300" +mev_flood_spam_container_networks: "{{ mev_flood_docker_networks }}" +mev_flood_spam_container_volumes: + - "{{ mev_flood_datadir }}:/app/cli/deployments" + - /etc/passwd:/etc/passwd:ro +mev_flood_spam_container_command: + - spam + - --loadFile=local.json + - --secondsPerBundle=15 + +mev_flood_spam_container_command_extra_args: [] diff --git a/roles/mev_flood/tasks/cleanup.yaml b/roles/mev_flood/tasks/cleanup.yaml new file mode 100644 index 00000000..df6c44cc --- /dev/null +++ b/roles/mev_flood/tasks/cleanup.yaml @@ -0,0 +1,11 @@ +- name: Remove mev_flood container + community.docker.docker_container: + name: "{{ mev_flood_container_name }}" + state: absent + when: mev_flood_cleanup + +- name: Remove mev_flood_spam container + community.docker.docker_container: + name: "{{ mev_flood_spam_container_name }}" + state: absent + when: mev_flood_cleanup diff --git a/roles/mev_flood/tasks/main.yml b/roles/mev_flood/tasks/main.yml new file mode 100644 index 00000000..244165e9 --- /dev/null +++ b/roles/mev_flood/tasks/main.yml @@ -0,0 +1,8 @@ +--- +# tasks file for mev_flood +- name: Setup mev_flood + ansible.builtin.import_tasks: setup.yaml + when: not mev_flood_cleanup + +- name: Cleanup mev_flood + ansible.builtin.import_tasks: cleanup.yaml diff --git a/roles/mev_flood/tasks/setup.yaml b/roles/mev_flood/tasks/setup.yaml new file mode 100644 index 00000000..2bbad1af --- /dev/null +++ b/roles/mev_flood/tasks/setup.yaml @@ -0,0 +1,52 @@ +- name: Add mev_flood user + ansible.builtin.user: + name: "{{ mev_flood_user }}" + register: mev_flood_user_meta + +- name: Setup docker network + ansible.builtin.include_role: + name: ethpandaops.general.docker_network + vars: + docker_network_name: "{{ mev_flood_docker_network_name }}" + +- name: Create directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: "0750" + owner: "{{ mev_flood_user }}" + group: "{{ mev_flood_user }}" + loop: + - "{{ mev_flood_datadir }}" + +- name: Set permissions + ansible.builtin.command: "chown -R {{ mev_flood_user }}:{{ mev_flood_user }} {{ mev_flood_datadir }}" # noqa no-free-form + changed_when: false + +- name: Run mev_flood container + community.docker.docker_container: + name: "{{ mev_flood_container_name }}" + image: "{{ mev_flood_container_image }}" + state: started + restart_policy: always + stop_timeout: "{{ mev_flood_container_stop_timeout }}" + volumes: "{{ mev_flood_container_volumes }}" + env: "{{ mev_flood_container_env }}" + networks: "{{ mev_flood_container_networks }}" + ports: "{{ mev_flood_container_ports }}" + command: "{{ mev_flood_container_command + mev_flood_container_command_extra_args }} " + user: "{{ mev_flood_user_meta.uid }}" + +- name: Run mev_flood_spam container + community.docker.docker_container: + name: "{{ mev_flood_spam_container_name }}" + image: "{{ mev_flood_spam_container_image }}" + state: started + restart_policy: always + stop_timeout: "{{ mev_flood_spam_container_stop_timeout }}" + volumes: "{{ mev_flood_spam_container_volumes }}" + env: "{{ mev_flood_spam_container_env }}" + networks: "{{ mev_flood_spam_container_networks }}" + ports: "{{ mev_flood_spam_container_ports }}" + command: "{{ mev_flood_spam_container_command + mev_flood_spam_container_command_extra_args }} " + user: "{{ mev_flood_user_meta.uid }}" diff --git a/roles/mev_relay/README.md b/roles/mev_relay/README.md new file mode 100644 index 00000000..9a83707e --- /dev/null +++ b/roles/mev_relay/README.md @@ -0,0 +1,43 @@ +# ethpandaops.general.mev_relay + +Setup [mev_relay](https://github.com/flashbots/mev-boost-relay/) and all required dependencies all in one server. + +## Requirements + +You'll need docker on the target system. Make sure to install it upfront. + +## Role Variables + +Default variables are defined in [defaults/main.yaml](defaults/main.yaml) + +## Dependencies + +You'll need docker and docker-compose to run this role. One way of installing docker could be via ansible galaxy with the following dependencies set within `requirements.yaml`: + +```yaml +roles: +- src: geerlingguy.docker + version: 6.0.3 +- src: geerlingguy.pip + version: 2.2.0 +``` + +## Example Playbook + +Your playbook could look like this: + +```yaml +- hosts: mev_relay + become: true + roles: + # Docker. Required dependency + - role: geerlingguy.docker + tags: [docker] + - role: geerlingguy.pip + pip_install_packages: + - name: docker + tags: [docker] + # Blockscout explorer + - role: mev_relay + tags: [mev_relay] +``` diff --git a/roles/mev_relay/defaults/main.yml b/roles/mev_relay/defaults/main.yml new file mode 100644 index 00000000..782b7b70 --- /dev/null +++ b/roles/mev_relay/defaults/main.yml @@ -0,0 +1,98 @@ +--- +mev_relay_cleanup_all: false + +mev_relay_user: mev_relay +mev_relay_datadir: "/data/mev_relay" +mev_relay_docker_network_name: shared +mev_relay_docker_networks: + - name: "{{ mev_relay_docker_network_name }}" + +# ------------------------------------------------------------------ +# mev-relay ports +mev_relay_database_port: 5432 +mev_relay_redis_port: 6379 +mev_relay_website_listening_port: 9060 +mev_relay_api_listening_port: 9062 + +# mev-relay-database +mev_relay_db_enabled: true +mev_relay_db_datadir: "{{ mev_relay_datadir }}/mev-relay-database" +mev_relay_db_container_name: mev-relay-database +mev_relay_db_container_image: bitnami/postgresql:15 +mev_relay_db_container_env: + POSTGRESQL_USERNAME: postgres + POSTGRESQL_PASSWORD: postgres + POSTGRESQL_DATABASE: boostrelay +mev_relay_db_container_ports: + - "127.0.0.1:{{ mev_relay_database_port }}:{{ mev_relay_database_port }}" +mev_relay_db_container_volumes: + - "{{ mev_relay_datadir }}:/bitnami/postgresql" +mev_relay_db_container_stop_timeout: "300" +mev_relay_db_container_pull: false +mev_relay_db_container_networks: "{{ mev_relay_docker_networks }}" + +# ------------------------------------------------------------------ +# mev-relay-redis +mev_relay_redis_enabled: true +mev_relay_redis_datadir: "{{ mev_relay_datadir }}/mev-relay-redis" +mev_relay_redis_container_name: mev-relay-redis +mev_relay_redis_container_image: bitnami/redis:6.2.12 +mev_relay_redis_container_env: + ALLOW_EMPTY_PASSWORD=yes +mev_relay_redis_container_ports: + - "127.0.0.1:{{ mev_relay_redis_port }}:{{ mev_relay_redis_port }}" +mev_relay_redis_container_volumes: + - "{{ mev_relay_datadir }}:/bitnami/redis/data" +mev_relay_redis_container_stop_timeout: "300" +mev_relay_redis_container_pull: false +mev_relay_redis_container_networks: "{{ mev_relay_docker_networks }}" + +# ------------------------------------------------------------------ +# mev-relay-housekeeper +mev_relay_housekeeper_enabled: true +mev_relay_housekeeper_datadir: "{{ mev_relay_datadir }}/mev-relay-housekeeper" +mev_relay_housekeeper_container_name: mev-relay-housekeeper +mev_relay_housekeeper_container_image: flashbots/mev-boost-relay:latest +mev_relay_housekeeper_container_env: [] +mev_relay_housekeeper_container_ports: [] +mev_relay_housekeeper_container_volumes: [] +mev_relay_housekeeper_container_stop_timeout: "300" +mev_relay_housekeeper_container_pull: false +mev_relay_housekeeper_container_networks: "{{ mev_relay_docker_networks }}" +mev_relay_housekeeper_container_command: + - housekeeper +mev_relay_housekeeper_container_command_extra_args: [] + +# ------------------------------------------------------------------ +# mev-relay-api +mev_relay_api_enabled: true +mev_relay_api_datadir: "{{ mev_relay_datadir }}/mev-relay-api" +mev_relay_api_container_name: mev-relay-api +mev_relay_api_container_image: flashbots/mev-boost-relay:latest +mev_relay_api_container_env: [] +mev_relay_api_container_ports: + - "127.0.0.1:{{ mev_relay_api_listening_port }}:{{ mev_relay_api_listening_port }}" +mev_relay_api_container_volumes: [] +mev_relay_api_container_stop_timeout: "300" +mev_relay_api_container_pull: false +mev_relay_api_container_networks: "{{ mev_relay_docker_networks }}" +mev_relay_api_container_command: + - api +mev_relay_api_container_command_extra_args: [] + +# ------------------------------------------------------------------ +# mev-relay-website +mev_relay_website_enabled: true +mev_relay_website_datadir: "{{ mev_relay_datadir }}/mev-relay-website" +mev_relay_website_container_name: mev-relay-website +mev_relay_website_container_image: flashbots/mev-boost-relay:latest +mev_relay_website_container_env: [] +mev_relay_website_container_ports: + - "127.0.0.1:{{ mev_relay_website_listening_port }}:{{ mev_relay_website_listening_port }}" +mev_relay_website_container_volumes: [] +mev_relay_website_container_stop_timeout: "300" +mev_relay_website_container_pull: false +mev_relay_website_container_networks: "{{ mev_relay_docker_networks }}" +mev_relay_website_container_command: + - website +mev_relay_website_container_command_extra_args: [] diff --git a/roles/mev_relay/meta/main.yml b/roles/mev_relay/meta/main.yml new file mode 100644 index 00000000..712a27a4 --- /dev/null +++ b/roles/mev_relay/meta/main.yml @@ -0,0 +1,10 @@ +galaxy_info: + author: flashbots_mev_relay + description: Deploy Flashbots MEV Relay and all required dependencies on a single machine. + license: MIT + min_ansible_version: "2.1" + galaxy_tags: ["ethereum", "mevrelay", "flashbots", "mev"] + platforms: + - name: GenericLinux + versions: ["all"] +dependencies: [] diff --git a/roles/mev_relay/tasks/cleanup.yml b/roles/mev_relay/tasks/cleanup.yml new file mode 100644 index 00000000..9ada9fd1 --- /dev/null +++ b/roles/mev_relay/tasks/cleanup.yml @@ -0,0 +1,22 @@ +- name: Stop mev_relay containers + community.docker.docker_container: + name: "{{ item }}" + state: absent + loop: + - "{{ mev_relay_api_container_name }}" + - "{{ mev_relay_db_container_name }}" + - "{{ mev_relay_housekeeper_container_name }}" + - "{{ mev_relay_website_container_name }}" + - "{{ mev_relay_redis_container_name }}" + +- name: Delete data directories + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: + - "{{ mev_relay_api_datadir }}" + - "{{ mev_relay_website_datadir }}" + - "{{ mev_relay_housekeeper_datadir }}" + - "{{ mev_relay_db_datadir }}" + - "{{ mev_relay_redis_datadir }}" + - "{{ mev_relay_datadir }}" diff --git a/roles/mev_relay/tasks/main.yml b/roles/mev_relay/tasks/main.yml new file mode 100644 index 00000000..fb3c8f03 --- /dev/null +++ b/roles/mev_relay/tasks/main.yml @@ -0,0 +1,7 @@ +- name: Setup mev_relay + ansible.builtin.import_tasks: setup.yml + when: not mev_relay_cleanup_all + +- name: Cleanup everything + ansible.builtin.import_tasks: cleanup.yml + when: mev_relay_cleanup_all diff --git a/roles/mev_relay/tasks/setup.yml b/roles/mev_relay/tasks/setup.yml new file mode 100644 index 00000000..5eb179a1 --- /dev/null +++ b/roles/mev_relay/tasks/setup.yml @@ -0,0 +1,96 @@ +- name: Add mev_relay user + ansible.builtin.user: + name: "{{ mev_relay_user }}" + register: mev_relay_user_meta + +- name: Setup docker network + ansible.builtin.include_role: + name: ethpandaops.general.docker_network + vars: + docker_network_name: "{{ mev_relay_docker_network_name }}" + +- name: Create directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: "0750" + owner: "{{ mev_relay_user }}" + group: "{{ mev_relay_user }}" + loop: + - "{{ mev_relay_api_datadir }}" + - "{{ mev_relay_website_datadir }}" + - "{{ mev_relay_housekeeper_datadir }}" + - "{{ mev_relay_db_datadir }}" + +- name: Setup mev_relay database container + community.docker.docker_container: + name: "{{ mev_relay_db_container_name }}" + image: "{{ mev_relay_db_container_image }}" + state: '{{ mev_relay_db_enabled | ternary("started", "absent") }}' + restart_policy: always + stop_timeout: "{{ mev_relay_db_container_stop_timeout }}" + ports: "{{ mev_relay_db_container_ports }}" + volumes: "{{ mev_relay_db_container_volumes }}" + env: "{{ mev_relay_db_container_env }}" + networks: "{{ mev_relay_db_container_networks }}" + pull: "{{ mev_relay_db_container_pull | bool }}" + user: "{{ mev_relay_user_meta.uid }}" + +- name: Setup mev_relay redis container + community.docker.docker_container: + name: "{{ mev_relay_redis_container_name }}" + image: "{{ mev_relay_redis_container_image }}" + state: '{{ mev_relay_redis_enabled | ternary("started", "absent") }}' + restart_policy: always + stop_timeout: "{{ mev_relay_redis_container_stop_timeout }}" + ports: "{{ mev_relay_redis_container_ports }}" + volumes: "{{ mev_relay_redis_container_volumes }}" + env: "{{ mev_relay_redis_container_env }}" + networks: "{{ mev_relay_redis_container_networks }}" + pull: "{{ mev_relay_redis_container_pull | bool }}" + user: "{{ mev_relay_user_meta.uid }}" + +- name: Setup mev_relay_housekeeper container + community.docker.docker_container: + name: "{{ mev_relay_housekeeper_container_name }}" + image: "{{ mev_relay_housekeeper_container_image }}" + state: '{{ mev_relay_housekeeper_enabled | ternary("started", "absent") }}' + restart_policy: always + stop_timeout: "{{ mev_relay_housekeeper_container_stop_timeout }}" + ports: "{{ mev_relay_housekeeper_container_ports }}" + volumes: "{{ mev_relay_housekeeper_container_volumes }}" + env: "{{ mev_relay_housekeeper_container_env }}" + networks: "{{ mev_relay_housekeeper_container_networks }}" + pull: "{{ mev_relay_housekeeper_container_pull | bool }}" + command: "{{ mev_relay_housekeeper_container_command + mev_relay_housekeeper_container_command_extra_args }} " + user: "{{ mev_relay_user_meta.uid }}" + +- name: Setup mev_relay_api container + community.docker.docker_container: + name: "{{ mev_relay_api_container_name }}" + image: "{{ mev_relay_api_container_image }}" + state: '{{ mev_relay_api_enabled | ternary("started", "absent") }}' + restart_policy: always + stop_timeout: "{{ mev_relay_api_container_stop_timeout }}" + ports: "{{ mev_relay_api_container_ports }}" + volumes: "{{ mev_relay_api_container_volumes }}" + env: "{{ mev_relay_api_container_env }}" + networks: "{{ mev_relay_api_container_networks }}" + pull: "{{ mev_relay_api_container_pull | bool }}" + command: "{{ mev_relay_api_container_command + mev_relay_api_container_command_extra_args }} " + user: "{{ mev_relay_user_meta.uid }}" + +- name: Setup mev_relay_website container + community.docker.docker_container: + name: "{{ mev_relay_website_container_name }}" + image: "{{ mev_relay_website_container_image }}" + state: '{{ mev_relay_website_enabled | ternary("started", "absent") }}' + restart_policy: always + stop_timeout: "{{ mev_relay_website_container_stop_timeout }}" + ports: "{{ mev_relay_website_container_ports }}" + volumes: "{{ mev_relay_website_container_volumes }}" + env: "{{ mev_relay_website_container_env }}" + networks: "{{ mev_relay_website_container_networks }}" + pull: "{{ mev_relay_website_container_pull | bool }}" + command: "{{ mev_relay_website_container_command + mev_relay_website_container_command_extra_args }} " + user: "{{ mev_relay_user_meta.uid }}"