test(did-webvh): regression tests for same-second versionTime collision (#600) - #605
Merged
Merged
Conversation
…on (#600) The VTA creates its did:webvh at `vta setup` and updates it moments later (e.g. `services didcomm enable` patching in the DIDComm mediator service). did:webvh serialises versionTime at second granularity and requires each entry to be strictly later than the previous, so two entries minted in the same wall-clock second serialise identically and the DID resolves back to the genesis (REST-only) entry — the operator sees `services didcomm enable` report success and write config.toml, yet the published DID document still advertises REST only at version 1. PR #600 fixed this by backdating + index-spacing versionTime on the genesis-create and standard-update entries (`backdated_version_time`), but shipped with only manual end-to-end validation. This adds automated guards: - A did_webvh e2e test driving create -> didcomm-enable *back-to-back with no sleep* (every other e2e test dodges the bug by sleeping past the second boundary), asserting the chain still validates and advertises DIDCommMessaging at version 2. Neutering `backdated_version_time` makes it fail with the exact didwebvh-rs error ("Current versionTime must be greater than previous versionTime ... Log truncated at 2-..."). - A unit test pinning `backdated_version_time`'s contract: timestamps are in the past and strictly increasing by entry index at second precision. Reuses the shared `with_didcomm_service` patcher rather than hand-rolling a service-array edit. Bumps vta-service 0.10.18 -> 0.10.19. Claude-Session: https://claude.ai/code/session_01HoRff8BDqXuSfQ7RNjm3ic Signed-off-by: Glenn Gore <glenn@affinidi.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
Investigating the reported bug — offline
vta services didcomm enableupdates config but the VTA's did:webvh document keeps advertising REST only (versionId stays1-) — traced to the same-secondversionTimecollision, not an offline-vs-online split.services_cli::run_services_didcomm_enable→enable_didcomm→update_did_webvh) does reach the WebVH LogEntry publish step; it has since the op was written. It is not "returns after only writing config" —update_did_webvhruns first, then config.toml is written.vta setup) and the enable's update entry are minted in the same wall-clock second. did:webvh serialisesversionTimeat second granularity and requires each entry to be strictly later than the previous, so entry 2 collides.config.tomlstill gets written because the library stamps the entry without validating strict-increase at build time — the failure only surfaces when a client resolvesdid.jsonl, which truncates the log back to the version-1 REST-only state.pnm services didcomm enableand offlinevta …) — any create-then-update in the same second.mediator_urlfrom the report is not reproducible on current code:resolve_mediatorextracts the endpoint viaServiceEndpoint::get_uri()(clean string). It points at a double-encodedserviceEndpointon the mediator side, not a VTA config-writer bug.Already fixed on main
The bug is already fixed by PR #600 (
c73d9db, "backdate + space the VTA's webvh versionTime"), which landed after v0.10.11 (the build in the report). The user should upgrade to ≥ the build containing #600 (main is now 0.10.19). #600 backdates + index-spacesversionTimeon bothcreate_did_webvh(genesis) andupdate_did_webvh, viabackdated_version_time.What this PR adds
#600 shipped with only manual end-to-end validation and no automated regression test. This closes that gap:
create_then_didcomm_enable_back_to_back_resolves(did_webvh e2e): drives create → didcomm-enable with no sleep in between (every other e2e test in the module dodges the bug by sleeping past the second boundary), then asserts the chain validates and advertisesDIDCommMessagingat version 2. Temporarily neuteringbackdated_version_timemakes it fail with the exact didwebvh-rs error:Current versionTime (...) must be greater than previous versionTime (...). Log truncated at 2-...— proving it's a genuine guard, not a vacuous pass.backdated_version_time_is_past_and_strictly_increasing(unit): pins the helper's contract — timestamps are in the past and strictly increasing by entry index at second precision.Reuses the shared
with_didcomm_servicepatcher rather than hand-rolling a service-array edit (per workspace CLAUDE.md).Validation
cargo fmtcleancargo clippy -p vta-service --all-targets— no new warnings (2 pre-existing, unrelated, inprovision_integration/preconditions.rs)cargo test -p vta-service— all greenhttps://claude.ai/code/session_01HoRff8BDqXuSfQ7RNjm3ic