Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 113 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ A decentralized health credential platform built on the Stellar Soroban Smart Co
- **Batch Verification**: Verify multiple credentials simultaneously for venues and organizations
- **Health Authority Integration**: Integration with certified health authorities for credential issuance
- **Cross-Border Recognition**: Standardized format for international travel and compliance
- **Robust Contract Upgrades**: Secure upgrade mechanism with timelock, proxy pattern, and state consistency validation

## 🏗️ Architecture

Expand Down Expand Up @@ -51,6 +52,15 @@ A decentralized health credential platform built on the Stellar Soroban Smart Co
- Stores health authority public keys and signatures
- Enables credential authority verification

#### Upgrade Mechanism
- **Proxy Pattern**: Seamless contract upgrades without data loss
- **Timelock Security**: 24-hour delay between scheduling and executing upgrades
- **Migration Registry**: Tracks all migrations with version, timestamp, and success status
- **State Consistency**: Validates storage integrity before upgrades
- **Access Control**: Admin-only upgrade functions with dual authorization for admin transfer
- **Emergency Pause**: Ability to temporarily disable upgrades for critical situations
- **Version Tracking**: Comprehensive version management with rollback prevention

### Off-Chain Components

#### Backend (NestJS)
Expand Down Expand Up @@ -293,7 +303,108 @@ NEXT_PUBLIC_API_URL=http://localhost:3001/api/v1
5. Click "Share Credential"
6. The recipient will receive access for the specified duration

## 🔧 API Documentation
## � Contract Upgrade Mechanism

### Overview

The ValidFi smart contracts include a robust upgrade mechanism that allows for secure, controlled contract upgrades without data loss. The system uses a proxy pattern with timelock security, state consistency validation, and comprehensive migration tracking.

### Upgrade Process

#### 1. Initialize Upgrade Mechanism

```bash
# Call initialize_upgrade with admin address and initial implementation hash
identity_registry.initialize_upgrade(admin_address, initial_wasm_hash)
```

#### 2. Schedule Upgrade

```bash
# Schedule an upgrade with a 24-hour timelock
identity_registry.schedule_upgrade(
admin_address,
new_wasm_hash,
proposed_version
)
```

#### 3. Wait for Timelock

The timelock period (24 hours) must expire before the upgrade can be executed. This provides time for community review and emergency cancellation if needed.

#### 4. Execute Upgrade

```bash
# After timelock expires, execute the upgrade
identity_registry.execute_upgrade(admin_address)
```

#### 5. Run Data Migration (if needed)

```bash
# Execute data migrations for the new version
identity_registry.migrate_v1_to_v2(admin_address)
```

### Security Features

- **Timelock Protection**: 24-hour delay prevents rushed upgrades
- **Admin Authorization**: Only designated admin can schedule/execute upgrades
- **State Validation**: System checks storage integrity before upgrade
- **Migration Tracking**: All migrations recorded with version and timestamp
- **Emergency Pause**: Admin can pause upgrades during critical situations
- **Dual Authorization**: Admin transfer requires both current and new admin signatures

### Monitoring Upgrades

```bash
# Check current version
identity_registry.get_version()

# Check pending upgrade
identity_registry.get_pending_upgrade()

# Check timelock end time
identity_registry.get_timelock_end()

# Check migration status
identity_registry.is_migration_executed(version)

# Get migration record
identity_registry.get_migration_record(version)
```

### Emergency Procedures

#### Cancel Pending Upgrade

```bash
identity_registry.cancel_upgrade(admin_address)
```

#### Emergency Pause Upgrades

```bash
identity_registry.emergency_pause_upgrades(admin_address)
```

#### Unpause Upgrades

```bash
identity_registry.unpause_upgrades(admin_address)
```

### Legacy Upgrade Method

For backward compatibility, a legacy upgrade method is available:

```bash
# Direct upgrade without timelock (not recommended for production)
identity_registry.upgrade(admin_address, new_wasm_hash)
```

## � API Documentation

### Authentication Endpoints

Expand Down Expand Up @@ -455,6 +566,7 @@ This project is licensed under the MIT License - see the LICENSE file for detail
- ✅ Basic wallet integration
- ✅ IPFS integration
- ✅ AI-powered verification
- ✅ Robust contract upgrade mechanism

### Phase 2 (In Progress)
- 🔄 Health credential-specific zk-proof circuits
Expand Down
11 changes: 11 additions & 0 deletions contracts/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,15 @@ pub enum Error {
SharedDocumentNotFound = 4,
Unauthorized = 5,
AlreadyInitialized = 6,
// Upgrade mechanism errors
UpgradeNotInitialized = 7,
InvalidUpgradeHash = 8,
MigrationAlreadyRun = 9,
StateInconsistency = 10,
UpgradeTimelockNotExpired = 11,
ProxyNotInitialized = 12,
InvalidImplementation = 13,
MigrationFailed = 14,
VersionMismatch = 15,
StorageCorrupted = 16,
}
84 changes: 82 additions & 2 deletions contracts/src/identity_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,35 @@ impl IdentityRegistry {
upgrade::set_admin(env, &admin);
}

/// Upgrade the running contract WASM to `new_wasm_hash`.
/// Initialize the upgrade mechanism with admin and proxy pattern.
/// This must be called once after deployment.
pub fn initialize_upgrade(env: &Env, admin: Address, implementation: BytesN<32>) {
admin.require_auth();
upgrade::initialize_upgrade(env, &admin, &implementation);
}

/// Schedule an upgrade with a timelock for security.
/// The upgrade can only be executed after the timelock period expires.
pub fn schedule_upgrade(
env: &Env,
admin: Address,
new_wasm_hash: BytesN<32>,
proposed_version: u32,
) {
upgrade::schedule_upgrade(env, &admin, new_wasm_hash, proposed_version);
}

/// Execute a scheduled upgrade after timelock expires.
pub fn execute_upgrade(env: &Env, admin: Address) {
upgrade::execute_upgrade(env, &admin);
}

/// Cancel a pending upgrade.
pub fn cancel_upgrade(env: &Env, admin: Address) {
upgrade::cancel_upgrade(env, &admin);
}

/// Upgrade the running contract WASM to `new_wasm_hash` (legacy method).
/// Only the upgrade admin may call this.
///
/// After this call the next ledger-round executes the new code; all
Expand All @@ -158,7 +186,7 @@ impl IdentityRegistry {
/// storage keys.
pub fn upgrade(env: &Env, admin: Address, new_wasm_hash: BytesN<32>) {
upgrade::require_admin(env, &admin);
upgrade::execute_upgrade(env, new_wasm_hash);
upgrade::execute_upgrade_legacy(env, new_wasm_hash);
}

/// Data migration: v1 → v2.
Expand Down Expand Up @@ -198,4 +226,56 @@ impl IdentityRegistry {
pub fn is_migration_complete(env: &Env) -> bool {
upgrade::is_migrated_v2(env)
}

// ── New Upgrade Mechanism Functions ───────────────────────────────────────

/// Get the current proxy implementation address.
pub fn get_implementation(env: &Env) -> Option<BytesN<32>> {
upgrade::get_implementation(env)
}

/// Get pending upgrade information.
pub fn get_pending_upgrade(env: &Env) -> Option<upgrade::PendingUpgrade> {
upgrade::get_pending_upgrade(env)
}

/// Get the timelock end timestamp.
pub fn get_timelock_end(env: &Env) -> Option<u64> {
upgrade::get_timelock_end(env)
}

/// Get the current state hash.
pub fn get_state_hash(env: &Env) -> BytesN<32> {
upgrade::get_state_hash(env)
}

/// Update the state hash for consistency validation.
pub fn update_state_hash(env: &Env, state_hash: BytesN<32>) {
upgrade::update_state_hash(env, state_hash);
}

/// Get migration record for a specific version.
pub fn get_migration_record(env: &Env, version: u32) -> Option<upgrade::MigrationRecord> {
upgrade::get_migration_record(env, version)
}

/// Check if a specific migration has been executed.
pub fn is_migration_executed(env: &Env, version: u32) -> bool {
upgrade::is_migration_executed(env, version)
}

/// Emergency pause: disable upgrades temporarily.
pub fn emergency_pause_upgrades(env: &Env, admin: Address) {
upgrade::emergency_pause_upgrades(env, &admin);
}

/// Unpause upgrades after emergency.
pub fn unpause_upgrades(env: &Env, admin: Address) {
upgrade::unpause_upgrades(env, &admin);
}

/// Check if upgrades are currently paused.
pub fn is_upgrades_paused(env: &Env) -> bool {
upgrade::is_upgrades_paused(env)
}
}
Loading
Loading