Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions .github/workflows/tests-rs-wallet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,30 @@ jobs:
--locked \
-- --no-deps -D warnings

# Mirrors the workspace job's non-shielded step for the wallet crates:
# same package subset, same `not test(~shield)` filter (shielded wallet
# tests are not run there either).
- name: Run wallet tests (non-shielded)
# No test filter: this job runs everything in the three wallet packages,
# shielded suite included. There is nothing here worth excluding —
# `wallet::shielded::` is 145 tests in ~6 s wall (~97 s of CPU) under
# nextest, and `--all-features` compiles those binaries whether or not
# they are selected, so skipping them saved execution time on artifacts
# already paid for and thrown away.
#
# This job and tests-rs-workspace.yml are mutually exclusive paths for a
# given PR, so the shielded suite has to run in BOTH or a wallet-scoped
# PR silently loses it. The workspace job carves the wallet packages out
# of its own shield exclusion for the same reason.
#
# `--no-tests fail` is the zero-match guard: a selection that matches
# nothing must fail the step, not pass green. Pinned rather than left to
# nextest's default, which is a default and not a promise.
- name: Run wallet tests
run: |
cargo nextest run \
--package platform-wallet \
--package platform-wallet-storage \
--package platform-wallet-ffi \
--all-features \
--locked \
-E 'not test(~shield)'
--no-tests fail
env:
RUST_MIN_STACK: 4194304
CARGO_PROFILE_DEV_DEBUG: "0"
Expand Down
21 changes: 20 additions & 1 deletion .github/workflows/tests-rs-workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,20 @@ jobs:
# caught minutes after merge — the same safety-net pattern as the
# shielded phase. Keeping this phase's filter identical across events
# keeps the `rust` codecov flag comparable between PR and push runs.
#
# `test(~shield)` is a substring match on the FULL test path, so it does
# not mean "the shielded suites" — it means "anything with the word in
# its name". The shielded phase below compensates for dpp / drive /
# drive-abci / dash-sdk, which genuinely need it: they are Orchard
# proving tests, and that phase runs them under `cargo test` in a shared
# process so one verifying key is built instead of one per test.
#
# The three wallet packages have no such compensator and no such need —
# their whole `wallet::shielded::` suite is 145 tests in ~6 s under
# nextest's process-per-test model — so excluding them dropped 145
# shielded tests plus ~47 more that merely contain the word (input
# selection, FFI error codes, memo encoding, SQLite viewing-key rows)
# into a gap no job covered. They are carved out of the exclusion here.
- name: Run non-shielded tests with nextest (parallel, compiles all packages)
if: steps.coverage-cache.outputs.reuse == 'false'
run: |
Expand Down Expand Up @@ -352,7 +366,8 @@ jobs:
--package keyword-search-contract \
--all-features \
--locked \
-E 'not test(~shield) and (not binary_id(=drive-abci::strategy_tests) or test(~comprehensive_mixed_operations))'
--no-tests fail \
-E '(not test(~shield) or package(platform-wallet) or package(platform-wallet-storage) or package(platform-wallet-ffi)) and (not binary_id(=drive-abci::strategy_tests) or test(~comprehensive_mixed_operations))'
env:
RUST_MIN_STACK: 4194304
CARGO_PROFILE_DEV_DEBUG: "0"
Expand All @@ -370,6 +385,9 @@ jobs:
# The chain simulations excluded from the phase above. PR runs skip
# them (and upload no rust-strategy coverage — codecov carries the base
# commit's forward); push, nightly, and dispatch runs execute them all.
# The `~shield` exclusion here IS compensated — drive-abci is in the
# shielded phase below — so it stays; `--no-tests fail` is the guard
# against the whole expression silently selecting nothing.
- name: Run full chain-simulation suite (push and nightly only)
id: strategy-tests
if: >-
Expand All @@ -380,6 +398,7 @@ jobs:
--package drive-abci \
--all-features \
--locked \
--no-tests fail \
-E 'binary_id(=drive-abci::strategy_tests) and not test(~comprehensive_mixed_operations) and not test(~shield)'
env:
RUST_MIN_STACK: 4194304
Expand Down
25 changes: 14 additions & 11 deletions packages/rs-platform-wallet/src/wallet/platform_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2303,23 +2303,24 @@ mod shield_input_selection_tests {

#[test]
fn regression_reports_max_from_usable_suffix_not_total_account_balance() {
// Real account snapshot: the leading address is below the reserve, so
// Account snapshot whose leading address cannot pay the fee, so
// capacity must come from the usable suffix, not the account total.
assert!(
297_264_780 <= reserve(),
"regression shape requires the leading address to stay below the reserve; \
re-seed the balances if the versioned reserve drops under 297_264_780"
);
// The leading balance is derived from the reserve — one credit below
// the strict `> reserve` viability threshold, the largest balance that
// must still be rejected as input 0 — so the shape holds whatever the
// versioned fee schedule does next.
let dust = reserve() - 1;
let usable = 3_623_849_220;
let candidates = vec![
(addr(1), 297_264_780),
(addr(1), dust),
(addr(2), 2_000_000_000),
(addr(3), 1_623_849_220),
];
let plan = plan(candidates).unwrap();
let expected_max = 3_623_849_220 - reserve();
let expected_max = usable - reserve();

assert_eq!(plan.preflight.account_balance_credits, 3_921_114_000);
assert_eq!(plan.preflight.usable_balance_credits, 3_623_849_220);
assert_eq!(plan.preflight.account_balance_credits, dust + usable);
assert_eq!(plan.preflight.usable_balance_credits, usable);
assert_eq!(plan.preflight.fee_reserve_credits, reserve());
assert_eq!(plan.preflight.max_shieldable_credits, expected_max);
assert!(plan.preflight.can_shield);
Expand All @@ -2329,11 +2330,13 @@ mod shield_input_selection_tests {
assert!(!chosen.contains_key(&addr(1)));
assert_eq!(chosen.values().sum::<u64>(), expected_max);

// `available` reports the usable suffix, never the account total —
// the whole point of the regression.
let err = plan.select_inputs(expected_max + 1).unwrap_err();
assert!(matches!(
err,
PlatformWalletError::PlatformShieldCapacityExceeded { available, required }
if available == 3_623_849_220 && required == 3_623_849_221
if available == usable && required == usable + 1
));
}

Expand Down
Loading