Skip to content

Commit a809d8f

Browse files
CopilotSteake
andauthored
Implement light client with header sync, Merkle proofs, and wallet mode (#114)
* Initial plan * Add light client implementation with header sync and Merkle proof verification Co-authored-by: Steake <530040+Steake@users.noreply.github.com> * Add light client example demonstrating header sync and wallet functionality Co-authored-by: Steake <530040+Steake@users.noreply.github.com> * Add light client implementation summary documentation * Address code review feedback: fix underflows, improve error handling, update docs, remove unused deps Co-authored-by: Steake <530040+Steake@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
1 parent 9de440c commit a809d8f

12 files changed

Lines changed: 2381 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ members = [
1313
"crates/bitcell-admin",
1414
"crates/bitcell-simulation",
1515
"crates/bitcell-wallet",
16-
"crates/bitcell-wallet-gui", "crates/bitcell-compiler",
16+
"crates/bitcell-wallet-gui",
17+
"crates/bitcell-compiler",
18+
"crates/bitcell-light-client",
1719
]
1820
resolver = "2"
1921

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "bitcell-light-client"
3+
version.workspace = true
4+
authors.workspace = true
5+
edition.workspace = true
6+
rust-version.workspace = true
7+
license.workspace = true
8+
repository.workspace = true
9+
10+
[dependencies]
11+
# Internal dependencies
12+
bitcell-consensus = { path = "../bitcell-consensus" }
13+
bitcell-crypto = { path = "../bitcell-crypto" }
14+
bitcell-network = { path = "../bitcell-network" }
15+
16+
# Serialization
17+
serde = { workspace = true }
18+
bincode = { workspace = true }
19+
20+
# Error handling
21+
thiserror = { workspace = true }
22+
23+
# Async runtime
24+
tokio = { workspace = true }
25+
26+
# Logging
27+
tracing = { workspace = true }
28+
29+
# Utilities
30+
parking_lot = { workspace = true }
31+
32+
[dev-dependencies]
33+
proptest = { workspace = true }
34+
tracing-subscriber = { workspace = true }
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# BitCell Light Client
2+
3+
A lightweight client implementation for BitCell blockchain, designed for resource-constrained devices.
4+
5+
## Features
6+
7+
- **Header-Only Sync**: Downloads and validates only block headers, reducing bandwidth and storage requirements
8+
- **Checkpoint Support**: Fast sync using trusted checkpoints
9+
- **Merkle Proof Verification**: Verifies state queries via Merkle proofs from full nodes
10+
- **Wallet Mode**: Support for balance queries and transaction submission without full state
11+
- **Resource Efficient**: Designed to use <100MB of memory
12+
13+
## Architecture
14+
15+
The light client consists of several key components:
16+
17+
### Header Chain (`header_chain.rs`)
18+
Maintains a chain of verified block headers without full block data. Implements:
19+
- Header validation (parent links, timestamps, VRF)
20+
- Fork choice (heaviest chain rule)
21+
- Memory-efficient pruning
22+
- Tip height tracking
23+
24+
### Checkpoint Manager (`checkpoints.rs`)
25+
Enables fast sync by allowing the client to skip validation of ancient blocks:
26+
- Hardcoded trusted checkpoints
27+
- Dynamic checkpoint addition
28+
- Checkpoint-based sync
29+
30+
### Sync Protocol (`sync.rs`)
31+
Manages the synchronization process:
32+
- Syncs from latest checkpoint
33+
- Batch header downloads
34+
- Progress tracking
35+
- Status reporting
36+
37+
### Merkle Proof System (`proofs.rs`)
38+
Verifies state queries without full state:
39+
- Account balance proofs
40+
- Account nonce proofs
41+
- Transaction inclusion proofs
42+
- Storage slot proofs
43+
44+
### Network Protocol (`protocol.rs`)
45+
Defines messages for light client <-> full node communication:
46+
- Header requests/responses
47+
- State proof requests/responses
48+
- Chain tip queries
49+
- Transaction submission
50+
51+
### Light Wallet (`wallet.rs`)
52+
Provides wallet functionality using only headers and proofs:
53+
- Read-only mode (balance queries)
54+
- Full mode (can sign and submit transactions)
55+
- Account info caching
56+
- Pending transaction tracking
57+
58+
## Usage
59+
60+
### Creating a Light Client
61+
62+
```rust
63+
use bitcell_light_client::*;
64+
use bitcell_crypto::SecretKey;
65+
use parking_lot::RwLock;
66+
use std::sync::Arc;
67+
68+
// Create header chain with genesis
69+
let genesis = /* get genesis header */;
70+
let config = HeaderChainConfig::default();
71+
let header_chain = Arc::new(HeaderChain::new(genesis, config));
72+
73+
// Create checkpoint manager
74+
let checkpoint_manager = Arc::new(RwLock::new(CheckpointManager::new()));
75+
76+
// Create sync manager
77+
let sync = HeaderSync::new(header_chain.clone(), checkpoint_manager);
78+
79+
// Start syncing
80+
sync.sync_to(target_height).await?;
81+
```
82+
83+
### Creating a Light Wallet
84+
85+
```rust
86+
use bitcell_light_client::*;
87+
88+
// Read-only wallet (balance queries only)
89+
let wallet = LightWallet::read_only(
90+
public_key,
91+
header_chain.clone(),
92+
protocol.clone()
93+
);
94+
95+
// Full wallet (can sign transactions)
96+
let secret_key = Arc::new(SecretKey::generate());
97+
let wallet = LightWallet::full(
98+
secret_key,
99+
header_chain.clone(),
100+
protocol.clone()
101+
);
102+
103+
// Query balance (requires network connection to full node)
104+
let balance = wallet.get_balance().await?;
105+
106+
// Create and submit transaction (full mode only)
107+
let tx = wallet.create_transaction(to, amount, nonce, gas_limit, gas_price)?;
108+
let tx_hash = wallet.submit_transaction(tx).await?;
109+
```
110+
111+
### Verifying State Proofs
112+
113+
```rust
114+
use bitcell_light_client::*;
115+
116+
// Request state proof from full node
117+
let proof_req = StateProofRequest::balance(block_height, account_address);
118+
119+
// Verify proof against header chain
120+
let header = header_chain.get_header(block_height).unwrap();
121+
proof.verify(&header.state_root)?;
122+
123+
// Extract balance from proof (only if verification succeeded)
124+
let balance = proof.extract_balance()?;
125+
```
126+
127+
## Resource Usage
128+
129+
The light client is designed for minimal resource usage:
130+
131+
- **Memory**: <100MB typical usage
132+
- ~500 bytes per header
133+
- Configurable header cache (default: 10,000 headers)
134+
- Account info caching
135+
- Automatic pruning of old headers
136+
137+
- **Bandwidth**: Minimal
138+
- Only downloads headers (~500 bytes each)
139+
- State queries via compact Merkle proofs
140+
- No full block downloads
141+
142+
- **Storage**: Optional
143+
- Can operate entirely in memory
144+
- Optional persistent storage for headers
145+
- No need for full blockchain data
146+
147+
## Checkpoints
148+
149+
Checkpoints are hardcoded trusted block headers that allow fast sync. They are updated with each software release and can be dynamically added by the user.
150+
151+
```rust
152+
let checkpoint = Checkpoint::new(header, "Checkpoint at height 100000".to_string());
153+
checkpoint_manager.write().add_checkpoint(checkpoint)?;
154+
```
155+
156+
## Network Protocol
157+
158+
The light client communicates with full nodes using the following message types:
159+
160+
- `GetHeaders`: Request headers in a range
161+
- `Headers`: Response with requested headers
162+
- `GetStateProof`: Request a Merkle proof for state
163+
- `StateProof`: Response with proof
164+
- `GetChainTip`: Query current tip
165+
- `ChainTip`: Response with tip info
166+
- `SubmitTransaction`: Submit a signed transaction
167+
- `TransactionResult`: Result of submission
168+
169+
## Security
170+
171+
The light client maintains security through:
172+
173+
1. **Header Validation**: All headers are currently validated for:
174+
- Correct parent hash linkage
175+
- Increasing timestamps
176+
177+
> **Warning:** Validation of VRF proofs and work calculations is **not yet implemented**. Until these checks are added, the light client is vulnerable to malicious peers providing invalid headers and state roots. Do **not** use in production or trust state proofs from untrusted sources.
178+
179+
2. **Merkle Proof Verification**: All state queries are verified against the state root in validated headers
180+
181+
3. **Checkpoint Trust**: Only trusted checkpoints are used for fast sync
182+
183+
4. **Fork Choice**: Follows the heaviest chain rule
184+
185+
## Future Enhancements
186+
187+
- Persistent storage for headers
188+
- P2P networking for multi-peer sync
189+
- Fraud proof system
190+
- More efficient proof formats (e.g., Patricia trie proofs)
191+
- Mobile device optimizations
192+
193+
## Testing
194+
195+
Run tests:
196+
```bash
197+
cargo test -p bitcell-light-client
198+
```
199+
200+
All tests should pass, validating:
201+
- Header chain management
202+
- Checkpoint functionality
203+
- Proof verification
204+
- Wallet operations
205+
- Network protocol encoding/decoding
206+
207+
## Compatibility
208+
209+
- Works on Raspberry Pi and similar resource-constrained devices
210+
- Compatible with full BitCell nodes for proof requests
211+
- Supports both read-only and full wallet modes

0 commit comments

Comments
 (0)