Skip to content

Commit

Permalink
[solana] add support for Geyser plugins (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
VladStarr authored May 31, 2024
1 parent d8a43bd commit accdfb1
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 14 deletions.
2 changes: 1 addition & 1 deletion dysnix/solana/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: solana
description: Solana blockchain node Helm chart
type: application

version: 0.1.26
version: 0.1.27
appVersion: "v1.17.34"

keywords:
Expand Down
34 changes: 21 additions & 13 deletions dysnix/solana/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ A Helm chart to deploy Solana node inside Kubernetes cluster.
| `serviceAccount.annotations` | Additional custom annotations for the ServiceAccount | `{}` |
| `podLabels` | Extra labels for pods | `{}` |
| `podAnnotations` | Annotations for pods | `{}` |
| `extraContainerPorts` | Additional ports to expose on Solana container | `[]` |
| `podSecurityContext` | Configure securityContext for entire pod | `{}` |
| `securityContext` | Configure securityContext for Solana container | `{}` |
| `resources` | Set container requests and limits for CPU or memory | `{}` |
Expand All @@ -40,6 +41,7 @@ A Helm chart to deploy Solana node inside Kubernetes cluster.
| `services.rpc.enabled` | Enable Solana RPC service | `true` |
| `services.rpc.type` | Solana RPC service type | `ClusterIP` |
| `services.rpc.port` | Solana RPC service port (+1 for websocket) | `8899` |
| `services.rpc.extraPorts` | Solana RPC service extra ports to expose | `[]` |
| `services.rpc.publishNotReadyAddresses` | Route trafic even when pod is not ready | `false` |
| `services.metrics.enabled` | Enable Solana metrics service | `false` |
| `services.metrics.type` | Solana metrics service type | `ClusterIP` |
Expand All @@ -66,19 +68,25 @@ A Helm chart to deploy Solana node inside Kubernetes cluster.

### Solana node configuration

| Name | Description | Value |
| -------------------------------------------- | ------------------------------------------------------------------ | --------------------------------- |
| `solanaArgs` | `solana-validator` arguments | `{}` |
| `gracefulShutdown.timeout` | Seconds to wait for graceful shutdown | `120` |
| `gracefulShutdown.options` | `solana-validator exit` arguments | `{}` |
| `gracefulShutdown.options.force` | Do not wait for restart-window, useful for non-validators | `false` |
| `gracefulShutdown.options.skip-health-check` | Skip health check before exit | `false` |
| `gracefulShutdown.options.skip-health-check` | Skip check for a new snapshot before exit | `false` |
| `rustLog` | Logging configuration | `solana=info,solana_metrics=warn` |
| `identity.validatorKeypair` | Validator keypair string (required) | `""` |
| `identity.voteKeypair` | Vote keypair string (required only for validator) | `""` |
| `identity.existingSecret` | Use existing secret with keypairs instead of specifying them above | `""` |
| `identity.mountPath` | Keypair files mount path | `/secrets` |
| Name | Description | Value |
| -------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------- |
| `solanaArgs` | `solana-validator` arguments | `{}` |
| `gracefulShutdown.timeout` | Seconds to wait for graceful shutdown | `120` |
| `gracefulShutdown.options` | `solana-validator exit` arguments | `{}` |
| `gracefulShutdown.options.force` | Do not wait for restart-window, useful for non-validators | `false` |
| `gracefulShutdown.options.skip-health-check` | Skip health check before exit | `false` |
| `gracefulShutdown.options.skip-health-check` | Skip check for a new snapshot before exit | `false` |
| `rustLog` | Logging configuration | `solana=info,solana_metrics=warn` |
| `plugins.enabled` | Enable download of Geyser plugins | `false` |
| `plugins.yellowstoneGRPC.enabled` | Enable download of Yellowstone gRPC | `false` |
| `plugins.yellowstoneGRPC.version` | Yellowstone gRPC version | `v1.14.2+solana.1.17.33` |
| `plugins.yellowstoneGRPC.baseUrl` | URL from where the plugin is downloaded | `https://github.com/rpcpool/yellowstone-grpc/releases/download/` |
| `plugins.yellowstoneGRPC.listenIP` | Yellowstone gRPC listen IP address, without port | `$(MY_POD_IP)` |
| `plugins.yellowstoneGRPC.config` | Yellowstone gRPC config.json file | `look in values.yaml` |
| `identity.validatorKeypair` | Validator keypair string (required) | `""` |
| `identity.voteKeypair` | Vote keypair string (required only for validator) | `""` |
| `identity.existingSecret` | Use existing secret with keypairs instead of specifying them above | `""` |
| `identity.mountPath` | Keypair files mount path | `/secrets` |

### Solana ledger db persistence config

Expand Down
13 changes: 13 additions & 0 deletions dysnix/solana/templates/configmap-plugins.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.plugins.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "solana.fullname" $ }}-plugins-config
labels:
{{- include "solana.labels" . | nindent 4 }}
data:
{{- if and .Values.plugins.yellowstoneGRPC.enabled .Values.plugins.yellowstoneGRPC.config }}
yellowstone-grpc-config.json: |-
{{- .Values.plugins.yellowstoneGRPC.config | nindent 4 }}
{{- end }}
{{- end }}
4 changes: 4 additions & 0 deletions dysnix/solana/templates/scripts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ data:
{{- include (print $.Template.BasePath "/scripts/_start.tpl") . | nindent 4 }}
health.sh: |-
{{- include (print $.Template.BasePath "/scripts/_health.tpl") . | nindent 4 }}
{{- if .Values.plugins.enabled }}
download-plugins.sh: |-
{{- include (print $.Template.BasePath "/scripts/_download-plugins.tpl") . | nindent 4 }}
{{- end }}
33 changes: 33 additions & 0 deletions dysnix/solana/templates/scripts/_download-plugins.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env sh
# shellcheck disable=SC3040,SC2046

set -e

YELLOWSTONE_GRPC__PLUGIN_DIR="$PLUGINS_DIR/yellowstone-grpc"

yellowstone_grpc_bootstrap() {
echo "Yellowstone gRPC: Downloading plugin version ${YELLOWSTONE_GRPC__VERSION}.."
mkdir -p "$YELLOWSTONE_GRPC__PLUGIN_DIR"
wget -q "${YELLOWSTONE_GRPC__DOWNLOAD_URL}/${YELLOWSTONE_GRPC__VERSION}/geyser.proto"
wget -q "${YELLOWSTONE_GRPC__DOWNLOAD_URL}/${YELLOWSTONE_GRPC__VERSION}/solana-storage.proto"
wget -qO- "${YELLOWSTONE_GRPC__DOWNLOAD_URL}/${YELLOWSTONE_GRPC__VERSION}/yellowstone-grpc-geyser-release-x86_64-unknown-linux-gnu.tar.bz2" | tar jxvf -

echo "Yellowstone gRPC: Copying proto and lib to ${YELLOWSTONE_GRPC__PLUGIN_DIR}.."
cp -r /tmp/*.proto "$YELLOWSTONE_GRPC__PLUGIN_DIR/"
cp -r /tmp/yellowstone-grpc-geyser-release/lib "$YELLOWSTONE_GRPC__PLUGIN_DIR/"

echo "Yellowstone gRPC: Copying config file to ${YELLOWSTONE_GRPC__PLUGIN_DIR}.."
cp -L "$YELLOWSTONE_GRPC__CONFIG_PATH" "$YELLOWSTONE_GRPC__PLUGIN_DIR/config.json"

echo "Yellowstone gRPC: Changing listen IP address in config file to ${YELLOWSTONE_GRPC__LISTEN_IP}.."
sed -i "s/LISTEN_IP/${YELLOWSTONE_GRPC__LISTEN_IP}/g" "$YELLOWSTONE_GRPC__PLUGIN_DIR/config.json"

echo "Yellowstone gRPC: Bootstrap done!"
}

main() {
cd /tmp
if [ "$YELLOWSTONE_GRPC__ENABLED" = "1" ]; then yellowstone_grpc_bootstrap; fi
}

main
3 changes: 3 additions & 0 deletions dysnix/solana/templates/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ spec:
targetPort: ws
protocol: TCP
name: ws
{{- with .extraPorts }}
{{- toYaml . | nindent 4 }}
{{- end }}
selector:
{{- include "solana.selectorLabels" $ | nindent 4 }}
{{- end }}
Expand Down
45 changes: 45 additions & 0 deletions dysnix/solana/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,37 @@ spec:
sysctl -w net.core.wmem_default=134217728
sysctl -w net.core.wmem_max=134217728
sysctl -w fs.nr_open=1000000
{{- with .Values.plugins }}
{{- if .enabled }}
- name: download-plugins
image: busybox:latest
command: ["/scripts/download-plugins.sh"]
env:
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: PLUGINS_DIR
value: /plugins
- name: YELLOWSTONE_GRPC__ENABLED
value: {{ ternary "1" "0" .yellowstoneGRPC.enabled | quote }}
- name: YELLOWSTONE_GRPC__DOWNLOAD_URL
value: {{ .yellowstoneGRPC.downloadURL }}
- name: YELLOWSTONE_GRPC__VERSION
value: {{ .yellowstoneGRPC.version }}
- name: YELLOWSTONE_GRPC__CONFIG_PATH
value: /config/yellowstone-grpc-config.json
- name: YELLOWSTONE_GRPC__LISTEN_IP
value: {{ .yellowstoneGRPC.listenIP }}
volumeMounts:
- name: plugins
mountPath: /plugins
- name: plugins-config
mountPath: /config
- name: scripts
mountPath: /scripts
{{- end }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
securityContext:
Expand Down Expand Up @@ -101,6 +132,9 @@ spec:
- name: ws
containerPort: {{ get .Values.solanaArgs "rpc-port" | add 1 }}
protocol: TCP
{{- with .Values.extraContainerPorts }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if .Values.startupProbe.enabled }}
{{- with (omit .Values.startupProbe "enabled") }}
startupProbe:
Expand Down Expand Up @@ -130,6 +164,10 @@ spec:
mountPath: /scripts
- name: identity
mountPath: {{ .Values.identity.mountPath }}
{{- if .Values.plugins.enabled }}
- name: plugins
mountPath: /plugins
{{- end }}
{{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
Expand Down Expand Up @@ -196,6 +234,13 @@ spec:
{{- else }}
secretName: {{ include "solana.fullname" . }}-identity
{{- end }}
{{- if .Values.plugins.enabled }}
- name: plugins
emptyDir: {}
- name: plugins-config
configMap:
name: {{ include "solana.fullname" . }}-plugins-config
{{- end }}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
Expand Down
102 changes: 102 additions & 0 deletions dysnix/solana/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,19 @@ serviceAccount:
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
##
podLabels: {}

## @param podAnnotations Annotations for pods
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
##
podAnnotations: {}

## @param extraContainerPorts [array] Additional ports to expose on Solana container
## Example:
## - name: grpc
## protocol: TCP
## containerPort: 10000
extraContainerPorts: []

## @param podSecurityContext [object] Configure securityContext for entire pod
## Example:
## podSecurityContext:
Expand Down Expand Up @@ -161,6 +169,14 @@ services:
## @param services.rpc.port Solana RPC service port (+1 for websocket)
##
port: 8899
## @param services.rpc.extraPorts Solana RPC service extra ports to expose
## Example:
## - name: grpc
## protocol: TCP
## port: 10000
## targetPort: grpc
##
extraPorts: []
## @param services.rpc.publishNotReadyAddresses Route trafic even when pod is not ready
##
publishNotReadyAddresses: false
Expand Down Expand Up @@ -320,6 +336,92 @@ gracefulShutdown:
##
rustLog: solana=info,solana_metrics=warn

plugins:
## @param plugins.enabled Enable download of Geyser plugins
##
enabled: false
yellowstoneGRPC:
## @param plugins.yellowstoneGRPC.enabled Enable download of Yellowstone gRPC
##
enabled: false
## @param plugins.yellowstoneGRPC.version Yellowstone gRPC version
##
version: v1.14.2+solana.1.17.33
## @param plugins.yellowstoneGRPC.downloadURL From where the plugin needs to be downloaded
##
downloadURL: https://github.com/rpcpool/yellowstone-grpc/releases/download/
## @param plugins.yellowstoneGRPC.listenIP Yellowstone gRPC listen IP address, without port
## works by replacing LISTEN_IP string inside json file with the value provided
## default: Pod IP address from K8s downward API
##
listenIP: $(MY_POD_IP)
## @param plugins.yellowstoneGRPC.config [string, default: look in values.yaml] Yellowstone gRPC config.json file
##
config: |-
{
"libpath": "lib/libyellowstone_grpc_geyser.so",
"log": {
"level": "info"
},
"grpc": {
"address": "LISTEN_IP:10000",
"max_decoding_message_size": "4_194_304",
"snapshot_plugin_channel_capacity": null,
"snapshot_client_channel_capacity": "50_000_000",
"channel_capacity": "100_000",
"unary_concurrency_limit": 100,
"unary_disabled": false,
"filters": {
"accounts": {
"max": 1,
"any": false,
"account_max": 10,
"account_reject": ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
"owner_max": 10,
"owner_reject": ["11111111111111111111111111111111"]
},
"slots": {
"max": 1
},
"transactions": {
"max": 1,
"any": false,
"account_include_max": 10,
"account_include_reject": ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
"account_exclude_max": 10,
"account_required_max": 10
},
"transactions_status": {
"max": 1,
"any": false,
"account_include_max": 10,
"account_include_reject": ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
"account_exclude_max": 10,
"account_required_max": 10
},
"blocks": {
"max": 1,
"account_include_max": 10,
"account_include_any": false,
"account_include_reject": ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
"include_transactions": true,
"include_accounts" : false,
"include_entries" : false
},
"blocks_meta": {
"max": 1
},
"entry": {
"max": 1
}
}
},
"prometheus": {
"address": "LISTEN_IP:8999"
},
"block_fail_action": "log"
}
## You need first to create a keypair JSON files
## I.e. solana-keygen new --no-bip39-passphrase --silent && cat /root/.config/solana/id.json
##
Expand Down

0 comments on commit accdfb1

Please sign in to comment.