Decompose monolithic lib.rs into feature modules - #185
Merged
ibrahimmosouf-png merged 2 commits intoJul 20, 2026
Merged
Conversation
Extract helpers from the monolithic lib.rs (~942 LOC) into dedicated feature modules, reducing lib.rs to ~175 LOC for the contract facade. New modules: - validation.rs: input validation, transition logic, asset resolution - reports.rs: campaign report building, refund calculation, analytics - docs/architecture.md: module tree and dependency documentation All existing tests (162) pass. No behavior changes. Closes OrbitChainLabs#97
2 tasks
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
…bs#121) Rebased onto the decomposed campaign crate (OrbitChainLabs#185): refresh_report_cache lives in reports.rs alongside build_campaign_report; the CachedReport key is appended after OrbitChainLabs#183's BlockedAsset at the DataKey tail. get_campaign_report recomputed from the campaign record, milestones, and counters on every call. The report is now cached in a single persistent entry, refreshed at the tail of every state-changing entrypoint (initialize, donate, claim_refund, end/cancel/extend, both releases; freeze/unfreeze and the asset block list excluded — none change a report field). New get_cached_report(env) serves it in one read, with a read-only compute fallback for pre-cache state. Tests assert the cache can never be observed stale across every transition, plus fallback and uninitialized cases. Closes OrbitChainLabs#121
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
…#119) Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key appended at the DataKey tail after CachedReport. donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>) recording each donor once per asset, in first-donation order. Dedup is O(1): a donor is appended only when their prior per-(donor, asset) amount is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and get_asset_donor_count(env, asset). Tests cover once-per-asset dedup, isolation between assets, order, every pagination window shape, and empty reads. Closes OrbitChainLabs#119
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185). Three insta snapshot tests pin the exact XDR ContractEvent shape of every lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock, cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI. Snapshots recorded once; any unreviewed change fails the build. Also removes the stale auto-generated campaign/test_snapshots/ folder and gitignores it — the insta snapshots are the reviewed event assertions. Closes OrbitChainLabs#115
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
…bs#121) Rebased onto the decomposed campaign crate (OrbitChainLabs#185): refresh_report_cache lives in reports.rs alongside build_campaign_report; the CachedReport key is appended after OrbitChainLabs#183's BlockedAsset at the DataKey tail. get_campaign_report recomputed from the campaign record, milestones, and counters on every call. The report is now cached in a single persistent entry, refreshed at the tail of every state-changing entrypoint (initialize, donate, claim_refund, end/cancel/extend, both releases; freeze/unfreeze and the asset block list excluded — none change a report field). New get_cached_report(env) serves it in one read, with a read-only compute fallback for pre-cache state. Tests assert the cache can never be observed stale across every transition, plus fallback and uninitialized cases. Closes OrbitChainLabs#121
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
…#119) Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key appended at the DataKey tail after CachedReport. donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>) recording each donor once per asset, in first-donation order. Dedup is O(1): a donor is appended only when their prior per-(donor, asset) amount is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and get_asset_donor_count(env, asset). Tests cover once-per-asset dedup, isolation between assets, order, every pagination window shape, and empty reads. Closes OrbitChainLabs#119
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185). Three insta snapshot tests pin the exact XDR ContractEvent shape of every lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock, cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI. Snapshots recorded once; any unreviewed change fails the build. Also removes the stale auto-generated campaign/test_snapshots/ folder and gitignores it — the insta snapshots are the reviewed event assertions. Closes OrbitChainLabs#115
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
…bs#121) Rebased onto the decomposed campaign crate (OrbitChainLabs#185): refresh_report_cache lives in reports.rs alongside build_campaign_report; the CachedReport key is appended after OrbitChainLabs#183's BlockedAsset at the DataKey tail. get_campaign_report recomputed from the campaign record, milestones, and counters on every call. The report is now cached in a single persistent entry, refreshed at the tail of every state-changing entrypoint (initialize, donate, claim_refund, end/cancel/extend, both releases; freeze/unfreeze and the asset block list excluded — none change a report field). New get_cached_report(env) serves it in one read, with a read-only compute fallback for pre-cache state. Tests assert the cache can never be observed stale across every transition, plus fallback and uninitialized cases. Closes OrbitChainLabs#121
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
…#119) Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key appended at the DataKey tail after CachedReport. donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>) recording each donor once per asset, in first-donation order. Dedup is O(1): a donor is appended only when their prior per-(donor, asset) amount is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and get_asset_donor_count(env, asset). Tests cover once-per-asset dedup, isolation between assets, order, every pagination window shape, and empty reads. Closes OrbitChainLabs#119
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 21, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185). Three insta snapshot tests pin the exact XDR ContractEvent shape of every lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock, cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI. Snapshots recorded once; any unreviewed change fails the build. Also removes the stale auto-generated campaign/test_snapshots/ folder and gitignores it — the insta snapshots are the reviewed event assertions. Closes OrbitChainLabs#115
2 tasks
ibrahimmosouf-png
pushed a commit
that referenced
this pull request
Jul 23, 2026
Rebased onto the decomposed campaign crate (#185): refresh_report_cache lives in reports.rs alongside build_campaign_report; the CachedReport key is appended after #183's BlockedAsset at the DataKey tail. get_campaign_report recomputed from the campaign record, milestones, and counters on every call. The report is now cached in a single persistent entry, refreshed at the tail of every state-changing entrypoint (initialize, donate, claim_refund, end/cancel/extend, both releases; freeze/unfreeze and the asset block list excluded — none change a report field). New get_cached_report(env) serves it in one read, with a read-only compute fallback for pre-cache state. Tests assert the cache can never be observed stale across every transition, plus fallback and uninitialized cases. Closes #121 Co-authored-by: merge-test <e2e@test.local>
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 23, 2026
…#119) Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key appended at the DataKey tail after CachedReport. donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>) recording each donor once per asset, in first-donation order. Dedup is O(1): a donor is appended only when their prior per-(donor, asset) amount is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and get_asset_donor_count(env, asset). Tests cover once-per-asset dedup, isolation between assets, order, every pagination window shape, and empty reads. Closes OrbitChainLabs#119
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 23, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185). Three insta snapshot tests pin the exact XDR ContractEvent shape of every lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock, cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI. Snapshots recorded once; any unreviewed change fails the build. Also removes the stale auto-generated campaign/test_snapshots/ folder and gitignores it — the insta snapshots are the reviewed event assertions. Closes OrbitChainLabs#115
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 23, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185). Three insta snapshot tests pin the exact XDR ContractEvent shape of every lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock, cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI. Snapshots recorded once; any unreviewed change fails the build. Also removes the stale auto-generated campaign/test_snapshots/ folder and gitignores it — the insta snapshots are the reviewed event assertions. Closes OrbitChainLabs#115
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 23, 2026
…#119) Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key appended at the DataKey tail after CachedReport. donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>) recording each donor once per asset, in first-donation order. Dedup is O(1): a donor is appended only when their prior per-(donor, asset) amount is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and get_asset_donor_count(env, asset). Tests cover once-per-asset dedup, isolation between assets, order, every pagination window shape, and empty reads. Closes OrbitChainLabs#119
neromtoobad
pushed a commit
to neromtoobad/OrbitChain-Contracts
that referenced
this pull request
Jul 23, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185). Three insta snapshot tests pin the exact XDR ContractEvent shape of every lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock, cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI. Snapshots recorded once; any unreviewed change fails the build. Also removes the stale auto-generated campaign/test_snapshots/ folder and gitignores it — the insta snapshots are the reviewed event assertions. Closes OrbitChainLabs#115
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
Implemented a production-ready fix while maintaining the existing architecture and coding standards.
Changes
lib.rs(~942 LOC) into feature modulesvalidation.rsfor input validation and transition logicreports.rsfor campaign report building and analyticsdocs/architecture.mddocumenting module tree and dependencieslib.rsto ~175 LOC (contract facade only)Closes #97