Skip to content

feat: implement subscription metadata storage and limits - #804

Closed
johnbiliyaminu-bit wants to merge 1 commit into
Stellabill:mainfrom
johnbiliyaminu-bit:feat/metadata-impl
Closed

johnbiliyaminu-bit wants to merge 1 commit into
Stellabill:mainfrom
johnbiliyaminu-bit:feat/metadata-impl

Conversation

@johnbiliyaminu-bit

@johnbiliyaminu-bit johnbiliyaminu-bit commented Aug 29, 2026

Copy link
Copy Markdown

Closes #790


Summary

Replaces stub metadata functions in contracts/subscription_vault with a fully working bounded persistent storage implementation.

Closes #(issue number for this metadata task)

What changed

File Change
contracts/Cargo.toml Workspace root for the Soroban contract
contracts/subscription_vault/Cargo.toml soroban-sdk 27.0.6 dependency
contracts/subscription_vault/src/lib.rs DataKey, Subscription, ContractError types; SubscriptionVault contract with register_subscription + metadata dispatch
contracts/subscription_vault/src/metadata.rs Full implementation of set_metadata, get_metadata, delete_metadata, list_metadata_keys
contracts/subscription_vault/src/test.rs 35 tests
docs/subscription_metadata.md Complete API contract document

Acceptance criteria addressed

  • Bounded persistent storageMap<Bytes, Bytes> stored under DataKey::Metadata(subscription_id) in persistent storage. Each subscription is independent.
  • Limits enforced (byte lengths)MAX_METADATA_KEYS = 10, MAX_METADATA_KEY_LENGTH = 32, MAX_METADATA_VALUE_LENGTH = 256. Updating an existing key at capacity is allowed; only new inserts are capped.
  • EventsMetadataSetEvent and MetadataDeletedEvent emitted via the #[contractevent] macro on every successful write/delete, each carrying subscription_id, key, and timestamp.
  • Authcaller must be the registered subscriber or merchant. Outsiders are rejected before require_auth runs. Read operations are unrestricted.
  • Documenteddocs/subscription_metadata.md covers limits, error codes, auth model, events, storage layout, failure modes, and backward-compatibility notes.

Security and failure-mode notes

  • Auth check compares caller to stored addresses before calling require_auth, so invalid callers never consume auth budget.
  • All error codes are stable numeric constants; new variants must use unused numbers.
  • list_metadata_keys returns an empty Vec (not an error) for unknown subscriptions so read-only callers don't need to handle SubscriptionNotFound.
  • Freed slots (after delete) are immediately reusable — delete-then-re-add works correctly.

Test results

cargo test --all
test result: ok. 35 passed; 0 failed; 0 ignored
Category Tests
Happy paths (set/get/delete/list by subscriber and merchant) 5
Boundary validation (key 31/32/33 bytes, value 255/256/257 bytes, 10th/11th key) 10
Authorization (outsider rejected, merchant accepted) 4
Subscription not found (set + delete on unregistered) 2
Missing key (get + delete + double-delete) 3
Event emission (MetadataSetEvent + MetadataDeletedEvent) 2
Subscription isolation 1
Capacity management (fill/free/refill, duplicate=update) 4
Concurrency simulation 1
Backward compatibility (list on unknown sub) 1
Regression 2

Replace stub metadata functions with bounded persistent storage.

Changes:
- contracts/Cargo.toml: workspace root for subscription_vault contract
- contracts/subscription_vault/Cargo.toml: soroban-sdk 27.0.6 dependency
- contracts/subscription_vault/src/lib.rs: DataKey, Subscription, ContractError
  types and SubscriptionVaultClient with register_subscription + metadata
  dispatch functions
- contracts/subscription_vault/src/metadata.rs: full implementation of
  set_metadata, get_metadata, delete_metadata, list_metadata_keys backed by
  persistent Map<Bytes, Bytes>; enforces MAX_METADATA_KEYS=10,
  MAX_METADATA_KEY_LENGTH=32, MAX_METADATA_VALUE_LENGTH=256 (byte lengths);
  emits MetadataSetEvent and MetadataDeletedEvent via #[contractevent] macro;
  requires subscriber-or-merchant auth
- contracts/subscription_vault/src/test.rs: 35 tests covering happy paths,
  boundary inputs (31/32/33-byte keys, 255/256/257-byte values), 10th/11th
  key cap, delete-frees-slot, update-does-not-count, outsider rejection,
  merchant access, subscription isolation, event emission, double-delete
- docs/subscription_metadata.md: API contract with limits, error codes,
  auth model, events, storage design, failure modes, and test coverage table
- contracts/.gitignore: exclude build artifacts

All 35 tests pass: cargo test --all (soroban-sdk 27.0.6)
@johnbiliyaminu-bit

Copy link
Copy Markdown
Author

closes #790

@johnbiliyaminu-bit
johnbiliyaminu-bit deleted the feat/metadata-impl branch August 29, 2026 10:19
@johnbiliyaminu-bit
johnbiliyaminu-bit restored the feat/metadata-impl branch August 29, 2026 10:20
@johnbiliyaminu-bit
johnbiliyaminu-bit deleted the feat/metadata-impl branch August 29, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add gzip-bomb and oversize-body rejection tests for request_size middleware

1 participant