diff --git a/specs/phase0/beacon-chain.md b/specs/phase0/beacon-chain.md index bdfb078380..536bba3364 100644 --- a/specs/phase0/beacon-chain.md +++ b/specs/phase0/beacon-chain.md @@ -178,6 +178,7 @@ The following values are (non-configurable) constants used throughout the specif | Name | Value | | - | - | +| `MAX_UINT_64` | `uint64(2**64 - 1)` | | `GENESIS_SLOT` | `Slot(0)` | | `GENESIS_EPOCH` | `Epoch(0)` | | `FAR_FUTURE_EPOCH` | `Epoch(2**64 - 1)` | @@ -599,6 +600,8 @@ def integer_squareroot(n: uint64) -> uint64: """ Return the largest integer ``x`` such that ``x**2 <= n``. """ + if n == MAX_UINT_64: + return uint64(4294967295) x = n y = (x + 1) // 2 while y < x: diff --git a/tests/core/pyspec/eth2spec/test/phase0/unittests/math/__init__.py b/tests/core/pyspec/eth2spec/test/phase0/unittests/math/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/core/pyspec/eth2spec/test/phase0/unittests/math/test_integer_squareroot.py b/tests/core/pyspec/eth2spec/test/phase0/unittests/math/test_integer_squareroot.py new file mode 100644 index 0000000000..988de1657c --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/phase0/unittests/math/test_integer_squareroot.py @@ -0,0 +1,23 @@ +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)