readiness.sh
Overview
`readiness.sh` is a shell script designed as a **readiness probe** for a Bitcoin (or Bitcoin-like) blockchain node daemon running inside a containerized environment, typically Kubernetes. Its primary purpose is to verify if the node is **fully synchronized** with the blockchain network and has **active peer connections** before signaling that the node is ready to serve traffic. This check is crucial to prevent routing client requests to a node that is still syncing or disconnected from the network.
The script performs the following key functions:
Checks if readiness probing is temporarily disabled via a sentinel file.
Queries the node's JSON-RPC API to retrieve:
Current number of connected peers.
Blockchain synchronization info (node's block height and network's latest block header).
Compares the node's block height against the network's latest block height with an allowable tolerance of 1 block.
Validates that the node has at least one connected peer.
Exits with status code
0if the node is ready, or1if not.
This script is optimized for minimal dependencies, using standard tools (`curl`, `jq`) and simple logic to integrate seamlessly as a Kubernetes readiness probe.
Detailed Explanation
Variables and Constants
Variable | Description |
|---|---|
Path to the sentinel file (`/data/disable_readiness`) that disables readiness checks if present. | |
`TOLERANCE` | Numeric tolerance for block height difference allowed between the node and network (set to 1). |
`CONNECTION_COUNT` | JSON-RPC response for the number of connected peers. |
JSON-RPC response containing blockchain sync info (node block height, headers, etc.). | |
`PEERS` | Extracted number of peers from `CONNECTION_COUNT`. |
`NODE_LATEST_BLOCK_HEIGHT` | Node's current blockchain height from [BLOCKCHAIN_INFO](/projects/291/69210). |
`NETWORK_LATEST_BLOCK_HEIGHT` | Network's latest block height (header count) from [BLOCKCHAIN_INFO](/projects/291/69210). |
`NOMINAL_BLOCKS` | Calculated minimum block height threshold for readiness (`NETWORK_LATEST_BLOCK_HEIGHT - TOLERANCE`). |
Script Workflow and Logic
Disable Readiness Check:
The script first checks for the existence of the file
/data/disable_readiness.If the file exists, the readiness probe is disabled, and the script prints
"readiness probe disabled"and exits with0(success).
Query Node for Connection Count:
The script sends a JSON-RPC request to the local node on port
8332to invoke the methodgetconnectioncount.If the request fails, the script immediately exits with
1(failure).
Query Node for Blockchain Info:
The script sends another JSON-RPC request to invoke the method
getblockchaininfo.If this request fails, the script exits with
1(failure).
Parse Responses:
Extracts the number of peers from
CONNECTION_COUNT.Extracts the node's latest block height and the network's latest block header count from BLOCKCHAIN_INFO.
Calculate Nominal Block Height:
The script subtracts the tolerance (
TOLERANCE=1) from the network's latest block height to allow a small lag.
Readiness Decision:
If the node's block height is greater than or equal to the nominal block height:
If the peer count is greater than 0, it prints
"node is synced with $PEERS peers"and exits with0(ready).Else, it prints
"node is synced, but has no peers"and exits with1(not ready).
If the node's block height is less than the nominal block height, it prints
"node is still syncing"and exits with1(not ready).
Usage Example
This script is typically invoked by Kubernetes as a readiness probe configured in the container spec:
readinessProbe:
exec:
command:
- /path/to/readiness.sh
initialDelaySeconds: 15
periodSeconds: 10
**Manual execution** for debugging:
chmod +x readiness.sh
./readiness.sh
Possible outputs:
readiness probe disabled
node is synced with 8 peers
node is synced, but has no peers
node is still syncing
Exit code `0` indicates readiness; exit code `1` indicates not ready.
Important Implementation Details
RPC Authentication:
The script uses hardcoded credentials (user:password) in thecurlrequests. In production, these should be securely provided via environment variables or Kubernetes secrets.Tolerance Level:
TheTOLERANCEis set to 1 block, reflecting that the node can be slightly behind the network header height and still be considered ready. This helps avoid flapping readiness status due to transient minor lags.Fail-Fast Behavior:
If any RPC call fails or returns invalid data, the script exits immediately with status1, signaling that the node is not ready.Use of
jq:
JSON parsing relies onjqto extract relevant fields from the RPC responses. This dependency is minimal but must be present in the container image.Peer Connectivity Check:
The node must have at least one peer connection to be considered fully ready. If no peers are connected, the node is considered not ready, even if block height is sufficient.Disable File Mechanism:
The presence of/data/disable_readinessdisables readiness checks, allowing manual override for maintenance or debugging without altering deployment manifests.
Interaction with Other System Components
Kubernetes:
The script is configured as a readiness probe in the Kubernetes pod spec for the blockchain daemon container. Kubernetes periodically runs this script to decide if the container is ready to accept requests.Blockchain Daemon:
This script runs inside the daemon's container and communicates directly with the node's JSON-RPC API endpoint (http://localhost:8332) to fetch status information.Health and Readiness Probes Framework:
Part of a broader set of scripts and tools that ensure blockchain nodes and related services are healthy and synchronized before serving traffic.Monitoring and Deployment Automation:
Probe failures cause Kubernetes to mark pods as not ready, which can trigger alerts or restarts. The script's exit status informs deployment automation tools about the node's health.
Mermaid Diagram — Script Workflow
flowchart TD
Start[Start readiness.sh] --> CheckDisable{Is /data/disable_readiness \nfile present?}
CheckDisable -- Yes --> Disabled[Print "readiness probe disabled"\nExit 0]
CheckDisable -- No --> GetConnections[Query RPC: getconnectioncount]
GetConnections -->|Success| GetBlockchainInfo[Query RPC: getblockchaininfo]
GetConnections -->|Fail| ExitFail1[Exit 1]
GetBlockchainInfo -->|Success| ParseData[Parse peers, blocks, headers]
GetBlockchainInfo -->|Fail| ExitFail2[Exit 1]
ParseData --> CalcNominal[Calculate nominal block height\nNETWORK_LATEST_BLOCK_HEIGHT - TOLERANCE]
CalcNominal --> CheckSync{NODE_LATEST_BLOCK_HEIGHT >= NOMINAL_BLOCKS?}
CheckSync -- No --> Syncing[Print "node is still syncing"\nExit 1]
CheckSync -- Yes --> CheckPeers{PEERS > 0?}
CheckPeers -- Yes --> Ready[Print "node is synced with $PEERS peers"\nExit 0]
CheckPeers -- No --> NoPeers[Print "node is synced, but has no peers"\nExit 1]
Summary
The `readiness.sh` script is a critical component ensuring that a Bitcoin-like blockchain node signals readiness only when it is fully synchronized and connected to peers. By implementing a simple yet robust check using node RPC endpoints, it integrates tightly with Kubernetes health checking mechanisms to maintain system stability and prevent premature traffic routing to unsynced or isolated nodes.