Skip to main content

Light Node Limitations

Overview

Savitri Network light nodes are designed for resource-constrained environments but have inherent limitations compared to full nodes. Understanding these limitations is crucial for developers and users to make informed decisions about when to use light nodes versus full nodes.

Technology Choice Rationale

Why Light Node Limitations Documentation

Problem Statement: Users and developers need clear understanding of what light nodes cannot do to avoid incorrect assumptions and failed implementations.

Chosen Solution: Comprehensive documentation of limitations with technical explanations, workarounds, and alternative approaches.

Rationale:

  • Transparency: Clear documentation of capabilities and limitations
  • Prevention: Avoid user frustration from unsupported features
  • Guidance: Provide alternative solutions for unsupported use cases
  • Education: Help users understand architectural trade-offs

Expected Results:

  • Clear understanding of light node capabilities
  • Informed decisions about node type selection
  • Proper expectations for performance and functionality
  • Knowledge of available workarounds and alternatives

Consensus Participation Limitations

No Direct Consensus Participation

Technical Limitation:

// Light nodes are always observers in consensus
pub enum SlotRole {
Leader, // Can propose blocks (bonded validators only)
Follower, // Can vote on blocks (bonded validators only)
Observer, // Can only observe (light nodes)
}

impl SlotScheduler {
pub fn get_validator_role(&self, validator: &ValidatorAddress, slot: u64) -> SlotRole {
let leader = match self.get_slot_leader(slot) {
Ok(leader) => leader,
Err(_) => return SlotRole::Observer,
};

if leader == *validator {
SlotRole::Leader
} else if self.validator_set.contains(validator) {
SlotRole::Follower
} else {
SlotRole::Observer // Light nodes always observers
}
}
}

Why Light Nodes Cannot Participate:

  1. Bond Requirements: Minimum 1M tokens (~$1M+ USD) for validator bonds
  2. Storage Requirements: Full blockchain state storage needed
  3. Network Requirements: Persistent high-speed connections
  4. Security Requirements: 99.9% uptime for slashing protection
  5. Economic Barriers: Mobile devices cannot meet validator economics

Impact:

  • Cannot propose blocks
  • Cannot vote on consensus
  • Cannot earn validator rewards
  • Cannot participate in BFT consensus

Alternative Approaches

Consensus Observation:

impl LightNode {
pub async fn observe_consensus(&self) -> Result<ConsensusObservation, ConsensusError> {
// 1. Monitor consensus finality
let finality_status = self.monitor_finality().await?;

// 2. Track validator set changes
let validator_changes = self.track_validator_changes().await?;

// 3. Verify consensus certificates
let certificate_verification = self.verify_consensus_certificates().await?;

Ok(ConsensusObservation {
finality_status,
validator_changes,
certificate_verification,
observation_time: Instant::now(),
})
}
}

Delegated Staking:

impl LightNode {
pub async fn delegate_stake(&self, validator: &ValidatorAddress, amount: u128) -> Result<StakeDelegation, StakeError> {
// 1. Create delegation transaction
let delegation_tx = self.create_delegation_transaction(validator, amount)?;

// 2. Sign transaction
let signed_tx = self.sign_transaction(&delegation_tx)?;

// 3. Submit to network
let tx_hash = self.submit_transaction(&signed_tx).await?;

// 4. Monitor delegation status
let delegation_status = self.monitor_delegation_status(&tx_hash).await?;

Ok(StakeDelegation {
validator: *validator,
amount,
tx_hash,
status: delegation_status,
})
}
}

Data Storage Limitations

No Full Blockchain State

Storage Limitations:

pub struct LightNodeStorage {
// Stored data
pub headers: Vec<BlockHeader>, // Only headers (last 1000)
pub monolith_headers: Vec<MonolithHeader>, // Only Monolith headers
pub proofs: Vec<StateProof>, // Only requested proofs
pub wallet_data: WalletData, // User wallet data

// Not stored
// pub full_blocks: Vec<Block>, // Full blocks not stored
// pub full_state: HashMap<Address, Account>, // Full state not stored
// pub all_transactions: Vec<Transaction>, // All transactions not stored
}

Storage Requirements:

  • Headers: Only recent headers (configurable, default 1000)
  • Monolith Headers: Only Monolith headers for verification
  • State Proofs: Only proofs for requested state
  • Wallet Data: User's own wallet data

Impact:

  • Cannot query arbitrary historical state
  • Cannot access full transaction history
  • Cannot provide full node services to others
  • Limited blockchain data access

Workarounds

State Proof Queries:

impl LightNode {
pub async fn get_account_state(&self, address: &Address, block_height: u64) -> Result<AccountState, StateError> {
// 1. Get block header for target height
let block_header = self.get_block_header(block_height).await?;

// 2. Request state proof from full node
let state_proof = self.request_state_proof(address, &block_header).await?;

// 3. Verify state proof
let verified_state = self.verify_state_proof(&state_proof, &block_header.state_root)?;

Ok(verified_state)
}
}

Archive Node Services:

impl LightNode {
pub async fn query_archive_node(&self, query: &ArchiveQuery) -> Result<ArchiveResponse, ArchiveError> {
// 1. Connect to archive node
let archive_connection = self.connect_to_archive_node().await?;

// 2. Submit query
let query_result = archive_connection.submit_query(query).await?;

// 3. Verify result
let verified_result = self.verify_archive_result(&query_result)?;

Ok(verified_result)
}
}

Performance Limitations

Synchronization Latency

Sync Performance Characteristics:

pub struct SyncPerformance {
pub initial_sync_time: Duration, // Initial sync time
pub incremental_sync_time: Duration, // Incremental sync time
pub header_download_rate: f64, // Headers per second
pub proof_verification_rate: f64, // Proofs per second
pub battery_impact: f64, // Battery impact percentage
}

impl SyncPerformance {
pub fn get_typical_performance() -> SyncPerformance {
SyncPerformance {
initial_sync_time: Duration::from_secs(180), // 3 minutes
incremental_sync_time: Duration::from_secs(30), // 30 seconds
header_download_rate: 50.0, // 50 headers/sec
proof_verification_rate: 100.0, // 100 proofs/sec
battery_impact: 0.02, // 2% per hour
}
}
}

Performance Factors:

  • Network Speed: Mobile network variability
  • CPU Performance: Mobile processor limitations
  • Memory Constraints: Limited RAM for processing
  • Battery Life: Background processing impact

Optimization Strategies

Adaptive Sync:

impl LightNode {
pub async fn adaptive_sync(&mut self) -> Result<SyncResult, SyncError> {
// 1. Check network conditions
let network_quality = self.assess_network_quality().await?;

// 2. Check battery level
let battery_level = self.get_battery_level().await?;

// 3. Adjust sync strategy
let sync_strategy = self.determine_sync_strategy(network_quality, battery_level);

// 4. Execute optimized sync
match sync_strategy {
SyncStrategy::Aggressive => self.aggressive_sync().await?,
SyncStrategy::Normal => self.normal_sync().await?,
SyncStrategy::Conservative => self.conservative_sync().await?,
SyncStrategy::Minimal => self.minimal_sync().await?,
}
}

fn determine_sync_strategy(&self, network_quality: NetworkQuality, battery_level: f64) -> SyncStrategy {
match (network_quality, battery_level) {
(NetworkQuality::Excellent, battery) if battery > 0.8 => SyncStrategy::Aggressive,
(NetworkQuality::Good, battery) if battery > 0.5 => SyncStrategy::Normal,
(NetworkQuality::Fair, battery) if battery > 0.2 => SyncStrategy::Conservative,
_ => SyncStrategy::Minimal,
}
}
}

Functional Limitations

Limited Transaction History

Transaction History Limitations:

pub struct TransactionHistory {
pub max_history_depth: u64, // Maximum history depth
pub stored_transactions: Vec<Transaction>, // Stored transactions
pub pruning_policy: PruningPolicy, // Pruning policy
}

impl TransactionHistory {
pub fn get_transaction_history(&self, address: &Address, limit: u64) -> Result<Vec<Transaction>, HistoryError> {
// 1. Check if address is user's own
if !self.is_user_address(address) {
return Err(HistoryError::NotUserAddress);
}

// 2. Get stored transactions for address
let user_transactions = self.stored_transactions
.iter()
.filter(|tx| tx.sender == *address || tx.recipient == *address)
.take(limit as usize)
.cloned()
.collect();

Ok(user_transactions)
}

pub fn get_foreign_transaction_history(&self, address: &Address, limit: u64) -> Result<Vec<Transaction>, HistoryError> {
// Cannot get full history for foreign addresses
// Must query full node or archive node
Err(HistoryError::ForeignAddressNotSupported)
}
}

Limited Smart Contract Interaction

Smart Contract Limitations:

pub struct ContractInteraction {
pub supported_operations: Vec<ContractOperation>, // Supported operations
pub gas_limit: u64, // Gas limit for operations
pub value_limit: u128, // Value limit for operations
}

impl ContractInteraction {
pub fn can_execute_contract_call(&self, call: &ContractCall) -> Result<bool, ContractError> {
// 1. Check if operation is supported
if !self.supported_operations.contains(&call.operation) {
return Ok(false);
}

// 2. Check gas limit
if call.gas_estimate > self.gas_limit {
return Ok(false);
}

// 3. Check value limit
if call.value > self.value_limit {
return Ok(false);
}

// 4. Check contract size
if call.contract_code.len() > MAX_CONTRACT_SIZE {
return Ok(false);
}

Ok(true)
}
}

Network Limitations

Peer Connection Limitations

Connection Limitations:

pub struct PeerConnectionLimits {
pub max_connections: usize, // Maximum connections
pub min_trusted_peers: usize, // Minimum trusted peers
pub connection_timeout: Duration, // Connection timeout
pub keep_alive_interval: Duration, // Keep-alive interval
}

impl PeerConnectionLimits {
pub fn get_mobile_limits() -> PeerConnectionLimits {
PeerConnectionLimits {
max_connections: 10, // Mobile devices limited
min_trusted_peers: 3, // Minimum for security
connection_timeout: Duration::from_secs(30),
keep_alive_interval: Duration::from_secs(60),
}
}
}

Network Reliability:

  • Mobile Networks: Variable connectivity and speed
  • WiFi Networks: More reliable but not always available
  • Battery Constraints: Background processing limited
  • Data Limits: Mobile data plans may be limited

Mitigation Strategies

Connection Management:

impl LightNode {
pub async fn manage_connections(&mut self) -> Result<ConnectionStatus, ConnectionError> {
// 1. Assess current network conditions
let network_assessment = self.assess_network_conditions().await?;

// 2. Adjust connection strategy
let connection_strategy = self.determine_connection_strategy(network_assessment);

// 3. Implement connection strategy
match connection_strategy {
ConnectionStrategy::Aggressive => self.aggressive_connections().await?,
ConnectionStrategy::Conservative => self.conservative_connections().await?,
ConnectionStrategy::Minimal => self.minimal_connections().await?,
}

// 4. Monitor connection health
self.monitor_connection_health().await?;

Ok(ConnectionStatus {
active_connections: self.get_active_connection_count(),
strategy: connection_strategy,
network_quality: network_assessment.quality,
})
}
}

Security Limitations

Limited Attack Detection

Attack Detection Limitations:

pub struct AttackDetectionLimits {
pub detection_window: Duration, // Detection window
pub max_peers_monitored: usize, // Maximum peers monitored
pub max_events_tracked: usize, // Maximum events tracked
pub detection_accuracy: f64, // Detection accuracy
}

impl AttackDetectionLimits {
pub fn get_light_node_limits() -> AttackDetectionLimits {
AttackDetectionLimits {
detection_window: Duration::from_secs(300), // 5 minutes
max_peers_monitored: 20, // Limited peer monitoring
max_events_tracked: 1000, // Limited event tracking
detection_accuracy: 0.7, // 70% accuracy
}
}
}

Security Trade-offs:

  • Limited Visibility: Cannot see full network activity
  • Delayed Detection: Attacks may be detected later
  • Resource Constraints: Limited resources for detection
  • Trust Dependencies: Relies on trusted peers

Enhanced Security Measures

Collaborative Security:

impl LightNode {
pub async fn collaborative_attack_detection(&self) -> Result<CollaborativeDetection, SecurityError> {
// 1. Share observations with trusted peers
let observations = self.collect_security_observations().await?;

// 2. Request peer observations
let peer_observations = self.request_peer_observations(&observations).await?;

// 3. Analyze combined data
let combined_analysis = self.analyze_combined_observations(&observations, &peer_observations)?;

// 4. Detect attacks with higher confidence
let detected_attacks = self.detect_attacks_with_combined_data(&combined_analysis)?;

Ok(CollaborativeDetection {
local_observations: observations,
peer_observations,
combined_analysis,
detected_attacks,
detection_confidence: combined_analysis.confidence,
})
}
}

Development Limitations

Limited Development Tools

Development Tool Limitations:

pub struct DevelopmentLimitations {
pub api_access_level: ApiAccessLevel, // API access level
pub debugging_capabilities: DebugCapabilities, // Debugging capabilities
pub testing_environment: TestingEnvironment, // Testing environment
pub monitoring_tools: MonitoringTools, // Monitoring tools
}

impl DevelopmentLimitations {
pub fn get_mobile_limitations() -> DevelopmentLimitations {
DevelopmentLimitations {
api_access_level: ApiAccessLevel::ReadOnly, // Read-only API access
debugging_capabilities: DebugCapabilities::Limited, // Limited debugging
testing_environment: TestingEnvironment::Simulated, // Simulated environment
monitoring_tools: MonitoringTools::Basic, // Basic monitoring
}
}
}

Development Workarounds

Remote Development:

impl LightNode {
pub async fn remote_development_session(&self) -> Result<DevelopmentSession, DevelopmentError> {
// 1. Connect to development server
let dev_server = self.connect_to_development_server().await?;

// 2. Establish secure channel
let secure_channel = self.establish_secure_channel(&dev_server).await?;

// 3. Request development tools
let dev_tools = self.request_development_tools(&secure_channel).await?;

// 4. Initialize remote debugging
let remote_debugger = self.initialize_remote_debugging(&secure_channel).await?;

Ok(DevelopmentSession {
server: dev_server,
channel: secure_channel,
tools: dev_tools,
debugger: remote_debugger,
})
}
}

Summary of Limitations

Critical Limitations

  1. No Consensus Participation: Cannot participate in BFT consensus
  2. No Full State Storage: Cannot store complete blockchain state
  3. Limited Transaction History: Cannot access full transaction history
  4. Network Dependency: Relies on full nodes for data
  5. Performance Constraints: Limited by mobile hardware

Acceptable Limitations

  1. Resource Efficiency: Designed for minimal resource usage
  2. Security Verification: Full cryptographic verification of received data
  3. Mobile Optimization: Battery and network optimized
  4. Scalability: Supports millions of light nodes
  5. User Experience: Fast synchronization and responsive UI

Mitigation Strategies

  1. Hybrid Architecture: Combine light nodes with full node services
  2. Delegated Operations: Use full nodes for heavy operations
  3. Collaborative Security: Share security observations
  4. Adaptive Performance: Adjust behavior based on conditions
  5. Fallback Mechanisms: Graceful degradation when needed

This limitations documentation helps users understand the trade-offs of using light nodes and provides guidance for working within these constraints effectively.