feat: implement vc-schema-registry contract #3#11
Conversation
Scaffolds the vc-schema-registry Soroban contract (initialize, register_schema, deprecate_schema, update_schema_uri, get_schema, schema_exists, admin, version), mirroring the vc-issuer-registry storage/error/event conventions. Adds the crate to the workspace. Closes ACTA-Team#3
📝 WalkthroughWalkthroughA new Changesvc-schema-registry Soroban contract
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
contracts/vc-schema-registry/src/storage.rs (1)
56-66: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd a persistent-TTL extension helper for schema reads.
write_schemaextends the persistent entry's TTL, but there is no equivalent helper for read paths. Pure-read access (get_schema,schema_exists) incontract.rsonly extends instance TTL, so a frequently-read but never-rewrittenSchemaRecordcan expire and be evicted. Consider adding a helper and calling it on reads.♻️ Proposed helper
pub fn read_schema(e: &Env, id: &Bytes) -> Option<SchemaRecord> { e.storage().persistent().get(&DataKey::Schema(id.clone())) } + +pub fn extend_schema_ttl(e: &Env, id: &Bytes) { + let key = DataKey::Schema(id.clone()); + if e.storage().persistent().has(&key) { + e.storage() + .persistent() + .extend_ttl(&key, PERSISTENT_TTL_THRESHOLD, PERSISTENT_TTL_EXTEND_TO); + } +}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@contracts/vc-schema-registry/src/storage.rs` around lines 56 - 66, The schema storage read path currently does not refresh persistent TTL, so frequently accessed SchemaRecord entries can still expire even when read often. Add a persistent-TTL extension helper in storage.rs alongside read_schema/write_schema, using the existing DataKey::Schema and TTL constants, and invoke it from the pure-read schema paths in contract.rs (such as get_schema and schema_exists) after successful reads. Keep write_schema behavior unchanged and reuse the new helper to centralize the persistent TTL refresh logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@contracts/vc-schema-registry/src/contract.rs`:
- Around line 95-105: The read helpers in `get_schema` and `schema_exists` only
refresh the instance TTL, so the persistent `Schema(id)` entry can still expire
on read-heavy paths. Update `contract::get_schema` and `contract::schema_exists`
to invoke the `extend_schema_ttl` helper from `storage.rs` whenever the schema
lookup succeeds, alongside the existing `extend_instance_ttl` call. Keep the
change localized to these read paths and use the existing `storage::read_schema`
/ `storage::has_schema` flow to locate the right spot.
In `@contracts/vc-schema-registry/src/lib.rs`:
- Around line 14-15: The crate declares a test module via `#[cfg(test)] mod
test;` but there is no matching `test.rs` or `test/mod.rs`, so the test build
will fail. Either add the missing backing test module for `test` in this crate,
or remove the `mod test;` declaration from `lib.rs` if it is not needed.
---
Nitpick comments:
In `@contracts/vc-schema-registry/src/storage.rs`:
- Around line 56-66: The schema storage read path currently does not refresh
persistent TTL, so frequently accessed SchemaRecord entries can still expire
even when read often. Add a persistent-TTL extension helper in storage.rs
alongside read_schema/write_schema, using the existing DataKey::Schema and TTL
constants, and invoke it from the pure-read schema paths in contract.rs (such as
get_schema and schema_exists) after successful reads. Keep write_schema behavior
unchanged and reuse the new helper to centralize the persistent TTL refresh
logic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0f7bfda0-a599-4e68-866c-581e20b88b09
📒 Files selected for processing (7)
Cargo.tomlcontracts/vc-schema-registry/Cargo.tomlcontracts/vc-schema-registry/src/contract.rscontracts/vc-schema-registry/src/error.rscontracts/vc-schema-registry/src/events.rscontracts/vc-schema-registry/src/lib.rscontracts/vc-schema-registry/src/storage.rs
| pub fn get_schema(e: Env, id: Bytes) -> SchemaRecord { | ||
| storage::extend_instance_ttl(&e); | ||
| storage::read_schema(&e, &id) | ||
| .unwrap_or_else(|| panic_with_error!(&e, ContractError::SchemaNotFound)) | ||
| } | ||
|
|
||
| /// Returns true if a schema with `id` is registered. | ||
| pub fn schema_exists(e: Env, id: Bytes) -> bool { | ||
| storage::extend_instance_ttl(&e); | ||
| storage::has_schema(&e, &id) | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Read paths don't refresh the schema entry TTL.
get_schema and schema_exists extend only the instance TTL, not the persistent Schema(id) entry. A read-heavy schema that is never rewritten can have its persistent entry expire. See the suggested extend_schema_ttl helper in storage.rs; call it here after a successful read.
♻️ Proposed change
pub fn get_schema(e: Env, id: Bytes) -> SchemaRecord {
- storage::extend_instance_ttl(&e);
- storage::read_schema(&e, &id)
- .unwrap_or_else(|| panic_with_error!(&e, ContractError::SchemaNotFound))
+ storage::extend_instance_ttl(&e);
+ storage::extend_schema_ttl(&e, &id);
+ storage::read_schema(&e, &id)
+ .unwrap_or_else(|| panic_with_error!(&e, ContractError::SchemaNotFound))
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@contracts/vc-schema-registry/src/contract.rs` around lines 95 - 105, The read
helpers in `get_schema` and `schema_exists` only refresh the instance TTL, so
the persistent `Schema(id)` entry can still expire on read-heavy paths. Update
`contract::get_schema` and `contract::schema_exists` to invoke the
`extend_schema_ttl` helper from `storage.rs` whenever the schema lookup
succeeds, alongside the existing `extend_instance_ttl` call. Keep the change
localized to these read paths and use the existing `storage::read_schema` /
`storage::has_schema` flow to locate the right spot.
| #[cfg(test)] | ||
| mod test; |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd -t f 'test.rs' contracts/vc-schema-registry/src
fd -t f 'mod.rs' contracts/vc-schema-registry/src/testRepository: ACTA-Team/contracts-acta-spikes
Length of output: 294
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== repo files ==\n'
git ls-files | rg '^contracts/vc-schema-registry/'
printf '\n== src tree ==\n'
fd -t f . contracts/vc-schema-registry/src
printf '\n== lib.rs ==\n'
cat -n contracts/vc-schema-registry/src/lib.rs
printf '\n== possible test module files ==\n'
fd -t f 'test.rs' contracts/vc-schema-registry
fd -t f 'mod.rs' contracts/vc-schema-registryRepository: ACTA-Team/contracts-acta-spikes
Length of output: 1196
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== repo files ==\n'
git ls-files | rg '^contracts/vc-schema-registry/'
printf '\n== src tree ==\n'
fd -t f . contracts/vc-schema-registry/src
printf '\n== lib.rs ==\n'
cat -n contracts/vc-schema-registry/src/lib.rs
printf '\n== possible test module files ==\n'
fd -t f 'test.rs' contracts/vc-schema-registry
fd -t f 'mod.rs' contracts/vc-schema-registryRepository: ACTA-Team/contracts-acta-spikes
Length of output: 1196
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== repo files ==\n'
git ls-files | rg '^contracts/vc-schema-registry/'
printf '\n== src tree ==\n'
fd -t f . contracts/vc-schema-registry/src
printf '\n== lib.rs ==\n'
cat -n contracts/vc-schema-registry/src/lib.rs
printf '\n== possible test module files ==\n'
fd -t f 'test.rs' contracts/vc-schema-registry
fd -t f 'mod.rs' contracts/vc-schema-registryRepository: ACTA-Team/contracts-acta-spikes
Length of output: 1196
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git ls-files | rg '^contracts/vc-schema-registry/src/(test\.rs|test/mod\.rs)$' || true
git ls-files | rg '^contracts/vc-schema-registry/src/lib\.rs$'Repository: ACTA-Team/contracts-acta-spikes
Length of output: 209
Add the backing test module or remove this declaration. #[cfg(test)] mod test; has no matching contracts/vc-schema-registry/src/test.rs or contracts/vc-schema-registry/src/test/mod.rs in this crate, so the test build will fail.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@contracts/vc-schema-registry/src/lib.rs` around lines 14 - 15, The crate
declares a test module via `#[cfg(test)] mod test;` but there is no matching
`test.rs` or `test/mod.rs`, so the test build will fail. Either add the missing
backing test module for `test` in this crate, or remove the `mod test;`
declaration from `lib.rs` if it is not needed.
Scaffolds the vc-schema-registry Soroban contract (initialize, register_schema, deprecate_schema, update_schema_uri, get_schema, schema_exists, admin, version), mirroring the vc-issuer-registry storage/error/event conventions. Adds the crate to the workspace.
Closes #3
Summary by CodeRabbit