arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 44

Kotal Open Source

Loading...

Loading...

Loading...

Loading...

Tutorials

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Reference

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Aptos

Support

You can support us by donating Eth or any token to our ENS address farghaly.eth or directly to the following Ethereum address:

0x5dfA5dB515748f3E2BCc8677A9332f4aFFad5A5E

Thank you!

Welcome

Kotal is an open sourcearrow-up-right alternative to centralized API gateway, Node as a service, and Staking service providers. Like Infura in Ethereum ecosystem, Onfinality in Polkadot ecosystem, and Hiro in Stacks ecosystem.

Kotal is multi-client, protocol-agnostic, and cloud-agnostic Blockchain Kubernetes Operator that makes it easy to deploy highly-available self-managing self-healing blockchain infrastructure on any cloud.

Kotal has been tested on Amazon Web Service, Google Cloud Platform, Microsoft Azure, DigitalOcean, Alibab Cloud, Tencent cloud 🤯.

hashtag
What can I do with Kotal ?

  • Deploy nodes across 10 Blockchain protocols (Aptos, Bitcoin, Chainkstack, Ethereum, Filecoin, IPFS, NEAR, Polkadot, Stacks)

  • Upgrade and Downgrade node client software

  • Load validator keys and start producing blocks

  • Manage storage and resources (CPU & Memory) allocated to the node

Bitcoin

We've extended Kubernetes with Node custom resource which can be used to deploy Bitcoin nodes from the given spec.

hashtag
Node

Node is Bitcoin node using Bitcoin Corearrow-up-right client, connecting to and syncing a specific chain.

apiVersion: bitcoin.kotal.io/v1alpha1
kind: Node
metadata:
  Name: bitcoin-node
spec:
  network: mainnet
  rpc: true
  ...

For all the fields associated with the Node API resource:

Full Bitcoin node reference is documented .

Installation

hashtag
Requirements

  • Kubernetes cluster

  • Cert Manager

hashtag
Kubernetes cluster

For development and testing purposes we recommend using (Kubernetes in Docker), it's an easy way to create and tear down kubernetes clusters in seconds. For staging and production purposes you can use any public cloud kubernetes as a service like , or .

kind installation guide can be found .

hashtag
Cert Manager

Cert Manager is a native Kubernetes certificate management controller. It can help with issuing certificates from a variety of sources, such as , , a simple signing key pair, or self-signed. It will ensure certificates are valid and up to date, and attempt to renew certificates at a configured time before expiry.

Kotal webhook component uses cert-manager for issuing certificates to default and validate your Blockchain resources such as nodes, beacon nodes, ipfs peers ... etc.

cert-manager installation guide can be found .

hashtag
Install kotal

The latest version of Kotal operator v0.3.0 can be installed into your Kubernetes cluster simply by:

  • Manage Secrets (private keys, passwords, tokens, certificates)

  • Monitor resources utilization

  • Fetch real time logs

  • Create TLS-secure API endpoints

  • View API endpoints usage

  • Create workspaces of nodes and resources

  • Invite members to workspaces and assign roles

  • kubectl explain nodes --api-version bitcoin.kotal.io/v1alpha1
    kubectl explain nodes.spec --api-version bitcoin.kotal.io/v1alpha1
    here
    kindarrow-up-right
    Amazon EKSarrow-up-right
    Azure AKSarrow-up-right
    Google GKEarrow-up-right
    herearrow-up-right
    Let’s Encryptarrow-up-right
    HashiCorp Vaultarrow-up-right
    herearrow-up-right
    kubectl apply -f https://github.com/kotalco/kotal/releases/download/v0.3.0/kotal.yaml

    Deploy Aptos Devnet Node

    Deploy Bitcoin RPC Node

    hashtag
    Generate JSON-RPC password secret

    Bitcoin nodes that enable JSON-RPC server are required to use basic authentication while calling JSON-RPC methods.

    Apply rpc-user-password.yaml to create the password secret:

    hashtag
    Deploy Bitcoin RPC Node

    The following manifest describes a Bitcoin node that syncs Bitcoin mainnet network: mainnet, enables HTTP JSON-RPC server rpc: true, defines JSON-RPC user credentials rpcUsers: ... and uses client:

    Apply bitcoin.yaml manifest:

    Kotal operator will notice your bitcoin-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed Bitcoin Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    It will return node logs similar to the following:

    hashtag
    Call JSON-RPC Method

    By default, Bitcoin node JSON-RPC server port is 8332, which can be changed using rpcPort.

    Forward localhost:8332 calls to the node pod:

    In another terminal window call getblockhash JSON-RPC method to get the genesis block hash:

    You will get JSON result similar to the following:

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Bitcoin Node controller.

    Quick Start

    Create rinkeby.yaml manifest that describes an Ethereum node which uses go-ethereum client, connecting to rinkeby network, and enabling JSON-RPC server:

    rinkeby.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: rinkeby-geth-node
    spec:
      network: rinkeby
      client: geth
      rpc: true

    Deploy the node using kubectl:

    kubectl apply -f rinkeby.yaml

    Within a couple of seconds, the node will be up and running. You can get the node using:

    kubectl get nodes.ethereum

    It will return an output similar to the following:

    Kotal will create all the necessary pods, volumes, services for the node. Get the pods by:

    It will return an output similar to the following:

    Finally delete the node by:

    Congratulations!

    rpc-user-password.yaml
    # WARNING: DON'T use the following secret in production
    apiVersion: v1
    kind: Secret
    metadata:
      name: kotal-rpc-user-password
    stringData:
      password: s3cr3t
    kubectl apply -f rpc-user-password.yaml
    NAME                 CLIENT   Network   Consensus
    rinkeby-geth-node    geth     rinkeby   poa
    kubectl get pods

    Aptos

    Bitcoin Corearrow-up-right
    NAME                     READY   STATUS    RESTARTS   AGE
    rinkeby-geth-node-0      1/1     Running   0          1m
    kubectl delete -f rinkeby.yaml
    bitcoin.yaml
    apiVersion: bitcoin.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: bitcoin-node
    spec:
      network: mainnet
      rpc: true
      rpcUsers:
        - username: kotal
          passwordSecretName: kotal-rpc-user-password
    kubectl apply -f bitcoin.yaml
    kubectl get nodes.bitcoin
    NAME            NETWORK    CLIENT
    bitcoin-node    mainnet    bitcoincore
    kubectl get pods
    NAME              READY   STATUS    RESTARTS   AGE
    bitcoin-node-0    1/1     Running   0          1m
    kubectl logs -f bitcoin-node-0
    2022-04-09T18:26:45Z Bitcoin Core version v22.0.0 (release build)
    2022-04-09T18:26:45Z InitParameterInteraction: parameter interaction: -bind set -> setting -listen=1
    2022-04-09T18:26:45Z Assuming ancestors of block 00000000000000000008a89e854d57e5667df88f1cdef6fde2fbca1de5b639ad have valid signatures.
    2022-04-09T18:26:45Z Setting nMinimumChainWork=00000000000000000000000000000000000000001fa4663bbbe19f82de910280
    2022-04-09T18:26:45Z Using the 'sse4(1way),sse41(4way),avx2(8way)' SHA256 implementation
    2022-04-09T18:26:45Z Using RdRand as an additional entropy source
    2022-04-09T18:26:45Z Wallet disabled!
    ...
    2022-04-09T18:27:02Z Synchronizing blockheaders, height: 9999 (~1.44%)
    2022-04-09T18:27:02Z Synchronizing blockheaders, height: 11999 (~1.73%)
    2022-04-09T18:27:02Z Synchronizing blockheaders, height: 13999 (~2.02%)
    2022-04-09T18:27:02Z Synchronizing blockheaders, height: 15999 (~2.31%)
    2022-04-09T18:27:02Z Synchronizing blockheaders, height: 17999 (~2.61%)
    2022-04-09T18:27:03Z Synchronizing blockheaders, height: 19999 (~2.90%)
    2022-04-09T18:27:03Z Synchronizing blockheaders, height: 21999 (~3.21%)
    2022-04-09T18:27:03Z Synchronizing blockheaders, height: 23999 (~3.51%)
    2022-04-09T18:27:04Z Synchronizing blockheaders, height: 25999 (~3.82%)
    2022-04-09T18:27:04Z Synchronizing blockheaders, height: 27999 (~4.13%)
    2022-04-09T18:27:04Z Synchronizing blockheaders, height: 29999 (~4.43%)
    ...
    kubectl port-forward bitcoin-node-0 8332
    curl --user "kotal:s3cr3t" --data-binary '{"jsonrpc": "1.0", "id": 1, "method": "getblockhash", "params": [0]}' -H 'content-type: text/plain;' http://0.0.0.0:8332
    {
      "result":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
      "error":null,
      "id":1
    }
    kubectl delete -f bitcoin.yaml

    NEAR

    We've extended Kubernetes with Node custom resource which can be used to deploy NEAR nodes from the given spec.

    hashtag
    Node

    Node is NEAR node using NEAR Corearrow-up-right client, connecting to and syncing a specific chain, and optionally validating blocks.

    apiVersion: near.kotal.io/v1alpha1
    kind: Node
    metadata:
      Name: near-node
    spec:
      network: mainnet
      rpc: true

    For all the fields associated with the Node API resource:

    Full NEAR node reference is documented .

    Ethereum

    We've extended Kubernetes with Node custom resource which can be used to deploy Ethereum nodes from the given spec.

    Using Ethereum Node custom resource, you can describe any public or private network node you want, and Kotal will create all the necessary Kubernetes resources like pods, persistent volumes, services, configmaps, and secrets for you.

    If you want to get all the deployted ethereum Node(s):

    Which will report node name, client, network, and consensus.

    IPFS

    IPFS is a distributed system for storing and accessing files, websites, applications, and data.

    We've extended Kubernetes with Peer and ClusterPeer custom resources which can be used to deploy IPFS peers, swarms, and clusters from the given spec.

    hashtag
    Peer

    Polkadot

    Polkadot is a sharded protocol that enables blockchain networks to operate together seamlessly. Polkadot is a 100% open-source project created to enable a decentralized web and better society.

    We've extended Kubernetes with Node custom resource which can be used to Polkadot, Kusama, Rococo, and substrate-based chains from the given spec.

    hashtag
    Node

    Node

    Filecoin

    We've extended Kubernetes with Node custom resource which can be used to create Filecoin nodes across different filecoin networks like Mainnet or calibration using lotus client from a given spec.

    Here's an example of a Filecoin node that syncs calibration chain:

    For all the fields associated with the Node API resource:

    Full filecoin node reference is documented .

    kubectl explain nodes --api-version near.kotal.io/v1alpha1
    kubectl explain nodes.spec --api-version near.kotal.io/v1alpha1
    here
    apiVersion: filecoin.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: calibration-node
    spec:
      network: calibration
    kubectl explain node --api-version filecoin.kotal.io/v1alpha1
    kubectl explain node.spec --api-version filecoin.kotal.io/v1alpha1
    here
    If you want to get all the fields associated with ethereum
    Node
    :

    For a comprehensive reference on Ethereum Node, check our ethereum reference

    hashtag
    Multi-client Support

    circle-exclamation

    Support for OpenEthereum (parity) client has been deprecated. OpenEthereum team is working with Erigon on a smooth transition path for users. More information can be found herearrow-up-right

    Kotal supports the following Ethereum 1 clients:

    • Hyperledger Besuarrow-up-right

    • Go-Ethereum (Geth)arrow-up-right

    • Nethermindarrow-up-right

    Peer is an ipfs peer running go-ipfs client and connecting to the public ipfs swarm or a private swarm secured by swarm key. Here's an example of a very basic ipfs peer connecting to the public ipfs swarm.

    For all the fields associated with the Peer API resource:

    Full ipfs peer reference is documented here.

    hashtag
    ClusterPeer

    ClusterPeer is an ipfs cluster peer running ipfs-cluster-service client, connecting to ipfs peer and optional bootstrap cluster peer(s). ClusterPeers provide data orchestration across a swarm of IPFS daemons by allocating, replicating and tracking a global pinset distributed among multiple peers. Here's an example of cluster peer connecting to ipfs peer.

    For all the fields associated with the ClusterPeer API resource:

    Full ipfs cluster peer reference is documented here.

    apiVersion: ipfs.kotal.io/v1alpha1
    kind: Peer
    metadata:
      Name: simple-peer
    spec: {}
    is Polkadot node using
    client, connecting to and syncing a specific chain, and optionally validating blocks.

    For all the fields associated with the Node API resource:

    Full polkadot node reference is documented here.

    apiVersion: polkadot.kotal.io/v1alpha1
    kind: Node
    metadata:
      Name: kusama-node
    spec:
      network: kusama
      rpc: true
    kubectl explain nodes --api-version polkadot.kotal.io/v1alpha1
    kubectl explain nodes.spec --api-version polkadot.kotal.io/v1alpha1
    parity polkadotarrow-up-right
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: my-node
    spec:
      # your node spec goes here
    $ kubectl get nodes.ethereum
    $ kubectl explain nodes --api-version ethereum.kotal.io/v1alpha1
    kubectl explain peers --api-version ipfs.kotal.io/v1alpha1
    kubectl explain peers.spec --api-version ipfs.kotal.io/v1alpha1
    apiVersion: ipfs.kotal.io/v1alpha1
    kind: ClusterPeer
    metadata:
      Name: simple-cluster-peer
    spec:
      peerEndpoint: /dns4/simple-peer/tcp/5001
    kubectl explain clusterpeers --api-version ipfs.kotal.io/v1alpha1
    kubectl explain clusterpeers.spec --api-version ipfs.kotal.io/v1alpha1

    Chainlink

    We've extended Kubernetes with Node custom resource which can be used to deploy Chainlink nodes from the given spec.

    apiVersion: chainlink.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: my-node
    spec:
      # your node spec goes here

    Using Chainlink Node custom resource, you can describe any chainlink node, connect to EVM chain node, add jobs and satisfy requests, and Kotal will create all the necessary Kubernetes resources like pods, persistent volumes, services, configmaps, and secrets for you.

    If you want to get all the deployted chainlink Node(s):

    kubectl get nodes.chainlink

    Which will report node name, client, Ethereum chain ID, and Link contract address.

    If you want to get all the fields associated with chainlink Node:

    For a comprehensive reference on Chainlink Node, check our

    Deploy Filecoin Node

    hashtag
    Deploy Node

    This is a simple filecoin Node that joins calibration test network.

    Let's deploy the node:

    kubectl apply -f calibration.yaml

    Kotal operator will notice your calibration-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods created for the node:

    It will return an output similar to the following:

    circle-info

    If pod STATUS is Pending, most probably it's due to not enough cpu and memory, because Kotal allocates lots of cpu cores and memory for public nodes. The required node resources can be changed using spec.resources.cpu, spec.resources.memory, and spec.resources.storage.

    Check the logs of the running node:

    Finally you can delete the filecoin node and all its resources by

    and kubernetes garbage collector will delete all resources created by the node controller.

    Stacks

    We've extended Kubernetes with Node custom resource which can be used to deploy Stacks rpc and miner nodes from the given spec.

    hashtag
    Node

    Node is Stacks node using Stacks Blockchain Nodearrow-up-right client, connecting to and syncing a specific chain, optionally mining or exposing JSON-RPC server to be used by clients.

    apiVersion: stacks.kotal.io/v1alpha1
    kind: Node
    metadata:
      Name: stacks-node
    spec:
      network: mainnet
      ...

    For all the fields associated with the Node API resource:

    Full Stacks node reference is documented .

    Deploy Validator Client

    Staking is the act of depositing 32 ETH to activate validator software. As a validator you’ll be responsible for storing data, processing transactions, and adding new blocks to the blockchain. This will keep Ethereum secure for everyone and earn you new ETH in the process. This process, known as proof-of-stake, is being introduced by the Beacon Chain.

    hashtag
    Deploy Validator Client

    In this validator client, we're using ConsenSys Teku Ethereum 2.0 client client: teku

    calibration.yaml
    apiVersion: filecoin.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: calibration-node
    spec:
      network: calibration
    kubectl explain nodes --api-version chainlink.kotal.io/v1alpha1
    chainlink reference
    kubectl get peers
    kubectl explain nodes --api-version stacks.kotal.io/v1alpha1
    kubectl explain nodes.spec --api-version stacks.kotal.io/v1alpha1
    here
    , validating pyrmont network blockchain
    network: pyrmont
    , connecting to beacon node endpoint using
    beaconEndpoints: ...
    , setting the graffiti text to include in the propsed blocks
    graffiti: validated by Kotal
    , and loading a validator keystore using
    keystores: ...
    from a kubernetes secret called
    my-validator
    .
    circle-exclamation

    The keystores loaded using spec.keystores[].secretName from kubernetes secret, must contain two data keys:

    • keystore key hodling the BLS12-381 keystore JSON file

    • password key holding the encryption key of the keystore.

    Let's deploy the validator client:

    Kotal operator will notice your teku-validator and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum 2.0 Validator using:

    It will return an output similar to the following:

    hashtag
    Fetch Validator Logs

    Get the pods created for the validator client:

    It will return an output similar to the following:

    Get the logs of the running validator pod:

    You'll get an output similar to the following:

    Finally delete the validator client:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Ethereum 2.0 Validator controller.

    sourcearrow-up-right
    NAME                NETWORK        CLIENT
    calibration-node    calibration    lotus
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    calibration-node-0    1/1     Running   0          5m
    kubectl logs -f calibration-node-0
    kubectl delete -f calibration.yaml
    validator.yaml
    apiVersion: ethereum2.kotal.io/v1alpha1
    kind: Validator
    metadata:
      name: teku-validator
    spec:
      client: teku
      network: pyrmont
      beaconEndpoints:
        - http://teku-beacon-node:9999
      graffiti: Validated by Kotal
      keystores:
        - secretName: my-validator
    kubectl apply -f validator.yaml
    kubectl get validators
    NAME             CLIENT   NETWORK   AGE
    teku-validator   teku     pyrmont   1m
    kubectl get pods
    NAME                 READY   STATUS    RESTARTS   AGE
    teku-validator-0     1/1     Running   0          1m
    kubectl logs -f teku-validator-0
    ...
    21:21:30.668 INFO  - Storing validator data in: /opt/teku/kotal-data/validator
    21:21:30.751 INFO  - Loading 1 validator keys...
    21:21:31.759 INFO  - Loaded 1 Validators: 83dbb18
    ...
    kubectl delete validator teku-validator

    Deploy Stacks RPC Node

    Stacks node requires a Bitcoin node to connect to on the back-end for Proof of Transferarrow-up-right. You can deploy a Bitcoin node using Kotal operator like we did in this guide. In this tutorial, we will be using Bitcoin node hosted by Stacks Foundation.

    circle-exclamation

    Make sure Bitcoin node is fully synced before deploying your Stacks node.

    hashtag
    Bitcoin node JSON-RPC user password

    Let's store Stacks Foundation Bitcoin node JSON-RPC password in a Kubernetes secret to be used by our node:

    Apply bitcoin-node-rpc-password.yaml to create the password secret:

    hashtag
    Deploy Stacks RPC Node

    The following manifest describes a Stacks node that syncs Stacks mainnet network: mainnet, and connects to the bitcoin node using configurations in bitcoinNode: ... for Proof of Transfer:

    Apply stacks.yaml manifest:

    Kotal operator will notice your stacks-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed Stacks Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    It will return node logs similar to the following:

    hashtag
    Call JSON-RPC Method

    By default, Stacks node JSON-RPC server port is 20443, which can be changed using rpcPort.

    Forward localhost:20443 calls to the node pod:

    circle-exclamation

    HTTP server will start after Bitcoin headers sync, till then you will get the following error if you tried to send JSON-RPC calls:

    In another terminal window call info JSON-RPC method to retrieve information about the Core API including the server version:

    You will get JSON result similar to the following:

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Stacks Node controller.

    Deploy Stacks Miner Node

    Stacks node requires a Bitcoin node to connect to on the back-end for Proof of Transferarrow-up-right. You can deploy a Bitcoin node using Kotal operator like we did in this guide. In this tutorial, we will be using Bitcoin node hosted by Stacks Foundation.

    circle-exclamation

    Make sure Bitcoin node is fully synced before deploying your Stacks node.

    hashtag
    Generating Miner Private Key

    circle-exclamation

    Don't use the following Miner private key in production!

    Generate Key chain using tool. Stacks CLI can be installed using:

    Generate key chain using:

    It will return an output similar to the following

    Store privateKey from the output above into a Kubernetes secret in data field called key:

    hashtag
    Bitcoin node JSON-RPC user password

    Let's store Stacks Foundation Bitcoin node JSON-RPC password in a Kubernetes secret to be used by our node:

    Apply bitcoin-node-rpc-password.yaml to create the password secret:

    hashtag
    Deploy Stacks Miner Node

    The following manifest describes a Stacks node that syncs Stacks mainnet network: mainnet, and connects to the bitcoin node using configurations in bitcoinNode: ... for Proof of Transfer, and loading miner private key using seedPrivateKeySecretName:

    Apply stacks.yaml manifest:

    Kotal operator will notice your stacks-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed Stacks Node using:

    It will return an output similar to the following:

    Note Miner is true in the previous output 🔥

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    It will return node logs similar to the following:

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Stacks Node controller.

    Deploy Beacon Node

    The Beacon Chain is the coordination mechanism of the new network, responsible for creating new blocks, making sure those new blocks are valid, and rewarding validators with ETH for keeping the network secure. Sourcearrow-up-right

    hashtag
    Deploy Beacon Node

    In this beacon node, we're using ConsenSys Teku Ethereum 2.0 client client: teku, and syncing the pyrmont network beacon chain network: pyrmont. We also enable REST API server rest: true at port 8888 restPort: 8888. We're connecting to Ethereum 1 endpoint eth1Endpoints: .... Check Ethereum on how to deploy an Ethereum node.

    Let's deploy the beacon node:

    Kotal operator will notice your teku-beacon-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum 2.0 BeaconNode using:

    It will return an output similar to the following:

    hashtag
    Fetch Beacon Node Logs

    Get the pods created for the beacon node:

    It will return an output similar to the following:

    Get the logs of the running beacon node:

    hashtag
    Call /eth/v1/beacon/genesis REST API

    Get the service created for the beacon node:

    It will return an output similar to the following:

    Forward the localhost:8888 calls to the beacon node

    In another terminal window, send REST API call to get chain genesis details:

    You'll get a result similar to the following:

    Finally delete the beacon node:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Ethereum 2.0 BeaconNode controller.

    Ethereum 2.0

    We've extended Kubernetes with BeaconNode and Validator custom resources which can be used to deploy Ethereum 2.0 beacon nodes and validator clients from the given spec.

    circle-info

    Kotal seperates between beacon node and validator client by using different API resources BeaconNode and Validator. So you can't run a beacon node and validator client in the same process/container.

    hashtag
    Beacon Node

    BeaconNode is Ethereum 2.0 beacon node -optionally- connecting to Ethereum 1 endpoint and syncing the beacon chain.

    Here's an example of ConsenSys Teku beacon node BeaconNode syncing mainnet beacon chain, connecting to Ethereum 1 JSON RPC endpoint, enabling REST API server which is listening at port 8888:

    For all the fields associated with the BeaconNode API resource:

    Full beacon node reference is documented .

    hashtag
    Validator Client

    Validator is Ethereum 2.0 validator client connecting to beacon node endpoint and validating blocks using the loaded keystores.

    Here's an example of ConsenSys Teku validator client connecting to beacon node endpoint, validating pyrmont blocks using 1 loaded validator keystore from its secret:

    For all the fields associated with the Validator API resource:

    Full validator client reference is documented .

    hashtag
    Multi-client Support

    Kotal supports the following Ethereum 2.0 beacon node and validator clients:

    • by ConsenSys.

    • by Sigma Prime.

    • by Prysmatic Labs.

    Setting validator or beacon node client is as simple as changing the spec.client to the desired client.

    Deploy Kusama Validator

    hashtag
    Deploy Kusama Node

    The following manifest describes Kusama node that syncs Kusama relay chain network: kusama, in archive mode pruning: false, and uses client:

    circle-info

    Deploy IPFS peer

    hashtag
    Deploy Peer

    This is a simple ipfs peer that joins the public ipfs swarm, and will starts with the all default settings that's similar to running ipfs init then ipfs daemon on your machine.

    Let's deploy the peer:

    Deploy Public Rinkeby Node

    hashtag
    Deploy Rinkeby Node

    Rinkeby is a Proof of Authority public Ethereum test network, used by developers to test their dApps.

    The following manifest describes an Ethereum node that joins rinkeby network network: rinkeby, and uses Hyperledger Besu client client: besu:

    Deploy NEAR Validator Node

    In this tutorial, we will learn how to deploy a NEAR validator node, and load a validator key into it.

    hashtag
    Generate Validator Key

    Generate validator account using tool. Which can be installed using:

    circle-exclamation

    Deploy NEAR RPC Node

    hashtag
    Deploy RPC Node

    The following manifest describes a NEAR node that syncs NEAR mainnet network: mainnet, enables HTTP JSON-RPC server rpc: true and uses client:

    Apply near.yaml manifest:

    beacon.yaml
    apiVersion: ethereum2.kotal.io/v1alpha1
    kind: BeaconNode
    metadata:
      name: teku-beacon-node
    spec:
      network: pyrmont
      client: teku
      rest: true
      restPort: 8888
      eth1Endpoints:
        - http://goerli-besu-node:8545
    Stacks CLIarrow-up-right
    tutorial

    Nimbusarrow-up-right by Status.im.

    here
    here
    Tekuarrow-up-right
    Lighthousearrow-up-right
    Prysmarrow-up-right

    By default, Validator nodes are in archive mode, but Kotal requires that node explicitly mark the node as archive node by setting pruning: false.

    Apply kusama.yaml manifest:

    Kotal operator will notice your kusama-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed Polkadot Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    It will return node logs similar to the following:

    hashtag
    Enable Validator

    Once the node is fully synced, enable validator by updating the node with validator: true:

    Apply the updated kusama.yaml Node manifest:

    Fetch the deployed Polkadot Node using:

    It will return an output similar to the following:

    Note that validator has changed from false to true.

    hashtag
    Remaining Steps

    The remainig steps in setting up a validator are:

    • Bonding KSM

    • Generating Session Keys

    • Setting Session Keys by signing and submitting an extrinsic

    • Relax 🏝️

    These steps are documented in Polkadot Wikiarrow-up-right.

    We will cover next how to generate a session key.

    hashtag
    Generating Session Key

    triangle-exclamation

    Validator nodes can't enable external HTTP or WS JSON-RPC servers.

    Session key can be generated by calling author_rotateKeys JSON-RPC method.

    Forward localhost:9933 calls to the node pod because rpcPort: 9933:

    circle-info

    9933 is the default HTTP JSON-RPC server listening port, can be changed by setting node .spec.rpcPort

    In another terminal window call author_rotateKeys JSON-RPC method to get a new session key:

    You will get JSON result similar to the following:

    You can set the sesison key as documented in Polkadot Wikiarrow-up-right.

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Polkadot Node controller.

    Parity Polkadotarrow-up-right
    Kotal operator will notice your simple-peer and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    It will return an output similar to the following:

    hashtag
    Fetch Peer Logs

    Get the pods created for the peer:

    It will return an output similar to the following:

    Check the logs of the running peer:

    You'll get output similar to the following:

    Your peer is up and running and ready to receive api calls.

    hashtag
    Read file Using IPFS HTTP API

    Let's forward localhost:5001 calls to simple-peer:5001

    In another terminal window, send http api call using cURL:

    You'll get the following output:

    You can also view ipfs webui by visiting http://0.0.0.0:5001/webui

    Finally, delete the ipfs peer:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal IPFS Peer controller.

    Kotal operator will notice your near-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed NEAR Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    It will return node logs similar to the following:

    hashtag
    Call JSON-RPC Method

    By default, NEAR node JSON-RPC server port is 3030, which can be changed using rpcPort.

    Forward localhost:3030 calls to the node pod:

    In another terminal window call status JSON-RPC method to get the general status of our node (sync status, nearcore node version, protocol version) and the current set of validators:

    You will get JSON result similar to the following:

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal NEAR Node controller.

    NEAR Corearrow-up-right
    bitcoin-node-rpc-password.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: bitcoin-node-rpc-password
    stringData:
      password: blockstacksystem
    kubectl apply -f bitcoin-node-rpc-password.yaml
    stacks.yaml
    apiVersion: stacks.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: stacks-node
    spec:
      network: mainnet
      bitcoinNode:
        endpoint: bitcoin.blockstack.com
        rpcPort: 8332
        p2pPort: 8333
        rpcUsername: blockstack
        rpcPasswordSecretName: bitcoin-node-rpc-password
    kubectl apply -f stacks.yaml
    kubectl get nodes.stacks
    NAME            NETWORK    CLIENT    MINER
    stacks-node     mainnet    stacks    false
    kubectl get pods
    NAME             READY   STATUS    RESTARTS   AGE
    stacks-node-0    1/1     Running   0          1m
    kubectl logs -f stacks-node-0
    INFO [1649597250.010714] [testnet/stacks-node/src/main.rs:113] [main] Loading config at path /home/stacks/kotal-config/config.toml
    INFO [1649597250.599067] [testnet/stacks-node/src/run_loop/neon.rs:341] [main] Start syncing Bitcoin headers, feel free to grab a cup of coffee, this can take a while
    INFO [1649597251.949664] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 0.3% (2000 out of 731268)
    INFO [1649597253.010039] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 0.5% (4000 out of 731268)
    INFO [1649597254.019798] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 0.8% (6000 out of 731268)
    INFO [1649597254.992070] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.1% (8000 out of 731268)
    INFO [1649597256.214756] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.4% (10000 out of 731268)
    INFO [1649597257.276950] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.6% (12000 out of 731268)
    INFO [1649597258.383248] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.9% (14000 out of 731268)
    ...
    kubectl port-forward bitcoin-node-0 20443
    curl: (52) Empty reply from server
    curl localhost:20443/v2/info
    {
      "peer_version": 402653189,
      "pox_consensus": "9bed78c9f02d2ba5a5950fe88c4746436b47c730",
      "burn_block_height": 666051,
      "stable_pox_consensus": "0000000000000000000000000000000000000000",
      "stable_burn_block_height": 666050,
      "server_version": "stacks-node No Version Info (No Branch Info:No Commit Info, release build, linux [x86_64])",
      "network_id": 1,
      "parent_network_id": 3652501241,
      "stacks_tip_height": 0,
      "stacks_tip": "0000000000000000000000000000000000000000000000000000000000000000",
      "stacks_tip_consensus_hash": "0000000000000000000000000000000000000000",
      "genesis_chainstate_hash": "74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b",
      "unanchored_tip": null,
      "unanchored_seq": null,
      "exit_at_block_height": null
    }
    kubectl delete -f stacks.yaml
    npm install -g @stacks/cli
    stx make_keychain
    {
      "mnemonic": "blue news bid also tell vault blame tonight crumble history tribe anxiety arch stove usage eight stick firm weapon wet chapter gravity seat idle",
      "keyInfo": {
        "privateKey": "7a3ef70a4a3ff3c389818ac11abec24b20ffbe3fb2cf6f71e947367a4ddbec6601",
        "address": "SPQG93WFTVV6GA4AEDMS18ZCSTKMKFHWEHEXQAJJ",
        "btcAddress": "15HcDuW1W2TqEe9mVER9ceJYtqMAED26jp",
        "wif": "L1KLjY5xMGUSSV9cfE9VoKRdVt3D1zJxoJwPVLHfgRNS1ETGUSvr",
        "index": 0
      }
    }
    kubectl create secret generic seed-private-key --from-literal=key=7a3ef70a4a3ff3c389818ac11abec24b20ffbe3fb2cf6f71e947367a4ddbec6601
    bitcoin-node-rpc-password.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: bitcoin-node-rpc-password
    stringData:
      password: blockstacksystem
    kubectl apply -f bitcoin-node-rpc-password.yaml
    stacks.yaml
    apiVersion: stacks.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: stacks-node
    spec:
      network: mainnet
      seedPrivateKeySecretName: seed-private-key
      bitcoinNode:
        endpoint: bitcoin.blockstack.com
        rpcPort: 8332
        p2pPort: 8333
        rpcUsername: blockstack
        rpcPasswordSecretName: bitcoin-node-rpc-password
    kubectl apply -f stacks.yaml
    kubectl get nodes.stacks
    NAME            NETWORK    CLIENT    MINER
    stacks-node     mainnet    stacks    true
    kubectl get pods
    NAME             READY   STATUS    RESTARTS   AGE
    stacks-node-0    1/1     Running   0          1m
    kubectl logs -f stacks-node-0
    INFO [1649610683.233993] [testnet/stacks-node/src/main.rs:113] [main] Loading config at path /home/stacks/kotal-config/config.toml
    INFO [1649610683.795606] [testnet/stacks-node/src/run_loop/neon.rs:341] [main] Start syncing Bitcoin headers, feel free to grab a cup of coffee, this can take a while
    INFO [1649610686.606279] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 0.3% (2000 out of 731294)
    INFO [1649610687.625014] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 0.5% (4000 out of 731294)
    INFO [1649610688.634560] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 0.8% (6000 out of 731294)
    INFO [1649610689.677533] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.1% (8000 out of 731294)
    INFO [1649610690.737928] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.4% (10000 out of 731294)
    INFO [1649610691.745002] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.6% (12000 out of 731294)
    INFO [1649610692.789689] [src/burnchains/bitcoin/spv.rs:923] [main] Syncing Bitcoin headers: 1.9% (14000 out of 731294)
    ...
    kubectl delete -f stacks.yaml
    kubectl apply -f beacon.yaml
    kubectl get beaconnodes
    NAME               CLIENT   Network   AGE
    teku-beacon-node   teku     pyrmont   1m
    kubectl get pods
    NAME                 READY   STATUS    RESTARTS   AGE
    teku-beacon-node-0   1/1     Running   0          1m
    kubectl logs -f teku-beacon-node-0
    kubectl get services
    NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
    teku-beacon-node   ClusterIP   10.96.197.218   <none>        9000/UDP,9000/TCP,8888/TCP   7s
    kubectl port-forward teku-beacon-node-0 8888
    curl localhost:8888/eth/v1/beacon/genesis
    {
      "data": {
        "genesis_time": "1606824023",
        "genesis_validators_root": "0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95",
        "genesis_fork_version": "0x00000000"
      }
    }
    kubectl delete beaconnode teku-beacon-node
    apiVersion: ethereum2.kotal.io/v1alpha1
    kind: BeaconNode
    metadata:
      name: teku-beacon-node
    spec:
      network: mainnet
      client: teku
      rest: true
      restPort: 8888
      eth1Endpoints:
        - http://besu-mainnet-node:8545
    kubectl explain beaconnode --api-version ethereum2.kotal.io/v1alpha1
    kubectl explain beaconnode.spec --api-version ethereum2.kotal.io/v1alpha1
    apiVersion: ethereum2.kotal.io/v1alpha1
    kind: Validator
    metadata:
      name: teku-validator
    spec:
      network: pyrmont
      client: teku
      beaconEndpoints:
        - http://teku-beacon-node:8888
      graffiti: Validated by Kotal
      keystores:
        - secretName: my-validator
    kubectl explain validator --api-version ethereum2.kotal.io/v1alpha1
    kubectl explain validator.spec --api-version ethereum2.kotal.io/v1alpha1
    kubectl explain validator.spec.keystores --api-version ethereum2.kotal.io/v1alpha1
    kusama.yaml
    apiVersion: polkadot.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: kusama-node
    spec:
      network: kusama
      pruning: false
    kubectl apply -f kusama.yaml
    kubectl get nodes.polkadot
    NAME             NETWORK     VALIDATOR
    kusama-node      kusama      fasle
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    kusama-node-0         1/1     Running   0          1m
    kubectl logs -f kusama-node-0
    2021-10-18 15:32:38 ----------------------------
    2021-10-18 15:32:38 This chain is not in any way
    2021-10-18 15:32:38       endorsed by the
    2021-10-18 15:32:38      KUSAMA FOUNDATION
    2021-10-18 15:32:38 ----------------------------
    2021-10-18 15:32:38 Parity Polkadot
    2021-10-18 15:32:38 ✌️  version 0.9.11-bfd38ed62-x86_64-linux-gnu
    2021-10-18 15:32:38 ❤️  by Parity Technologies <[email protected]>, 2017-2021
    2021-10-18 15:32:38 📋 Chain specification: Kusama
    2021-10-18 15:32:38 🏷 Node name: validator-node-sample
    2021-10-18 15:32:38 👤 Role: AUTHORITY
    2021-10-18 15:32:38 💾 Database: RocksDb at /polkadot/kotal-data/chains/ksmcc3/db/full
    2021-10-18 15:32:38 ⛓  Native runtime: kusama-9110 (parity-kusama-0.tx7.au2)
    2021-10-18 15:32:38 🔨 Initializing Genesis block/state (state: 0xb000…ef6b, header-hash: 0xb0a8…dafe)
    2021-10-18 15:32:38 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
    2021-10-18 15:32:39 ⏱  Loaded block-time = 6s from block 0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe
    2021-10-18 15:32:39 👶 Creating empty BABE epoch changes on what appears to be first startup.
    2021-10-18 15:32:39 🏷 Local node identity is: 12D3KooWFEHU9FXqGCL6ify4rqcon31WYViCnUfA6aVYTjRXqJ5F
    2021-10-18 15:32:39 📦 Highest known block at #0
    2021-10-18 15:32:39 〽️ Prometheus exporter started at 0.0.0.0:9615
    2021-10-18 15:32:39 Listening for new connections on 127.0.0.1:9944.
    2021-10-18 15:32:39 👶 Starting BABE Authorship worker
    ...
    kusama.yaml
    apiVersion: polkadot.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: kusama-node
    spec:
      network: kusama
      pruning: false
      validator: true
    kubectl apply -f kusama.yaml
    kubectl get nodes.polkadot
    NAME             NETWORK     VALIDATOR
    kusama-node      kusama      true
    kubectl port-forward polkadot-node-0 9933
    curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' http://127.0.0.1:9933
    {
      "jsonrpc": "2.0",
      "result": "0x159256d69a61b523a211d7845a92d5a238f6a97b53627c4aa92665eb6bc2959dc88c9c279ad01b8acf90573ca005f6565c4a0d88d19951740b8f8ec38c63b344b2c186e703ce88f0f4b628263265ffefa1cdc148c79a5608ccc7734e6a0bfb077076c5f370491331819d17884b9aa4e41d4e2bec774b5c31251203266c446a2ec02d89f5ecefcc75777d4de74766a57fbafe65b1850500875e8cf2fed3325f65",
      "id": 1
    }
    kubectl delete -f kusama.yaml
    
    node.polkadot.kotal.io "kusama-node" deleted
    peer.yaml
    apiVersion: ipfs.kotal.io/v1alpha1
    kind: Peer
    metadata:
      name: simple-peer
    spec: {}
    kubectl apply -f peer.yaml
    kubectl get peers
    NAME          CLIENT
    simple-peer   go-ipfs
    kubectl get pods
    NAME            READY   STATUS    RESTARTS   AGE
    simple-peer-0   1/1     Running   0          5m
    kubectl logs -f simple-peer-0
    Initializing daemon...
    go-ipfs version: 0.8.0-ce693d7
    Repo version: 11
    System version: amd64/linux
    Golang version: go1.14.4
    Swarm listening on /ip4/10.244.0.6/tcp/4001
    Swarm listening on /ip4/10.244.0.6/udp/4001/quic
    Swarm listening on /ip4/127.0.0.1/tcp/4001
    Swarm listening on /ip4/127.0.0.1/udp/4001/quic
    Swarm listening on /ip6/::1/tcp/4001
    Swarm listening on /ip6/::1/udp/4001/quic
    Swarm listening on /p2p-circuit
    Swarm announcing /ip4/10.244.0.6/tcp/4001
    Swarm announcing /ip4/10.244.0.6/udp/4001/quic
    Swarm announcing /ip4/127.0.0.1/tcp/4001
    Swarm announcing /ip4/127.0.0.1/udp/4001/quic
    Swarm announcing /ip6/::1/tcp/4001
    Swarm announcing /ip6/::1/udp/4001/quic
    API server listening on /ip4/0.0.0.0/tcp/5001
    WebUI: http://0.0.0.0:5001/webui
    Gateway (readonly) server listening on /ip4/0.0.0.0/tcp/8080
    Daemon is ready
    kubectl port-forward simple-peer-0 5001
    curl -X POST "http://127.0.0.1:5001/api/v0/cat?arg=QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme"
    Hello and Welcome to IPFS!
    
    ██╗██████╗ ███████╗███████╗
    ██║██╔══██╗██╔════╝██╔════╝
    ██║██████╔╝█████╗  ███████╗
    ██║██╔═══╝ ██╔══╝  ╚════██║
    ██║██║     ██║     ███████║
    ╚═╝╚═╝     ╚═╝     ╚══════╝
    
    If you're seeing this, you have successfully installed
    IPFS and are now interfacing with the ipfs merkledag!
    
     -------------------------------------------------------
    | Warning:                                              |
    |   This is alpha software. Use at your own discretion! |
    |   Much is missing or lacking polish. There are bugs.  |
    |   Not yet secure. Read the security notes for more.   |
     -------------------------------------------------------
    
    Check out some of the other files in this directory:
    
      ./about
      ./help
      ./quick-start     <-- usage examples
      ./readme          <-- this file
      ./security-notes
    kubectl delete -f peer.yaml
    near.yaml
    apiVersion: near.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: near-node
    spec:
      network: mainnet
      rpc: true
    kubectl apply -f near.yaml
    kubectl get nodes.near
    NAME         NETWORK    CLIENT      VALIDATOR
    near-node    mainnet    nearcore    fasle
    kubectl get pods
    NAME              READY   STATUS    RESTARTS   AGE
    near-node-0       1/1     Running   0          1m
    kubectl logs -f near-node-0
    Apr 07 12:18:33.280  INFO neard: Version: 1.23.1, Build: 1.23.0-9-gc0551c84b-modified, Latest Protocol: 50
    Apr 07 12:18:33.287  INFO near: Did not find "/home/near/kotal-data/data" path, will be creating new store database
    Apr 07 12:18:33.806  INFO stats: Server listening at ed25519:[email protected]:24567
    Apr 07 12:18:43.816  INFO stats: # 9820210 Downloading headers 0.00% (53203932)   5/3/40 peers ⬇ 7.2kiB/s ⬆ 0.4kiB/s 0.00 bps 0 gas/s CPU: 0%, Mem: 0 B
    Apr 07 12:18:53.819  INFO stats: # 9820210 Downloading headers 0.00% (53203933)   5/3/40 peers ⬇ 7.2kiB/s ⬆ 0.5kiB/s 0.00 bps 0 gas/s CPU: 10%, Mem: 134.4 MiB
    Apr 07 12:19:03.787  INFO stats: # 9820210 Downloading headers 0.00% (53203933)   5/3/40 peers ⬇ 7.2kiB/s ⬆ 0.5kiB/s 0.00 bps 0 gas/s CPU: 24%, Mem: 165.9 MiB
    Apr 07 12:19:13.790  INFO stats: # 9820210 Downloading headers 0.00% (53203933)   5/3/40 peers ⬇ 7.2kiB/s ⬆ 0.5kiB/s 0.00 bps 0 gas/s CPU: 9%, Mem: 175.0 MiB
    ...
    kubectl port-forward near-node-0 3030
    curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "status"}' 0.0.0.0:3030
    {
      "jsonrpc": "2.0",
      "result": {
        "version": {
          "version": "1.23.1",
          "build": "1.23.0-9-gc0551c84b-modified"
        },
        "chain_id": "mainnet",
        "protocol_version": 29,
        "latest_protocol_version": 50,
        "rpc_addr": "0.0.0.0:3030",
        "validators": [
          {
            "account_id": "nfvalidator2.near",
            "is_slashed": false
          },
          {
            "account_id": "nfvalidator1.near",
            "is_slashed": false
          },
          {
            "account_id": "nfvalidator4.near",
            "is_slashed": false
          },
          {
            "account_id": "nfvalidator3.near",
            "is_slashed": false
          }
        ],
        "sync_info": {
          "latest_block_hash": "EPnLgE7iEq9s7yTkos96M3cWymH5avBAPm3qx3NXqR8H",
          "latest_block_height": 9820210,
          "latest_state_root": "5o1trt9N9YgDL4xeY33z9adS5Ub3jMmuyQpWM7UHowrq",
          "latest_block_time": "2020-07-21T16:55:51.591948Z",
          "syncing": true,
          "earliest_block_hash": "EPnLgE7iEq9s7yTkos96M3cWymH5avBAPm3qx3NXqR8H",
          "earliest_block_height": 9820210,
          "earliest_block_time": "2020-07-21T16:55:51.591948Z"
        },
        "validator_account_id": "validator"
      },
      "id": 53
    }
    kubectl delete -f near.yaml
    circle-info

    Joining any Ethereum network is as easy as setting node's spec.network value, which accepts values like mainnet, rinkeby, goerli, xdai ... etc. After the node is created, you can't change spec.network.

    Apply rinkeby.yaml manifest:

    Kotal operator will notice your rinkeby-besu-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed Ethereum Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    circle-info

    If pod STATUS is Pending, most probably it's due to not enough cpu and memory, because Kotal allocates lots of cpu cores and memory for public nodes. The required node resources can be changed using spec.resources.cpu, spec.resources.memory, and spec.resources.storage.

    Get the logs of the running node:

    hashtag
    Call JSON-RPC Method

    Let's update our node by enabling JSON-RPC HTTP server:

    circle-info

    Kotal defaults node missing spec parameters like:

    • JSON-RPC HTTP server port is defaulted to 8545.

    • JSON-RPC HTTP server enabled modules are defaulted to: eth, net, and web3.

    • Blocks Synchronization mode is defauled to fast in public networks.

    For a comprehensive reference on Ethereum Node and default spec parameter values, check our

    Apply the new version of rinkeby.yaml:

    Forward localhost:8545 calls to the node pod:

    In another terminal window call eth_syncing JSON-RPC method

    You will get JSON result similar to the following:

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Ethereum Node controller.

    Validator account must have the name validator.

    An ed25519 private key will be generated and saved in current user home directory under .near-credentials/testnet

    It will return an output similar to the following

    circle-exclamation

    Change private_key field to secret_key.

    hashtag
    Generate Secret for Validator Private Key

    Create a Kubernetes secret from the generated private key in the previous step:

    hashtag
    Deploy NEAR Validator Node

    The following manifest describes a NEAR node that syncs NEAR testnet network: testnet, enables HTTP JSON-RPC server rpc: true, loads validator key from the Kubernetes secret that we've created in the previous step, and uses NEAR Corearrow-up-right client:

    Apply near.yaml manifest:

    Kotal operator will notice your near-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed NEAR Node using:

    It will return an output similar to the following:

    Note that validator is true in the prevous output 😇

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    It will return node logs similar to the following:

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal NEAR Node controller.

    hashtag
    Further Reading

    1. Deploy NEAR stacking poolarrow-up-right

    2. Staking on NEARarrow-up-right

    3. Upgradable staking poolarrow-up-right

    NEAR CLIarrow-up-right

    Deploy Chainlink Node

    hashtag
    Prerequisites

    hashtag
    Ethereum Node

    Chainlink node requires access to an EVM chain node with WebSocket server enabled. Here's how to deploy a simple Ethereum Rinkeby node with WebSocket server enabled:

    After deploying this node, it can be accessed in-cluster using ws://besu-rinkeby-node:8546 🔥. Read for more details on how to deploy public and private network nodes.

    hashtag
    PostgreSQL Database

    Chainlink requires access to database instance.

    You can use a hosted database a service to obtain PostgreSQL database:

    You can also deploy your own PostgreSQL database instance from official PostgreSQL .

    hashtag
    Keystore and API Password

    Chainlink node requires a strong password for securing access to keystore (wallet) and API. We will store this password in Kubernetes secret my-password:

    hashtag
    TLS Certificate

    Chainlink optionally requires TLS certificate to secure access to the node API. Using we can issue a simple self-signed certificate and store it in a Kubernetes secret:

    hashtag
    Deploying Chainlink Node

    With access to Ethereum Rinkeby node, PostgreSQL database, tls certificate and a strong password. We're ready to deploy our Chainlink node to create jobs and satisfy requests:

    In this manifest, we're describing Chainlink node that connects to Ethereum Rinkeby node using ethereumWsEndpoint, setting ethereum chain ID using ethereumChainId, setting link contract address using linkContractAddress, connecting to postgress database instance using databaseURL, setting wallet password using keystorePasswordSecretName which accepts a name of k8s secret, setting tls configuration using certSecretName which accepts k8s secret name that holds tls.key and tls.crt, and finally setting API credentials using apiCredentials.

    Apply chainlink.yaml manifest:

    Kotal operator will notice your chainlink-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed Chainlink Node using:

    It will return an output similar to the following:

    If you added -o wide it will return more info like link contract address

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    hashtag
    Open Chainlink User Interface

    Chainlink node comes with a user interface for managing the node, and it's being served by default on port 6688.

    Forward localhost:6688 calls to the node pod:

    Open https://localhost:6688 and it will take you to Chainlink node UI. It will ask you for API credentials. Enter the email address in your node's .spec.apiCredentials.email, and in the password field, enter fE2xXKDnR3ns489X.

    🔥🔥🔥

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Chainlink Node controller.

    Bitcoin

    Syntax
    Type
    Description
    Default

    required

    string

    Bitcoin network to join and sync

    hashtag
    network

    network is Bitcoin network to join and sync. Possible values are mainnet and testnet.

    network is immutable, can't be changed after node is created.

    hashtag
    p2pPort

    p2pPort is p2p communications port.

    hashtag
    p2pHost

    p2pHost is p2p communications host.

    hashtag
    rpc

    rpc enables JSON-RPC server.

    hashtag
    rpcPort

    rpcPort is JSON-RPC server port.

    hashtag
    rpcHost

    rpcHost is JSON-RPC server host.

    hashtag
    rpcUsers

    rpcUsers is a list of JSON-RPC users credentials:

    Syntax
    Type
    Description

    hashtag
    wallet

    wallet loads local wallet and enables wallet RPC calls.

    hashtag
    txIndex

    txIndex maintains a full transaction index.

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    Syntax
    Type
    Description
    Default

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1), 1500m, 2, and 4.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    Deploy Polkadot Node

    hashtag
    Deploy Polkadot Node

    The following manifest describes a Polkadot node that syncs Polkadot relay chain network: polkadot, enables HTTP JSON-RPC server rpc: true on custom port rpcPort: 8888, and uses Parity Polkadotarrow-up-right client:

    Apply polkadot.yaml manifest:

    Kotal operator will notice your polkadot-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets neccessary.

    You can fetch the deployed Polkadot Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    It will return node logs similar to the following:

    hashtag
    Call JSON-RPC Method

    Forward localhost:8888 calls to the node pod because rpcPort: 8888:

    In another terminal window call eth_getBlock JSON-RPC method to get the latest synced block:

    You will get JSON result similar to the following:

    Finally you can delete the node by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Polkadot Node controller.

    Deploy Private Clique Network

    hashtag
    Deploy Private Network Node

    triangle-exclamation

    In this tutorial we will use the following private keys and their corresponding addresses.

    NEAR

    Syntax
    Type
    Description
    Default
    rinkeby.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: rinkeby-besu-node
    spec:
      network: rinkeby
      client: besu
    kubectl apply -f rinkeby.yaml
    kubectl get nodes.ethereum
    NAME                 CLIENT   Consensus   Network
    rinkeby-besu-node    besu     poa         rinkeby
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    rinkeby-besu-node-0   1/1     Running   0          1m
    kubectl logs -f rinkeby-besu-node-0
    rinkeby.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: rinkeby-besu-node
    spec:
      network: rinkeby
      client: besu
      rpc: true
    kubectl apply -f rinkeby.yaml
    kubectl port-forward rinkeby-besu-node-0 8545
    curl -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":32}' http://127.0.0.1:8545
    {
      "jsonrpc" : "2.0",
      "id" : 32,
      "result" : {
        "startingBlock" : "0x0",
        "currentBlock" : "0x1518",
        "highestBlock" : "0x9567a3",
        "pulledStates" : "0x203ca",
        "knownStates" : "0x200636"
      }
    }
    kubectl delete -f rinkeby.yaml
    
    node.ethereum.kotal.io "rinkeby-besu-node" deleted
    npm install -g near-cli
    near generate-key validator
    cat ~/.near-credentials/testnet/validator.json
    {
      "account_id": "validator",
      "public_key": "ed25519:CdTBLXMmu9gzoCbNKdUnej1tJNMz5tzRjJF2a9DwAgUr",
      "private_key": "ed25519:4k83DwbSpD3zzai4ZPdeRJcfXttU3Uq68mWWhni6ra2RKnG3jyVKEZyP14gDJZ9W1oqFujpAkidoNrYY4TLqijsG"
    }
    kubectl create secret generic validator-key  --from-file=key=$HOME/.near-credentials/testnet/validator.json
    near.yaml
    apiVersion: near.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: near-node
    spec:
      network: testnet
      validatorSecretName: validator-key
      rpc: true
    kubectl apply -f near.yaml
    kubectl get nodes.near
    NAME         NETWORK    CLIENT      VALIDATOR
    near-node    testnet    nearcore    true
    kubectl get pods
    NAME              READY   STATUS    RESTARTS   AGE
    near-node-0       1/1     Running   0          1m
    kubectl logs -f near-node-0
    Apr 08 12:24:09.930  INFO neard: Version: 1.23.1, Build: 1.23.0-9-gc0551c84b-modified, Latest Protocol: 50
    Apr 08 12:24:09.937  INFO near: Did not find "/home/near/kotal-data/data" path, will be creating new store database
    Apr 08 12:24:10.438  INFO stats: Server listening at ed25519:[email protected]:24567
    Apr 08 12:24:20.444  INFO stats: # 9820210 Downloading headers 0.00% (53273496)   5/3/40 peers ⬇ 0.7kiB/s ⬆ 0.2kiB/s 0.00 bps 0 gas/s CPU: 0%, Mem: 0 B
    Apr 08 12:24:30.447  INFO stats: # 9820210 Downloading headers 0.00% (53273498)   5/3/40 peers ⬇ 0.7kiB/s ⬆ 0.2kiB/s 0.00 bps 0 gas/s CPU: 4%, Mem: 78.4 MiB
    Apr 08 12:24:40.417  INFO stats: # 9820210 Downloading headers 0.00% (53273497)   5/3/40 peers ⬇ 0.7kiB/s ⬆ 0.2kiB/s 0.00 bps 0 gas/s CPU: 10%, Mem: 99.6 MiB
    ...
    kubectl delete -f near.yaml
    polkadot.yaml
    apiVersion: polkadot.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: polkadot-node
    spec:
      network: polkadot
      rpc: true
      rpcPort: 8888
    ethereum reference
    NEAR validator bootcamparrow-up-right

    4

    memory

    string

    memory this node requires

    4Gi

    memoryLimit

    string

    memory this node is limited to

    8Gi

    storage

    string

    disk space this node requires

    100Gi

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    number

    p2p communications port

    8333 for mainnet, 18333 for testnet

    p2pHost

    string

    p2p communication host

    0.0.0.0

    rpc

    boolean

    Enables JSON-RPC server

    false

    rpcPort

    number

    JSON-RPC server port

    8332 for mainnet, 18332 for testnet

    rpcHost

    string

    JSON-RPC server host

    0.0.0.0

    rpcUsers

    array

    JSON-RPC users credentials

    wallet

    boolean

    Load local wallet and enables wallet RPC calls

    false

    txIndex

    boolean

    Maintains a full transaction index

    false

    resources

    object

    node compute and storage resources to alloacte

    username

    string

    JSON-RPC user name

    passwordSecretName

    string

    Kubernetes secret name holding JSON-RPC user password

    cpu

    string

    number of cpu cores this node requires

    2

    cpuLimit

    string

    network
    p2pPort

    number of cpu cores this node is limited to

    Ethereum guide
    PostgreSQLarrow-up-right
    Amazon AWSarrow-up-right
    Azurearrow-up-right
    Google Cloudarrow-up-right
    docker imagearrow-up-right
    cert-managerarrow-up-right
    DON'T use these keys in production.
    Address
    Private Key

    0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa

    fb5411342ae51291447515c89bcf6a057e3dbd0b51e060c45cb73406c38f851d

    0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d

    153b174f5e9948ae4678baed54f88244cc9c39d56b9f17ecef93d7ede633f56b

    0x7DE985E2f878c83C4e91b6B1312c0f63A56C844a

    89b03c4de62d61be16d22e09c8a48929a9bccd11fa6b37809cfef290292bcba3

    Let's describe an Ethereum Node that uses a custom genesis block to join a private Proof of Authority network using Clique consensus configuration in the genesis block.

    In this node, we're using Hyperledger besu client client: besu, enabling JSON-RPC server rpc: true so we can query number of peers later in this tutorial, and we're loading the node private key from Kubernetes secretd called besu-clique-nodekey.

    The node private key will give the node a unique identity and node URL, and will allow the node to generate blocks, because the address 0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa that's corresponding to the node private key is in the initial block signers.

    We're defining a genesis block that uses the value 4444 as network and chain identifier, and we start the chain with 3 signers as defined by spec.genesis.clique.signers.

    This node private key secret can be created by:

    circle-info

    Private key must not start with 0x, and must be stored in secret data field called key.

    Let's deploy the node:

    Kotal operator will notice your besu-clique-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    hashtag
    Deploy a Second Node

    Let's deploy another go-ethereum node, and connect it to the previous node in our private proof of authority network.

    circle-info

    Genesis block must be the same in both nodes, or they will fork at genesis block, and won't reach consensus.

    In this node, we're using go-ethereum client client: geth, starting the PoA consensus engine miner: true, setting the second address in the genesis signers list spec.genesis.clique.signers as the coinbase coinbase: "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d", and loading the signer account private key and password from kubernetes secrets privateKeySecretName: ... and passwordSecretName: .... We're connecting to the first node using staticNodes option which accepts Node name or enode url.

    circle-info

    staticNodes accept Node name or enode URL. Node name has the format of name.namespace, namespace is optional if Node is in the same namespace. If the node doesn't exist, or is not up and running yet, Kotal will not raise an error.

    You can create the private key and password secrets using:

    Deploy the second node using:

    Kotal operator will notice your second geth-clique-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum Nodes using:

    It will return an output similar to the following:

    hashtag
    Call JSON-RPC Method net_peerCount

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Forward localhost:8545 calls to the node pod:

    In another terminal window call net_peerCount JSON-RPC method

    You will get JSON result similar to the following:

    hashtag
    Homework

    Deploy a third node that uses Nethermind client, and signing blocks using the third key in the signers list spec.genesis.clique.signers. Nethermind client is similar to geth, you will import signer account private key and password from kubernetes secrets, and use the same genesis as the other nodes.

    Finally you can delete all the nodes by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Ethereum Node controller.

    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: besu-rinkeby-node
    spec:
      network: rinkeby
      client: besu
      ws: true
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-password
    stringData:
      password: fE2xXKDnR3ns489X
    # create self-signed certificate issuer
    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: self-signed-issuer
    spec:
      selfSigned: {}
    ---
    # create certificate for chainlink node
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: chainlink-node-cert
    spec:
      dnsNames:
        - "chainlink-node.svc"
        - "chainlink-node.svc.cluster.local"
      # store tls.crt and tls.key in this kubernetes secret
      secretName: chainlink-node-cert
      issuerRef:
        name: self-signed-issuer
    chainlink.yaml
    apiVersion: chainlink.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: chainlink-node
    spec:
      ethereumChainId: 4
      ethereumWsEndpoint: "ws://besu-rinkeby-node:8546"
      linkContractAddress: "0x01BE23585060835E02B77ef475b0Cc51aA1e0709"
      databaseURL: "postgresql://username:password@server:port/name"
      keystorePasswordSecretName: "my-password"
      certSecretName: "chainlink-node-cert"
      apiCredentials:
        email: "[email protected]"
        passwordSecretName: "my-password"
    kubectl apply -f chainlink.yaml
    kubectl get nodes.chainlink
    NAME             CLIENT      EthereumChainId
    chainlink-node   chainlink   4
    NAME             CLIENT      EthereumChainId   LinkContractAddress
    chainlink-node   chainlink   4                 0x01BE23585060835E02B77ef475b0Cc51aA1e0709
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    chainlink-node-0      1/1     Running   0          1m
    kubectl logs -f chainlink-node-0
    kubectl port-forward chainlink-node-0 6688
    kubectl delete -f chainlink.yaml
    
    node.chainlink.kotal.io "chainlink-node" deleted
    kubectl apply -f polkadot.yaml
    kubectl get nodes.polkadot
    NAME             NETWORK     VALIDATOR
    polkadot-node    polkadot    fasle
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    polkadot-node-0       1/1     Running   0          1m
    kubectl logs -f polkadot-node-0
    2021-10-17 22:15:12 Parity Polkadot
    2021-10-17 22:15:12 ✌️  version 0.9.11-bfd38ed62-x86_64-linux-gnu
    2021-10-17 22:15:12 ❤️  by Parity Technologies <[email protected]>, 2017-2021
    2021-10-17 22:15:12 📋 Chain specification: Polkadot
    2021-10-17 22:15:12 🏷 Node name: polkadot-node
    2021-10-17 22:15:12 👤 Role: FULL
    2021-10-17 22:15:12 💾 Database: RocksDb at /polkadot/kotal-data/chains/polkadot/db/full
    2021-10-17 22:15:12 ⛓  Native runtime: polkadot-9110 (parity-polkadot-0.tx8.au0)
    2021-10-17 22:15:12 🔨 Initializing Genesis block/state (state: 0x29d0…4e17, header-hash: 0x91b1…90c3)
    2021-10-17 22:15:12 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
    2021-10-17 22:15:13 ⏱  Loaded block-time = 6s from block 0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3
    2021-10-17 22:15:13 👶 Creating empty BABE epoch changes on what appears to be first startup.
    2021-10-17 22:15:13 🏷 Local node identity is: 12D3KooWRo3vvfgPdsJ44tXu1Y2GeFNmC9ror2HsdJjvSjEcfZdw
    2021-10-17 22:15:13 📦 Highest known block at #0
    2021-10-17 22:15:13 Listening for new connections on 127.0.0.1:9944.
    2021-10-17 22:15:13 🔍 Discovered new external address for our node: /ip4/102.189.29.174/tcp/30333/ws/p2p/12D3KooWRo3vvfgPdsJ44tXu1Y2GeFNmC9ror2HsdJjvSjEcfZdw
    2021-10-17 22:15:18 ⚙️  Syncing, target=#7304424 (1 peers), best: #64 (0x4983…1114), finalized #0 (0x91b1…90c3), ⬇ 37.0kiB/s ⬆ 17.6kiB/s
    kubectl port-forward polkadot-node-0 8888
    curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getBlock", "params": []}' 0.0.0.0:8888
    {
      "jsonrpc": "2.0",
      "result": {
        "block": {
          "extrinsics": [
            "0x280403000be06ab2527201",
            "0x14040a00912e",
            "0x1004140000"
          ],
          "header": {
            "digest": {
              "logs": [
                "0x0642414245b501030000000042eacc0f00000000f414617b1dbce8671e029af90ae45c4b51d2f8d77d7876ae5f19dd42b7cb213775f40642dc2d86dd0a16169008e2d8735c849d7113da468be33b1c85819310024daffbee165156a2c17919fdc592754960a5587b6affc81f3e9c260364da2200",
                "0x054241424501019243678a110c1271c784ba9abaf03e08ae635ea766ce953853bfb1e3c0f70b5c95907240de74e57aa379c8428cd9933f097e32f9ef82caf261277ba4dc573b8b"
              ]
            },
            "extrinsicsRoot": "0xd9c14a96f36005ef6487ff56cb4722ff64afa3535cb1464c988767084094566c",
            "number": "0xba7",
            "parentHash": "0xcfb74aa6750036482897f63806191b3b14447186e45f69c43fcb72e02b57871f",
            "stateRoot": "0x5116aa11f10b1b1ce7c05ea85de08238b7db4c2c485bc88a9167e3b0a153368b"
          }
        },
        "justifications": null
      },
      "id": 1
    }
    kubectl delete -f polkadot.yaml
    
    node.polkadot.kotal.io "polkadot-node" deleted
    besu-clique-node.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: besu-clique-node
    spec:
      client: besu
      nodePrivateKeySecretName: besu-clique-nodekey
      rpc: true
      genesis:
        chainId: 4444
        networkId: 4444
        clique:
          signers:
            - "0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa"
            - "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d"
            - "0x7DE985E2f878c83C4e91b6B1312c0f63A56C844a"
    kubectl create secret generic besu-clique-nodekey --from-literal=key=fb5411342ae51291447515c89bcf6a057e3dbd0b51e060c45cb73406c38f851d
    kubectl apply -f besu-clique-node.yaml
    kubectl get nodes.ethereum
    NAME                 CLIENT   Consensus   Network
    besu-clique-node     besu     poa         private
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    besu-clique-node-0    1/1     Running   0          1m
    kubectl logs -f besu-clique-node-0
    geth-clique-node.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: geth-clique-node
    spec:
      client: geth
      miner: true
      coinbase: "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d"
      import:
        privateKeySecretName: geth-clique-account-key
        passwordSecretName: geth-clique-account-password
      staticNodes:
        - besu-clique-node
      genesis:
        chainId: 4444
        networkId: 4444
        clique:
          signers:
            - "0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa"
            - "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d"
            - "0x7DE985E2f878c83C4e91b6B1312c0f63A56C844a"
    kubectl create secret generic geth-clique-account-key --from-literal=key=153b174f5e9948ae4678baed54f88244cc9c39d56b9f17ecef93d7ede633f56b
    kubectl create secret generic geth-clique-account-password --from-literal=password=s3cr3t
    kubectl apply -f geth-clique-node.yaml
    kubectl get nodes.ethereum
    NAME                 CLIENT   Consensus   Network
    besu-clique-node     besu     poa         private
    geth-clique-node     geth     poa         private
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    besu-clique-node-0    1/1     Running   0          1m
    geth-clique-node-0    1/1     Running   0          1m
    kubectl port-forward besu-clique-node-0 8545
    curl -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":32}' http://127.0.0.1:8545
    {
      "jsonrpc" : "2.0",
      "id" : 32,
      "result" : "0x1"
    }
    kubectl delete nodes.ethereum --all

    Kubernetes secret name holding node Ed25519 private key

    string

    Kubernetes secret name holding node Ed25519 validator key

    number

    Minimum number of peers to start syncing/producing blocks

    5

    boolean

    Keeps old blocks in the storage

    false

    number

    p2p protocol tcp port

    24567

    string

    p2p host

    0.0.0.0

    boolean

    Enables JSON-RPC server

    false

    number

    JSON-RPC server listening port

    3030

    string

    JSON-RPC server listening host

    0.0.0.0

    number

    Prometheus exporter port

    9615

    string

    Prometheus exporter host

    0.0.0.0

    string

    Telemetry service URL

    array

    Boot nodes to bootstrap network from

    object

    node compute and storage resources to alloacte

    hashtag
    network

    network is NEAR network to join and sync. Possible values are mainnet, testnet, and betanet.

    network is immutable, it can't be changed after node is created.

    hashtag
    nodePrivateKeySecretName

    nodePrivateKeySecretName is Kubernetes secret name holding node Ed25519 private key in data field key, from which node public key is generated, and p2p messages are signed.

    hashtag
    validatorSecretName

    validatorSecretName is Kubernetes secret name holding node Ed25519 validator key in data field key.

    hashtag
    minPeers

    minPeers is the minimum number of peers to start syncing/producing blocks.

    hashtag
    archive

    archive keeps old blocks in the storage.

    hashtag
    p2pPort

    p2pPort is p2p protocol tcp port.

    hashtag
    p2pHost

    p2pHost is p2p host address.

    hashtag
    rpc

    rpc enables JSON-RPC server.

    hashtag
    rpcPort

    rpcPort is JSON-RPC server listening port.

    hashtag
    rpcHost

    rpcHost is JSON-RPC server listening host address.

    hashtag
    prometheusPort

    prometheusPort is Prometheus exporter port.

    hashtag
    prometheusHost

    prometheusHost is Prometheus exporter host address.

    hashtag
    telemetryURL

    telemetryURL is Telemetry service URL.

    hashtag
    bootnodes

    bootnodes is a list of boot nodes to bootstrap network from

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    Syntax
    Type
    Description
    Default

    cpu

    string

    number of cpu cores this node requires

    4

    cpuLimit

    string

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1), 1500m, 2, and 4.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    network required

    string

    NEAR network to join and sync

    nodePrivateKeySecretName

    string

    Deploy Private IBFT 2.0 Network

    hashtag
    Deploy Private Network Node

    triangle-exclamation

    In this tutorial we will use the following private keys and their corresponding addresses.

    DON'T use these keys in production.

    Address
    Private Key

    Let's describe an Ethereum Node that uses a custom genesis block to join a private Proof of Authority network using ibft2 consensus configuration in the genesis block.

    In this node, we're using Hyperledger besu client client: besu, enabling JSON-RPC server rpc: true so we can query number of peers later in this tutorial, and we're loading the node private key from Kubernetes secretd called besu-ibft2-nodekey.

    The node private key will give the node a unique identity and node URL, and will allow the node to generate blocks, because the address 0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa that's corresponding to the node private key is in the initial block validators.

    We're defining a genesis block that uses the value 4444 as network and chain identifier, and we start the chain with 3 validators as defined by spec.genesis.ibft2.validators.

    This node private key secret can be created by:

    circle-info

    Private key must not start with 0x, and must be stored in secret data field called key.

    Let's deploy the node:

    Kotal operator will notice your besu-ibft2-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    hashtag
    Deploy a Second Node

    Let's deploy another go-ethereum node, and connect it to the previous node in our private proof of authority network.

    circle-info

    Genesis block must be the same in both nodes, or they will fork at genesis block, and won't reach consensus.

    In this node, we're using go-ethereum client client: geth, starting the PoA consensus engine miner: true, setting the second address in the genesis validators list spec.genesis.ibft2.validators as the coinbase coinbase: "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d", and loading the validator account private key and password from kubernetes secrets privateKeySecretName: ... and passwordSecretName: .... We're connecting to the first node using staticNodes option which accepts Node name or enode url.

    circle-info

    staticNodes accept Node name or enode URL. Node name has the format of name.namespace, namespace is optional if Node is in the same namespace. If the node doesn't exist, or is not up and running yet, Kotal will not raise an error.

    You can create the private key and password secrets using:

    Deploy the second node using:

    Kotal operator will notice your second geth-ibft2-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum Nodes using:

    It will return an output similar to the following:

    hashtag
    Call JSON-RPC Method net_peerCount

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Forward localhost:8545 calls to the node pod:

    In another terminal window call net_peerCount JSON-RPC method

    You will get JSON result similar to the following:

    hashtag
    Homework

    Deploy a third node that uses Nethermind client, and signing blocks using the third key in the validators list spec.genesis.ibft2.validators. Nethermind client is similar to geth, you will import validator account private key and password from kubernetes secrets, and use the same genesis as the other nodes.

    Finally you can delete all the nodes by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Ethereum Node controller.

    Stacks

    Syntax
    Type
    Description
    Default

    required

    string

    Stacks network to join and sync

    hashtag
    network

    network is Stacks network to join and sync. Possible values are mainnet and testnet.

    network is immutable, can't be changed after node is created.

    hashtag
    rpcPort

    rpcPort is JSON-RPC server port.

    hashtag
    rpcHost

    rpcHost is JSON-RPC server host.

    hashtag
    p2pPort

    p2pPort is p2p bind port.

    hashtag
    p2pHost

    p2pHost is p2p bind host.

    hashtag
    bitcoinNode

    bitcoinNode is Bitcoin node details for Stacks node to connect and query:

    Syntax
    Type
    Description

    hashtag
    miner

    miner enables mining.

    hashtag
    seedPrivateKeySecretName

    seedPrivateKeySecretName is Kubernetes secret name holding seed private key used for mining.

    hashtag
    mineMicroblocks

    mineMicroblocks enables mining Stacks micro blocks.

    hashtag
    nodePrivateKeySecretName

    nodePrivateKeySecretName is Kubernetes secret name holding node private key.

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    Syntax
    Type
    Description
    Default

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1), 1500m, 2, and 4.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    number of cpu cores this node is limited to

    8

    memory

    string

    memory this node requires

    4Gi

    memoryLimit

    string

    memory this node is limited to

    8Gi

    storage

    string

    disk space this node requires

    250Gi for non archival node, 4Ti for archive node

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    validatorSecretName
    minPeers
    archive
    p2pPort
    p2pHost
    rpc
    rpcPort
    rpcHost
    prometheusPort
    prometheusHost
    telemetryURL
    bootnodes
    resources

    number

    JSON-RPC server host

    rpcUsername

    string

    Bitcoin node JSON-RPC username

    rpcPasswordSecretName

    string

    Kubernetes secret name holding bitcoin node JSON-RPC password

    4

    memory

    string

    memory this node requires

    4Gi

    memoryLimit

    string

    memory this node is limited to

    8Gi

    storage

    string

    disk space this node requires

    100Gi

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    number

    JSON-RPC server port

    20443

    rpcHost

    string

    JSON-RPC server host

    0.0.0.0

    p2pPort

    number

    p2p bind port

    20444

    p2pHost

    string

    p2p bind host

    0.0.0.0

    bitcoinNode

    object

    Bitcoin node details

    miner

    boolean

    Enables mining

    false

    seedPrivateKeySecretName

    string

    Kubernetes secret name holding seed private key used for mining

    mineMicroblocks

    boolean

    Mines Stacks micro blocks

    false

    nodePrivateKeySecretName

    string

    Kubernetes secret name holding node private key

    resources

    object

    node compute and storage resources to alloacte

    endpoint

    string

    Stacks network to join and sync

    p2pPort

    number

    p2p bind port

    cpu

    string

    number of cpu cores this node requires

    2

    cpuLimit

    string

    network
    rpcPort

    rpcPort

    number of cpu cores this node is limited to

    0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa

    fb5411342ae51291447515c89bcf6a057e3dbd0b51e060c45cb73406c38f851d

    0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d

    153b174f5e9948ae4678baed54f88244cc9c39d56b9f17ecef93d7ede633f56b

    0x7DE985E2f878c83C4e91b6B1312c0f63A56C844a

    89b03c4de62d61be16d22e09c8a48929a9bccd11fa6b37809cfef290292bcba3

    besu-ibft2-node.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: besu-ibft2-node
    spec:
      client: besu
      nodePrivateKeySecretName: besu-ibft2-nodekey
      rpc: true
      genesis:
        chainId: 4444
        networkId: 4444
        ibft2:
          validators:
            - "0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa"
            - "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d"
            - "0x7DE985E2f878c83C4e91b6B1312c0f63A56C844a"
    kubectl create secret generic besu-ibft2-nodekey --from-literal=key=fb5411342ae51291447515c89bcf6a057e3dbd0b51e060c45cb73406c38f851d
    kubectl apply -f besu-ibft2-node.yaml
    kubectl get nodes.ethereum
    NAME                 CLIENT   Consensus   Network
    besu-ibft2-node      besu     ibft2       private
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    besu-ibft2-node-0     1/1     Running   0          1m
    kubectl logs -f besu-ibft2-node-0
    geth-ibft2-node.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: geth-ibft2-node
    spec:
      client: geth
      miner: true
      coinbase: "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d"
      import:
        privateKeySecretName: geth-ibft2-account-key
        passwordSecretName: geth-ibft2-account-password
      staticNodes:
        - besu-ibft2-node
      genesis:
        chainId: 4444
        networkId: 4444
        ibft2:
          validators:
            - "0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa"
            - "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d"
            - "0x7DE985E2f878c83C4e91b6B1312c0f63A56C844a"
    kubectl create secret generic geth-ibft2-account-key --from-literal=key=153b174f5e9948ae4678baed54f88244cc9c39d56b9f17ecef93d7ede633f56b
    kubectl create secret generic geth-ibft2-account-password --from-literal=password=s3cr3t
    kubectl apply -f geth-ibft2-node.yaml
    kubectl get nodes.ethereum
    NAME                 CLIENT   Consensus   Network
    besu-ibft2-node      besu     poa         private
    geth-ibft2-node      geth     poa         private
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    besu-ibft2-node-0     1/1     Running   0          1m
    geth-ibft2-node-0     1/1     Running   0          1m
    kubectl port-forward besu-ibft2-node-0 8545
    curl -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":32}' http://127.0.0.1:8545
    {
      "jsonrpc" : "2.0",
      "id" : 32,
      "result" : "0x1"
    }
    kubectl delete nodes.ethereum --all

    Filecoin

    circle-info

    Kotal uses only lotus client for Filecoin nodes, that's why there's no .spec.client option.

    Syntax
    Type
    Description
    Default

    hashtag
    network

    network is the network this node should join and sync its blockchain data.

    network possible values are mainnet, and calibration.

    circle-exclamation

    butterfly and nerpa networks have been deprecated 🥺

    hashtag
    api

    api enables API server.

    hashtag
    apiPort

    apiPort is API server listening port.

    hashtag
    apiHost

    apiHost is API server host.

    hashtag
    apiRequestTimeout

    apiRequestTimeout is API request timeout in seconds.

    hashtag
    disableMetadataLog

    disableMetadataLog disables metadata logging.

    hashtag
    p2pPort

    p2pPort is p2p port.

    hashtag
    p2pHost

    p2pHost is p2p host.

    hashtag
    ipfsPeerEndpoint

    ipfsPeerEndpoint ipfs peer endpoint.

    hashtag
    ipfsOnlineMode

    ipfsOnlineMode sets sets ipfs online mode.

    hashtag
    ipfsForRetrieval

    ipfsForRetrieval uses ipfs for retrieval.

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    Syntax
    Type
    Description
    Default

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1), 1500m, 2, and 4.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    1234

    string

    API server host

    0.0.0.0

    number

    API request timeout in seconds

    30

    boolean

    disables metadata logging

    false

    string

    p2p port

    4444

    string

    p2p host

    0.0.0.0

    string

    ipfs peer endpoint

    boolean

    ipfs online mode

    false

    boolean

    use ipfs for retrieval

    false

    object

    node compute and storage resources to alloacte

    number of cpu cores this node is limited to

    8 in nerpa, 16 in other networks

    memory

    string

    memory this node requires

    8Gi in nerpa, 16Gi in other networks

    memoryLimit

    string

    memory this node is limited to

    16Gi in nerpa, 32Gi in other networks

    storage

    string

    disk space this node requires

    100Gi in nerpa, 200Gi in other networks

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    network

    string

    network to join and sync

    api

    boolean

    enables API server

    false

    apiPort

    number

    cpu

    string

    number of cpu cores this node requires

    4 in nerpa, 8 in other networks

    cpuLimit

    API server listening port

    string

    Chainlink

    Syntax
    Type
    Description
    Default

    number

    Ethereum chain id

    hashtag
    ethereumChainId

    ethereumChainId is ethereum chain id.

    hashtag
    linkContractAddress

    linkContractAddress is Link contract address.

    hashtag
    ethereumWsEndpoint

    ethereumWsEndpoint is Ethereum node's WebSocket server endpoint.

    hashtag
    ethereumHttpEndpoints

    ethereumHttpEndpoints is array of Ethereum HTTP endpoints used for heavy requests and as fallback in case of Ethereum node bug or failure.

    hashtag
    databaseURL

    databaseURL is Postgres database connection URL.

    hashtag
    keystorePasswordSecretName

    keystorePasswordSecretName is k8s secret name that holds keystore (wallet) password in data field called password.

    hashtag
    apiCredentials

    apiCredentials is the credetials used to access Chainlink node UI:

    Syntax
    Type
    Description

    hashtag
    corsDomains

    corsDomains is a list of domains from which to accept cross origin requests.

    hashtag
    certSecretName

    certSecretName is k8s secret name that holds TLS private key in tls.key data field and TLS certificate in tls.crt data field.

    hashtag
    apiPort

    apiPort is the port used for node API and GUI.

    hashtag
    tlsPort

    tlsPort is the port used for HTTPS connections.

    hashtag
    p2pPort

    p2pPort is the port used for p2p communcations.

    hashtag
    secureCookies

    secureCookies enables secure cookies for authentication.

    hashtag
    logging

    logging is logging verbosity level. Possible values are debug, info, warn, error, and panic.

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    Syntax
    Type
    Description
    Default

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1), 1500m, 2, and 4.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    Deploy IPFS cluster peer

    IPFS Cluster provides data orchestration across a swarm of IPFS daemons by allocating, replicating and tracking a global pinset distributed among multiple peers. Sourcearrow-up-right

    hashtag
    Prerequisites

    Before we start, you need to:

    hashtag
    Step 1 - Deploy IPFS Peer

    Deploy an ipfs peer Peer because it's required by ClusterPeer. Check our tutorial.

    hashtag
    Step 2 - Generate Cluster Secret

    Create a cluster secret which secures access to the cluster:

    circle-exclamation

    Cluster secret must be 32-byte hex-encoded (64 characters) without the leading 0x. It must be hold in data field called secret in the Kubernetes secret.

    hashtag
    Step 3 - Generate ID and Private Key

    Create cluster peer ID and private key using

    It will return an output similar to the following:

    hashtag
    Step 4 - Deploy Private Key Secret

    create Kubernetes secret from the generated private key in step(3) above.

    hashtag
    Deploying First Cluster Peer

    Now we're ready to deploy the cluster peer and connect it to the peer we've deployed in step(1)

    circle-info

    Note that id and privateKeySecretName are optional, they're useful to get predictable cluster peer id to be used in future steps as bootstrap peer.

    Let's deploy cluster peer manifest file:

    Kotal operator will notice your cluster-peer and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed IPFS ClusterPeer using:

    It will return an output similar to the following:

    hashtag
    Fetch Cluster Peer Logs

    Get the pods created for our cluster peer:

    It will return an output similar to the following:

    Check the logs of the running cluster peer:

    It will return an output similar to the following:

    As you can see from the logs that our cluster peer is up and running as indicated by the healthy logs IPFS Cluster is READY.

    hashtag
    Update Cluster Pinset

    Let's add some content to the pinset by executing commands inside cluster peer container:

    Let's fetch the pinset of the ipfs peer by executing commands inside peer -created in step(1)- container:

    As you can see, content pinned by the cluster peer, has been added to the pinset of the ipfs peer and available in its local storage.

    hashtag
    Deploying Second Cluster Peer

    The only prerequisite to the second cluster peer is to:

    hashtag
    Step 1 - Deploy IPFS Peer

    Deploy an ipfs peer Peer, and name it peer-sample-two. Check our tutorial.

    We will reuse cluster secret that was generated in step(2) during deploying first cluster peer above.

    circle-info

    The first cluster peer multiaddress is predictable because we've used a pre-generated id and private key in step(3). /ip4/{cluster peer k8s service name}/tcp/9096/p2p/{cluster peer ID}

    Deploying this cluster manifest will deploy a cluster peer that connects to the first cluster peer and will connect to its own ipfs peer peer-sample-two instance.

    You can fetch the deployed cluster peers by:

    It will return an output similar to the following:

    hashtag
    Fetch Second Cluster Peer Logs

    Get the pods created by our cluster peer:

    It will return an output similar to the following:

    Check the logs of cluster peer two:

    It will return an output similar to the following:

    As you can see cluster peer two is up and running as indicated by the healthy logs and IPFS Cluster is READY.

    Cluster peer two has joined the first cluster peer as indicated by the highlighted log line joined 12D...uiq's cluster

    Finally, delete all peers and cluster peers:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal IPFS Peer and ClusterPeer controllers.

    apiHost
    apiRequestTimeout
    disableMetadataLog
    p2pPort
    p2pHost
    ipfsPeerEndpoint
    ipfsOnlineMode
    ipfsForRetrieval
    resources

    number of cpu cores this node is limited to

    4

    memory

    string

    memory this node requires

    2Gi

    memoryLimit

    string

    memory this node is limited to

    4Gi

    storage

    string

    disk space this node requires

    20Gi

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    linkContractAddress

    string

    Link contract address

    ethereumWsEndpoint

    string

    Ethereum node WebSocket server endpoint

    ethereumHttpEndpoints

    array

    Ethereum HTTP endpoints

    databaseURL

    string

    Postgres database connection URL

    keystorePasswordSecretName

    string

    k8s secret name that holds keystore password

    apiCredentials

    object

    API credentials

    corsDomains

    array

    Domains from which to accept cross origin requests

    *

    certSecretName

    string

    k8s secret name that holds tls.key and tls.crt

    apiPort

    number

    Port used for node API and GUI

    6688

    tlsPort

    number

    Port used for HTTPS connections

    6689

    p2pPort

    number

    Port used for p2p communcations

    30303

    secureCookies

    boolean

    Enable secure cookies for authentication

    false

    logging

    string

    Logging verbosity level

    info

    resources

    object

    node compute and storage resources to alloacte

    email

    string

    User email

    passwordSecretName

    string

    k8s secret name that holds password in data field called password

    cpu

    string

    number of cpu cores this node requires

    2

    cpuLimit

    ethereumChainId

    string

    Deploy IPFS Peer
    ipfs-keyarrow-up-right
    Deploy IPFS Peer
    CLUSTER_SECRET=$(openssl rand -hex 32)
    kubectl create secret generic cluster-secret --from-literal=secret=$CLUSTER_SECRET
    ipfs-key -type ed25519 | base64
    Generating a 2048 bit ed25519 key...
    Success!
    ID for generated key: 12D3KooWBcEtY8GH4mNkri9kM3haeWhEXtQV7mi81ErWrqLYGuiq
    CAESQOH/DvUJmeJ9z6m3wAStpkrlBwJQxIyNSK0YGf0EI5ZRGpwsWxl4wmgReqmHl8LQjTC2iPM0QbYAjeY3Z63AFnI=
    CLUSTER_PEER_PRIVATEKEY=CAESQOH/DvUJmeJ9z6m3wAStpkrlBwJQxIyNSK0YGf0EI5ZRGpwsWxl4wmgReqmHl8LQjTC2iPM0QbYAjeY3Z63AFnI=
    kubectl create secret generic cluster-peer-privatekey --from-literal=key=$CLUSTER_PEER_PRIVATEKEY
    cluster-peer.yaml
    apiVersion: ipfs.kotal.io/v1alpha1
    kind: ClusterPeer
    metadata:
      Name: cluster-peer
    spec:
      consensus: crdt
      # from step(3)
      id: "12D3KooWBcEtY8GH4mNkri9kM3haeWhEXtQV7mi81ErWrqLYGuiq"
      # from step(4)
      privateKeySecretName: cluster-peer-privatekey
      # from step(1)
      peerEndpoint: /dns4/peer-sample/tcp/5001
      # from step(2)
      clusterSecretName: cluster-secret
    kubectl apply -f cluster-peer.yaml
    kubectl get clusterpeers
    NAME           CLIENT                 CONSENSUS
    cluster-peer   ipfs-cluster-service   crdt
    kubectl get pods
    NAME             READY   STATUS    RESTARTS   AGE
    cluster-peer-0   1/1     Running   0          2m
    kubectl logs -f cluster-peer-0
    2021-04-30T00:31:24.109Z	INFO	service	ipfs-cluster-service/daemon.go:46	Initializing. For verbose output run with "-l debug". Please wait...
    2021-04-30T00:31:24.133Z	INFO	cluster	ipfs-cluster/cluster.go:136	IPFS Cluster v0.13.2+git812c8e3631d4d6771a6e04112e12cd7726e23f7a listening on:
    
            /ip4/10.244.0.8/tcp/9096/p2p/12D3KooWBcEtY8GH4mNkri9kM3haeWhEXtQV7mi81ErWrqLYGuiq
            /ip4/127.0.0.1/tcp/9096/p2p/12D3KooWBcEtY8GH4mNkri9kM3haeWhEXtQV7mi81ErWrqLYGuiq
    
    2021-04-30T00:31:24.134Z	INFO	ipfsproxy	ipfsproxy/ipfsproxy.go:320	IPFS Proxy: /ip4/127.0.0.1/tcp/9095 -> /ip4/127.0.0.1/tcp/5001
    2021-04-30T00:31:24.134Z	INFO	restapi	rest/restapi.go:521	REST API (HTTP): /ip4/127.0.0.1/tcp/9094
    2021-04-30T00:31:24.134Z	INFO	crdt	[email protected]/crdt.go:278	crdt Datastore created. Number of heads: 0. Current max-height: 0
    2021-04-30T00:31:24.136Z	INFO	cluster	ipfs-cluster/cluster.go:651	Cluster Peers (without including ourselves):
    2021-04-30T00:31:24.136Z	INFO	cluster	ipfs-cluster/cluster.go:653	    - No other peers
    2021-04-30T00:31:24.136Z	INFO	cluster	ipfs-cluster/cluster.go:666	** IPFS Cluster is READY **
    $ kubectl exec -it cluster-peer-0 -- sh
    # now we're inside cluster-peer container
    
    $ echo "kotal simplifies Blockchain DevOps" > kotal.txt
    
    # add kotal.txt to the pinset
    $ ipfs-cluster-ctl add kotal.txt
    added QmUiwYtz1VxeryVCpTLWqrbeUi9HyGH4AnpSG6BrmdMhzL kotal.txt
    
    # leave cluster-peer container
    $ exit
    $ kubectl exec -it peer-sample-0 -- sh
    # now we're inside peer-sample container
    
    # List objects pinned to local storage
    $ ipfs pin ls
    QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn recursive
    QmUiwYtz1VxeryVCpTLWqrbeUi9HyGH4AnpSG6BrmdMhzL recursive
    
    $ ipfs cat QmUiwYtz1VxeryVCpTLWqrbeUi9HyGH4AnpSG6BrmdMhzL
    kotal simplifies Blockchain DevOps
    
    # leave ipfs peer container
    $ exit
    cluster-peer-two.yaml
    apiVersion: ipfs.kotal.io/v1alpha1
    kind: ClusterPeer
    metadata:
      Name: cluster-peer-two
    spec:
      # from step(1)
      peerEndpoint: /dns4/peer-sample-twp/tcp/5001
      # generated during deploying first cluster peer in step(2)
      clusterSecretName: cluster-secret
      # first cluster peer listening address
      bootstrapPeers:
        - /ip4/cluster-peer/tcp/9096/p2p/12D3KooWBcEtY8GH4mNkri9kM3haeWhEXtQV7mi81ErWrqLYGuiq
    kubectl apply -f cluster-peer-two.yaml
    kubectl get clusterpeers
    NAME               CLIENT                 CONSENSUS
    cluster-peer       ipfs-cluster-service   crdt
    cluster-peer-two   ipfs-cluster-service   crdt
    kubectl get pods
    NAME                 READY   STATUS    RESTARTS   AGE
    cluster-peer-0       1/1     Running   0          10m
    cluster-peer-two-0   1/1     Running   0          2m
    kubectl logs -f cluster-peer-two-0
    2021-05-01T19:17:12.043Z	INFO	service	ipfs-cluster-service/daemon.go:46	Initializing. For verbose output run with "-l debug". Please wait...
    2021-05-01T19:17:12.352Z	INFO	cluster	ipfs-cluster/cluster.go:136	IPFS Cluster v0.13.2+git812c8e3631d4d6771a6e04112e12cd7726e23f7a listening on:
    
            /ip4/10.244.0.35/tcp/9096/p2p/12D3KooWGVZek7gdarvj7gePvnV9x8ekSeSdruYojgj5dmU466Wv
            /ip4/127.0.0.1/tcp/9096/p2p/12D3KooWGVZek7gdarvj7gePvnV9x8ekSeSdruYojgj5dmU466Wv
    
    
    2021-05-01T19:17:12.441Z	INFO	restapi	rest/restapi.go:521	REST API (HTTP): /ip4/127.0.0.1/tcp/9094
    2021-05-01T19:17:12.441Z	INFO	ipfsproxy	ipfsproxy/ipfsproxy.go:320	IPFS Proxy: /ip4/127.0.0.1/tcp/9095 -> /ip4/127.0.0.1/tcp/5001
    2021-05-01T19:17:12.441Z	INFO	service	ipfs-cluster-service/daemon.go:218	Bootstrapping to /dns4/cluster-peer/tcp/9096/p2p/12D3KooWBcEtY8GH4mNkri9kM3haeWhEXtQV7mi81ErWrqLYGuiq
    2021-05-01T19:17:12.442Z	INFO	crdt	[email protected]/crdt.go:278	crdt Datastore created. Number of heads: 0. Current max-height: 0
    2021-05-01T19:17:12.442Z	INFO	crdt	crdt/consensus.go:277	'trust all' mode enabled. Any peer in the cluster can modify the pinset.
    2021-05-01T19:17:12.447Z	INFO	cluster	ipfs-cluster/cluster.go:651	Cluster Peers (without including ourselves):
    2021-05-01T19:17:12.447Z	INFO	cluster	ipfs-cluster/cluster.go:653	    - No other peers
    2021-05-01T19:17:12.448Z	INFO	cluster	ipfs-cluster/cluster.go:666	** IPFS Cluster is READY **
    2021-05-01T19:17:12.551Z	INFO	cluster	ipfs-cluster/cluster.go:1020	12D3KooWGVZek7gdarvj7gePvnV9x8ekSeSdruYojgj5dmU466Wv: joined 12D3KooWBcEtY8GH4mNkri9kM3haeWhEXtQV7mi81ErWrqLYGuiq's cluster
    kubectl delete peers --all
    kubectl delete clusterpeers --all

    Polkadot

    Syntax
    Type
    Description
    Default

    string

    Polkadot node client image

    last stable and tested client

    hashtag
    image

    image is polkadot node client image. Kotal dashboard uses image information published .

    hashtag
    extraArgs

    extraArgs are extra arguments to pass down to the node client. This can be useful if kotal doesn't support something you're inttersted in.

    circle-info

    Note that extraArgs adds arguments only, and doesn't remove arguments. Future release will support removing arguments. Use this feature with care.

    hashtag
    replicas

    replicas is number of replicas. Accepted values are 0 and 1 only.

    circle-info

    replicas is used to start and shutdown node gracefully.

    hashtag
    network

    network is the polkadot network/chain to join and sync. Possible values are polkadot, kusama, rococo, westend and other chains supported by client.

    hashtag
    p2pPort

    p2pPort is p2p protocol tcp port.

    hashtag
    nodePrivateKeySecretName

    nodePrivateKeySecretName is Kubernetes secret name holding node Ed25519 private key in data field called key.

    Node private can be generated using tool from Parity Substrate.

    Create node private key secret:

    polkadot-node-key secret can be used in your polkadot Node by updating .spec with nodePrivateKeySecretName: polkadot-node-key.

    hashtag
    validator

    validator enables validator.

    triangle-exclamation

    Node must sync blocks in archive mode pruning: false if validator is enabled.

    hashtag
    syncMode

    syncMode is blockchain synchronization mode. Available values are fast and full.

    hashtag
    pruning

    pruning controls whether to keep only recent or all blocks. Setting pruning to false runs the node in archive mode.

    hashtag
    retainedBlocks

    retainedBlocks is the number of blocks to keep state for. It's only considered if .spec.pruning is set to true.

    hashtag
    database

    database is database backend. Possible values are auto, paritydb or rocksdb.

    hashtag
    logging

    logging is logging verboisty level. Available logging levels are error, warn, info, debug, and trace.

    hashtag
    telemetry

    telemetry enables connecting to telemetry server.

    hashtag
    telemetryURL

    telemetryURL is telemetry service URL. It's only considered if .spec.telemetry is set to true.

    hashtag
    promethems

    prometheus exposes prometheus exporter endpoint.

    hashtag
    prometheusPort

    prometheusPort is prometheus exporter port

    hashtag
    rpc

    rpc enables JSON-RPC server.

    hashtag
    rpcPort

    rpcPort is JSON-RPC server port.

    hashtag
    ws

    ws enables Websocket server.

    hashtag
    wsPort

    wsPort is Websocket server port.

    hashtag
    corsDomains

    corsDomains is browser origins allowed to access the JSON-RPC HTTP and WS servers.

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    Syntax
    Type
    Description
    Default

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1), 1500m, 2, and 4.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    8

    memory

    string

    memory this node requires

    4Gi

    memoryLimit

    string

    memory this node is limited to

    8Gi

    storage

    string

    disk space this node requires

    80Gi

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    array

    Extra arguments to pass down to the node client

    replicas

    number

    number of replicas

    1

    network required

    string

    polkadot network/chain to join and sync

    p2pPort

    string

    p2p protocol tcp port

    30333

    nodePrivateKeySecretName

    string

    Kubernetes secret name holding node Ed25519 private key

    validator

    boolean

    enables validator

    false

    syncMode

    string

    blockchain synchronization mode

    full

    pruning

    boolean

    whether to keep only recent or all blocks

    false

    retainedBlocks

    number

    number of blocks to keep state for

    256

    database

    string

    database backend

    auto

    logging

    string

    logging verboisty level

    info

    telemetry

    boolean

    enables connecting to telemetry server

    false

    telemetryURL

    string

    telemetry service URL

    wss://telemetry.polkadot.io/submit/ 0

    prometheus

    string

    exposes prometheus exporter endpoint

    false

    prometheusPort

    number

    prometheus exporter port

    9615

    rpc

    boolean

    enables JSON-RPC server

    false

    rpcPort

    number

    JSON-RPC server port

    9933

    ws

    boolean

    enables Websocket server

    false

    wsPort

    number

    Websocket server port

    9944

    corsDomains

    array

    browser origins allowed to access the JSON-RPC HTTP and WS servers

    all

    resources

    object

    node compute and storage resources to alloacte

    cpu

    string

    number of cpu cores this node requires

    4

    cpuLimit

    string

    herearrow-up-right
    Parity Polkadotarrow-up-right
    subkeyarrow-up-right
    image
    extraArgs

    number of cpu cores this node is limited to

    # these extra arguments will be passed as follow to the client
    # --arg1 val1 --toggle --arg2 val2
    extraArgs:
      "--arg1": val1
      "--toggle": ""
      "--arg2": val2
    # generate binary node key and save it in node.key file
    subkey generate-node-key node.key
    # convert node.key binary file into hexadecimal node.key.hex file
    xxd -p -c 32 node.key > node.key.hex
    kubectl create secret generic polkadot-node-key  --from-file=key=node.key.hex

    IPFS

    hashtag
    Peer

    circle-info

    Kotal uses only go-ipfs client for IPFS peers, that's why there's no .spec.client

    option.
    Syntax
    Type
    Description
    Default

    Array

    List of initial configuration profiles

    default-datastore

    hashtag
    initProfiles

    initProfiles is al list of initial ipfs configuration profile.

    initialProfiles available values are server, randomports, default-datastore, local-discovery, test, default-networking, flatfs, badgerds, and lowpower.

    initProfiles can't be updated (immutable).

    hashtag
    profiles

    profiles is the list of configuration profiles to apply after peer initialization.

    profiles available values are server, randomports, default-datastore, local-discovery, test, default-networking, flatfs, badgerds, and lowpower.

    hashtag
    apiHost

    apiHost is API server host.

    circle-info

    If you set apiHost to host other than 0.0.0.0, api calls forwarded to the container won't hit the API server. This is useful if you want to disallow calls to API server.

    hashtag
    apiPort

    apiPort is API server port.

    hashtag
    gatewayHost

    gatewayHost is local ipfs gateway host.

    circle-info

    If you set gatewayHost to host other than 0.0.0.0, gateway won't work. This is useful if you want to disable to access gateway from outside.

    hashtag
    gatewayPort

    gatewayPort is API server port.

    hashtag
    routing

    routing is the content routing mechanism.

    routing available values are none, dht, dhtclient, dhtserver.

    hashtag
    swarmKeySecretName

    swarmKeySecretName is the kubernetes secret name that's holding the swarm key in a key called secret.

    hashtag
    resources

    resources allocates compute and storage resources to the peer.

    resources object has the following fields:

    Syntax
    Type
    Description
    Defalt

    cpu

    string

    number of cpu cores this peer requires

    1

    cpuLimit

    Memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1 core), 1500m which is 1.5 core, 2 cores, and 4 cores.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    hashtag
    ClusterPeer

    circle-info

    Kotal uses only ipfs-cluster-service for IPFS cluster peers that runs along with go-ipfs, that's why there's no .spec.client option.

    Syntax
    Type
    Description
    Default

    string

    Cluster peer ID

    hashtag
    id

    id is cluster peer id derived from private key.

    id is required if privateKeySecretName is provided.

    id can be generated using ipfs-keyarrow-up-right tool.

    It will return an output similar to the following:

    hashtag
    privateKeySecretName

    privateKeySecretName is the name of the k8s secret holding base64 cluster peer privatekey in a key called key.

    privateKeySecretName is required if id is provided.

    privateKeySecretName can be generated using ipfs-keyarrow-up-right tool.

    It will return an output similar to the following:

    hashtag
    trustedPeers

    trustedPeers is a list of peer IDs that can manage the cluster pinset in crdt consensus clusters.

    trustedPeers is ignored in raft consensus clusters.

    trustedPeers default value is * which is trust all peers.

    hashtag
    bootstrapPeers

    bootstrapPeers is a list of peers to connect to on startup.

    circle-exclamation

    bootstrapPeers will be trusted peers in crdt clusters.

    hashtag
    consensus

    consensus is the cluster consensus algorithm.

    hashtag
    peerEndpoint

    peerEndpoint id ipfs peer http API endpoint.

    peerEndpoint is required for the cluster peer to function correctly.

    hashtag
    clusterSecretName

    clusterSecretName is the k8s secret name holding 32-bit hex-encoded (without 0x) cluster secret in a key called secret.

    clusterSecretName can be generated using openssl tool:

    hashtag
    resources

    resources allocates compute and storage resources to the peer.

    resources object has the following fields:

    Syntax
    Type
    Description
    Defalt

    cpu

    string

    number of cpu cores this peer requires

    1

    cpuLimit

    Memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1 core), 1500m which is 1.5 core, 2 cores, and 4 cores.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    kubectl create secret generic swarm-key --from-literal=secret=$w@rmk3y
    ipfs-key -type ed25519 | base64
    Generating a 2048 bit ed25519 key...
    Success!
    ID for generated key: 12D3KooWT2bqgwZPxHthAGBV9Ut8ZLraz1LARtB7vG3mF26Mtof1
    CAESQLepaunFGa/PI0oNS3plrbVSInqab/X/U1laEDe2V2cL/7kbF9H6x3xBiwpbVnYT/jDA8EhAznXALlbwzEsuKaw=
    ipfs-key -type ed25519 | base64
    Generating a 2048 bit ed25519 key...
    Success!
    ID for generated key: 12D3KooWT2bqgwZPxHthAGBV9Ut8ZLraz1LARtB7vG3mF26Mtof1
    CAESQLepaunFGa/PI0oNS3plrbVSInqab/X/U1laEDe2V2cL/7kbF9H6x3xBiwpbVnYT/jDA8EhAznXALlbwzEsuKaw=
    CLUSTER_SECRET=$(openssl rand -hex 32)
    kubectl create secret generic cluster-secret --from-literal=secret=$CLUSTER_SECRET

    Array

    List of configuration profiles to apply after peer initialization

    apiHost

    string

    API server host

    0.0.0.0

    apiPort

    number

    API server port

    5001

    gatewayHost

    string

    Local ipfs gateway host

    0.0.0.0

    gatewayPort

    number

    Local ipfs gateway port

    8080

    routing

    string

    Content routing mechanism

    dht

    swarmKeySecretName

    string

    Name of the k8s secret holding swarm secret key

    resources

    object

    Compute and storage resources

    string

    number of cpu cores this peer is limited to

    2

    memory

    string

    memory this peer requires

    2Gi

    memoryLimit

    string

    memory this peer is limited to

    4Gi

    storage

    string

    disk space this peer requires

    10Gi

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    string

    Name of the k8s secret holding cluster peer privatekey

    * if consensus is crdt

    trustedPeers

    array

    Peer IDs that can manage the pinset in crdt consensus

    bootstrapPeers

    array

    Peers to connect to on startup

    consensus

    string

    Cluster consensus algorithm

    crdt

    peerEndpoint required

    string

    ipfs peer http API endpoint

    clusterSecretName required

    string

    Name of the k8s secret holding cluster secret

    resources

    object

    Compute and storage resources

    string

    number of cpu cores this peer is limited to

    2

    memory

    string

    memory this peer requires

    2Gi

    memoryLimit

    string

    memory this peer is limited to

    4Gi

    storage

    string

    disk space this peer requires

    10Gi

    initProfiles
    profiles
    id
    privateKeySecretName

    Deploy Private Ethash Network

    hashtag
    Deploy Private Network Node

    triangle-exclamation

    In this tutorial we will use the following private keys and their corresponding addresses.

    DON'T use these keys in production.

    Address
    Private Key

    Let's describe an Ethereum Node that uses a custom genesis block to join a private Proof of Work network using Ethash consensus configuration in the genesis block.

    In this node, we're using Hyperledger besu client client: besu, enabling JSON-RPC server rpc: true so we can query number of peers later in this tutorial, turning on Proof of Work mining miner: true, setting the address that will collect block reward using coinbase, and we're loading the node private key from Kubernetes secretd called besu-ethash-nodekey, this is the private from which the coinbase address is derived.

    We're defining a genesis block that uses the value 4444 as network and chain identifier, and used ethash proof of work consensus engine.

    circle-info

    ethash is required in proof of work networks, even if it's empty like in our example: ethash: {}.

    This node private key secret can be created by:

    circle-info

    Private key must not start with 0x, and must be stored in secret data field called key.

    Let's deploy the node:

    Kotal operator will notice your besu-ethash-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum Node using:

    It will return an output similar to the following:

    hashtag
    Fetch Node Logs

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Get the logs of the running node:

    hashtag
    Deploy a Second Node

    Let's deploy another go-ethereum node, and connect it to the previous node in our private proof of work network.

    circle-info

    Genesis block must be the same in both nodes, or they will fork at genesis block, and won't reach consensus.

    In this node, we're using go-ethereum client client: geth, turning on Proof of Work mining miner: true, setting the address that will collect block reward using coinbase, and loading the miner account private key and password from kubernetes secrets privateKeySecretName: ... and passwordSecretName: .... We're connecting to the first node using staticNodes option which accepts Node name or enode url.

    circle-info

    staticNodes accept Node name or enode URL. Node name has the format of name.namespace, namespace is optional if Node is in the same namespace. If the node doesn't exist, or is not up and running yet, Kotal will not raise an error.

    You can create the private key and password secrets using:

    Deploy the second node using:

    Kotal operator will notice your second geth-ethash-node and will create all the necessary pods, persistent volumes, services, configmaps, and secrets.

    You can fetch the deployed Ethereum Nodes using:

    It will return an output similar to the following:

    hashtag
    Call JSON-RPC Method net_peerCount

    Get the pods that has been created by Kotal for the node:

    It will return an output similar to the following:

    Forward localhost:8545 calls to the node pod:

    In another terminal window call net_peerCount JSON-RPC method

    You will get JSON result similar to the following:

    hashtag
    Homework

    Deploy a third node that uses Nethermind client, and use the third private key and address from the table above. Nethermind client is similar to geth, you will import signer account private key and password from kubernetes secrets, and use the same genesis as the other nodes.

    Finally you can delete all the nodes by:

    Kubernetes garbage collector will delete all the resources that has been created by Kotal Ethereum Node controller.

    0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa

    fb5411342ae51291447515c89bcf6a057e3dbd0b51e060c45cb73406c38f851d

    0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d

    153b174f5e9948ae4678baed54f88244cc9c39d56b9f17ecef93d7ede633f56b

    0x7DE985E2f878c83C4e91b6B1312c0f63A56C844a

    89b03c4de62d61be16d22e09c8a48929a9bccd11fa6b37809cfef290292bcba3

    besu-ethash-node.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: besu-ethash-node
    spec:
      client: besu
      nodePrivateKeySecretName: besu-ethash-nodekey
      rpc: true
      miner: true
      coinbase: "0xbAa5f05af4A67A467cEcA89085f162aFb4206Aaa"
      genesis:
        chainId: 4444
        networkId: 4444
        ethash: {}
    kubectl create secret generic besu-ethash-nodekey --from-literal=key=fb5411342ae51291447515c89bcf6a057e3dbd0b51e060c45cb73406c38f851d
    kubectl apply -f besu-ethash-node.yaml
    kubectl get nodes.ethereum
    NAME                 CLIENT   Consensus   Network
    besu-ethash-node     besu     pow         private
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    besu-ethash-node-0    1/1     Running   0          1m
    kubectl logs -f besu-ethash-node-0
    geth-ethash-node.yaml
    apiVersion: ethereum.kotal.io/v1alpha1
    kind: Node
    metadata:
      name: geth-ethash-node
    spec:
      client: geth
      rpc: true
      miner: true
      coinbase: "0xc1381ED43B327e3C7A1ADb21285f1e9cB82Bc00d"
      import:
        privateKeySecretName: geth-ethash-account-key
        passwordSecretName: geth-ethash-account-password
      staticNodes:
        - besu-ethash-node
      genesis:
        chainId: 4444
        networkId: 4444
        ethash: {}
    kubectl create secret generic geth-ethash-account-key --from-literal=key=153b174f5e9948ae4678baed54f88244cc9c39d56b9f17ecef93d7ede633f56b
    kubectl create secret generic geth-ethash-account-password --from-literal=password=s3cr3t
    kubectl apply -f geth-ethash-node.yaml
    kubectl get nodes.ethereum
    NAME                 CLIENT   Consensus   Network
    besu-ethash-node     besu     pow         private
    geth-ethash-node     geth     pow         private
    kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    besu-ethash-node-0    1/1     Running   0          1m
    geth-ethash-node-0    1/1     Running   0          1m
    kubectl port-forward besu-ethash-node-0 8545
    curl -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":32}' http://127.0.0.1:8545
    {
      "jsonrpc" : "2.0",
      "id" : 32,
      "result" : "0x1"
    }
    kubectl delete nodes.ethereum --all

    Ethereum 2.0

    hashtag
    BeaconNode

    Syntax
    Type
    Description
    Default

    hashtag
    network

    network is Ethereum 2.0 network to join and sync its beacon chain.

    hashtag
    client

    client is the Ethereum 2.0 client to use.

    client possible values are teku,prysm,lighthouse, and nimbus.

    hashtag
    eth1Endpoints

    eth1Endpoints is array of Ethereum 1 JSON RPC endpoints.

    circle-info

    prysm, teku, and lighthouse clients support multiple endpoints in eth1Endpoints.

    nimbus client supports only 1 endpoint in eth1Endpoints.

    hashtag
    hosts

    hosts is a list of host names to whitelist for RPC access (server enforced).

    hashtag
    corsDomains

    corsDomains is a list of domains from which to accept cross-origin requests (browser enforced).

    hashtag
    rest

    rest enables REST API server.

    circle-info

    REST API server is only supported by teku and lighthouse.

    hashtag
    restHost

    restHost is the REST API server host.

    hashtag
    restPort

    restPort is the REST API server port.

    hashtag
    rpc

    rpc enables JSON RPC server.

    circle-info

    JSON RPC server is only supported by nimbus and prysm.

    hashtag
    rpcHost

    rpcHost is the JSON RPC server host.

    hashtag
    rpcPort

    rpcPort is the JSON RPC server port.

    hashtag
    grpc

    grpc enables GRPC gateway server.

    circle-info

    GRPC gateway is only supported by prysm client.

    hashtag
    grpcHost

    grpcHost is the GRPC gateway server host.

    hashtag
    grpcPort

    grpcPort is the GRPC gateway server port.

    hashtag
    p2pPort

    p2pPort is the p2p and discovery port.

    hashtag
    certSecretName

    certSecretName is k8s secret name that holds TLS private key in data field called tls.key and TLS certificate in data field called tls.crt.

    certSecretName is supported only by prysm client.

    hashtag
    logging

    logging is logging verbosity level.

    Different levels are supported by different Ethereum 2.0 beacon node clients.

    Logging/Client
    Teku
    Lighthouse
    Prysm
    Nimbus

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    resources object has the following fields:

    Syntax
    Type
    Description
    Defalt

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1 core), 1500m which is 1.5 core, 2 cores, and 4 cores.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    hashtag
    Validator

    Syntax
    Type
    Description
    Default

    hashtag
    network

    network is the Network to validate blocks for.

    hashtag
    client

    client is the Ethereum 2.0 client to use.

    hashtag
    beaconEndpoints

    beaconEndpoints is a list of beacon node endpoints.

    circle-info

    lighthouse is the only client that supports multiple endpoints. All other clients supports only a single endpoint.

    hashtag
    certSecretName

    certSecretName is k8s secret name that holds TLS certificate in data field called tls.crt.

    certSecretName is supported only by prysm client.

    hashtag
    graffiti

    graffiti is the text to include in proposed blocks.

    hashtag
    walletPasswordSecretName

    walletPasswordSecretName is prysm wallet password kubernetes secret.

    circle-info

    walletPasswordSecretName is supported only by prysm client.

    circle-exclamation

    Wallet password secret must be deployed before deploying the validator.

    Wallet password secret must contain the password in key named password.

    hashtag
    keystores

    keystores is array of keystore objects.

    Syntax
    Type
    Description
    circle-info

    Validator keystore public key is required in case of client: lighthouse

    circle-exclamation

    Keystore secret must be deployed before deploying the validator.

    Keystore secret must contain the BLS12-381 keystore JSON file in data field key called keystore key, and password in password key.

    hashtag
    logging

    logging is logging verbosity level.

    Different levels are supported by different Ethereum 2.0 beacon node clients.

    circle-exclamation

    Teku validator client doesn't support logging. Verbosity level will be ignored 🙈

    Logging/Client
    Lighthouse
    Prysm
    Nimbus

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    resources object has the following fields:

    Syntax
    Type
    Description
    Defalt

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1 core), 1500m which is 1.5 core, 2 cores, and 4 cores.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    fatal

    ✔️

    ❌

    ✔️

    ✔️

    none

    ❌

    ❌

    ❌

    ✔️

    notice

    ❌

    ❌

    ❌

    ✔️

    error

    ✔️

    ✔️

    ✔️

    ✔️

    warn

    ✔️

    ✔️

    ✔️

    ✔️

    info

    ✔️

    ✔️

    ✔️

    ✔️

    debug

    ✔️

    ✔️

    ✔️

    ✔️

    trace

    ✔️

    ❌

    ✔️

    ✔️

    all

    ✔️

    ❌

    ❌

    ❌

    critical

    ❌

    ✔️

    ❌

    ❌

    panic

    ❌

    ❌

    ✔️

    ❌

    number of cpu cores this node is limited to

    8

    memory

    string

    memory this node requires

    8Gi

    memoryLimit

    string

    memory this node is limited to

    16Gi

    storage

    string

    disk space this node requires

    200Gi

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    Ethereum 2.0 client to use

    array

    List of beacon node endpoints

    string

    k8s secret name that holds tls.crt

    string

    Text to include in proposed blocks

    Powered by Kotal

    string

    Wallet password kubernetes secret

    array

    Validator keystores

    string

    logging verbosity level

    info

    object

    Validator compute and storage resources

    ✔️

    ✔️

    none

    ❌

    ❌

    ✔️

    notice

    ❌

    ❌

    ✔️

    error

    ✔️

    ✔️

    ✔️

    warn

    ✔️

    ✔️

    ✔️

    info

    ✔️

    ✔️

    ✔️

    debug

    ✔️

    ✔️

    ✔️

    trace

    ❌

    ✔️

    ✔️

    all

    ❌

    ❌

    ❌

    critical

    ✔️

    ❌

    ❌

    panic

    ❌

    ✔️

    ❌

    number of cpu cores this node is limited to

    8

    memory

    string

    memory this node requires

    8Gi

    memoryLimit

    string

    memory this node is limited to

    16Gi

    storage

    string

    disk space this node requires

    200Gi

    network

    string

    Network to join

    client

    string

    Ethereum 2.0 client to use

    eth1Endpoints

    array

    Ethereum 1 JSON RPC endpoints

    hosts

    array

    hostnames to whitelist for RPC access

    *

    corsDomains

    array

    domains from which to accept cross origin requests

    *

    rest

    bool

    Enable REST API server

    false

    restHost

    string

    REST API server host

    0.0.0.0

    restPort

    number

    REST API server port

    5051

    rpc

    bool

    Enables JSON RPC server

    false

    rpcHost

    string

    JSON RPC server host

    0.0.0.0

    rpcPort

    number

    JSON RPC server port

    4000

    grpc

    bool

    GRPC gateway server

    false

    grpcHost

    string

    GRPC gateway server host

    0.0.0.0

    grpcPort

    number

    GRPC gateway server port

    3500

    p2pPort

    number

    p2p and discovery port

    9000

    certSecretName

    string

    k8s secret name that holds tls.key and tls.crt

    logging

    string

    logging verbosity level

    info

    resources

    object

    Node compute and storage resources

    off

    ✔️

    ❌

    ❌

    ❌

    cpu

    string

    number of cpu cores this node requires

    4

    cpuLimit

    network

    string

    Network to validate blocks for

    client

    secretName

    string

    kubernetes secret name holding keystore and password

    publicKey

    string

    Validator public key in hexadecimal

    off

    ❌

    ❌

    ❌

    fatal

    cpu

    string

    number of cpu cores this node requires

    4

    cpuLimit

    string

    string

    ❌

    string

    # create k8s secret from password value
    kubectl create secret wallet-password --from-literal=password=<actual-password>
    # create k8s secret from password file
    kubectl create secret wallet-password --from-file=password=<password-file-path>
    # create k8s secret from keystore and password file
    kubectl create secret my-validator --from-file=keystore=/path/to/keystore.json --from-file=password=/path/to/password.txt
    beaconEndpoints
    certSecretName
    graffiti
    walletPasswordSecretName
    keystores
    logging
    resources

    Ethereum

    hashtag
    Node

    Syntax
    Type
    Description
    Default

    hashtag
    network

    network is the public network name to join, like rinkeby.

    network can't be provided in private networks, where .spec.genesis is not null.

    network can't be updated (immutable).

    hashtag
    highly available

    highlyAvailable controls if Ethereum nodes will be scheduled on different Kubernetes nodes.

    hashtag
    topology key

    topologyKey is Kubernetes node label key used to distribute ethereum nodes pods on different kubernetes nodes.

    hashtag
    bootnodes

    bootnodes is ethereum node URLs for p2p network discovery and bootstraping.

    bootnodes accepts ethereum node URL enodeURL or a reference to kotal Node in the form of name.namespace where namespace is optional if referenced node is in the same namespace.

    circle-exclamation

    Ethereum clients have hardcoded bootnodes for public main and test networks. bootnodes will override these bootnodes.

    hashtag
    client

    circle-exclamation

    Support for OpenEthereum (parity) client has been deprecated. OpenEthereum team is working with Erigon on a smooth transition path for users. More information can be found

    client is the Ethereum client name powering the node.

    client possible values are besu, geth, nethermind.

    Only besu client can be used if network consensus is ibft2.

    Only besu can be used in fixed difficulty proof of work networks, where spec.genesis.ethash.fixedDifficulty is not null.

    hashtag
    coinbase

    coinbase is ethereum account to which mining rewards are paid.

    coinbase is required if the node is mining miner: true.

    hashtag
    corsDomains

    corsDomains is a list of domains from which to accept cross-origin requests (browser enforced).

    Default value * will be used if HTTP RPC server is enabled rpc: true or web socket server is enabled ws: true or graphQL server is enabled graphql: true.

    hashtag
    graphql

    graphql enables the GraphQL server.

    circle-exclamation
    • Nethermind client doesn't support GraphQL.

    • Geth (Go-Ethereum) GraphQL server can be used only if RPC is enabled as of geth

    hashtag
    graphqlPort

    graphqlPort GraphQL server listening port.

    The default value 8547 will be used if the graphQL server is enabled graphql: true.

    hashtag
    hosts

    hosts is a list of host names to whitelist for RPC access (server enforced).

    hashtag
    import

    import is the ethereum account to import. Only for nodes running with geth or nethermind.

    During account creation, it will be encrypted with the password, and during import it will be unlocked using the same password.

    Nodes that import accounts can't enable HTTP RPC server, web socket server, or GraphQL server to prevent funds drainage if exposed to the internet.

    Account must be imported if the node is running with geth or nethermind clients wants to be a signer or miner.

    Syntax
    Type
    Description

    hashtag
    logging

    logging is Ethereum node logging verbosity level.

    logging possible values are off, fatal, error, warn, debug, info, trace and all.

    Different clients support different logging vrbosity levels as shown in the following table:

    Logging/Client
    Hyperledger Besu
    Go Ethereum
    Nethermind

    hashtag
    miner

    miner enables node mining or signing blocks.

    hashtag
    nodePrivateKeySecretName

    nodePrivateKeySecretName is the node private key.

    nodePrivateKeySecretName is required if the node is a boot node bootnode: true, or if besu node with client: besu is a signer in proof of authority clique network or validator in ibft2 network.

    hashtag
    p2pPort

    p2pPort is node p2p port for communication (TCP) and discovery (UDP).

    hashtag
    resources

    resources allocates compute and storage resources to the node.

    Syntax
    Type
    Description
    Default

    memory and storage requests and limits must use the pattern ^[1-9][0-9]*[KMGTPE]i$ for example 1500Mi, 30Gi, and 1Ti.

    cpu requests and limits must use the pattern ^[1-9][0-9]*m?$ for example 1000m (which is equal to 1), 1500m, 2, and 4.

    cpuLimit can't be less than cpu.

    memoryLimit can't be less than or equal to memory.

    storageClass field is immutable, it cannot be changed after creation.

    hashtag
    rpc

    rpc enables the HTTP RPC server.

    hashtag
    rpcPort

    rpcPort is the HTTP RPC server listening port.

    Default value 8545 will be used if the HTTP RPC server is enabled with rpc: true.

    hashtag
    rpcAPI

    rpcAPI is a list of RPC services to enable.

    Default value ["web3", "eth", "net] will be used if HTTP RPC server is enabeld with rpc: true.

    hashtag
    staticNodes

    staticNodes is a set of trusted ethereum nodes to maintain connection to.

    circle-info

    Static nodes are exempt from maximum peer and remote connection limits. Ethereum clients periodically initiating a connection to any unconnected static node.

    staticNodes accepts ethereum node URL enodeURL or a reference to kotal Node in the form of name.namespace where namespace is optional if referenced node is in the same namespace.

    hashtag
    syncMode

    circle-exclamation

    Nethermind client which was activated by syncMode: light.

    syncMode is Blockchain synchronization mode.

    syncMode possible values are light, full, snap or fast.

    light and snap sync modes are only supported by go-ethereum client.

    hashtag
    ws

    ws enables the web socket server.

    hashtag
    wsPort

    wsPort is the web socket server listening port.

    The default value 8546 is used if the web socket server is enabled with ws: true.

    hashtag
    wsAPI

    wsAPI is a list of rpc services to enable.

    the default value ["web3", "eth", "net] will be used if the web socket server is enabeld with ws: true.

    hashtag
    genesis

    genesis is the genesis block configuration.

    Genesis block configuration genesis is required in private networks.

    Syntax
    Type
    Description
    Default

    hashtag
    chainId

    chainId is the chain id value used in transaction signature to prevent transactions reply

    chainId is required.

    chainId can't reuse existing public network chain id to avoid transaction replay.

    Network
    Chain id

    hashtag
    networkId

    id is the network id used for p2p communications between network nodes in private networks.

    id is required in private networks.

    id can't be provided while joining a public network.

    id can't be updated (immutable).

    hashtag
    coinbase

    coinbase is the beneficiary (ethereum address) of mining reward.

    coinbase is optional.

    hashtag
    difficulty

    difficulty is the difficulty of the genesis block.

    difficulty is optional.

    hashtag
    mixHash

    mixHash is combined with the nonce to prove the effort spent to create a block.

    mixHash is optional.

    hashtag
    gasLimit

    gasLimit is the total gas limit for all transactions in a block.

    gasLimit is optional.

    hashtag
    nonce

    nonce is a random number used in block computation.

    nonce is optional.

    hashtag
    timestamp

    timestamp is block creation date.

    timestamp is optional.

    hashtag
    forks

    forks is an object, where the key is fork name and the value is the block number at which to activate this fork.

    forks is optional.

    if forks is missing, all forks will be activated at block 0 (genesis block) except DAO.

    Later forks like muirglacier can't be activated before earlier forks like homestead. They must be ordered as in the following table:

    Syntax
    Type
    Description

    hashtag
    accounts

    accounts is an array of accounts to fund or store code.

    accounts is optional.

    accounts is recommended for networks where signers or validators are not rewarded with eth.

    a single account has no defaults.

    Syntax
    Type
    Description

    hashtag
    ethash

    ethash is Proof of Work consensus engine configuration.

    ethash is optional.

    ethash can be set only in proof of work private networks.

    ethash.fixedDifficulty has no default value.

    circle-exclamation

    ethash.fixedDifficulty is only supported by Hyperledger Besu Client client: besu

    Syntax
    Type
    Description
    Default

    hashtag
    clique

    clique is Proof of Authority clique consensus engine configuration.

    clique is optional.

    clique can be set only in proof of authority clique private networks.

    At least one signer in clique.signers is required.

    Syntax
    Type
    Description
    Default

    hashtag
    ibft2

    ibft2 is IBFT2 engine configuration.

    ibft2 is optional.

    ibft2 can be set only in IBFT2 private networks.

    At least one validator in ibft2.validators is required.

    Syntax
    Type
    Description
    Default

    ❌

    ❌

    error

    ✔️

    ✔️

    ✔️

    warn

    ✔️

    ✔️

    ✔️

    debug

    ✔️

    ✔️

    ✔️

    info

    ✔️

    ✔️

    ✔️

    trace

    ✔️

    ❌

    ✔️

    all

    ✔️

    ✔️

    ❌

    number of cpu cores this node is limited to

    3 in private, 6 in public

    memory

    string

    memory this node requires

    4Gi in private, 8Gi in public

    memoryLimit

    string

    memory this node is limited to

    8Gi in private, 16Gi in public

    storage

    string

    disk space this node requires

    100Gi in private, 6Ti in mainnet with full sync, 750Gi in mainnet wit fast sync, 25Gi in public test networks

    storageClass

    string

    Node volume storage class

    Cluster's default storage class will be used as defined by cluster admin or cloud provider

    used in network p2p communications

    string

    benefeciary (ethereum address) of mining reward

    address(0)

    string

    difficulty (hexadecimal number) of the genesis block

    0x1

    string

    hash (hexadecimal) combined with nonce to prove effort spent to create block

    0x00..00

    string

    total gas limit (hexadecimal number) for all transactions in a block

    0x47b760

    string

    random hexadecimal number used in block computation

    0x0

    string

    genesis block creation date (hexadecimal)

    0x0

    Array

    array of accounts to prefund and store code

    object

    supported forks and corresponding block number

    object

    Proof of Work consensus configuration

    object

    Proof of Authority consensus configuration

    object

    IBFT2 consensus configuration

    5

    kotti

    6

    ethereum classic

    61

    Mordor

    63

    development

    2018

    eip150

    number

    fork activation block number

    eip155

    number

    fork activation block number

    eip158

    number

    fork activation block number

    byzantium

    number

    fork activation block number

    constantinople

    number

    fork activation block number

    petersburg

    number

    fork activation block number

    istanbul

    number

    fork activation block number

    muirglacier

    number

    fork activation block number

    berlin

    number

    fork activation block number

    london

    number

    fork activation block number

    arrowGlacier

    number

    fork activation block number

    code

    string

    bytecode in hexadecimal

    storage

    map

    key is the storage location in hexadecimal, and value in hexadecimal is the storage value

    number of blocks after which to reset all votes

    1000

    signers

    Array

    array of ethereum addresses

    number of blocks after which to reset all votes

    1000

    validators

    array

    array of ethereum addresses

    requestTimeout

    number

    timeout for each consensus round in seconds

    10

    messageQueueLimit

    number

    message queue limit

    1000

    duplicateMessageLimit

    number

    duplicate messages limit

    100

    futureMessagesLimit

    number

    future messages buffer limit

    1000

    futureMessagesMaxDistance

    number

    maximum height from current chain height for buffering future messages

    10

    network

    string

    Public network name to join, like mainnet, rinkeby, and goerli

    highlyAvailable

    boolean

    Ethereum nodes will be scheduled on different kubernetes nodes

    false

    topologyKey

    string

    kubernetes node label key used to distribute ethereum nodes

    topology.kubernetes.io/zone

    genesis

    object

    Genesis block configuration

    bootnodes

    array

    ethereum node URLs for p2p discovery bootstrap

    client

    string

    ethereum client powering the node

    coinbase

    string

    ethereum account to which mining rewards are paid

    corsDomains

    array

    domains from which to accept cross origin requests (browser enforced)

    *

    graphql

    boolean

    enable GraphQL server

    false

    graphqlPort

    number

    GraphQL server listening port

    8547

    hosts

    array

    hostnames to whitelist for RPC access (server enforced)

    *

    import

    object

    ethereum account to import for geth node

    logging

    string

    node logging verbosity level

    info

    miner

    boolean

    node is mining or signing blocks ?

    false

    nodePrivateKeySecretName

    string

    name of kubernetes secret holding node private key

    p2pPort

    string

    node p2p port

    30303

    resources

    object

    node compute and storage resources to alloacte

    rpc

    boolean

    enable HTTP RPC server

    false

    rpcPort

    number

    HTTP RPC server listening port

    8545

    rpcAPI

    array

    services to enable

    web3, eth, and net

    staticNodes

    array

    set of trusted ethereum nodes to maintain connection to

    syncMode

    string

    blockchain synchronization mode

    fast in public, full in private

    ws

    boolean

    enable web socket server

    false

    wsPort

    number

    web socket server listening port

    8546

    wsAPI

    array

    services to enable

    web3, eth, and net

    privateKeySecretName

    string

    name of the k8s secret holding account private key in hexadecimal (without 0x) in data field called key

    passwordSecretName

    string

    name of the k8s secret holding encryption secret in data field called password

    off

    ✔️

    ✔️

    ❌

    fatal

    cpu

    string

    number of cpu cores this node requires

    2 in private, 4 in public

    cpuLimit

    chainId

    number

    used in transaction signature to prevent transactions reply eip155arrow-up-right

    networkId

    mainnet

    1

    ropsten

    3

    rinkeby

    4

    homestead

    number

    Homesteadarrow-up-right fork activation block number

    dao

    number

    DAOarrow-up-right fork activation block number

    address

    string

    ethereum address

    balance

    string

    account balance in hexadecimal

    fixedDifficulty

    number

    fixed difficulty used in block computation

    blockPeriod

    number

    block time in seconds

    15

    epochLength

    blockPeriod

    number

    block time in seconds

    15

    epochLength

    herearrow-up-right
    v1.9.19 release notesarrow-up-right
    removed support for beam syncarrow-up-right
    eip155arrow-up-right

    ✔️

    string

    number

    goerli

    number

    number

    coinbase
    difficulty
    mixHash
    gasLimit
    nonce
    timestamp
    accounts
    forks
    ethash
    clique
    ibft2
    eip150arrow-up-right
    eip155arrow-up-right
    eip158arrow-up-right
    Byzantiumarrow-up-right
    Constantipolearrow-up-right
    Petersburgarrow-up-right
    Istanbularrow-up-right
    Muir Glacierarrow-up-right
    Berlinarrow-up-right
    Londonarrow-up-right
    Arrow Glacierarrow-up-right