ICN API Versioning Guide
Document: ICN-DOC-VERSIONING-01 Last Updated: 2025-12-04 Status: Complete
This guide covers versioning strategies for all ICN interfaces: the REST Gateway API, RPC protocol, and P2P network protocol.
Table of Contents
- Overview
- Gateway REST API Versioning
- RPC Protocol Versioning
- P2P Protocol Versioning
- Capability-Based Features
- Migration Strategies
- Deprecation Policy
- Version Compatibility Matrix
1. Overview
ICN uses semantic versioning (SemVer) for releases and maintains three separate versioned interfaces:
| Interface | Current Version | Scope |
|---|---|---|
| Gateway REST API | v1 | External applications |
| RPC Protocol | 1.0 | Node-to-node admin |
| P2P Protocol | 1 | Network layer |
Versioning Philosophy:
- Backward compatibility is prioritized for all interfaces
- Breaking changes require major version bumps
- Additive changes (new endpoints, fields) are non-breaking
- Deprecation precedes removal by at least 2 minor versions
2. Gateway REST API Versioning
2.1 URL Path Versioning
All Gateway API endpoints use URL path versioning with the /v1/ prefix:
http://localhost:8080/v1/coops
http://localhost:8080/v1/ledger/{coop_id}/balance/{did}
http://localhost:8080/v1/compute/submit
Why path versioning?
- Clear and explicit in requests
- Easy to route at load balancer level
- Simple to test with curl/httpie
2.2 Version Lifecycle
| State | Description | Duration |
|---|---|---|
| Current | Actively developed, full support | Until next major |
| Supported | Bug fixes, security patches only | 12 months after deprecation |
| Deprecated | Scheduled for removal | 6 months notice |
| Removed | No longer available | - |
2.3 Adding New API Version
When adding /v2/ endpoints:
Create new API module:
// icn-gateway/src/api/v2/mod.rs pub mod coops; pub mod ledger; pub mod compute;Register both versions:
// server.rs App::new() .service(web::scope("/v1").configure(v1::config)) .service(web::scope("/v2").configure(v2::config))Maintain parallel implementations during transition period
2.4 Response Format Changes
Non-breaking additions (allowed within same version):
- New optional fields in responses
- New optional query parameters
- New endpoints
Breaking changes (require version bump):
- Removing fields from responses
- Changing field types
- Changing endpoint paths
- Removing endpoints
Example: Adding a field
// v1 original response
{
"id": "coop-123",
"name": "Food Coop"
}
// v1 updated response (backward compatible)
{
"id": "coop-123",
"name": "Food Coop",
"created_at": "2025-01-15T10:30:00Z" // New optional field
}
2.5 Request Validation
New optional request fields can be added without breaking clients:
// v1 original request
{
"id": "coop-123",
"name": "Food Coop"
}
// v1 updated - server accepts both
{
"id": "coop-123",
"name": "Food Coop",
"description": "A local food cooperative" // Optional, ignored if missing
}
3. RPC Protocol Versioning
3.1 JSON-RPC Method Naming
RPC methods follow the pattern: namespace.method:
{
"jsonrpc": "2.0",
"method": "network.peers",
"params": {},
"id": 1
}
Current namespaces:
auth.*- Authentication methodsnetwork.*- Network operationsgossip.*- Gossip protocolledger.*- Ledger operationscompute.*- Compute tasksgovernance.*- Governance domains/proposalsidentity.*- Identity management
3.2 Adding RPC Methods
New methods can be added without breaking existing clients:
// Add new method in server.rs
"compute.cancel" => self.handle_compute_cancel(params).await,
3.3 Evolving Method Parameters
Non-breaking (add with defaults):
// Before
{"method": "compute.submit", "params": {"code": "...", "fuel_limit": 1000}}
// After (priority is optional, defaults to "normal")
{"method": "compute.submit", "params": {"code": "...", "fuel_limit": 1000, "priority": "high"}}
Breaking (requires new method):
// Don't change semantics - create new method instead
{"method": "compute.submit_v2", "params": {...}}
3.4 RPC Error Codes
Standard JSON-RPC error codes are used:
| Code | Meaning |
|---|---|
| -32700 | Parse error |
| -32600 | Invalid request |
| -32601 | Method not found |
| -32602 | Invalid params |
| -32603 | Internal error |
| -32001 | Authentication required |
| -32002 | Authorization denied |
| -32003 | Rate limited |
Custom error codes use -32100 to -32199 range.
4. P2P Protocol Versioning
4.1 Protocol Version Negotiation
ICN nodes negotiate protocol versions during the Hello handshake:
pub struct VersionInfo {
/// Current protocol version this node is running
pub current_version: u32,
/// Minimum protocol version this node supports
pub min_supported: u32,
/// Maximum protocol version this node supports
pub max_supported: u32,
/// Optional capabilities bitmap for feature detection
pub capabilities: CapabilityFlags,
/// Software version string (e.g., "icnd-0.1.0")
pub software_version: String,
}
Constants (defined in icn-net/src/protocol.rs):
pub const PROTOCOL_VERSION: u32 = 1; // Current
pub const MIN_SUPPORTED_VERSION: u32 = 1; // Minimum we accept
pub const MAX_SUPPORTED_VERSION: u32 = 1; // Maximum we support
4.2 Negotiation Algorithm
Nodes negotiate to the highest mutually supported version:
fn negotiate_version(local: &VersionInfo, remote: &VersionInfo) -> Result<u32> {
// Find the overlap between supported versions
let negotiated = std::cmp::min(local.max_supported, remote.max_supported);
// Verify it's within both nodes' supported range
if negotiated < local.min_supported || negotiated < remote.min_supported {
bail!("No compatible version");
}
Ok(negotiated)
}
Example:
Node A: min=1, max=2, current=2
Node B: min=1, max=1, current=1
Negotiated: min(2, 1) = 1 ✓ (both support v1)
4.3 Handshake Sequence
Client Server
| |
|---- Hello + VersionInfo ----------->|
| | (validate version)
|<--- Hello + VersionInfo ------------|
| |
| (Both nodes compute negotiated version)
| |
|<=========== Connection OK ==========>|
4.4 Incrementing Protocol Version
When to increment the protocol version:
| Change Type | Action |
|---|---|
| New message type | No change (additive) |
| New field in message | No change (additive) |
| Remove field | Increment version |
| Change field semantics | Increment version |
| Change message format | Increment version |
Steps to increment:
Update constants:
pub const PROTOCOL_VERSION: u32 = 2; pub const MAX_SUPPORTED_VERSION: u32 = 2; // Keep MIN_SUPPORTED = 1 for backward compatHandle both versions in message parsing:
match negotiated_version { 1 => parse_v1_message(bytes), 2 => parse_v2_message(bytes), _ => Err("Unsupported version"), }Update tests and documentation
5. Capability-Based Features
5.1 Capability Flags
Beyond version numbers, ICN uses capability flags for fine-grained feature detection:
pub struct CapabilityFlags: u64 {
const E2E_ENCRYPTION = 0b00000001; // Phase 10
const SIGNED_MESSAGES = 0b00000010; // Phase 9
const GRACEFUL_RESTART = 0b00000100; // Track B1
const TOPOLOGY_AWARE = 0b00001000; // Phase 16C
const TRUST_RATE_LIMITING = 0b00010000; // Phase 7
const GOSSIP_PULL = 0b00100000; // Phase 7
const MULTI_DEVICE = 0b01000000; // Phase 11
const ECONOMIC_SAFETY = 0b10000000; // Phase 12
}
5.2 Feature Detection Pattern
Check peer capabilities before using optional features:
let common = common_capabilities(&local_version, &peer_version);
if common.contains(CapabilityFlags::E2E_ENCRYPTION) {
// Use encrypted envelope
send_encrypted_message(peer, payload);
} else {
// Fall back to signed-only envelope
send_signed_message(peer, payload);
}
5.3 Adding New Capabilities
Add flag constant:
const NEW_FEATURE = 0b100000000; // Next available bitUpdate
current()when feature is implemented:impl CapabilityFlags { pub fn current() -> Self { Self::E2E_ENCRYPTION | Self::SIGNED_MESSAGES | ... | Self::NEW_FEATURE // Add when ready } }Document the capability in this guide
6. Migration Strategies
6.1 Rolling Upgrades
For networks with mixed versions:
- Upgrade executors first - They need newest features
- Upgrade coordinators - Intermediate nodes
- Upgrade leaf nodes last - Members, gateways
During rolling upgrade:
- Maintain backward compatibility window (e.g., support N and N-1)
- Monitor metrics for version distribution
- Set deadline for upgrade completion
6.2 Data Migration
When storage formats change:
# Check current version
icnctl version --data-dir ~/.icn
# Run migration
icnctl migrate --from 0.1.x --to 0.2.x
# Verify migration
icnctl verify --data-dir ~/.icn
Migration principles:
- Always backup before migration
- Migrations are one-way (no downgrade path)
- Test migrations on copy first
6.3 API Migration Checklist
For Gateway API version transitions:
- Create new version endpoints
- Update OpenAPI spec
- Update TypeScript SDK
- Add deprecation warnings to old endpoints
- Update documentation
- Communicate timeline to API consumers
- Monitor usage of deprecated endpoints
- Remove old endpoints after sunset period
7. Deprecation Policy
7.1 Deprecation Process
- Announce - Document deprecation in CHANGELOG, add header to responses
- Warn - Log warnings when deprecated features used
- Monitor - Track usage of deprecated features
- Remove - After sunset period, remove feature
7.2 Deprecation Signals
REST API: Add response header
Deprecation: Sun, 01 Jun 2025 00:00:00 GMT
Sunset: Sun, 01 Dec 2025 00:00:00 GMT
Link: </v2/coops>; rel="successor-version"
RPC: Return warning in response
{
"jsonrpc": "2.0",
"result": {...},
"id": 1,
"_warning": "Method 'compute.submit' is deprecated. Use 'compute.submit_v2' instead."
}
P2P: Log warning, emit metric
metrics::counter!("icn_protocol_deprecated_messages_total").increment(1);
tracing::warn!(
method = %msg.method,
peer = %peer_did,
"Received deprecated message type"
);
7.3 Timeline Guidelines
| Severity | Notice Period | Support Period |
|---|---|---|
| Minor (field removal) | 1 minor release | 2 minor releases |
| Major (endpoint removal) | 2 minor releases | 6 months |
| Critical (security fix) | Immediate | Best effort |
8. Version Compatibility Matrix
8.1 Current Compatibility
| ICN Version | Protocol | Gateway API | RPC | Min Compatible |
|---|---|---|---|---|
| 0.1.x | 1 | v1 | 1.0 | 0.1.0 |
| 0.2.x (planned) | 1-2 | v1 | 1.0 | 0.1.0 |
8.2 Feature Availability by Version
| Feature | Introduced | Protocol | Capability Flag |
|---|---|---|---|
| Basic networking | 0.1.0 | 1 | - |
| Signed messages | 0.1.0 | 1 | SIGNED_MESSAGES |
| E2E encryption | 0.1.0 | 1 | E2E_ENCRYPTION |
| Graceful restart | 0.1.0 | 1 | GRACEFUL_RESTART |
| Trust rate limiting | 0.1.0 | 1 | TRUST_RATE_LIMITING |
| Multi-device | 0.1.0 | 1 | MULTI_DEVICE |
| Economic safety | 0.1.0 | 1 | ECONOMIC_SAFETY |
| Topology awareness | 0.1.0 | 1 | TOPOLOGY_AWARE |
8.3 Testing Compatibility
Run compatibility tests before deployment:
# Test against older version
./scripts/test-compatibility.sh --old-version 0.1.0 --new-version 0.2.0
# Test protocol negotiation
cargo test -p icn-net test_negotiate
# Test API backward compatibility
cargo test -p icn-gateway test_v1_compat
References
- ARCHITECTURE.md - System architecture
- capability-based-features.md - Detailed capability guide
- deployment-guide.md - Deployment procedures
- CHANGELOG.md - Version history
Changelog
| Date | Change |
|---|---|
| 2025-12-04 | Initial document creation |