Skip to content

fix: CI event checker, save_sub helper, vault-registry events test, c… - #149

Merged
Busiii-adetiba merged 1 commit into
SynapsVault:mainfrom
allhandghost:fix/issues-121-122-123-125
Oct 18, 2026
Merged

Busiii-adetiba merged 1 commit into
SynapsVault:mainfrom
allhandghost:fix/issues-121-122-123-125

Conversation

@allhandghost

@allhandghost allhandghost commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

…hangelog

Closes #121, #122, #123, #125

──────────────────────────────────────────────────────────────────── Issue #121 — CI check: contractevent topics vs docs/CONTRACTS.md ──────────────────────────────────────────────────────────────────── Problem
The event tables in docs/CONTRACTS.md had drifted from the
#[contractevent] definitions in the Rust source with no automated
guard to catch the difference. Any PR that added or renamed an event
could silently leave the docs stale, breaking downstream indexers
that rely on the documented topic strings.

Solution
scripts/check_events.py — a pure-Python script (no third-party deps,
no Rust toolchain required) that:
1. Scans each contract's src/lib.rs for every #[contractevent(topics = ["", ...])] annotation and collects the first (discriminator) topic string.
2. Parses the '### Events' table for each contract slug in docs/CONTRACTS.md and extracts the same discriminator strings from the backtick-quoted rows.
3. Computes a symmetric diff: topics in Rust but not in docs, and topics in docs but not in Rust.
4. Exits 0 when every topic matches, exits 1 with a clear error listing every mismatch.

Running the script on the existing repo immediately surfaced real
drift:
- vault-registry: "delist" and "retire" were defined in source but absent from the Events table.
- access-lease: "proposeadmin" and "acceptadmin" (added in a previous session for issue #42) were not reflected in docs.
- subscription: source emits "plan" but docs said "createplan"; docs listed "setprice" and "transfer" with no corresponding #[contractevent] in the source. All of these were corrected in docs/CONTRACTS.md as part of this PR.

.github/workflows/ci.yml — added a new 'check-events' job that runs
before lint and test. It requires only Python 3 (pre-installed on
ubuntu-latest) and no Rust build, so it fails fast and cheaply on
every PR.

Files changed

  • scripts/check_events.py
    ~ .github/workflows/ci.yml (new check-events job)
    ~ docs/CONTRACTS.md (event tables corrected for all 3 contracts)

──────────────────────────────────────────────────────────────────── Issue #122 — Factor save_sub helper in subscription/src/lib.rs ──────────────────────────────────────────────────────────────────── Problem
In subscription/src/lib.rs the pattern:
env.storage().persistent().set(&key, &sub);
env.storage().persistent().extend_ttl(&key, BUMP_THRESH, BUMP);
appeared verbatim three times — once each in subscribe(), renew(),
and cancel(). A future change to the TTL policy would require
updating all three sites consistently; missing one would silently
create an inconsistent archival window for that path.

Solution
Added a private helper on SubscriptionManager:
fn save_sub(env: &Env, key: &DataKey, sub: &Subscription)
modelled on vault-registry's existing save() helper (same pattern,
same rationale). The helper performs the set + extend_ttl pair in
one call. All three public entrypoints now call Self::save_sub()
instead of the inline pair, reducing duplication from 6 lines × 3
to 1 line × 3.

No observable behaviour change — the storage write and TTL bump are
identical; only the call site is consolidated.

Files changed
~ contracts/subscription/src/lib.rs
- added save_sub() to the private impl block
- subscribe(): replaced set+extend_ttl with save_sub()
- renew(): replaced set+extend_ttl with save_sub()
- cancel(): replaced set+extend_ttl with save_sub()

──────────────────────────────────────────────────────────────────── Issue #123 — Comprehensive events test for vault-registry ──────────────────────────────────────────────────────────────────── Problem
The existing events_have_documented_shape test in
contracts/vault-registry/src/test.rs only covered two event types:
'register' and 'setprice'. The contract emits 11 distinct events
(init, register, setprice, updmeta, settags, setlisted, delist,
proptrans, transfer, canceltrans, upgrade) and the remaining 9 were
completely untested, meaning wire-format regressions on those paths
would go undetected.

Solution
Replaced the partial test with a comprehensive events_have_documented_shape
test that exercises every event type emitted by vault-registry in a
single test function. Each contract call is immediately followed by
an assertion on env.events().all().filter_by_contract() that checks
both the topics tuple and the data value against the shapes
documented in docs/CONTRACTS.md. The upgrade event is tested last
because uploading the fixture WASM is itself a host call that would
interfere with earlier event assertions.

Events covered: init, register, setprice, updmeta, settags, delist,
setlisted, proptrans, canceltrans, transfer, upgrade (11/11).

Files changed
~ contracts/vault-registry/src/test.rs
- events_have_documented_shape replaced with full 11-event version

──────────────────────────────────────────────────────────────────── Issue #125 — CHANGELOG.md tracking interface and error-code changes ──────────────────────────────────────────────────────────────────── Problem
There was no file in the repository tracking what changed between
releases at the public-interface level. Operators upgrading contracts
had to diff the Rust source directly to find out whether an upgrade
involved any storage-layout, entrypoint, event, or error-code change
that required special handling.

Solution
Added CHANGELOG.md at the repo root following the Keep a Changelog
convention (https://keepachangelog.com/en/1.1.0/). The file:
- Documents what constitutes a MAJOR / MINOR / PATCH change for these contracts (breaking vs additive vs internal).
- Carries an [Unreleased] section that already records the interface additions made in this PR (propose_admin/accept_admin for access-lease, new error codes NoPendingAdmin/NotPendingAdmin) and any other additions made since 0.1.0.
- Carries a [0.1.0] section that lists the full initial public interface, storage keys, events, and error codes for all three contracts so the baseline is on record.
- Includes a note directing maintainers to update both CHANGELOG.md and docs/CONTRACTS.md in any PR that touches the public interface, reinforcing the existing docs/CONTRACTS.md note and the new CI check-events guard.

Closes #121,
closes #122,
closes #123,
closes #125

…hangelog

Closes SynapsVault#121, SynapsVault#122, SynapsVault#123, SynapsVault#125

────────────────────────────────────────────────────────────────────
Issue SynapsVault#121 — CI check: contractevent topics vs docs/CONTRACTS.md
────────────────────────────────────────────────────────────────────
Problem
  The event tables in docs/CONTRACTS.md had drifted from the
  #[contractevent] definitions in the Rust source with no automated
  guard to catch the difference. Any PR that added or renamed an event
  could silently leave the docs stale, breaking downstream indexers
  that rely on the documented topic strings.

Solution
  scripts/check_events.py — a pure-Python script (no third-party deps,
  no Rust toolchain required) that:
    1. Scans each contract's src/lib.rs for every
           #[contractevent(topics = ["<topic>", ...])]
       annotation and collects the first (discriminator) topic string.
    2. Parses the '### Events' table for each contract slug in
       docs/CONTRACTS.md and extracts the same discriminator strings
       from the backtick-quoted rows.
    3. Computes a symmetric diff: topics in Rust but not in docs, and
       topics in docs but not in Rust.
    4. Exits 0 when every topic matches, exits 1 with a clear error
       listing every mismatch.

  Running the script on the existing repo immediately surfaced real
  drift:
    - vault-registry: "delist" and "retire" were defined in source
      but absent from the Events table.
    - access-lease: "proposeadmin" and "acceptadmin" (added in a
      previous session for issue SynapsVault#42) were not reflected in docs.
    - subscription: source emits "plan" but docs said "createplan";
      docs listed "setprice" and "transfer" with no corresponding
      #[contractevent] in the source.
  All of these were corrected in docs/CONTRACTS.md as part of this PR.

  .github/workflows/ci.yml — added a new 'check-events' job that runs
  before lint and test. It requires only Python 3 (pre-installed on
  ubuntu-latest) and no Rust build, so it fails fast and cheaply on
  every PR.

Files changed
  + scripts/check_events.py
  ~ .github/workflows/ci.yml   (new check-events job)
  ~ docs/CONTRACTS.md          (event tables corrected for all 3 contracts)

────────────────────────────────────────────────────────────────────
Issue SynapsVault#122 — Factor save_sub helper in subscription/src/lib.rs
────────────────────────────────────────────────────────────────────
Problem
  In subscription/src/lib.rs the pattern:
      env.storage().persistent().set(&key, &sub);
      env.storage().persistent().extend_ttl(&key, BUMP_THRESH, BUMP);
  appeared verbatim three times — once each in subscribe(), renew(),
  and cancel(). A future change to the TTL policy would require
  updating all three sites consistently; missing one would silently
  create an inconsistent archival window for that path.

Solution
  Added a private helper on SubscriptionManager:
      fn save_sub(env: &Env, key: &DataKey, sub: &Subscription)
  modelled on vault-registry's existing save() helper (same pattern,
  same rationale). The helper performs the set + extend_ttl pair in
  one call. All three public entrypoints now call Self::save_sub()
  instead of the inline pair, reducing duplication from 6 lines × 3
  to 1 line × 3.

  No observable behaviour change — the storage write and TTL bump are
  identical; only the call site is consolidated.

Files changed
  ~ contracts/subscription/src/lib.rs
      - added save_sub() to the private impl block
      - subscribe(): replaced set+extend_ttl with save_sub()
      - renew():     replaced set+extend_ttl with save_sub()
      - cancel():    replaced set+extend_ttl with save_sub()

────────────────────────────────────────────────────────────────────
Issue SynapsVault#123 — Comprehensive events test for vault-registry
────────────────────────────────────────────────────────────────────
Problem
  The existing events_have_documented_shape test in
  contracts/vault-registry/src/test.rs only covered two event types:
  'register' and 'setprice'. The contract emits 11 distinct events
  (init, register, setprice, updmeta, settags, setlisted, delist,
  proptrans, transfer, canceltrans, upgrade) and the remaining 9 were
  completely untested, meaning wire-format regressions on those paths
  would go undetected.

Solution
  Replaced the partial test with a comprehensive events_have_documented_shape
  test that exercises every event type emitted by vault-registry in a
  single test function. Each contract call is immediately followed by
  an assertion on env.events().all().filter_by_contract() that checks
  both the topics tuple and the data value against the shapes
  documented in docs/CONTRACTS.md. The upgrade event is tested last
  because uploading the fixture WASM is itself a host call that would
  interfere with earlier event assertions.

  Events covered: init, register, setprice, updmeta, settags, delist,
  setlisted, proptrans, canceltrans, transfer, upgrade (11/11).

Files changed
  ~ contracts/vault-registry/src/test.rs
      - events_have_documented_shape replaced with full 11-event version

────────────────────────────────────────────────────────────────────
Issue SynapsVault#125 — CHANGELOG.md tracking interface and error-code changes
────────────────────────────────────────────────────────────────────
Problem
  There was no file in the repository tracking what changed between
  releases at the public-interface level. Operators upgrading contracts
  had to diff the Rust source directly to find out whether an upgrade
  involved any storage-layout, entrypoint, event, or error-code change
  that required special handling.

Solution
  Added CHANGELOG.md at the repo root following the Keep a Changelog
  convention (https://keepachangelog.com/en/1.1.0/). The file:
    - Documents what constitutes a MAJOR / MINOR / PATCH change for
      these contracts (breaking vs additive vs internal).
    - Carries an [Unreleased] section that already records the
      interface additions made in this PR (propose_admin/accept_admin
      for access-lease, new error codes NoPendingAdmin/NotPendingAdmin)
      and any other additions made since 0.1.0.
    - Carries a [0.1.0] section that lists the full initial public
      interface, storage keys, events, and error codes for all three
      contracts so the baseline is on record.
    - Includes a note directing maintainers to update both
      CHANGELOG.md and docs/CONTRACTS.md in any PR that touches the
      public interface, reinforcing the existing docs/CONTRACTS.md
      note and the new CI check-events guard.

Files changed
  + CHANGELOG.md
@drips-wave

drips-wave Bot commented Oct 18, 2026

Copy link
Copy Markdown

@allhandghost Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Busiii-adetiba
Busiii-adetiba merged commit 954348e into SynapsVault:main Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment