From f9933bf438ff0173b43f50838889ab125e9078de Mon Sep 17 00:00:00 2001 From: Mehdi Bechiri Date: Thu, 17 Aug 2023 06:56:36 -0700 Subject: [PATCH] feat(helm): create charts for deployment (#51) --- .github/workflows/tests.yaml | 2 +- .gitignore | 3 +- .pre-commit-config.yaml | 26 +++++ .pre-commit-hooks.yaml | 8 ++ Dockerfile | 2 +- charts/eth-validator-watcher/Chart.yaml | 9 ++ charts/eth-validator-watcher/README.md | 62 +++++++++++ .../templates/_helpers.tpl | 62 +++++++++++ .../templates/configmap.yaml | 14 +++ .../templates/deployment.yaml | 103 ++++++++++++++++++ .../templates/service.yaml | 15 +++ .../templates/serviceaccount.yaml | 12 ++ .../templates/servicemonitor.yaml | 40 +++++++ charts/eth-validator-watcher/values.yaml | 98 +++++++++++++++++ pyproject.toml | 2 +- tests/beacon/assets/block.json | 2 +- tests/beacon/assets/committees.json | 2 +- tests/beacon/assets/genesis.json | 2 +- .../assets/liveness_request_beacon_api.json | 2 +- .../assets/liveness_request_lighthouse.json | 2 +- .../beacon/assets/liveness_request_teku.json | 2 +- tests/beacon/assets/liveness_response.json | 2 +- tests/beacon/assets/proposer_duties.json | 2 +- tests/beacon/assets/validators.json | 2 +- tests/execution/assets/block.json | 2 +- tests/fee_recipient/assets/block.json | 2 +- .../assets/empty_execution_block.json | 2 +- .../fee_recipient/assets/execution_block.json | 2 +- .../suboptimal_attestations/assets/block.json | 2 +- 29 files changed, 468 insertions(+), 18 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 .pre-commit-hooks.yaml create mode 100644 charts/eth-validator-watcher/Chart.yaml create mode 100644 charts/eth-validator-watcher/README.md create mode 100644 charts/eth-validator-watcher/templates/_helpers.tpl create mode 100644 charts/eth-validator-watcher/templates/configmap.yaml create mode 100644 charts/eth-validator-watcher/templates/deployment.yaml create mode 100644 charts/eth-validator-watcher/templates/service.yaml create mode 100644 charts/eth-validator-watcher/templates/serviceaccount.yaml create mode 100644 charts/eth-validator-watcher/templates/servicemonitor.yaml create mode 100644 charts/eth-validator-watcher/values.yaml diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 999a3c2..f3ae294 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -23,4 +23,4 @@ jobs: - name: Run tests run: poetry run pytest --cov eth_validator_watcher --cov-report xml - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 \ No newline at end of file + uses: codecov/codecov-action@v3 diff --git a/.gitignore b/.gitignore index 30d4424..2ed77d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ .mypy_cache -.coverage \ No newline at end of file +.coverage +.idea diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..56c99de --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,26 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + exclude: ^docs/ + - id: end-of-file-fixer + exclude: ^docs/ + - id: check-added-large-files + exclude: ^docs/ + - id: check-yaml + exclude: ^charts/ +- repo: https://github.com/norwoodj/helm-docs + rev: v1.11.0 + hooks: + - id: helm-docs + args: + # Make the tool search for charts only under the `example-charts` directory + - --chart-search-root=charts + + # The `./` makes it relative to the chart-search-root set above + - --template-files=./_templates.gotmpl + + # Repeating the flag adds this to the list, now [./_templates.gotmpl, README.md.gotmpl] + # A base filename makes it relative to each chart directory found + - --template-files=README.md.gotmpl diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml new file mode 100644 index 0000000..ccf40ec --- /dev/null +++ b/.pre-commit-hooks.yaml @@ -0,0 +1,8 @@ +- id: helm-docs + args: [] + description: Uses 'helm-docs' to create documentation from the Helm chart's 'values.yaml' file, and inserts the result into a corresponding 'README.md' file. + entry: git-hook/helm-docs + files: (README\.md\.gotmpl|(Chart|requirements|values)\.yaml)$ + language: script + name: Helm Docs + require_serial: true diff --git a/Dockerfile b/Dockerfile index aa1e7f9..631389e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,4 @@ COPY liveness_check.py /usr/local/bin/liveness_check.py ENV PYTHONPATH=/usr/local/lib/python3.9/site-packages -ENTRYPOINT [ "python", "/usr/local/bin/eth-validator-watcher" ] +ENTRYPOINT [ "python", "/usr/local/bin/eth-validator-watcher" ] diff --git a/charts/eth-validator-watcher/Chart.yaml b/charts/eth-validator-watcher/Chart.yaml new file mode 100644 index 0000000..cb3fee8 --- /dev/null +++ b/charts/eth-validator-watcher/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +description: A Helm chart for running eth-validator-watcher +name: eth-validator-watcher +type: application +version: 1.0.0 +maintainers: + - name: Alluvial + email: contact@alluvial.finance + url: https://alluvial.finance diff --git a/charts/eth-validator-watcher/README.md b/charts/eth-validator-watcher/README.md new file mode 100644 index 0000000..ba4d5d0 --- /dev/null +++ b/charts/eth-validator-watcher/README.md @@ -0,0 +1,62 @@ +# eth-validator-watcher + +![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) + +A Helm chart for running eth-validator-watcher + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Alluvial | | | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| args | list | `[]` | Specifies the arguments to the command line Please refer to https://github.com/kilnfi/eth-validator-watcher/blob/main/README.md#description | +| env | object | `{}` | | +| envFrom | object | `{}` | | +| fullnameOverride | string | `""` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"ghcr.io/kilnfi/eth-validator-watcher"` | | +| image.tag | string | `"latest"` | | +| imagePullSecrets | list | `[]` | | +| livenessProbe.exec.command[0] | string | `"/usr/bin/python3.9"` | | +| livenessProbe.exec.command[1] | string | `"/usr/local/bin/liveness_check.py"` | | +| livenessProbe.exec.command[2] | string | `"/tmp/liveness"` | | +| livenessProbe.failureThreshold | int | `10` | | +| livenessProbe.initialDelaySeconds | int | `120` | | +| livenessProbe.periodSeconds | int | `60` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | | +| podSecurityContext | object | `{}` | | +| readinessProbe.exec.command[0] | string | `"/usr/bin/python3.9"` | | +| readinessProbe.exec.command[1] | string | `"/usr/local/bin/liveness_check.py"` | | +| readinessProbe.exec.command[2] | string | `"/tmp/liveness"` | | +| readinessProbe.failureThreshold | int | `10` | | +| readinessProbe.initialDelaySeconds | int | `30` | | +| readinessProbe.periodSeconds | int | `60` | | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| securityContext | object | `{}` | | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | +| serviceMonitor.additionalLabels | object | `{}` | | +| serviceMonitor.enabled | bool | `false` | | +| serviceMonitor.metricRelabelings | list | `[]` | | +| serviceMonitor.namespace | string | `""` | | +| serviceMonitor.namespaceSelector | object | `{}` | | +| serviceMonitor.scrapeInterval | string | `"60s"` | | +| serviceMonitor.targetLabels | list | `[]` | | +| startupProbe | object | `{}` | | +| tolerations | list | `[]` | | +| volumeMounts | list | `[]` | | +| volumes | list | `[]` | | +| watchedKeys | list | `[]` | List of public keys to watch. See https://github.com/kilnfi/eth-validator-watcher/blob/main/README.md#command-lines-examples | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) diff --git a/charts/eth-validator-watcher/templates/_helpers.tpl b/charts/eth-validator-watcher/templates/_helpers.tpl new file mode 100644 index 0000000..b6d897a --- /dev/null +++ b/charts/eth-validator-watcher/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "eth-validator-watcher.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "eth-validator-watcher.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "eth-validator-watcher.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "eth-validator-watcher.labels" -}} +helm.sh/chart: {{ include "eth-validator-watcher.chart" . }} +{{ include "eth-validator-watcher.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "eth-validator-watcher.selectorLabels" -}} +app.kubernetes.io/name: {{ include "eth-validator-watcher.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "eth-validator-watcher.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "eth-validator-watcher.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/eth-validator-watcher/templates/configmap.yaml b/charts/eth-validator-watcher/templates/configmap.yaml new file mode 100644 index 0000000..ff2f616 --- /dev/null +++ b/charts/eth-validator-watcher/templates/configmap.yaml @@ -0,0 +1,14 @@ +{{- if .Values.watchedKeys }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "eth-validator-watcher.fullname" . }} + labels: + {{- include "eth-validator-watcher.labels" . | nindent 4 }} +data: + watched-keys.txt: | + {{- range .Values.watchedKeys }} + {{- . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/eth-validator-watcher/templates/deployment.yaml b/charts/eth-validator-watcher/templates/deployment.yaml new file mode 100644 index 0000000..c19c970 --- /dev/null +++ b/charts/eth-validator-watcher/templates/deployment.yaml @@ -0,0 +1,103 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "eth-validator-watcher.fullname" . }} + labels: + {{- include "eth-validator-watcher.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "eth-validator-watcher.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "eth-validator-watcher.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "eth-validator-watcher.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: eth-validator-watcher + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + {{- if .Values.watchedKeys }} + - --pubkeys-file-path=/data/keys/watched-keys.txt + {{- end }} + {{- with .Values.args }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: metrics + containerPort: 8000 + protocol: TCP + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupProbe }} + startupProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.env .Values.envFrom }} + env: + {{- with .Values.envFrom }} + {{- range $key, $value := . }} + - name: {{ $key }} + {{- toYaml $value | nindent 12 }} + {{- end }} + {{- end }} + {{- with .Values.env }} + {{- range $key, $value := . }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.watchedKeys }} + volumeMounts: + - name: "watched-keys" + mountPath: "/data/keys" + readOnly: true + {{- end }} + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.watchedKeys }} + volumes: + - name: "watched-keys" + configMap: + name: {{ include "eth-validator-watcher.fullname" . }} + {{- end }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/eth-validator-watcher/templates/service.yaml b/charts/eth-validator-watcher/templates/service.yaml new file mode 100644 index 0000000..370653a --- /dev/null +++ b/charts/eth-validator-watcher/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "eth-validator-watcher.fullname" . }} + labels: + {{- include "eth-validator-watcher.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: metrics + port: 8000 + targetPort: metrics + protocol: TCP + selector: + {{- include "eth-validator-watcher.selectorLabels" . | nindent 4 }} diff --git a/charts/eth-validator-watcher/templates/serviceaccount.yaml b/charts/eth-validator-watcher/templates/serviceaccount.yaml new file mode 100644 index 0000000..1070f43 --- /dev/null +++ b/charts/eth-validator-watcher/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "eth-validator-watcher.serviceAccountName" . }} + labels: + {{- include "eth-validator-watcher.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/eth-validator-watcher/templates/servicemonitor.yaml b/charts/eth-validator-watcher/templates/servicemonitor.yaml new file mode 100644 index 0000000..a37b354 --- /dev/null +++ b/charts/eth-validator-watcher/templates/servicemonitor.yaml @@ -0,0 +1,40 @@ +{{- if .Values.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "eth-validator-watcher.fullname" . }} +{{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace | quote }} +{{- end }} + labels: + {{- include "eth-validator-watcher.labels" . | nindent 4 }} + {{- if .Values.serviceMonitor.additionalLabels }} + {{- toYaml .Values.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: metrics + interval: {{ .Values.serviceMonitor.scrapeInterval }} + {{- if .Values.serviceMonitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.serviceMonitor.metricRelabelings | nindent 8 }} + {{- end }} +{{- if .Values.serviceMonitor.namespaceSelector }} + namespaceSelector: {{ toYaml .Values.serviceMonitor.namespaceSelector | nindent 4 }} +{{ else }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} +{{- if .Values.serviceMonitor.targetLabels }} + targetLabels: + {{- range .Values.serviceMonitor.targetLabels }} + - {{ . }} + {{- end }} +{{- end }} + selector: + matchLabels: + {{- include "eth-validator-watcher.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/eth-validator-watcher/values.yaml b/charts/eth-validator-watcher/values.yaml new file mode 100644 index 0000000..5140344 --- /dev/null +++ b/charts/eth-validator-watcher/values.yaml @@ -0,0 +1,98 @@ +replicaCount: 1 + +image: + repository: ghcr.io/kilnfi/eth-validator-watcher + pullPolicy: IfNotPresent + tag: "latest" + +# -- Specifies the arguments to the command line +# Please refer to https://github.com/kilnfi/eth-validator-watcher/blob/main/README.md#description +args: [] + +env: {} +envFrom: {} + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # -- Specifies whether a service account should be created + create: true + # -- Annotations to add to the service account + annotations: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +livenessProbe: + periodSeconds: 60 + initialDelaySeconds: 120 + failureThreshold: 10 + exec: + command: + - /usr/bin/python3.9 + - /usr/local/bin/liveness_check.py + - /tmp/liveness +readinessProbe: + periodSeconds: 60 + initialDelaySeconds: 30 + failureThreshold: 10 + exec: + command: + - /usr/bin/python3.9 + - /usr/local/bin/liveness_check.py + - /tmp/liveness +startupProbe: {} + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +volumes: [] + +volumeMounts: [] + +serviceMonitor: + enabled: false + additionalLabels: {} + namespace: "" + namespaceSelector: {} + # Default: scrape .Release.Namespace only + # To scrape all, use the following: + # namespaceSelector: + # any: true + scrapeInterval: 60s + # honorLabels: true + targetLabels: [] + metricRelabelings: [] + +# -- List of public keys to watch. See https://github.com/kilnfi/eth-validator-watcher/blob/main/README.md#command-lines-examples +watchedKeys: [] diff --git a/pyproject.toml b/pyproject.toml index 7311824..3a54834 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,4 +29,4 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.poetry.scripts] -eth-validator-watcher = "eth_validator_watcher.entrypoint:app" \ No newline at end of file +eth-validator-watcher = "eth_validator_watcher.entrypoint:app" diff --git a/tests/beacon/assets/block.json b/tests/beacon/assets/block.json index 24aab51..c895dad 100644 --- a/tests/beacon/assets/block.json +++ b/tests/beacon/assets/block.json @@ -109,4 +109,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/beacon/assets/committees.json b/tests/beacon/assets/committees.json index 37fdfee..b60e2c6 100644 --- a/tests/beacon/assets/committees.json +++ b/tests/beacon/assets/committees.json @@ -38,4 +38,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/tests/beacon/assets/genesis.json b/tests/beacon/assets/genesis.json index 00538eb..2125fef 100644 --- a/tests/beacon/assets/genesis.json +++ b/tests/beacon/assets/genesis.json @@ -4,4 +4,4 @@ "genesis_validators_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "genesis_fork_version": "0x00000000" } -} \ No newline at end of file +} diff --git a/tests/beacon/assets/liveness_request_beacon_api.json b/tests/beacon/assets/liveness_request_beacon_api.json index 9526a0e..e606865 100644 --- a/tests/beacon/assets/liveness_request_beacon_api.json +++ b/tests/beacon/assets/liveness_request_beacon_api.json @@ -2,4 +2,4 @@ "42", "44", "46" -] \ No newline at end of file +] diff --git a/tests/beacon/assets/liveness_request_lighthouse.json b/tests/beacon/assets/liveness_request_lighthouse.json index 05fc2fd..5447980 100644 --- a/tests/beacon/assets/liveness_request_lighthouse.json +++ b/tests/beacon/assets/liveness_request_lighthouse.json @@ -5,4 +5,4 @@ 46 ], "epoch": 1664 -} \ No newline at end of file +} diff --git a/tests/beacon/assets/liveness_request_teku.json b/tests/beacon/assets/liveness_request_teku.json index 4c56a61..342b971 100644 --- a/tests/beacon/assets/liveness_request_teku.json +++ b/tests/beacon/assets/liveness_request_teku.json @@ -4,4 +4,4 @@ 44, 46 ] -} \ No newline at end of file +} diff --git a/tests/beacon/assets/liveness_response.json b/tests/beacon/assets/liveness_response.json index d5fa6b6..4f5c99d 100644 --- a/tests/beacon/assets/liveness_response.json +++ b/tests/beacon/assets/liveness_response.json @@ -16,4 +16,4 @@ "is_live": true } ] -} \ No newline at end of file +} diff --git a/tests/beacon/assets/proposer_duties.json b/tests/beacon/assets/proposer_duties.json index 8efe7cb..459bb1a 100644 --- a/tests/beacon/assets/proposer_duties.json +++ b/tests/beacon/assets/proposer_duties.json @@ -17,4 +17,4 @@ "slot": "209346" } ] -} \ No newline at end of file +} diff --git a/tests/beacon/assets/validators.json b/tests/beacon/assets/validators.json index a7bff0a..5998adc 100644 --- a/tests/beacon/assets/validators.json +++ b/tests/beacon/assets/validators.json @@ -77,4 +77,4 @@ } } ] -} \ No newline at end of file +} diff --git a/tests/execution/assets/block.json b/tests/execution/assets/block.json index a10662b..aa16f47 100644 --- a/tests/execution/assets/block.json +++ b/tests/execution/assets/block.json @@ -47,4 +47,4 @@ } ] } -} \ No newline at end of file +} diff --git a/tests/fee_recipient/assets/block.json b/tests/fee_recipient/assets/block.json index 24aab51..c895dad 100644 --- a/tests/fee_recipient/assets/block.json +++ b/tests/fee_recipient/assets/block.json @@ -109,4 +109,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/fee_recipient/assets/empty_execution_block.json b/tests/fee_recipient/assets/empty_execution_block.json index 8cecef2..251bee5 100644 --- a/tests/fee_recipient/assets/empty_execution_block.json +++ b/tests/fee_recipient/assets/empty_execution_block.json @@ -4,4 +4,4 @@ "result": { "transactions": [] } -} \ No newline at end of file +} diff --git a/tests/fee_recipient/assets/execution_block.json b/tests/fee_recipient/assets/execution_block.json index a10662b..aa16f47 100644 --- a/tests/fee_recipient/assets/execution_block.json +++ b/tests/fee_recipient/assets/execution_block.json @@ -47,4 +47,4 @@ } ] } -} \ No newline at end of file +} diff --git a/tests/suboptimal_attestations/assets/block.json b/tests/suboptimal_attestations/assets/block.json index b3261b4..5b8cbdf 100644 --- a/tests/suboptimal_attestations/assets/block.json +++ b/tests/suboptimal_attestations/assets/block.json @@ -90,4 +90,4 @@ } } } -} \ No newline at end of file +}