From 5c9a71e4f1c322eafab5e19424df83a91968f05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ois=C3=ADn=20Kyne?= Date: Thu, 19 Jun 2025 19:24:21 +0100 Subject: [PATCH] Hacked example of running aztec full-node on stack --- README.md | 3 + charts/aztec-node/Chart.yaml | 6 + charts/aztec-node/README.md | 192 +++++++++++ charts/aztec-node/templates/_helpers.tpl | 72 +++++ charts/aztec-node/templates/clusterrole.yaml | 10 + .../templates/clusterrolebinding.yaml | 16 + charts/aztec-node/templates/role.yaml | 10 + charts/aztec-node/templates/rolebinding.yaml | 15 + charts/aztec-node/templates/secret.yaml | 15 + .../aztec-node/templates/serviceaccount.yaml | 13 + charts/aztec-node/templates/statefulset.yaml | 305 ++++++++++++++++++ charts/aztec-node/templates/svc.headless.yaml | 33 ++ charts/aztec-node/templates/svc.nodeport.yaml | 31 ++ charts/aztec-node/templates/svc.yaml | 35 ++ charts/aztec-node/values.yaml | 195 +++++++++++ obolup/manifests/kind_host.yaml | 4 + values/erpc.yaml | 16 + values/hoodi/aztec-node.yaml | 48 +++ 18 files changed, 1019 insertions(+) create mode 100644 charts/aztec-node/Chart.yaml create mode 100644 charts/aztec-node/README.md create mode 100644 charts/aztec-node/templates/_helpers.tpl create mode 100644 charts/aztec-node/templates/clusterrole.yaml create mode 100644 charts/aztec-node/templates/clusterrolebinding.yaml create mode 100644 charts/aztec-node/templates/role.yaml create mode 100644 charts/aztec-node/templates/rolebinding.yaml create mode 100644 charts/aztec-node/templates/secret.yaml create mode 100644 charts/aztec-node/templates/serviceaccount.yaml create mode 100644 charts/aztec-node/templates/statefulset.yaml create mode 100644 charts/aztec-node/templates/svc.headless.yaml create mode 100644 charts/aztec-node/templates/svc.nodeport.yaml create mode 100644 charts/aztec-node/templates/svc.yaml create mode 100644 charts/aztec-node/values.yaml create mode 100644 values/hoodi/aztec-node.yaml diff --git a/README.md b/README.md index 4f20824..82f91d8 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,9 @@ The Obol Stack is built on Helm, so you can add your own Helm Chart repository e obol repo add ithaca https://github.com/ithacaxyz/obol-charts # Install a chart from the new 'App Store' obol install ithaca/op-reth + +helm upgrade --install aztec ../charts/aztec-node -f ../values/hoodi/aztec-node.yaml --namespace aztec --create-namespace + ``` ### Custom deployments diff --git a/charts/aztec-node/Chart.yaml b/charts/aztec-node/Chart.yaml new file mode 100644 index 0000000..08d59c0 --- /dev/null +++ b/charts/aztec-node/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: aztec-node +description: A Helm chart for deploying an Aztec node +type: application +version: 0.1.0 +appVersion: "1.0.0" diff --git a/charts/aztec-node/README.md b/charts/aztec-node/README.md new file mode 100644 index 0000000..088fb2e --- /dev/null +++ b/charts/aztec-node/README.md @@ -0,0 +1,192 @@ +## Aztec Node Chart + +A chart for deploying a Stateful set of nodes into a kubernetes cluster. + +## Networking +There are two options on how to run these containers with external networking. +- hostNetwork +- nodePort + +***Host Networking*** +Host networking is useful whenever you want to deploy multiple replicas that all have open ports on the nodes they are running on. However, this will only work if the pod's affinity is set accordingly. +If you deploy a set of containers that all have the same p2p ports, they need to be scheduled onto different k8s nodes. + +***Node Port*** +If you do not have access to multiple k8s nodes, you can deploy using the `service.p2p.enableNodePort` option. If you want to run multiple instances on the same k8s node, you will need to deploy this chart mulitple +times, each with a different p2p port set. + +## Examples +### Running an aztec full node +```yaml +# -- Image to use for the container +image: + # -- Image repository + repository: aztecprotocol/aztec + # -- Image tag + tag: 0.85.0-alpha-testnet.9 + # -- Container pull policy + pullPolicy: IfNotPresent + +network: alpha-testnet + +hostNetwork: true + +node: + replicas: 1 + logLevel: "debug; info: aztec:simulator, json-rpc" + + l1ExecutionUrls: [] + l1ConsensusUrls: [] + + startCmd: + - --node + - --archiver + + startupProbe: + # -- Period seconds + periodSeconds: 60 + # -- Failure threshold + failureThreshold: 60 + +persistence: + enabled: true + size: 512Gi + storageClassName: standard + accessModes: + - ReadWriteOnce + selector: {} + +service: + p2p: + enabled: true + nodePortEnabled: false + port: 40400 + announcePort: 40400 + admin: + enabled: true + port: 8081 + httpPort: 8080 +``` + +## Example running a validator node +```yaml +image: + repository: aztecprotocol/aztec + tag: 0.85.0-alpha-testnet.9 + pullPolicy: IfNotPresent + +network: alpha-testnet +hostNetwork: true + +node: + replicas: 1 + logLevel: "debug; info: aztec:simulator, json-rpc" + + l1ExecutionUrls: [] + l1ConsensusUrls: [] + + l1Publisher: + mnemonic: "your validator mnemonic" + mnemonicStartIndex: 0 + + startCmd: + - --node + - --archiver + - --sequencer + + startupProbe: + # -- Period seconds + periodSeconds: 60 + # -- Failure threshold + failureThreshold: 60 + +persistence: + enabled: true + size: 512Gi + storageClassName: standard + accessModes: + - ReadWriteOnce + selector: {} + +service: + p2p: + enabled: true + nodePortEnabled: false + port: 40400 + announcePort: 40400 + admin: + enabled: true + port: 8081 + httpPort: 8080 +``` + +# All options +| Option Path | Default | Description | +|------------|---------|-------------| +| nameOverride | "" | Overrides the chart name | +| fullnameOverride | "" | Overrides the chart computed fullname | +| image.repository | aztecprotocol/aztec | Image repository for the container | +| image.tag | alpha-testnet | Image tag for the container | +| image.pullPolicy | IfNotPresent | Container pull policy | +| podManagementPolicy | Parallel | Pod management policy | +| network | - | Network name - predefined network (alpha-testnet, devnet) | +| customNetwork.l1ChainId | - | L1 chain ID for custom network | +| customNetwork.registryContractAddress | - | Registry contract address for custom network | +| customNetwork.slashFactoryAddress | - | Slash factory address for custom network | +| customNetwork.feeAssetHandlerContractAddress | - | Fee asset handler contract address for custom network | +| rollupVersion | "canonical" | Which rollup contract to follow from the registry | +| hostNetwork | false | Use host network (disables nodePort service) | +| node.replicas | 1 | Number of replicas | +| node.logLevel | "info" | Log level (info, verbose, debug, trace) | +| node.l1Publisher.privateKeys | [] | Private keys for L1 publisher | +| node.l1Publisher.mnemonic | - | Mnemonic for L1 publisher | +| node.l1Publisher.mnemonicStartIndex | - | Starting index for mnemonic | +| node.l1ExecutionUrls | [] | Ethereum hosts (comma-separated list) | +| node.l1ConsensusUrls | [] | L1 consensus host URLs (comma-separated list) | +| node.l1ConsensusHostApiKeys | [] | API keys for L1 consensus hosts | +| node.l1ConsensusHostApiKeyHeaders | [] | API key headers for L1 consensus hosts | +| node.startCmd | ["--node", "--archiver"] | Startup command for the node | +| node.remoteUrl.archiver | - | Remote URL for archiver | +| node.remoteUrl.proverBroker | - | Remote URL for prover broker | +| node.remoteUrl.proverCoordinationNodes | [] | Remote URLs for prover coordination nodes | +| node.remoteUrl.blobSink | - | Remote URL for blob sink | +| node.coinbase | - | Address that will receive block or proof rewards | +| node.sentinel.enabled | false | Enable sentinel configuration for slashing information | +| node.metrics.otelExcludeMetrics | "" | Comma-separated list of metrics to exclude | +| node.metrics.otelCollectorEndpoint | "" | Collector endpoint (e.g., http://localhost:4318) | +| node.metrics.useGcloudLogging | false | Use GCP logging | +| node.storage.dataDirectory | /data | Data directory | +| node.storage.dataStoreMapSize | - | Data store map size (kB) | +| node.storage.worldStateMapSize | - | World state map size (kB) | +| node.storage.p2pStorageMapSize | - | P2P storage map size (kB) | +| node.storage.archiveStorageMapSize | - | Archive storage map size (kB) | +| node.nodeJsOptions | ["--no-warnings", "--max-old-space-size=4096"] | Node.js options | +| node.startupProbe.periodSeconds | 30 | Period seconds for startup probe | +| node.startupProbe.failureThreshold | 3 | Failure threshold for startup probe | +| persistence.enabled | false | Enable persistence (uses emptyDir when disabled) | +| persistence.existingClaim | null | Use an existing PVC | +| persistence.accessModes | ["ReadWriteOnce"] | Access modes for persistence | +| persistence.size | 100Gi | Requested size for persistence | +| persistence.storageClassName | null | Storage class name for persistence | +| persistence.annotations | {} | Annotations for volume claim template | +| persistence.selector | {} | Selector for volume claim template | +| updateStrategy.type | RollingUpdate | Update strategy for the statefulset | +| initContainers | [] | Additional init containers | +| service.ingress.enabled | false | Enable ingress | +| service.ingress.annotations | {} | Ingress annotations | +| service.ingress.hosts | [] | Ingress hosts | +| service.p2p.enabled | true | Enable P2P service | +| service.p2p.nodePortEnabled | true | Enable node port for P2P service | +| service.p2p.port | 40400 | P2P port | +| service.p2p.announcePort | 40400 | P2P announce port | +| service.admin.enabled | true | Enable admin service | +| service.admin.port | 8081 | Admin port | +| service.httpPort | 8080 | HTTP port | +| certificate.enabled | false | Enable certificate configuration | +| certificate.domains | [] | Certificate domains | +| rbac.create | true | Create RBAC resources | +| rbac.clusterRules | See values.yaml | Required ClusterRole rules | +| rbac.rules | See values.yaml | Required Role rules | +| serviceAccount.create | true | Create a service account | +| serviceAccount.name | "" | Name of the service account | +| serviceAccount.annotations | {} | Annotations for the service account | diff --git a/charts/aztec-node/templates/_helpers.tpl b/charts/aztec-node/templates/_helpers.tpl new file mode 100644 index 0000000..524e8c5 --- /dev/null +++ b/charts/aztec-node/templates/_helpers.tpl @@ -0,0 +1,72 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | 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 "chart.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 }} + +{{/* +Common labels +*/}} +{{- define "chart.labels" -}} +helm.sh/chart: {{ include "chart.chart" . }} +{{ include "chart.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "chart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "chart.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the cluster role. +It needs to be namespace prefixed to avoid naming conflicts when using the same deployment name across namespaces. +*/}} +{{- define "chart.clusterRoleName" -}} +{{ .Release.Namespace }}-{{ include "chart.fullname" . }} +{{- end }} + diff --git a/charts/aztec-node/templates/clusterrole.yaml b/charts/aztec-node/templates/clusterrole.yaml new file mode 100644 index 0000000..fc07c5e --- /dev/null +++ b/charts/aztec-node/templates/clusterrole.yaml @@ -0,0 +1,10 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "chart.clusterRoleName" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +rules: +{{- toYaml .Values.rbac.clusterRules | nindent 0 }} +{{- end }} diff --git a/charts/aztec-node/templates/clusterrolebinding.yaml b/charts/aztec-node/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..7b0bfd3 --- /dev/null +++ b/charts/aztec-node/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "chart.clusterRoleName" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "chart.clusterRoleName" . }} +subjects: + - kind: ServiceAccount + name: {{ include "chart.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/aztec-node/templates/role.yaml b/charts/aztec-node/templates/role.yaml new file mode 100644 index 0000000..10d5acb --- /dev/null +++ b/charts/aztec-node/templates/role.yaml @@ -0,0 +1,10 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "chart.serviceAccountName" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +rules: +{{- toYaml .Values.rbac.rules | nindent 0 }} +{{- end }} diff --git a/charts/aztec-node/templates/rolebinding.yaml b/charts/aztec-node/templates/rolebinding.yaml new file mode 100644 index 0000000..32d7a79 --- /dev/null +++ b/charts/aztec-node/templates/rolebinding.yaml @@ -0,0 +1,15 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "chart.serviceAccountName" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "chart.serviceAccountName" . }} +subjects: + - kind: ServiceAccount + name: {{ include "chart.serviceAccountName" . }} +{{- end }} diff --git a/charts/aztec-node/templates/secret.yaml b/charts/aztec-node/templates/secret.yaml new file mode 100644 index 0000000..0e057fb --- /dev/null +++ b/charts/aztec-node/templates/secret.yaml @@ -0,0 +1,15 @@ +{{- if or (has "--sequencer" .Values.node.startCmd) (has "--prover-node" .Values.node.startCmd) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "chart.fullname" . }}-l1-publisher + labels: + {{- include "chart.labels" . | nindent 4 }} +data: + {{- if .Values.node.l1Publisher.mnemonic }} + mnemonic: {{ .Values.node.l1Publisher.mnemonic | b64enc }} + mnemonicStartIndex: {{ or .Values.node.l1Publisher.mnemonicStartIndex 1 | toString | b64enc }} + {{- else }} + privateKeys: {{ join "\n" .Values.node.l1Publisher.privateKeys | b64enc }} + {{- end }} +{{- end }} diff --git a/charts/aztec-node/templates/serviceaccount.yaml b/charts/aztec-node/templates/serviceaccount.yaml new file mode 100644 index 0000000..068ee50 --- /dev/null +++ b/charts/aztec-node/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "chart.serviceAccountName" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/aztec-node/templates/statefulset.yaml b/charts/aztec-node/templates/statefulset.yaml new file mode 100644 index 0000000..a3d641f --- /dev/null +++ b/charts/aztec-node/templates/statefulset.yaml @@ -0,0 +1,305 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + serviceName: {{ include "chart.fullname" . }} + replicas: {{ .Values.node.replicas }} + podManagementPolicy: {{ .Values.podManagementPolicy }} + updateStrategy: + {{- toYaml .Values.node.updateStrategy | nindent 4 }} + selector: + matchLabels: + {{- include "chart.selectorLabels" . | nindent 6 }} + app: node + template: + metadata: + labels: + {{- include "chart.selectorLabels" . | nindent 8 }} + app: node + spec: + serviceAccountName: {{ include "chart.serviceAccountName" . }} + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: {{ .Values.hostNetwork }} + {{- if or .Values.service.p2p.nodePortEnabled .Values.hostNetwork }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - node + topologyKey: kubernetes.io/hostname + namespaceSelector: {} + {{- end }} + initContainers: + {{- if .Values.initContainers }} + {{- tpl (toYaml .Values.initContainers | nindent 8) $ }} + {{- end }} + {{- if or .Values.service.p2p.nodePortEnabled .Values.hostNetwork }} + - name: init-nodeport + image: bitnami/kubectl + securityContext: + runAsNonRoot: false + runAsUser: 0 + command: + - sh + - -c + - > + export POD_INDEX=$(echo ${POD_NAME} | awk -F'-' '{print $NF}'); + + # If running host network, we don't need to get the node port from the service + {{- if not .Values.hostNetwork }} + export EXTERNAL_PORT=$(kubectl get services -l "pod-index in (${POD_INDEX}), type in (p2p)" -o jsonpath='{.items[0].spec.ports[0].nodePort}'); + echo "export EXTERNAL_PORT=$EXTERNAL_PORT" > /env/init-nodeport; + echo "export P2P_PORT=$EXTERNAL_PORT" >> /env/init-nodeport; + {{- end }} + + # Get the external IP of the node + export EXTERNAL_IP=$(kubectl get nodes "${NODE_NAME}" -o jsonpath='{.status.addresses[?(@.type=="ExternalIP")].address}'); + + echo "export EXTERNAL_IP=$EXTERNAL_IP" >> /env/init-nodeport; + echo "export P2P_IP=$EXTERNAL_IP" >> /env/init-nodeport; + cat /env/init-nodeport; + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: init-nodeport + mountPath: /env + {{- end }} + containers: + - name: aztec + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /bin/bash + - -c + - | + {{- if or .Values.service.p2p.nodePortEnabled .Values.hostNetwork }} + source /env/init-nodeport; + {{- else }} + export P2P_IP=$(hostname -i) + {{- end }} + + start_cmd=("node" "/usr/src/yarn-project/aztec/dest/bin/index.js" "start") + pod_index=$(echo $K8S_POD_NAME | awk -F'-' '{print $NF}') + + {{- if or (has "--sequencer" .Values.node.startCmd) (has "--prover-node" .Values.node.startCmd) }} + if [[ -f /config/l1-publisher/mnemonic ]]; then + mnemonic=$(cat /config/l1-publisher/mnemonic) + mnemonic_start_index=$(cat /config/l1-publisher/mnemonicStartIndex) + + + export L1_PUBLISHER_KEY=$(cast wallet private-key --mnemonic "$mnemonic" --mnemonic-index $(($mnemonic_start_index + $pod_index))) + export VALIDATOR_PRIVATE_KEY=$L1_PUBLISHER_KEY + export SEQ_PUBLISHER_PRIVATE_KEY=$L1_PUBLISHER_KEY + + elif [[ -f /config/l1-publisher/privateKeys ]]; then + line_index=$(($pod_index + 1)) + export L1_PUBLISHER_KEY=$(sed -n -e "${line_index}p;${line_index}q" /config/l1-publisher/privateKeys) + + if [[ -z $L1_PUBLISHER_KEY ]]; then + echo "Private key for pod $K8S_POD_NAME not found" + exit 1 + fi + + else + echo "No mnemonic or private keys configured." + exit 1 + fi + {{- end }} + + start_cmd+=({{ join " " .Values.node.startCmd }}) + + {{- if .Values.node.preStartScript }} + {{ .Values.node.preStartScript | nindent 14 }} + + {{- end }} + "${start_cmd[@]}" + startupProbe: + httpGet: + path: /status + port: {{ .Values.service.httpPort }} + periodSeconds: {{ .Values.node.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.node.startupProbe.failureThreshold }} + livenessProbe: + httpGet: + path: /status + port: {{ .Values.service.httpPort }} + initialDelaySeconds: 30 + periodSeconds: 5 + timeoutSeconds: 30 + failureThreshold: 3 + volumeMounts: + - name: storage + mountPath: {{ .Values.node.storage.dataDirectory }} + {{- if or .Values.service.p2p.nodePortEnabled .Values.hostNetwork }} + - name: init-nodeport + mountPath: /env + {{- end }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: K8S_POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + - name: K8S_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OTEL_SERVICE_NAME + value: node + - name: K8S_NAMESPACE_NAME + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.network }} + - name: NETWORK + value: "{{ .Values.network }}" + {{- else }} + - name: REGISTRY_CONTRACT_ADDRESS + value: "{{ .Values.customNetwork.registryContractAddress }}" + - name: L1_CHAIN_ID + value: "{{ .Values.customNetwork.l1ChainId }}" + - name: SLASH_FACTORY_ADDRESS + value: "{{ .Values.customNetwork.slashFactoryAddress }}" + - name: FEE_ASSET_HANDLER_CONTRACT_ADDRESS + value: "{{ .Values.customNetwork.feeAssetHandlerContractAddress }}" + {{- end }} + - name: NODE_OPTIONS + value: {{ join " " .Values.node.nodeJsOptions | quote }} + - name: AZTEC_PORT + value: "{{ .Values.service.httpPort }}" + - name: AZTEC_ADMIN_PORT + value: "{{ .Values.service.admin.port }}" + - name: LOG_LEVEL + value: "{{ .Values.node.logLevel }}" + - name: LOG_JSON + value: "1" + - name: P2P_ENABLED + value: "{{ .Values.service.p2p.enabled }}" + - name: P2P_PORT + value: "{{ .Values.service.p2p.port }}" + - name: P2P_QUERY_FOR_IP + value: "true" + {{- if .Values.node.remoteUrl.archiver }} + - name: ARCHIVER_URL + value: {{ .Values.node.remoteUrl.archiver | quote }} + {{- end }} + {{- if .Values.node.remoteUrl.proverBroker }} + - name: PROVER_BROKER_HOST + value: {{ .Values.node.remoteUrl.proverBroker | quote }} + {{- end }} + {{- if .Values.node.remoteUrl.blobSink }} + - name: BLOB_SINK_URL + value: {{ .Values.node.remoteUrl.blobSink | quote }} + {{- end }} + {{- if gt (len .Values.node.remoteUrl.proverCoordinationNodes) 0 }} + - name: PROVER_COORDINATION_NODE_URLS + value: {{ join "," .Values.node.remoteUrl.proverCoordinationNodes | quote }} + {{- end }} + {{- if gt (len .Values.node.l1ExecutionUrls) 0 }} + - name: ETHEREUM_HOSTS + value: {{ join "," .Values.node.l1ExecutionUrls | quote }} + {{- end }} + {{- if gt (len .Values.node.l1ConsensusUrls) 0 }} + - name: L1_CONSENSUS_HOST_URLS + value: {{ join "," .Values.node.l1ConsensusUrls | quote }} + - name: L1_CONSENSUS_HOST_API_KEYS + value: {{ join "," .Values.node.l1ConsensusHostApiKeys | quote }} + - name: L1_CONSENSUS_HOST_API_KEY_HEADERS + value: {{ join "," .Values.node.l1ConsensusHostApiKeyHeaders | quote }} + {{- end }} + - name: ARCHIVER_POLLING_INTERVAL_MS + value: "10000" + - name: DATA_DIRECTORY + value: {{ .Values.node.storage.dataDirectory | quote }} + - name: DATA_STORE_MAP_SIZE_KB + value: {{ .Values.node.storage.dataStoreMapSize | quote }} + - name: WS_DB_MAP_SIZE_KB + value: {{ .Values.node.storage.worldStateMapSize | quote }} + - name: USE_GCLOUD_LOGGING + value: {{ .Values.node.metrics.useGcloudLogging | quote }} + {{- if .Values.node.metrics.otelCollectorEndpoint }} + - name: OTEL_EXCLUDE_METRICS + value: {{ .Values.node.metrics.otelExcludeMetrics | quote }} + - name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT + value: "{{ .Values.node.metrics.otelCollectorEndpoint }}/v1/metrics" + - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT + value: "{{ .Values.node.metrics.otelCollectorEndpoint }}/v1/traces" + - name: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT + value: "{{ .Values.node.metrics.otelCollectorEndpoint }}/v1/logs" + {{- end }} + {{- if .Values.node.coinbase }} + - name: COINBASE + value: {{ .Values.node.coinbase | quote }} + - name: PROVER_ID + value: {{ .Values.node.coinbase | quote }} + {{- end }} + - name: SENTINEL_ENABLED + value: {{ .Values.node.sentinel.enabled | quote }} + ports: + - containerPort: {{ .Values.service.httpPort }} + name: http-rpc + {{- if .Values.service.admin.enabled }} + - containerPort: {{ .Values.service.admin.port }} + name: admin + {{- end }} + {{- if .Values.service.p2p.enabled }} + - containerPort: {{ .Values.service.p2p.port }} + name: p2p-tcp + - containerPort: {{ .Values.service.p2p.port }} + protocol: UDP + name: p2p-udp + {{- end }} + resources: + {{- toYaml .Values.node.resources | nindent 12 }} + volumes: + {{- if or (has "--sequencer" .Values.node.startCmd) (has "--prover-node" .Values.node.startCmd) }} + - name: l1-publisher + secret: + secretName: {{ include "chart.fullname" . }}-l1-publisher + {{- end }} + {{- if or .Values.service.p2p.nodePortEnabled .Values.hostNetwork }} + - name: init-nodeport + emptyDir: {} + {{- end }} + {{- if not .Values.persistence.enabled }} + - name: storage + emptyDir: {} + {{- else if .Values.persistence.existingClaim }} + - name: storage + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim }} + {{- else }} + volumeClaimTemplates: + - metadata: + name: storage + annotations: + {{- toYaml .Values.persistence.annotations | nindent 10 }} + spec: + accessModes: + {{- toYaml .Values.persistence.accessModes | nindent 12 }} + resources: + requests: + storage: {{ .Values.persistence.size | quote}} + storageClassName: {{ .Values.persistence.storageClassName }} + {{- if .Values.persistence.selector }} + selector: + {{- toYaml .Values.persistence.selector | nindent 12 }} + {{- end }} + {{- end }} diff --git a/charts/aztec-node/templates/svc.headless.yaml b/charts/aztec-node/templates/svc.headless.yaml new file mode 100644 index 0000000..2c9256e --- /dev/null +++ b/charts/aztec-node/templates/svc.headless.yaml @@ -0,0 +1,33 @@ +{{- if .Values.service.headless.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "chart.fullname" . }}-headless + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + {{- if .Values.service.p2p.enabled }} + - port: {{ .Values.service.p2p.port }} + targetPort: p2p-tcp + protocol: TCP + name: p2p-tcp + - port: {{ .Values.service.p2p.port }} + targetPort: p2p-udp + protocol: UDP + name: p2p-udp + {{- end }} + - port: {{ .Values.service.httpPort }} + targetPort: http-rpc + protocol: TCP + name: http-rpc + {{- if .Values.service.admin.enabled }} + - port: {{ .Values.service.admin.port }} + targetPort: admin + protocol: TCP + name: admin + {{- end }} + selector: + {{- include "chart.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/aztec-node/templates/svc.nodeport.yaml b/charts/aztec-node/templates/svc.nodeport.yaml new file mode 100644 index 0000000..06a29b2 --- /dev/null +++ b/charts/aztec-node/templates/svc.nodeport.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.service.p2p.enabled .Values.service.p2p.nodePortEnabled (not .Values.hostNetwork) -}} +{{- range $i, $e := until (.Values.node.replicas | int) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "chart.fullname" $ }}-p2p-node-port-{{ $i }} + labels: + {{- include "chart.labels" $ | nindent 4 }} + app: node + type: p2p + pod-index: "{{ $i }}" +spec: + type: NodePort + externalTrafficPolicy: Local + ports: + - name: p2p-tcp + port: {{ $.Values.service.p2p.port }} + protocol: TCP + targetPort: p2p-tcp + nodePort: {{ add $.Values.service.p2p.port $i }} + - name: p2p-udp + port: {{ $.Values.service.p2p.port }} + protocol: UDP + targetPort: p2p-udp + nodePort: {{ add $.Values.service.p2p.port $i }} + selector: + {{- include "chart.selectorLabels" $ | nindent 4 }} + statefulset.kubernetes.io/pod-name: "{{ include "chart.fullname" $ }}-{{ $i }}" +{{- end }} +{{- end }} diff --git a/charts/aztec-node/templates/svc.yaml b/charts/aztec-node/templates/svc.yaml new file mode 100644 index 0000000..5c7ad63 --- /dev/null +++ b/charts/aztec-node/templates/svc.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} + {{- with .Values.service.ingress.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} +spec: + type: ClusterIP + ports: + {{- if .Values.service.p2p.enabled }} + - port: {{ .Values.service.p2p.port }} + targetPort: p2p-tcp + protocol: TCP + name: p2p-tcp + - port: {{ .Values.service.p2p.port }} + targetPort: p2p-udp + protocol: UDP + name: p2p-udp + {{- end }} + - port: {{ .Values.service.httpPort }} + targetPort: http-rpc + protocol: TCP + name: http-rpc + {{- if .Values.service.admin.enabled }} + - port: {{ .Values.service.admin.port }} + targetPort: admin + protocol: TCP + name: admin + {{- end }} + selector: + {{- include "chart.selectorLabels" . | nindent 4 }} diff --git a/charts/aztec-node/values.yaml b/charts/aztec-node/values.yaml new file mode 100644 index 0000000..86e3aba --- /dev/null +++ b/charts/aztec-node/values.yaml @@ -0,0 +1,195 @@ +# -- Overrides the chart name +nameOverride: "" +# -- Overrides the chart computed fullname +fullnameOverride: "" + +# -- Image to use for the container +image: + # -- Image repository + repository: aztecprotocol/aztec + # -- Image tag + tag: alpha-testnet + # -- Container pull policy + pullPolicy: IfNotPresent + +# -- Pod management policy +podManagementPolicy: Parallel + +# -- Network name - this is a predefined network - alpha-testnet, devnet +network: + +# -- Custom network - (not recommended) - Only for custom testnet usecases, (must have deployed your own protocol contracts first) +customNetwork: + l1ChainId: + registryContractAddress: + slashFactoryAddress: + feeAssetHandlerContractAddress: + +# Which rollup contract we want to follow from the registry +rollupVersion: "canonical" + +# -- Use host network - this will disable nodePort service and use host networking instead +hostNetwork: false + +# -- Aztec node configuration +node: + # -- Number of replicas + replicas: 1 + # -- Log level - info, verbose, debug, trace + logLevel: "info" + + l1Publisher: + privateKeys: [] + mnemonic: + mnemonicStartIndex: + + # -- Ethereum configuration + # -- Ethereum hosts - comma separated list of hosts (geth, reth are currently supported) + l1ExecutionUrls: [] + # -- L1 consensus host urls - comma separated list of urls + l1ConsensusUrls: [] + ## Only when api key is required via header, otherwise just provide in l1ConsensusHostUrls + ## Example: "1234abcd" + l1ConsensusHostApiKeys: [] + ## Example: "X-API-KEY" + l1ConsensusHostApiKeyHeaders: [] + + preStartScript: "" + + startCmd: + - --node + - --archiver + + remoteUrl: + archiver: + proverBroker: + proverCoordinationNodes: [] + blobSink: + + # the address that will receive block or proof rewards + coinbase: + + # -- Sentinel configuration - gathers slashing information + sentinel: + enabled: false + + # -- Metrics configuration + metrics: + # -- Exclude metrics - comma separated list of metrics to exclude + otelExcludeMetrics: "" + # -- Collector endpoint - e.g. http://localhost:4318 + otelCollectorEndpoint: "" + # -- Use GCP logging + useGcloudLogging: false + + storage: + # -- Data directory + dataDirectory: /data + # -- Data store map size (kB) + dataStoreMapSize: + # -- World state map size (kB) + worldStateMapSize: + # -- P2P storage map size (kB) + p2pStorageMapSize: + # -- Archive storage map size (kB) + archiveStorageMapSize: + + nodeJsOptions: + - --no-warnings + - --max-old-space-size=4096 + + startupProbe: + # -- Period seconds + periodSeconds: 30 + # -- Failure threshold + failureThreshold: 3 + resources: {} + +persistence: + # -- Uses an emptyDir when not enabled + enabled: false + # -- Use an existing PVC + existingClaim: null + # -- AccessModes + accessModes: + - ReadWriteOnce + # -- Requested size + size: 100Gi + # -- Use a specific storage class + storageClassName: null + # -- Annotations for volume claim template + annotations: {} + # -- Selector for volume claim template + selector: {} + +# -- Update strategy for the statefulset +updateStrategy: + type: RollingUpdate + +# -- Additional init containers +initContainers: [] +# - name: my-init-container +# image: busybox:latest +# command: ['sh', '-c', 'echo hello'] + +service: + ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.global-static-ip-name: my-static-ip + hosts: [] + # - node.example.com + + headless: + enabled: true + + p2p: + enabled: true + nodePortEnabled: true + port: 40400 + announcePort: 40400 + admin: + enabled: true + port: 8081 + httpPort: 8080 + +# Certificate configuration +certificate: + enabled: false + domains: [] + # - example.com + # - api.example.com + +rbac: + # -- Specifies whether RBAC resources are to be created + create: true + # -- Required ClusterRole rules + # @default -- See `values.yaml` + clusterRules: + # Required to obtain the nodes external IP + - apiGroups: [""] + resources: + - "nodes" + verbs: + - "get" + - "list" + - "watch" + # -- Required ClusterRole rules + # @default -- See `values.yaml` + rules: + # Required to get information about the services nodePort. + - apiGroups: [""] + resources: + - "services" + verbs: + - "get" + - "list" + - "watch" + +serviceAccount: + # -- Create a service account + create: true + # -- Name of the service account - if not set, the fullname will be used + name: "" + # -- Annotations for the service account + annotations: {} diff --git a/obolup/manifests/kind_host.yaml b/obolup/manifests/kind_host.yaml index e2c7c46..0fb1634 100644 --- a/obolup/manifests/kind_host.yaml +++ b/obolup/manifests/kind_host.yaml @@ -10,3 +10,7 @@ nodes: - containerPort: 443 hostPort: 443 protocol: TCP + # For aztec testing + - containerPort: 40400 + hostPort: 40400 + protocol: TCP diff --git a/values/erpc.yaml b/values/erpc.yaml index d09f4d4..826a13e 100644 --- a/values/erpc.yaml +++ b/values/erpc.yaml @@ -77,6 +77,19 @@ config: | hedge: delay: 500ms maxCount: 1 + - architecture: evm + evm: + chainId: 11155111 + alias: sepolia + failsafe: + timeout: + duration: 30s + retry: + maxAttempts: 3 + delay: 0ms + hedge: + delay: 500ms + maxCount: 1 upstreams: - endpoint: http://l1-light-client-helios.l1.svc.cluster.local:8545 - endpoint: https://ethereum-rpc.publicnode.com @@ -85,6 +98,9 @@ config: | - endpoint: https://ethereum-hoodi-rpc.publicnode.com evm: chainId: 560048 + - endpoint: https://ethereum-sepolia-rpc.publicnode.com + evm: + chainId: 11155111 # -- Secret env variables injected via a created secret # These env variables can be used to populate the erpc config file with sensitive data such as RPC API keys diff --git a/values/hoodi/aztec-node.yaml b/values/hoodi/aztec-node.yaml new file mode 100644 index 0000000..798117a --- /dev/null +++ b/values/hoodi/aztec-node.yaml @@ -0,0 +1,48 @@ +# -- Image to use for the container +image: + # -- Image repository + repository: aztecprotocol/aztec + # -- Image tag + tag: 0.87.9 + # -- Container pull policy + pullPolicy: IfNotPresent + +network: alpha-testnet + +hostNetwork: true + +node: + replicas: 1 + logLevel: "debug; info: aztec:simulator, json-rpc" + + l1ExecutionUrls: ["https://ethereum-sepolia-rpc.publicnode.com"] + l1ConsensusUrls: ["https://ethereum-sepolia-beacon-api.publicnode.com"] + + startCmd: + - --node + - --archiver + + startupProbe: + # -- Period seconds + periodSeconds: 60 + # -- Failure threshold + failureThreshold: 60 + +persistence: + enabled: true + size: 100Gi + storageClassName: standard + accessModes: + - ReadWriteOnce + selector: {} + +service: + p2p: + enabled: true + nodePortEnabled: true + port: 40400 + announcePort: 40400 + admin: + enabled: true + port: 8081 + httpPort: 8080 \ No newline at end of file