hedera-node-manager
v1.0.2
Published
A TypeScript library for managing Hedera network nodes with automatic health monitoring, failure detection, and load balancing.
Readme
Hedera Node Manager
A TypeScript library for managing Hedera network nodes with automatic health monitoring, failure detection, and load balancing.
Features
- Automatic Node Discovery: Fetches node information from Hedera mirror nodes
- Health Monitoring: Tracks node health status and failure counts
- Load Balancing: Randomly selects healthy nodes for transactions
- Failure Recovery: Implements cooldown periods and automatic status recovery
- Network Support: Works with both mainnet and testnet
Installation
npm install hedera-node-managerUsage
Basic Example
const { NodeManager } = require('hedera-node-manager');
const manager = new NodeManager({ network: 'mainnet' });
await manager.init();
const node = await manager.getHealthyNode();
console.log('Using node:', node.accountId);
// Simulate a transaction...
const success = Math.random() > 0.3;
if (success) {
manager.reportSuccess(node.accountId);
} else {
const error = new Error('INVALID_NODE_ACCOUNT');
manager.reportFailure(node.accountId, error);
}Testing the Example
There are several ways to test the example.ts functionality:
1. Basic Example
Run the basic example:
npm run example
# or
npm run example:basic2. Enhanced Example (Recommended)
Run the enhanced example with detailed output:
npm run example enhancedThis provides:
- Detailed initialization status
- Node information with addresses
- Transaction simulation results
- Final node status report
Options:
npm run example enhanced testnet- Run on testnetnpm run example enhanced mainnet 5- Run 5 iterations on mainnetnpm run example enhanced testnet 3- Run 3 iterations on testnet
3. Test Suite
Run comprehensive integration tests:
npm test
# or
npm run example testThis runs:
- Node initialization tests
- Health node selection tests
- Failure reporting tests
- Testnet functionality tests
- Transaction simulation tests
- Configuration validation tests
4. Direct Execution
Run directly with tsx:
npx tsx src/example.ts
npx tsx src/example.ts enhanced testnet 3Example Output
🚀 Enhanced Example for mainnet network
📊 Running 1 iteration(s)
✅ NodeManager initialized successfully
📋 Found 10 nodes in the network
🔄 Iteration 1/1:
Using node: 0.0.10 (healthy)
Address: 3.248.27.48
Stake: 181942312100000000 (1819423121.00 HBAR)
✅ Transaction succeeded
📈 Final Node Status Report:
🟢 0.0.3: healthy (1806803055.00 HBAR)
🟢 0.0.4: healthy (1805843070.00 HBAR)
🟢 0.0.6: healthy (1819423121.00 HBAR)
🟢 0.0.7: healthy (1819355508.00 HBAR)
🟢 0.0.8: healthy (1819239113.00 HBAR)
🟢 0.0.9: healthy (1819316884.00 HBAR)
🟢 0.0.10: healthy (1819423121.00 HBAR)
🟢 0.0.12: healthy (1819355508.00 HBAR)
🟢 0.0.13: healthy (1819239113.00 HBAR)
🟢 0.0.14: healthy (1819316884.00 HBAR)
📊 Health Metrics:
🟢 Healthy: 10
🟡 Degraded: 0
🔴 Excluded: 0
📊 Total: 10NodeManager Configuration
interface NodeManagerOptions {
network: 'mainnet' | 'testnet'; // Required
failureThreshold?: number; // Default: 3, Min: 1
cooldownPeriodMs?: number; // Default: 5 minutes, Min: 0
refreshIntervalMs?: number; // Default: 1 hour, Min: 1000ms
fallbackAccountId?: string; // Default: '0.0.3', Format: 0.0.xxx
}Configuration Validation
The NodeManager validates all configuration options and throws descriptive errors for invalid values:
- Network: Must be 'mainnet' or 'testnet'
- Failure Threshold: Must be >= 1
- Cooldown Period: Must be >= 0
- Refresh Interval: Must be >= 1000ms
- Fallback Account ID: Must match format 0.0.xxx
Node Status
- healthy: Node is available and working
- degraded: Node has exceeded failure threshold
- excluded: Node is no longer in the network
- fallback: Using fallback node when no healthy nodes available
Node Selection Strategy
The NodeManager prioritizes nodes by stake weight to align with network consensus:
- Stake-based Selection: Nodes with higher
stake_rewardedvalues are selected first - Consensus Alignment: Higher stake nodes have more voting power in the network
- Automatic Fallback: If high-stake nodes fail, lower-stake nodes are used
- Health Override: Degraded nodes are avoided unless no healthy nodes are available
API Methods
init(): Initialize and fetch node listgetHealthyNode(): Get a healthy node prioritized by stake weightreportSuccess(accountId): Report successful transactionreportFailure(accountId, error): Report failed transaction with error analysisgetAllNodes(): Get all known nodes with their statusgetNodeHealthStats(): Get health metrics (healthy, degraded, excluded, total counts)cleanup(): Clean up stale node data to prevent memory leaks
Testing Approaches
Integration Testing
- Use
npm testfor comprehensive integration tests with real API calls - Tests cover initialization, node selection, failure reporting, and transaction simulation
- Tests both mainnet and testnet networks
- Includes configuration validation testing
End-to-End Testing
- Use
npm run example enhancedfor realistic transaction simulation - Demonstrates real API integration with stake-based selection
- Simulates realistic transaction patterns and failure scenarios
Test Coverage
- Integration Tests: Real API integration and error handling
- Configuration Tests: Validation of all configuration options
- Error Tests: Network failures, invalid responses, and edge cases
- Stake-based Selection: Tests prioritize nodes by stake weight
Error Handling & Resilience
Custom Error Types
The NodeManager uses custom error types for better error handling:
export class NodeManagerError extends Error {
constructor(message: string, public readonly code: string) {
super(message);
this.name = 'NodeManagerError';
}
}Error Codes
MISSING_NETWORK: Network parameter is requiredINVALID_NETWORK: Network must be 'mainnet' or 'testnet'INVALID_THRESHOLD: Failure threshold must be >= 1INVALID_COOLDOWN: Cooldown period must be >= 0INVALID_REFRESH_INTERVAL: Refresh interval must be >= 1000msINVALID_FALLBACK_ACCOUNT: Invalid fallback account ID formatAPI_ERROR: HTTP error from mirror node APIINVALID_RESPONSE: Invalid API response formatNO_NODES_AVAILABLE: No nodes available in networkFALLBACK_NODE_MISSING: Fallback node not found
Node Error Detection
The NodeManager intelligently detects node-related errors and only reports failures for relevant errors:
Node-Related Errors (Trigger Failure Reporting):
INVALID_NODE_ACCOUNT: Invalid node accountTRANSACTION_OVERSIZE: Transaction too largePLATFORM_NOT_ACTIVE: Platform not activePLATFORM_TRANSACTION_NOT_CREATED: Transaction creation failedINVALID_TRANSACTION_START: Invalid transaction startBUSY: Node is busyUNKNOWN: Unknown node errorUNAVAILABLE: Node unavailable
Non-Node Errors (Ignored):
INSUFFICIENT_FUNDS: Account balance issuesINVALID_SIGNATURE: Signature validation errorsACCOUNT_NOT_FOUND: Account doesn't exist- Other application-level errors
Retry Logic
The NodeManager implements exponential backoff retry logic:
- Max Retry Attempts: 3
- Base Delay: 1 second
- Exponential Backoff: 1s, 2s, 4s delays
- Automatic Recovery: Resets retry attempts on success
Resource Management
- Automatic Cleanup: Removes stale excluded nodes after 24 hours
- Memory Leak Prevention: Prevents unbounded growth of node data
- Connection Resilience: Graceful handling of network failures
Troubleshooting
Common Issues
- "undefined" node accountId: Fixed by updating the API field mapping
- Network errors: The system falls back to existing nodes
- No healthy nodes: Uses fallback node (0.0.3)
Debug Mode
Add console logging to see detailed API responses:
const manager = new NodeManager({ network: 'mainnet' });
await manager.init();
console.log('All nodes:', manager.getAllNodes());Development
Building
npm run buildRunning Tests
# Run comprehensive tests
npm testProject Structure
src/
├── NodeManager.ts # Main NodeManager class
└── example.ts # Comprehensive example with multiple modesLicense
ISC
