LogoLogo
SDKAPI
Next
Next
  • Learn
    • Introduction
      • Obol Collective
      • OBOL Incentives
      • Key Staking Concepts
      • Obol vs Other DV Implementations
      • Obol Splits
      • DV Launchpad
      • Frequently Asked Questions
    • Charon
      • Introduction to Charon
      • Distributed Key Generation
      • Cluster Configuration
      • Charon Networking
      • CLI Reference
    • Futher Reading
      • Ethereum and Its Relationship With DVT
      • Community Testing
      • Peer Score
      • Useful Links
  • Run a DV
    • Quickstart
      • Quickstart Overview
      • Create a DV Alone
      • Create a DV With a Group
      • Push Metrics to Obol Monitoring
    • Prepare to Run a DV
      • How and Where To Run DVs
      • Deployment Best Practices
      • Test a Cluster
    • Running a DV
      • Activate a DV
      • Update a DV
      • Monitoring Your Node
      • Claim Rewards
      • Exit a DV
    • Partner Integrations
      • Create an EigenLayer DV
      • Create a Lido CSM DV
      • DappNode
  • Advanced & Troubleshooting
    • Advanced Guides
      • Create a DV Using the SDK
      • Migrate an Existing Validator
      • Enable MEV
      • Combine DV Private Key Shares
      • Self-Host a Relay
      • Advanced Docker Configs
      • Beacon node authentication
    • Troubleshooting
      • Errors & Resolutions
      • Handling DKG Failure
      • Client Configuration
      • Test Commands
    • Security
      • Overview
      • Centralization Risks and Mitigation
      • Obol Bug Bounty Program
      • Smart Contract Audit
      • Software Development at Obol
      • Charon Threat Model
      • Contacts
  • Community & Governance
    • Governance
      • Collective Overview
      • The Token House
      • The RAF
      • The OBOL Token
      • Delegate Guide
      • RAF1 Guide
    • Community
      • Staking Mastery Program
      • Techne
    • Contribution & Feedback
      • Filing a Bug Report
      • Documentation Standards
      • Feedback
  • Walkthrough Guides
    • Walkthroughs
      • Walkthrough Guides
  • SDK
    • Intro
    • Enumerations
      • FORK_MAPPING
    • Classes
      • Client
    • Interfaces
      • ClusterDefinition
      • RewardsSplitPayload
    • Type-Aliases
      • BuilderRegistration
      • BuilderRegistrationMessage
      • ClusterCreator
      • ClusterLock
      • ClusterOperator
      • ClusterPayload
      • ClusterValidator
      • DepositData
      • DistributedValidator
      • ETH_ADDRESS
      • OperatorPayload
      • SplitRecipient
      • TotalSplitPayload
    • Functions
      • validateClusterLock
  • API
    • What is this API?
    • System
    • Metrics
    • Cluster Definition
    • Cluster Lock
    • State
    • DV Exit
    • Cluster Effectiveness
    • Terms And Conditions
    • Techne Credentials
    • Address
    • OWR Information
  • Specification
Powered by GitBook
On this page
  • What is Charon?
  • Charon Architecture
  • Determine when duties need to be performed
  • Fetch and come to consensus on what data to sign
  • Wait for the VC to sign
  • Share partial signatures
  • Threshold Aggregate partial signatures
  • Broadcast final signature
  • Ports
  • Getting started
Edit on GitHub
  1. Learn
  2. Charon

Introduction to Charon

Charon - The Distributed Validator Client

PreviousCharonNextDistributed Key Generation

Last updated 2 months ago

This section introduces and outlines the Charon [kharon] middleware, Obol's implementation of DVT. Please see the section as background and context.

What is Charon?

Charon is a GoLang-based, HTTP middleware built by Obol to enable any existing Ethereum validator clients to operate together as part of a distributed validator.

Charon sits as a middleware between a normal validating client and its connected beacon node, intercepting and proxying API traffic. Multiple Charon clients are configured to communicate together to come to consensus on validator duties and behave as a single unified proof-of-stake validator together. The nodes form a cluster that is byzantine-fault tolerant and continues to progress assuming a supermajority of working/honest nodes is met.

Charon Architecture

Charon is an Ethereum proof of stake distributed validator (DV) client. Like any validator client, its main purpose is to perform validation duties for the Beacon Chain, primarily attestations and block proposals. The beacon client handles a lot of the heavy lifting, leaving the validator client to focus on fetching duty data, signing that data, and submitting it back to the beacon client.

Charon is designed as a generic event-driven workflow with different components coordinating to perform validation duties. All duties follow the same flow, the only difference being the signed data. The workflow can be divided into phases consisting of one or more components:

Determine when duties need to be performed

Fetch and come to consensus on what data to sign

A DV cluster consists of multiple operators each provided with one of the M-of-N threshold BLS private key shares per validator. The key shares are imported into the validator clients which produce partial signatures. Charon threshold aggregates these partial signatures before broadcasting them to the Beacon Chain. But to threshold aggregate partial signatures, each validator must sign the same data. The cluster must therefore coordinate and come to a consensus on what data to sign.

Fetcher fetches the unsigned duty data from the beacon node upon receiving an event from Scheduler. For attestations, this is the unsigned attestation, for block proposals, this is the unsigned block.

Wait for the VC to sign

Charon is a middleware distributed validator client. That means Charon doesn’t have access to the validator private key shares and cannot sign anything on demand. Instead, operators import the key shares into industry-standard validator clients (VC) that are configured to connect to their local Charon client instead of their local Beacon node directly.

The VC queries the ValidatorAPI for unsigned data which is retrieved from the DutyDB. It then signs it and submits it back to the ValidatorAPI which stores it in the PartialSignatureDB.

Share partial signatures

The PartialSignatureDB stores the partially signed data submitted by the local Charon client’s VC. But it also stores all the partial signatures submitted by the VCs of other peers in the cluster. This is achieved by the PartialSignatureExchange component that exchanges partial signatures between all peers in the cluster. All Charon clients, therefore, store all partial signatures the cluster generates.

Threshold Aggregate partial signatures

The SignatureAggregator is invoked as soon as sufficient (any M of N) partial signatures are stored in the PartialSignatureDB. It performs BLS threshold aggregation of the partial signatures resulting in a final signature that is valid for the beacon chain.

Broadcast final signature

Finally, the Broadcaster component broadcasts the final threshold aggregated signature to the Beacon client, thereby completing the duty.

Ports

The following is an outline of the services that can be exposed by Charon.

  • :3610 - Charon P2P port. This is the port that Charon clients use to communicate with one another via TCP. This endpoint should be port-forwarded on your router and exposed publicly, preferably on a static IP address. This IP address should then be set on the charon run command with --p2p-external-ip or CHARON_P2P_EXTERNAL_IP.

  • :3620 - Monitoring port. This port hosts a webserver that serves Prometheus metrics on /metrics, a readiness endpoint on /readyz and a liveness endpoint on /livez, and a pprof server on /debug/pprof. This port should not be exposed publicly.

Getting started

The beacon chain is divided into and , which divides it into deterministically fixed-size time chunks. The first step is to determine when (which slot/epoch) duties need to be performed. This is done by the scheduler component. It queries the beacon node to detect which validators defined in the cluster lock are active, and what duties they need to perform for the upcoming epoch and slots. When such a slot starts, the scheduler emits an event indicating which validator needs to perform what duty.

The Consensus component listens to events from Fetcher and starts a consensus game with the other Charon nodes in the cluster for that specific duty and slot. When consensus is reached, the resulting unsigned duty data is stored in the DutyDB.

Charon, therefore, serves the from the ValidatorAPI component and intercepts some endpoints while proxying other endpoints directly to the upstream Beacon node.

:3600 - The validator REST API. This is the port that serves the consensus layer's . This is the port validator clients should talk to instead of their standard consensus client REST API port. Charon subsequently proxies these requests to the upstream consensus client specified by --beacon-node-endpoints.

For more information on running Charon, take a look at our .

slots
epochs
QBFT
Ethereum Beacon Node API
beacon node API
Quickstart Guides
key concepts