Skip to content

test: add adversarial cancel_issuer_transfer coverage (#1060) - #1

Closed
ASIDISG wants to merge 6 commits into
masterfrom
test/1060-cancel-issuer-transfer-coverage
Closed

ASIDISG wants to merge 6 commits into
masterfrom
test/1060-cancel-issuer-transfer-coverage

Conversation

@ASIDISG

@ASIDISG ASIDISG commented Sep 28, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a dedicated adversarial test suite for the issuer-side cancel of a pending issuer transfer (closes RevoraOrg#1060):

  • New module src/test_issuer_transfer_cancel.rs — 12 tests pinning cancel_issuer_transfer beyond the happy path:

    • Success: pending proposal is removed, exactly one iss_canc event is emitted carrying the (cancelling_issuer, cancelled_target) payload, the entry is consumed (second cancel → NoTransferPending), and the offering stays fully operational under the original issuer.
    • Typed rejections: unknown offering → OfferingNotFound; no pending proposal → NoTransferPending (including wrong-namespace binding and cancel-after-accept); frozen → ContractFrozen; paused → ContractPaused.
    • Unauthorized callers (observable Layer 2): cancel authenticates the primary issuer by identity before any require_auth, so a non-issuer caller observes the typed NotAuthorized/OfferingNotFound path catchable via try_* (see module docs for the auth-layer rationale).
    • State-unchanged after reject: every failed cancel leaves the pending proposal intact — the new issuer can still accept, and the issuer can still cancel once authorized/unpaused/unfrozen.
    • Expiry independence: only accept enforces the expiry window; cancel works long after the 7-day default window closes.
    • Isolation: cancelling one offering's proposal leaves a sibling proposal (same issuer+token, different namespace) untouched.
  • Compile/lint fixes to restored test modules (completes the quarantine-restoration series):

    • test_faucet_metrics.rs, test_indexer_fixtures.rs: topics.len() >= 1 → !topics.is_empty() (clippy len_zero), slice(before as u32..) → slice(before..), Vec::new(&env) → Vec::new(env), explicit RevoraRevenueShareClient<'_> return lifetime.

Verification

  • cargo check --all-targets ✅
  • cargo clippy --all-targets ✅ (no warnings)
  • cargo test --lib test_issuer_transfer_cancel — 12/12 passed ✅
  • Full suite: cargo test --lib — 307 passed, 0 failed ✅

🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com

ASIDISG and others added 6 commits September 28, 2026 04:49
The Aug-31 merge chain (RevoraOrg#858-RevoraOrg#864) left the crate unbuildable: src/lib.rs
was re-inflated from divergent branch points and thirteen test-support
files referenced APIs that no longer exist, while CI's `|| true` masking
kept the breakage invisible.

- Repair src/lib.rs, tax_bucket, vesting, and 12 test files so the lib
  and its tests compile against the current API surface; move the 13
  stale test files to src/quarantined/ (preserved verbatim) with a
  README documenting why and how to restore each one.
- Regenerate tools/storage_layout_schema.rs and docs/STORAGE_LAYOUT.json
  at layout_version 5 to match the contract constant, restoring the 49
  DataKey3 key annotations that had dropped out of the registry.
- Add gen_registry.py, an idempotent generator that derives both
  artifacts from the source enums; its LAYOUT_VERSION is the single
  source of truth kept in sync by tests/storage_layout_json.rs.
- Ignore __pycache__/.

cargo test: 209 passed, 0 failed; cargo fmt --check clean.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Move test_close_period.rs back out of src/quarantined/ (12 files remain)
and port it to the live contract surface so it compiles and passes again:

- Exercise preflight_close_period through the generated public client
  instead of the raw free-function call (client methods return the bare
  value, so no unwrap).
- Mint payment tokens via crate::test_utils with one canonical
  stellar-asset registration per test, replacing the old re-register
  mint hack that could land on a different asset address.
- Drop the legacy DeferredDataKey::DeferredReports flush suite: the live
  contract no longer reads that key (deferred distributions moved to the
  DataKey3::DeferredQueue priority queue, issue RevoraOrg#551) and the 2-arg
  close_period it called was a private test harness, not an entry point.
- Inline shuffle_vec_with_seed (proptest_helpers is still quarantined)
  and lift the Env budget for the 512-iteration preflight loop and the
  1000-holder CPU setup, which exceed the default cumulative budget.
- Adapt the dual-sig same-signer test: close_period_dual_sig requires
  auth on both signers before the distinctness check and the host
  rejects duplicate-signer authorization, so the DualSigSameSigner
  branch is unreachable via the public client; assert rejection plus an
  unsealed period instead.

Verified: 24/24 restored tests pass, the other 189 lib tests are
unaffected, integration targets stay green, cargo fmt --check clean.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Move test_deferred_priority.rs back out of src/quarantined/ (11 files
remain) and port it to the live API surface — the deferred-distribution
priority queue (issue RevoraOrg#551) it targets survived the merge chain, so the
port is small:

- Pass explicit None::<Address> / None::<bool> generics to initialize;
  the generated client can no longer infer bare &None arguments.
- Rewrite the deferred_priority_set event lookup as an index-based
  reverse scan: env.events().all() yields (Address, Vec<Val>, Val)
  tuples, topics.get(0) returns an Option (the quarantined
  `if let Ok(...)` pattern predates that change), and the soroban Vec
  iterator is not double-ended so `.iter().rev()` no longer compiles.
- Annotate the 50-entry stress loop index as u64 and cast the priority
  to u32; the original inferred i as both, which no longer type-checks.

Verified: 16/16 restored tests pass, the other 205 lib tests are
unaffected, integration targets stay green, cargo fmt --check clean.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
… the current API

Move the faucet test pair back from src/quarantined/ and port it to the
current client surface. Restoring the metrics tests surfaced a contract
regression: the Aug-31 merge chain dropped the fct_mtr1 emission helper
(fb12481, PR RevoraOrg#676) while its constant, storage counters, docs, and indexer
fixture survived, so the contract documented an event it never emitted.
Restore the emission with per-window counter rollover via the new
FaucetDataKey union (DataKey3 is at the 50-case XDR spec-union limit),
and register it in the storage-layout schema + docs/STORAGE_LAYOUT.json.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
The Aug-31 merge chain dropped `mod test_indexer_fixtures;` from lib.rs
(last present in 0acd0b5), leaving all 22 indexer-fixture tests — including
the fct_mtr1 event-shape fixtures guarding the emission restored in the
previous commit — silently uncompiled; CI's `|| true` masked this as well.
Re-declare the module and port the file to the current API: SDK-21 topic
comparisons via try_into_val instead of raw Val equality, destructuring of
the (v2, v3) tuple returned by get_indexer_fixture_topics, decoding of the
version-wrapped emit_v2_event payload, env.as_contract for cost-basis
seeding, and corrected tax_lt1 amount expectation (50% of the 100_000
deposit is 50_000, not 5_000).

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Pin cancel_issuer_transfer behavior beyond the happy path: iss_canc event
payload and entry consumption, typed rejections (OfferingNotFound,
NoTransferPending, ContractFrozen, ContractPaused, NotAuthorized),
state-unchanged guarantees after rejected cancels, expiry independence
(only accept enforces the window), and cross-offering isolation. Also
apply the current-API/lint fixes to the restored test_faucet_metrics and
test_indexer_fixtures modules so they compile warning-free.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

ASIDISG commented Sep 28, 2026

Copy link
Copy Markdown
Owner Author

Superseded by upstream PR RevoraOrg#1279 — this fork-local PR was opened by mistake.

@ASIDISG ASIDISG closed this Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add adversarial coverage for cancel_issuer_transfer in lib

1 participant