readiness.sh
Overview
`readiness.sh` is a shell script designed to serve as a Kubernetes readiness probe for an Ethereum daemon node. Its primary purpose is to verify whether the Ethereum node running locally is fully synchronized with the Ethereum mainnet and ready to serve API requests.
The script performs a synchronization check by querying the local Ethereum node via JSON-RPC to determine if it is still syncing. If the node reports it is no longer syncing, the script fetches the current block height from the local node and cross-validates this against multiple external trusted Ethereum RPC endpoints ("reference nodes") to ensure the node's block height is within an acceptable tolerance of the network's latest block height. If all checks pass, the script exits with a success status (0), indicating readiness. Otherwise, it signals failure (exit 1).
This mechanism prevents Kubernetes from routing traffic to an out-of-sync node, thereby enhancing service reliability and data consistency.
Detailed Explanation
Script Workflow
Disable Readiness Check via File Sentinel
The script first checks for the existence of the file
/data/disable_readiness.If present, it immediately prints
"readiness probe disabled"and exits with status0(success), effectively bypassing readiness checks.This mechanism allows manual override during maintenance or debugging without disrupting the Kubernetes readiness lifecycle.
Source External Utility Script
It sources the script
/evm.sh, which provides utility functions includingget_best_reference_block_numberandreference_validation. These functions are responsible for querying external reference nodes and validating block height synchronization.Set Block Height Tolerance
Defines a tolerance threshold of
5blocks (BLOCK_HEIGHT_TOLERANCE=5) which represents the maximum allowable lag behind the network's best block height before considering the node out of sync.Query Local Node Syncing Status
Sends a JSON-RPC request to the local node's HTTP endpoint (
http://localhost:8545) with the methodeth_syncing.The
eth_syncingRPC method returns eitherfalse(not syncing) or an object describing syncing progress.
Evaluate Syncing Status
If the node reports
false(not syncing), the script proceeds to fetch the current block number from the local node by calling theeth_blockNumberRPC method.Converts the returned hex block number to an integer.
Fetch Best Reference Block Number
Calls
get_best_reference_block_numberwith three trusted Ethereum RPC endpoints:https://ethereum.publicnode.comhttps://eth-mainnet.g.alchemy.com/v2/demohttps://rpc.ankr.com/eth
This function queries the block number from each endpoint and returns the highest (best) block number among them.
Reference Validation
Invokes
reference_validationwith parameters:"daemon"to indicate the context.Local node's current block number.
Best reference block number.
Block height tolerance.
This function compares the local node's block number against the reference block height, considering the tolerance. If the local node falls outside the tolerance window, the validation fails.
Exit Codes and Output
If all validation steps pass, the script prints
"daemon is synced"and exits with0.If the node is still syncing or any command fails, it prints
"daemon is still syncing"and exits with1.
Functions and Methods
While the script itself does not declare explicit functions, it uses two key utility functions sourced from `/evm.sh`:
1. get_best_reference_block_number [URL1 URL2 URL3 ...]
Purpose: Queries multiple external Ethereum RPC nodes for their current block number and returns the highest block number found.
Parameters: List of RPC endpoint URLs.
Returns: Integer representing the best (highest) block number across all references.
Usage Example:
best_block=$(get_best_reference_block_number https://ethereum.publicnode.com https://eth-mainnet.g.alchemy.com/v2/demo https://rpc.ankr.com/eth)
2. reference_validation <context> <local_block_number> <reference_block_number> <tolerance>
Purpose: Validates that the local node's block height is within the allowed tolerance of the best reference block height.
Parameters:
context(string): identifies the caller type, e.g.,"daemon".local_block_number(int): current block number of the local node.reference_block_number(int): best block number from reference nodes.tolerance(int): maximum allowed block lag.
Returns: Exits with success if within tolerance; otherwise, exits with failure.
Usage Example:
reference_validation daemon $current_block_number $best_reference_block_number 5
Important Implementation Details
Use of Curl and jq:
The script usescurlto send JSON-RPC POST requests andjqto parse JSON responses, ensuring robust extraction of required fields.Hexadecimal Block Number Conversion:
Ethereum block numbers are returned in hexadecimal format (e.g.,"0x10d4f"). The script converts this hex string to decimal using bash arithmetic expansion:current_block_number=$(($current_block_number_hex))Fail Fast Behavior:
The script exits immediately with1for any failure incurlor parsing commands, ensuring Kubernetes detects node un-readiness promptly.Disable File Mechanism:
The sentinel file/data/disable_readinessprovides an operational override without requiring pod or container restarts.Tolerance Parameterization:
The block height tolerance is set to 5 blocks, balancing the need for freshness with network variability and propagation delays.
Interaction with Other System Components
Kubernetes Readiness Probe:
This script is configured as the readiness probe command in the Ethereum daemon pod's container spec. Kubernetes calls this script periodically to determine if the pod is ready to receive traffic.Ethereum Node (Local):
The script interacts directly with the local Ethereum node's JSON-RPC endpoint (http://localhost:8545), which must be accessible within the container.Reference RPC Nodes:
It queries external Ethereum RPC providers to obtain the latest block height as a source of truth for synchronization validation.Utility Script (
/evm.sh):
Sourced for shared functions that encapsulate querying reference nodes and validating block heights.
Usage Example
This script is not intended to be executed manually in typical operations but is invoked automatically by Kubernetes. However, for testing, an operator could run:
./readiness.sh
If the node is synced and within tolerance, output:
daemon is syncedand exit code
0.If the node is still syncing or out of sync, output:
daemon is still syncingand exit code
1.If
/data/disable_readinessfile exists, output:readiness probe disabledand exit code
0.
Mermaid Diagram - Workflow of readiness.sh
flowchart TD
Start[Start readiness.sh script] --> CheckDisable{Is /data/disable_readiness present?}
CheckDisable -- Yes --> Disabled[Print "readiness probe disabled" & exit 0]
CheckDisable -- No --> QuerySyncing[Send eth_syncing RPC to local node]
QuerySyncing --> ParseSync[Parse syncing status from response]
ParseSync -- "false" --> QueryBlockNum[Send eth_blockNumber RPC to local node]
ParseSync -- not "false" --> Syncing[Print "daemon is still syncing" & exit 1]
QueryBlockNum --> ParseBlockNum[Parse block number (hex to int)]
ParseBlockNum --> GetReferenceBlocks[Call get_best_reference_block_number with external RPCs]
GetReferenceBlocks --> ReferenceValidation[Call reference_validation]
ReferenceValidation --> Validated{Is local block within tolerance?}
Validated -- Yes --> Synced[Print "daemon is synced" & exit 0]
Validated -- No --> NotSynced[Print "daemon is still syncing" & exit 1]
Summary
Purpose: Checks if an Ethereum daemon node is ready by verifying it is fully synchronized and within an acceptable lag tolerance compared to the Ethereum mainnet.
Key Steps: Check for disable flag → Query local node syncing status → If synced, get current block → Compare with best reference block from external RPC endpoints → Validate block height tolerance → Exit with success or failure accordingly.
Integration: Used as Kubernetes readiness probe for Ethereum daemon containers, ensuring only fully synced nodes receive traffic.
Dependencies: Requires
curl,jq, and sourced/evm.shutility script.Benefits: Prevents routing traffic to lagging or syncing nodes, improving system reliability and data consistency.
This script is a critical component in maintaining the health and availability of Ethereum daemon services within a containerized or orchestrated environment.