test(token): cover storage collisions during initialization - #650
Open
Rufai-Ahmed wants to merge 1 commit into
Open
test(token): cover storage collisions during initialization#650Rufai-Ahmed wants to merge 1 commit into
Rufai-Ahmed wants to merge 1 commit into
Conversation
Adds a test-only module proving initialization cannot alias a storage slot. Covers re-initialization leaving every slot intact, the frozen set of DataKey slot names, the DataKey::Admin / AdminKey::Admin cross-module alias, and the instance/persistent namespace split. Closes BCPathway#486
|
@Rufai-Ahmed 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! 🚀 |
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.
Closes #486
What this adds
contracts/token/src/storage_collisions.rs, a test-only module with 9 tests proving that initializingBcForgeTokencannot alias a storage slot. The only production change is the one#[cfg(test)] mod storage_collisions;line inlib.rs.Coverage:
initializeis also called directly insideenv.as_contractbecause a failed client invocation has its storage rolled back by the host, so the client-only version of these assertions passes even against an implementation that overwrites everything before returning the error.initializewrites only its documented slots, enumerated across all four key enums in both the instance and persistent namespaces.DataKeykeys encode as the variant name plus arguments, so renaming a variant remaps a stored entry.DATA_KEY_SLOT_NAMESpins all 13 names against standalone literals, and the exhaustivedata_key_namematch makes adding or removing a variant a compile error.crate::DataKey::Adminandbc_forge_admin::AdminKey::Adminare the same instance slot, covered in both the read and the write direction.Symbolinto persistent storage viareentrancy_guard!, the one key family that is not a#[contracttype]enum.initializetakes no guard, which is why the role grant is its only persistent write.Verification
Every test was mutation-checked rather than assumed correct. Mutations applied to production code and confirmed to break the suite, then reverted:
has_adminre-init guard removed frominitializeinitializegutted to a no-opinitializealso writesDataKey::Treasuryinitializealso writes to persistent storageDataKey::Treasuryrenamed, identifiers propagatedAdminKey::AdminrenamedLifecycleKey::Pausedrenamed to collide withDataKey::Supplywrite_allowancebuildsAllowance(from, from)GuardExit::dropstops releasing the guardcargo test -p bc-forge-token41 passed,cargo fmt --all -- --checkclean,cargo clippy -p bc-forge-token --all-targets --all-features -- -D warningsclean.Two things worth your call, no code changed for either
contracts/token/src/lib.rs:46saysDataKey::PendingAdminis "retained to preserve storage discriminant order". A#[contracttype]enum key encodes as the variant name, not a discriminant, so reordering variants is safe and it is renaming that is dangerous. Verified: moving a variant's position produced a byte-identical ledger key. KeepingPendingAdmincosts nothing, but the stated reason is misleading.contracts/admin/src/lib.rsstates "The AdminKey enum is a distinct type from any other contract's DataKey enum, ensuring zero slot overlap". That is not true for the token:DataKey::AdminandAdminKey::Adminresolve to the same instance slot. The tests document the current behaviour rather than change it. The same unusedDataKey::Adminexists inwrapperandvesting.Both look like separate issues rather than drive-by edits here.