Skip to content

fix(spammer): reject too many exponential generators instead of overflowing#138

Open
Jr-kenny wants to merge 1 commit into
circlefin:mainfrom
Jr-kenny:fix/exponential-partition-shift-overflow
Open

fix(spammer): reject too many exponential generators instead of overflowing#138
Jr-kenny wants to merge 1 commit into
circlefin:mainfrom
Jr-kenny:fix/exponential-partition-shift-overflow

Conversation

@Jr-kenny

Copy link
Copy Markdown

Fixes #137

Problem

The guard in partition_exponential that should reject more generators than the account space can hold computes 1 << (num_generators - 1) before checking whether that exponent even fits in the word. Once num_generators - 1 reaches 64 the shift itself overflows, so the friendly "too many generators" bail never gets to fire. Full walkthrough in the issue.

What that looks like on current main with partition_accounts(130, 65):

  • Debug build: panic at accounts.rs:103 with "attempt to shift left with overflow"
  • Release build: the shift distance wraps and the input sails through the guard. The partition comes back as Ok with garbage:
[(0, 130), (130, 0), (0, 0), (0, 0), ... 50+ empty ranges ..., (0, 1), (1, 1), (1, 2), (2, 4), ..., (65, 130)]

The first generator gets all 130 accounts, the second gets an inverted range, and the tail ranges all overlap the first one, so generators collide on the same accounts and nonces.

Fix

Short-circuit the guard on the shift width. Once the exponent reaches the word size, 2^(num_generators - 1) already exceeds any possible num_accounts, so the smallest bucket is empty and bailing is the right answer anyway:

let shift = num_generators - 1;
if shift >= usize::BITS as usize || round_div(num_accounts, 1 << shift) == 0 {
    eyre::bail!("too many generators: it would result in a bucket with size 0");
}

This also keeps the boundary loop below safe, since it can no longer be reached with an out-of-range exponent.

Testing

  • Added a regression test next to the existing partition tests covering (130, 65) and (200, 100), both now return the same graceful error as smaller over-subscriptions like (100, 9)
  • The repro panics on main and passes with this change, existing partition tests still pass
  • fmt and clippy clean

…lowing

The guard in partition_exponential that should reject more generators than
the account space can hold computes 1 << (num_generators - 1). Once that
exponent reaches the word size the shift overflows, so the guard panics in
debug builds and silently passes (with wrapped denominators) in release,
producing garbage account ranges. Short-circuit on the shift width so the
bail fires cleanly, and add a regression test.
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.

bug: spammer partition_exponential panics on shift overflow instead of rejecting too many generators

1 participant