Skip to content

Commit

Permalink
Merge pull request #3600 from ethereum/integer_squareroot
Browse files Browse the repository at this point in the history
Handle `integer_squareroot` bound case
  • Loading branch information
hwwhww authored Feb 15, 2024
2 parents 2faa44b + e3d91d8 commit f82a3af
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 12 deletions.
3 changes: 3 additions & 0 deletions specs/phase0/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ The following values are (non-configurable) constants used throughout the specif

| Name | Value |
| - | - |
| `UINT64_MAX` | `uint64(2**64 - 1)` |
| `GENESIS_SLOT` | `Slot(0)` |
| `GENESIS_EPOCH` | `Epoch(0)` |
| `FAR_FUTURE_EPOCH` | `Epoch(2**64 - 1)` |
Expand Down Expand Up @@ -599,6 +600,8 @@ def integer_squareroot(n: uint64) -> uint64:
"""
Return the largest integer ``x`` such that ``x**2 <= n``.
"""
if n == UINT64_MAX:
return uint64(4294967295)
x = n
y = (x + 1) // 2
while y < x:
Expand Down
2 changes: 1 addition & 1 deletion tests/core/pyspec/eth2spec/test/helpers/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,4 @@
#
# Number
#
MAX_UINT_64 = 2**64 - 1
UINT64_MAX = 2**64 - 1
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import random
from math import isqrt
from eth2spec.test.context import (
spec_test,
single_phase,
with_all_phases,
)


@with_all_phases
@spec_test
@single_phase
def test_integer_squareroot(spec):
values = [0, 100, 2**64 - 2, 2**64 - 1]
for n in values:
uint64_n = spec.uint64(n)
assert spec.integer_squareroot(uint64_n) == isqrt(n)

rng = random.Random(5566)
for _ in range(10):
n = rng.randint(0, 2**64 - 1)
uint64_n = spec.uint64(n)
assert spec.integer_squareroot(uint64_n) == isqrt(n)

try:
spec.integer_squareroot(spec.uint64(2**64))
assert False
except ValueError:
pass
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
spec_state_test,
with_all_phases,
)
from eth2spec.test.helpers.constants import MAX_UINT_64
from eth2spec.test.helpers.constants import UINT64_MAX
from eth2spec.test.helpers.forks import (
is_post_altair, is_post_bellatrix,
)
Expand All @@ -16,9 +16,9 @@ def check_bound(value, lower_bound, upper_bound):
@with_all_phases
@spec_state_test
def test_validators(spec, state):
check_bound(spec.VALIDATOR_REGISTRY_LIMIT, 1, MAX_UINT_64)
check_bound(spec.MAX_COMMITTEES_PER_SLOT, 1, MAX_UINT_64)
check_bound(spec.TARGET_COMMITTEE_SIZE, 1, MAX_UINT_64)
check_bound(spec.VALIDATOR_REGISTRY_LIMIT, 1, UINT64_MAX)
check_bound(spec.MAX_COMMITTEES_PER_SLOT, 1, UINT64_MAX)
check_bound(spec.TARGET_COMMITTEE_SIZE, 1, UINT64_MAX)

# Note: can be less if you assume stricters bounds on validator set based on total ETH supply
maximum_validators_per_committee = (
Expand All @@ -30,24 +30,24 @@ def test_validators(spec, state):
check_bound(spec.config.MIN_PER_EPOCH_CHURN_LIMIT, 1, spec.VALIDATOR_REGISTRY_LIMIT)
check_bound(spec.config.CHURN_LIMIT_QUOTIENT, 1, spec.VALIDATOR_REGISTRY_LIMIT)

check_bound(spec.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, spec.TARGET_COMMITTEE_SIZE, MAX_UINT_64)
check_bound(spec.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, spec.TARGET_COMMITTEE_SIZE, UINT64_MAX)


@with_all_phases
@spec_state_test
def test_balances(spec, state):
assert spec.MAX_EFFECTIVE_BALANCE % spec.EFFECTIVE_BALANCE_INCREMENT == 0
check_bound(spec.MIN_DEPOSIT_AMOUNT, 1, MAX_UINT_64)
check_bound(spec.MAX_EFFECTIVE_BALANCE, spec.MIN_DEPOSIT_AMOUNT, MAX_UINT_64)
check_bound(spec.MAX_EFFECTIVE_BALANCE, spec.EFFECTIVE_BALANCE_INCREMENT, MAX_UINT_64)
check_bound(spec.MIN_DEPOSIT_AMOUNT, 1, UINT64_MAX)
check_bound(spec.MAX_EFFECTIVE_BALANCE, spec.MIN_DEPOSIT_AMOUNT, UINT64_MAX)
check_bound(spec.MAX_EFFECTIVE_BALANCE, spec.EFFECTIVE_BALANCE_INCREMENT, UINT64_MAX)


@with_all_phases
@spec_state_test
def test_hysteresis_quotient(spec, state):
check_bound(spec.HYSTERESIS_QUOTIENT, 1, MAX_UINT_64)
check_bound(spec.HYSTERESIS_QUOTIENT, 1, UINT64_MAX)
check_bound(spec.HYSTERESIS_DOWNWARD_MULTIPLIER, 1, spec.HYSTERESIS_QUOTIENT)
check_bound(spec.HYSTERESIS_UPWARD_MULTIPLIER, spec.HYSTERESIS_QUOTIENT, MAX_UINT_64)
check_bound(spec.HYSTERESIS_UPWARD_MULTIPLIER, spec.HYSTERESIS_QUOTIENT, UINT64_MAX)


@with_all_phases
Expand All @@ -68,7 +68,7 @@ def test_time(spec, state):
assert spec.SLOTS_PER_EPOCH <= spec.SLOTS_PER_HISTORICAL_ROOT
assert spec.MIN_SEED_LOOKAHEAD < spec.MAX_SEED_LOOKAHEAD
assert spec.SLOTS_PER_HISTORICAL_ROOT % spec.SLOTS_PER_EPOCH == 0
check_bound(spec.SLOTS_PER_HISTORICAL_ROOT, spec.SLOTS_PER_EPOCH, MAX_UINT_64)
check_bound(spec.SLOTS_PER_HISTORICAL_ROOT, spec.SLOTS_PER_EPOCH, UINT64_MAX)
check_bound(spec.MIN_ATTESTATION_INCLUSION_DELAY, 1, spec.SLOTS_PER_EPOCH)


Expand Down

0 comments on commit f82a3af

Please sign in to comment.