nimbus-eth2/tests/test_bitseqs.nim
Jacek Sieka 867d8f3223
Perform attestation check before broadcast (#2550)
Currently, we have a bit of a convoluted flow where when sending
attestations, we start broadcasting them over gossip then pass them to
the attestation validation to include them in the local attestation pool
- it should be the other way around: we should be checking attestations
_before_ gossipping them - this serves as an additional safety net to
ensure that we don't publish junk - this becomes more important when
publishing attestations from the API.

Also, the REST API was performing its own validation meaning
attestations coming from REST would be validated twice - finally, the
JSON RPC wasn't pre-validating and would happily broadcast invalid
attestations.

* Unified attestation production pipeline with the same flow for gossip,
locally and API-produced attestations: all are now validated and entered
into the pool, then broadcast/republished
* Refactor subnet handling with specific SubnetId alias, streamlining
where subnets are computed, avoiding the need to pass around the number
of active validators
* Move some of the subnet handling code to eth2_network
* Use BitArray throughout for subnet handling
2021-05-10 09:13:36 +02:00

129 lines
2.3 KiB
Nim

{.used.}
import
unittest2,
strformat,
../beacon_chain/ssz/bitseqs,
./testutil
suite "Bit fields":
test "roundtrips BitArray":
var
a = BitArray[100]()
b = BitArray[100]()
check:
not a[0]
a.setBit 1
check:
not a[0]
a[1]
a + b == a
a - b == a
b + a == a
b - a == b # b is empty
b.setBit 2
check:
(a + b)[2]
(b - a)[2]
not (b - a)[1]
a.incl(b)
check:
not a[0]
a[1]
a[2]
a.clear()
check:
not a[1]
test "roundtrips BitSeq":
var
a = BitSeq.init(100)
b = BitSeq.init(100)
check:
not a[0]
a.isZeros()
a.setBit 1
check:
not a[0]
a[1]
a.countOnes() == 1
a.countZeros() == 99
not a.isZeros()
a.countOverlap(a) == 1
b.setBit 2
a.incl(b)
check:
not a[0]
a[1]
a[2]
a.countOverlap(a) == 2
a.countOverlap(b) == 1
b.countOverlap(a) == 1
b.countOverlap(b) == 1
a.clear()
check:
not a[1]
test "iterating words":
for bitCount in [8, 3, 7, 8, 14, 15, 16, 19, 260]:
checkpoint &"trying bit count {bitCount}"
var
a = BitSeq.init(bitCount)
b = BitSeq.init(bitCount)
bitsInWord = sizeof(uint) * 8
expectedWordCount = (bitCount div bitsInWord) + 1
for i in 0 ..< expectedWordCount:
let every3rdBit = i * sizeof(uint) * 8 + 2
a[every3rdBit] = true
b[every3rdBit] = true
for word in words(a):
check word == 4
word = 2
for wa, wb in words(a, b):
check wa == 2 and wb == 4
wa = 1
wb = 2
for i in 0 ..< expectedWordCount:
for j in 0 ..< bitsInWord:
let bitPos = i * bitsInWord + j
if bitPos < bitCount:
check a[j] == (j == 0)
check b[j] == (j == 1)
test "overlaps":
for bitCount in [1, 62, 63, 64, 91, 127, 128, 129]:
checkpoint &"trying bit count {bitCount}"
var
a = BitSeq.init(bitCount)
b = BitSeq.init(bitCount)
for pos in [4, 8, 9, 12, 29, 32, 63, 64, 67]:
if pos + 2 < bitCount:
a.setBit(pos)
b.setBit(pos + 2)
check:
not a.overlaps(b)
not b.overlaps(a)
a.countOverlap(b) == 0