learn-token: storage size tracking, plus edge-case coverage for per-address minting, claim history, and pause - #373
Merged
DeFiVC merged 5 commits intoAug 30, 2026
Conversation
storage.rs defined is_paused/set_paused twice with identical bodies -- once under the original Emergency Pause section (ChainLearnOfficial#189) and again under the pause-events section (ChainLearnOfficial#238), added by two PRs merged back to back without either noticing the other had already added the same pair. Rust rejects the duplicate definitions (E0428), so main currently fails to build. Keep the original definitions and drop the redundant pair; both events and pause/unpause logic already call through the one storage.rs API surface, so nothing else changes.
PR ChainLearnOfficial#365 added Minter/Pauser role checks to mint(), pause(), and unpause(), giving each an extra caller: Address parameter, and updated the call sites that existed at the time. It landed back to back with two other PRs (ChainLearnOfficial#363, ChainLearnOfficial#366) that added their own tests calling the pre-refactor 2-and-0-argument signatures, or referencing an admin binding some of those same tests never captured (destructured as _ or _admin because they didn't need it before). None of the three PRs conflicted at the git-diff level, so all three merged cleanly and the test suite has been failing to compile since. Capture admin from setup() wherever a fixed test now needs it as the mint/pause/unpause caller, and fix one unrelated pre-existing get_proposal(prop_id) call that needed a borrow. No behavioral changes -- cargo test -p learn-token now compiles and all 63 tests pass.
Soroban prices persistent storage by entry count and size but gives a contract no host API to enumerate or count its own keys, so there is currently no way to answer "how much storage is this contract using" short of an off-chain state export. Add get_storage_size(), backed by a StorageEntryCount counter that storage.rs increments/decrements around every write to a per-entity key -- reward claims, claim history, roles, whitelist entries, snapshots, vesting schedules and claimed amounts, proposals, votes, allowance-spender registries, permit nonces, and per-address minting totals -- guarded by a has() check so overwriting an existing entry never double-counts it. Deliberately excluded: singleton config (admin, name/symbol/decimal, total/max supply, metadata, transfer restriction, wasm hash, upgrade version, paused flag, proposal counter) since those don't grow with usage, and Balance/Allowance since balances are written on every transfer/mint/burn (the issue's "no performance impact" criterion argues against adding a has() check to that path) and allowances live in temporary rather than persistent storage. Closes ChainLearnOfficial#254
…tory, and pause total_minted_to() (ChainLearnOfficial#251), get_claim_history() (ChainLearnOfficial#252), and pause/unpause (ChainLearnOfficial#253) were already implemented and tested on main (merged in ChainLearnOfficial#363 for near-duplicate issues ChainLearnOfficial#236/ChainLearnOfficial#237/ChainLearnOfficial#238, before this repo's issue numbers ChainLearnOfficial#251-253 were filed against the same scope). Add the edge cases their existing coverage didn't reach: - total_minted_to: a zero-amount mint is allowed (only negative amounts are rejected) and should leave the queryable total at 0. - get_claim_history: existing tests only covered multiple quizzes within one course; verify records also stay correctly distinguished by course_id when a learner claims across different courses. - pause: existing coverage only exercised transfer and mint; burn, claim_reward, and claim_vested are also gated by require_not_paused() and hadn't been exercised while paused. Closes ChainLearnOfficial#251, Closes ChainLearnOfficial#252, Closes ChainLearnOfficial#253
|
@bbjiggy 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! 🚀 |
iduhtheman
added a commit
to iduhtheman/chainlearn-contracts
that referenced
this pull request
Aug 30, 2026
…laim_record A duplicate closing brace after append_claim_record's own closing brace broke parsing for the entire learn-token crate, and therefore the whole workspace (root-level integration tests depend on every workspace member). Pre-existing on upstream/main since ChainLearnOfficial#373; needed as a prerequisite to build and test anything in this workspace.
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
get_storage_size()tolearn-token, backed by a counter that tracks the number of persistent entries the contract has created (net of removals), so storage costs can be monitored and forecast on-chain (. Add storage size tracking #254).maincurrently fails to build and its test suite fails to compile — both unrelated to this work but blocking any verification. Fixed both as prerequisite commits (details below).total_minted_to(),get_claim_history(), andpause/unpausewith edge cases their existing tests didn't reach (. Add token supply tracking by address #251, . Add reward claiming history #252, . Add contract pause events #253). Note: the core functionality for these three was already implemented and tested onmainvia feat: course content hash, per-address minting, claim history, pause events #363, which closed near-duplicate issues . Add token supply tracking by address #236/. Add reward claiming history #237/. Add contract pause events #238 covering the same scope before . Add token supply tracking by address #251-253 were filed.Details
Prerequisite fixes (both pre-existing on
main, unrelated to #251-254):storage.rsdefinedis_paused/set_pausedtwice — once from the original Emergency Pause PR (Feat/implement missing features #365) and again from the pause-events PR (feat: course content hash, per-address minting, claim history, pause events #363) — merged back to back without either noticing the other had added the same pair. Rust rejects this (E0428), somaindoesn't compile. Removed the redundant pair.mint(),pause(), andunpause()(an extracaller: Addressparam), and updated the call sites that existed at the time. It landed back to back with two other PRs (feat: course content hash, per-address minting, claim history, pause events #363, feat: governance voting, token vesting, permit gasless approval, and … #366) whose tests called the pre-refactor signatures or referenced anadminbinding they never captured. None of the three PRs conflicted at the diff level, so all merged cleanly andcargo test -p learn-tokenhas been failing to compile since. Fixed the affected call sites; no behavioral changes.get_storage_size()(#254): increments/decrements around every write to a per-entity persistent key (reward claims, claim history, roles, whitelist, snapshots, vesting schedules/claims, proposals, votes, allowance-spender registries, permit nonces, per-address minting totals), guarded by ahas()check so overwrites never double-count. Deliberately excludes singleton config (doesn't grow with usage) andBalance/Allowance(hottest write paths / temporary storage — see commit message for the full rationale).Edge-case tests (#251, #252, #253): zero-amount mint leaves
total_minted_toat 0 (only negative amounts are rejected); claim history stays correctly distinguished bycourse_idacross different courses; pause blocksburn,claim_reward, andclaim_vestedin addition to the already-testedtransfer/mint.Test plan
cargo test -p learn-token— 78 passed, 0 failedcargo test --workspace— all crates passcargo build --workspace— clean (one pre-existing, unrelated dead-code warning)Closes #251, Closes #252, Closes #253, Closes #254