Skip to content

[Smart Contracts] Add Error Expiration/TTL with Configurable Retention and Automatic Cleanup #166

Description

@devJaja

🎯 Objective

Add error expiration/TTL with configurable retention and automatic cleanup to prevent unbounded storage growth of error entries in the agent_registry Soroban contract.


📁 Files to Modify

Action File Path Description
Modify smart-contracts/contracts/agent_registry/src/lib.rs Add TTL fields to ErrorEntry, add cleanup function

📁 Reference Files

File Path Purpose
smart-contracts/contracts/agent_registry/src/lib.rs (line ~520) ErrorEntry struct definition
smart-contracts/contracts/agent_registry/src/lib.rs (line ~536) resolve_errors function
smart-contracts/contracts/agent_registry/src/lib.rs (line ~580) report_error function
smart-contracts/contracts/agent_registry/src/lib.rs (line ~600) extend_ttl_batch function (pattern to follow)

💥 Impact

  • Error entries persist indefinitely in persistent storage
  • Persistent storage costs Stellar network rent
  • No way to garbage-collect old, irrelevant errors
  • Storage grows linearly with error reports

✅ Expected Implementation

1. Add TTL Fields to ErrorEntry

#[contracttype]
pub struct ErrorEntry {
    pub id: BytesN<32>,
    pub reporter: Address,
    pub message: String,
    pub resolved: bool,
    pub resolution: Resolution,
    pub created_at: u64,    // ADD: Ledger sequence at creation
    pub expires_at: u64,    // ADD: Ledger sequence at expiration
}

2. Add TTL Storage Key

#[derive(Clone)]
pub enum DataKey {
    // ... existing keys ...
    ErrorTTL,  // ADD: Configurable TTL in ledger sequences
}

3. Add Cleanup Function

pub fn cleanup_expired_errors(env: Env) -> u32 {
    let current_seq = env.ledger().sequence() as u64;
    let mut removed = 0u32;

    // Iterate stored errors and remove expired ones
    // (Soroban doesn't have iterator over all keys,
    //  so this requires a registry of error IDs or
    //  a caller-provided list of error IDs to check)

    removed
}

4. Add Admin TTL Configuration

pub fn set_error_ttl(env: Env, ttl_ledgers: u64) {
    let admin = get_admin(&env);
    admin.require_auth();
    env.storage().instance().set(&DataKey::ErrorTTL, &ttl_ledgers);
}

5. Update report_error to Set Expiration

pub fn report_error(...) {
    let ttl = env.storage().instance()
        .get::<DataKey, u64>(&DataKey::ErrorTTL)
        .unwrap_or(518_400); // Default: ~30 days at 5s/ledger

    let entry = ErrorEntry {
        // ... existing fields ...
        created_at: env.ledger().sequence() as u64,
        expires_at: env.ledger().sequence() as u64 + ttl,
    };
}

📁 Reference Patterns

File Path Pattern to Follow
smart-contracts/contracts/agent_registry/src/lib.rs extend_ttl_batch() — how existing TTL extension works
smart-contracts/contracts/agent_registry/src/lib.rs GasConfig — how admin-configurable params are stored
smart-contracts/contracts/agent_registry/src/lib.rs pause()/unpause() — admin auth pattern

✅ Acceptance Criteria

  • Add created_at and expires_at fields to ErrorEntry struct
  • Add DataKey::ErrorTTL storage key
  • Add set_error_ttl(ttl_ledgers) admin function with require_auth()
  • Add cleanup_expired_errors() function (admin or permissionless)
  • Update report_error to set expires_at based on configured TTL
  • Extend TTL for error entries on access (like agent records)
  • Add gas budget estimation for cleanup operations
  • Add unit test: error expires after TTL
  • Add unit test: cleanup removes expired errors
  • Add unit test: non-admin cannot set TTL

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions