Existing K8s
Chronicle operates a distributed network of validators run by reputable projects in the space, including MakerDAO/Sky, Etherscan, Gnosis, Bitcoin Suisse, and others. This structure reinforces both security and decentralization, setting Chronicle apart from other oracle solutions.
Note: Running a validator is a permissioned process. This documentation is intended for projects that have already been approved to run a validator.
Deploying the validator into an existing kubernetes cluster.
Helm Chart details:​
Notable changes include:​
ChartVersion 0.5.1: The tor-controller and its associated CRDs have been removed from the chart. The chart upgrade will automatically remove tor-related pods, services, and secrets that were previously managed by Helm. After upgrading, remove any remaining tor resources manually:
# Remove the onionservice resource (if present)
kubectl delete onionservice ghost -n $FEED_NAME --ignore-not-found
# If the tor-controller namespace was deployed, remove it
kubectl delete namespace tor-controller-system --ignore-not-found
# Remove all CRD's IF NOT USED BY OTHER APPS
kubectl delete -f https://raw.githubusercontent.com/chronicleprotocol/charts/validator-0.3.24/charts/validator/crds/tor-controller.yaml --ignore-not-found
Sample config:
global:
logLevel: "warn"
ghost:
ethConfig:
ethFrom:
existingSecret: '<somesecret>'
key: "ethFrom"
ethKeys:
existingSecret: '<somesecret>'
key: "ethKeyStore"
ethPass:
existingSecret: '<somesecret>'
key: "ethPass"
ethRpcUrl: "https://MY_L1_RPC_URL"
rpcUrl: "https://MY_L1_RPC_URL"
env:
normal:
CFG_LIBP2P_EXTERNAL_ADDR: '/ip4/1.2.3.4' # public/reachable ip address of node. If DNS hostname set to `/dns/my.validator.com`
vao:
env:
normal:
CFG_LIBP2P_EXTERNAL_ADDR: '/ip4/1.2.3.4' # public/reachable ip address of node. If DNS hostname set to `/dns/my.validator.com`
Requirements​
EOA Keys​
You will need to generate a new encrypted keystore with Ethereum address matching a specific first byte identifier.
Please look at the script here, which will help you do this
Create Namespace​
We advise running a feed in its own dedicated namespace:
kubectl create ns my-feed-namespace
Prep Secrets​
We can create secrets that will be used by the validator pod in the feed as below:
kubectl create secret generic somesecretname-eth-keys \
--from-file=ethKeyStore=ethkeystore.json \
--from-literal=ethFrom=${ETH_FROM_ADDRESS} \
--from-literal=ethPass="" \
--namespace my-feed-namespace
Installation​
Add Chronicle helm chart repository:
helm repo add chronicle https://chronicleprotocol.github.io/charts/
Update your helm repository:
helm repo update chronicle
Create a values.yaml file as shown below, with the reference to the secrets created in the previous steps:
global:
logLevel: info
ghost:
ethConfig:
ethFrom:
existingSecret: 'somesecretname-eth-keys'
key: "ethFrom"
ethKeys:
existingSecret: 'somesecretname-eth-keys'
key: "ethKeyStore"
ethPass:
existingSecret: 'somesecretname-eth-keys'
key: "ethPass"
# ethereum RPC client (should always be ETH mainnet)
ethRpcUrl: "https://my.eth.rpc"
# default RPC client (target chain, eth mainnet or sepolia eg)
rpcUrl: "https://my.eth.rpc"
env:
normal:
# please place your nodes actual public ip address here
CFG_LIBP2P_EXTERNAL_ADDR: '/ip4/1.2.3.4'
# if using a LoadBalancer that has DNS:
# CFG_LIBP2P_EXTERNL_ADDR" '/dns/my.hostname.xyz`
vao:
env:
normal:
# please place your nodes actual public ip address here
CFG_LIBP2P_EXTERNAL_ADDR: '/ip4/1.2.3.4'
# if using a LoadBalancer that has DNS:
# CFG_LIBP2P_EXTERNL_ADDR" '/dns/my.hostname.xyz`
Then install the helm release using this values file:
helm install my-feed-name -f path/to/values.yaml chronicle/validator --namespace my-feed-namespace --version 0.5.1
You can do a dry-run by passing --debug and --dry-run to the helm command. This is useful if you want to inspect the resources before deploying them to the cluster
View all resources created in the namespace​
kubectl get pods,deployment,service,secrets -n my-feed-namespace
NAME READY STATUS RESTARTS AGE
pod/ghost-5c4cfb47bf-wvsvf 1/1 Running 0 14s
pod/ghost-vao-79d77454c7-l5qch 1/1 Running 0 14s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ghost 1/1 1 1 14s
deployment.apps/ghost-vao 1/1 1 1 14s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ghost ClusterIP 10.43.109.192 <none> 8000/TCP,8080/TCP 14s
service/ghost-vao ClusterIP 10.43.44.21 <none> 8001/TCP 14s
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 287d
NAME TYPE DATA AGE
secret/somesecretname-eth-keys Opaque 3 30s
secret/sh.helm.release.v1.my-validator.v1 helm.sh/release.v1 1 14s
View pod logs:​
kubectl logs -n demo deployment/ghost
kubectl logs -n demo deployment/ghost-vao
You can view the logs the pods to verify no errors:
kubectl logs deployments/ghost --namespace my-feed-namespace
time="2023-08-30T13:47:15Z" level=info msg="Ethereum Key" address=0x3fe0e49b5daa14f4ddc60e296270cedd702ce76c name=default tag=CONFIG_ETHEREUM
time="2023-08-30T13:47:15Z" level=info msg="Ethereum Client" name=default tag=CONFIG_ETHEREUM url="https://eth.public-rpc.com"
time="2023-08-30T13:47:15Z" level=info msg="Ethereum Client" name=ethereum tag=CONFIG_ETHEREUM url="https://eth.public-rpc.com"
time="2023-08-30T13:47:15Z" level=info msg=Feed address=0x0....................................... tag=LIBP2P
time="2023-08-30T13:47:15Z" level=info msg=Feed address=0x5....................................... tag=LIBP2P
time="2023-08-30T13:47:15Z" level=info msg=Feed address=0x7....................................... tag=LIBP2P
time="2023-08-30T13:47:15Z" level=info msg=Feed address=0xc....................................... tag=LIBP2P
time="2023-08-30T13:47:15Z" level=info msg=Feed address=0x....................................... tag=LIBP2P
time="2023-08-30T13:47:15Z" level=info msg=Bootstrap address=/dns/spire-bootstrap1.domain.com/tcp/8000/p2p/12D111222333aaaaabbbbbccccdddddeee tag=LIBP2P
time="2023-08-30T13:47:16Z" level=debug msg=Call duration=861.851113ms method=eth_call name="https://eth.public-rpc.com" tag=RPCSPLITTER
If you encounter any issues please refer to the Trouble Shooting docs