feat: end_campaign and permissionless update_status with auto-transition on expiry - #57
Merged
ayshadogo merged 2 commits intoAug 22, 2026
Conversation
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.
Summary
Implements #35 (stacked on #55 - contains that commit since upstream main's tests currently do not compile):
end_campaign(): creator-only early termination. Requires creator auth, rejects when frozen or when status is not Active/GoalReached, sets status toEnded, emitscampaign_ended. Does NOT touch the stored campaign end time (ending is not a failure mode, so no refund window starts) and does not block the final milestone release (release_milestonevalidates milestone state, not campaign status).update_status(): permissionless transition of an expired-but-still-Activecampaign toEnded, emittingcampaign_ended. Anyone may call it: deadline enforcement must not depend on creator cooperation, otherwise a passive creator could keep a dead campaign nominally Active and block downstream flows keyed off status. Idempotent no-op when not expired or already ended.donate()now triggers the sameActive -> Endedtransition (with event) when a donation arrives after the deadline, so the status can never remainActivepast expiry.soroban_sdk::testutils::Ledger/IntoValtrait imports to test.rs - without these the test target fails to compile with 9 pre-existing E0599 errors (present on main and on the feat: campaign lifecycle controls (cancel, extend deadline, status) #55 branch).update_status; idempotent re-call;update_statusbefore deadline is a no-op; post-deadline donation rejects withCampaignEndedand flips status to Ended.Tests
Windows cannot execute Soroban host tests (environmental fail-fast), validated with:
cargo +1.85.0 clippy -p campaign --features testutils --all-targets: compiles clean (0 errors; baseline branch had 9)cargo +1.85.0 fmt --check: cleanCloses #35