Guard the lens draw's divisor directly (L1 c1.s1.f2)
The draw checked `draws()` over the map's values and then divided by a sum over `Lens::ALL`. Those were two computations that happened to agree: weakening the guard alone reached a modulo by zero. The draw now sums the total first and refuses a zero total, as `select_band` does; `draws()` stays the admission rule and no longer guards the draw. Builds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
1a402e1d45
commit
dfb3c52b01
1 changed files with 7 additions and 5 deletions
|
|
@ -186,7 +186,13 @@ pub(crate) fn draw(
|
|||
world_id: WorldId,
|
||||
command_id: CommandId,
|
||||
) -> Result<Lens, KernelError> {
|
||||
if !weights.draws() {
|
||||
// The guard is on the divisor itself, as `select_band`'s is: no other
|
||||
// statement of "these weights draw" can let the modulo below divide by zero.
|
||||
let total: u128 = Lens::ALL
|
||||
.iter()
|
||||
.map(|lens| u128::from(weights.get(*lens)))
|
||||
.sum();
|
||||
if total == 0 {
|
||||
return Err(KernelError::Invariant("lens weights never draw".into()));
|
||||
}
|
||||
let preimage = digest(&LensPreimage {
|
||||
|
|
@ -198,10 +204,6 @@ pub(crate) fn draw(
|
|||
.and_then(|hex| hex.get(..16))
|
||||
.and_then(|head| u64::from_str_radix(head, 16).ok())
|
||||
.ok_or_else(|| KernelError::Invariant("lens draw digest is not hex".into()))?;
|
||||
let total: u128 = Lens::ALL
|
||||
.iter()
|
||||
.map(|lens| u128::from(weights.get(*lens)))
|
||||
.sum();
|
||||
let mut position = u128::from(head) % total;
|
||||
for lens in Lens::ALL {
|
||||
let weight = u128::from(weights.get(lens));
|
||||
|
|
|
|||
Loading…
Reference in a new issue