🎯 Objective
Add configurable storage size limits per agent to prevent unbounded persistent storage growth in the agent_registry Soroban contract.
📁 Files to Modify
| Action |
File Path |
Description |
| Modify |
smart-contracts/contracts/agent_registry/src/lib.rs |
Add max agent count, per-capability limits, and total_agents() read function |
📁 Reference Files
| File Path |
Purpose |
smart-contracts/contracts/agent_registry/src/lib.rs (line ~183) |
append_capability_index — unbounded Vec growth |
smart-contracts/contracts/agent_registry/src/lib.rs (line ~335) |
register_agent — where to add limit check |
smart-contracts/contracts/agent_registry/src/lib.rs (GasConfig) |
Pattern for admin-configurable params |
💥 Impact
- Each agent record costs persistent storage rent on Stellar
- Capability index
Vec<Symbol> grows without limit per capability
lookup_agents iterates the entire vector — expensive for large sets
- No way to know total agent count without full state scan
✅ Expected Implementation
1. Add Storage Config
#[contracttype]
pub struct StorageConfig {
pub max_agents: u32, // Global limit (0 = unlimited)
pub max_per_capability: u32, // Per-capability limit (0 = unlimited)
}
2. Add Storage Key
#[derive(Clone)]
pub enum DataKey {
// ... existing ...
StorageConfig, // ADD
TotalAgents, // ADD: counter for fast total_agents() reads
}
3. Add Validation in register_agent
pub fn register_agent(env: Env, record: AgentParams) -> Result<(), Error> {
// ... existing checks ...
// Check global limit
let config = get_storage_config(&env);
if config.max_agents > 0 {
let total = get_total_agents(&env);
if total >= config.max_agents {
return Err(Error::StorageLimitReached); // New error variant
}
}
// Check per-capability limit
if config.max_per_capability > 0 {
let cap_index = get_capability_index(&env, &record.capability);
if cap_index.len() >= config.max_per_capability {
return Err(Error::CapabilityLimitReached); // New error variant
}
}
// ... rest of registration ...
}
4. Add Read Function
pub fn total_agents(env: Env) -> u32 {
get_total_agents(&env)
}
pub fn get_storage_config(env: Env) -> StorageConfig {
env.storage()
.instance()
.get(&DataKey::StorageConfig)
.unwrap_or(StorageConfig { max_agents: 0, max_per_capability: 0 })
}
5. Add Admin Configuration
pub fn set_storage_config(env: Env, config: StorageConfig) {
let admin = get_admin(&env);
admin.require_auth();
env.storage().instance().set(&DataKey::StorageConfig, &config);
}
📁 Reference Patterns
| File Path |
Pattern |
smart-contracts/contracts/agent_registry/src/lib.rs (GasConfig) |
How admin-configurable params are stored |
smart-contracts/contracts/agent_registry/src/lib.rs (set_gas_config) |
Admin auth pattern |
✅ Acceptance Criteria
🎯 Objective
Add configurable storage size limits per agent to prevent unbounded persistent storage growth in the
agent_registrySoroban contract.📁 Files to Modify
smart-contracts/contracts/agent_registry/src/lib.rs📁 Reference Files
smart-contracts/contracts/agent_registry/src/lib.rs(line ~183)append_capability_index— unbounded Vec growthsmart-contracts/contracts/agent_registry/src/lib.rs(line ~335)register_agent— where to add limit checksmart-contracts/contracts/agent_registry/src/lib.rs(GasConfig)💥 Impact
Vec<Symbol>grows without limit per capabilitylookup_agentsiterates the entire vector — expensive for large sets✅ Expected Implementation
1. Add Storage Config
2. Add Storage Key
3. Add Validation in register_agent
4. Add Read Function
5. Add Admin Configuration
📁 Reference Patterns
smart-contracts/contracts/agent_registry/src/lib.rs(GasConfig)smart-contracts/contracts/agent_registry/src/lib.rs(set_gas_config)✅ Acceptance Criteria
StorageConfigstruct withmax_agentsandmax_per_capabilityDataKey::StorageConfigandDataKey::TotalAgentsstorage keystotal_agents()read-only functionget_storage_config()read-only functionset_storage_config(config)admin functionregister_agentfor global limitregister_agentsbatch for global limitStorageLimitReachedandCapabilityLimitReachederror variants