Skip to content

Commit

Permalink
Address review comments.
Browse files Browse the repository at this point in the history
Fix aggregated attestation scoring to use MAX_VALIDATORS_PER_COMMITTEE.
Fix sync committee contributions to use SYNC_SUBCOMMITTEE_SIZE.
Add getUniqueVotes test vectors.
  • Loading branch information
cheatfate committed Nov 7, 2023
1 parent 17a5457 commit 4774db1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 41 deletions.
46 changes: 20 additions & 26 deletions beacon_chain/validator_client/scoring.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import "."/common

{.push raises: [].}

type
CommitteeBitsArray = BitArray[int(MAX_VALIDATORS_PER_COMMITTEE)]
CommitteeTable = Table[CommitteeIndex, CommitteeBitsArray]

const
DefaultCommitteeTable =
default(Table[CommitteeIndex, CommitteeValidatorsBits])
DefaultCommitteeBits =
default(CommitteeValidatorsBits)
DefaultCommitteeTable = default(CommitteeTable)
DefaultCommitteeBitsArray = default(CommitteeBitsArray)

func perfectScore*(score: float64): bool =
score == Inf
Expand Down Expand Up @@ -73,7 +75,7 @@ proc getAggregatedAttestationDataScore*(
adata: GetAggregatedAttestationResponse
): float64 =
let
length = len(adata.data.aggregation_bits)
length = int(MAX_VALIDATORS_PER_COMMITTEE)
ones = countOnes(adata.data.aggregation_bits)
res = if length == ones: Inf else: float64(ones) / float64(length)

Expand All @@ -85,7 +87,7 @@ proc getSyncCommitteeContributionDataScore*(
cdata: ProduceSyncCommitteeContributionResponse
): float64 =
let
length = len(cdata.data.aggregation_bits)
length = int(SYNC_SUBCOMMITTEE_SIZE)
ones = countOnes(cdata.data.aggregation_bits)
res = if length == ones: Inf else: float64(ones) / float64(length)

Expand Down Expand Up @@ -133,34 +135,26 @@ proc getSyncCommitteeMessageDataScore*(
getSyncCommitteeMessageDataScore(
vc.rootsSeen, vc.beaconClock.now().slotOrZero(), cdata)

proc processVotes(bits: var CommitteeValidatorsBits,
attestation: Attestation): uint64 =
var res = 0'u64
proc processVotes(bits: var CommitteeBitsArray,
attestation: Attestation): int =
doAssert(len(attestation.aggregation_bits) <= len(bits))
var res = 0
for index in 0 ..< len(attestation.aggregation_bits):
if attestation.aggregation_bits[index]:
if not(bits[index]):
inc(res)
bits[index] = true
res

proc getUniqueVotes*(attestations: openArray[Attestation]): uint64 =
proc getUniqueVotes*(attestations: openArray[Attestation]): int =
var
res = 0'u64
attested: Table[Slot, Table[CommitteeIndex, CommitteeValidatorsBits]]
res = 0
attested: Table[Slot, CommitteeTable]
for attestation in attestations:
let
data = attestation.data
count =
attested.mgetOrPut(data.slot, DefaultCommitteeTable).
mgetOrPut(CommitteeIndex(data.index), DefaultCommitteeBits).
processVotes(attestation)
let count =
attested.mgetOrPut(attestation.data.slot, DefaultCommitteeTable).
mgetOrPut(CommitteeIndex(attestation.data.index),
DefaultCommitteeBitsArray).
processVotes(attestation)
res += count
res

proc getAttestationVotes*(response: ProduceBlockResponseV2): int =
withBlck(response):
let count = getUniqueVotes(distinctBase(blck.body.attestations))

proc getBlockProposalScore*(bdata: ProduceBlockResponseV2): float64 =
let data = getAttestationVotes(bdata)
float64(data)
46 changes: 31 additions & 15 deletions tests/test_validator_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ type
target: uint64
]

AttestationBitsObject* = object
AttestationBitsObject = object
data: CommitteeValidatorsBits

SyncCommitteeBitsObject* = object
SyncCommitteeBitsObject = object
data: SyncCommitteeAggregationBits

const
Expand Down Expand Up @@ -220,14 +220,13 @@ const
]

AggregatedDataVectors = [
("0xff00000001", "0.2500"),
("0xffff000001", "0.5000"),
("0xffffff0001", "0.7500"),
("0xffffffff01", "<perfect>"),
("0xfffffff701", "0.9688"),
("0xffffefdf01", "0.9375")
("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01", "<perfect>"),
("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0.2500"),
("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0.5000"),
("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0.7500"),
("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01", "0.9995"),
("0x0101", "0.0005"),
]

ContributionDataVectors = [
("0xffffffffffffffffffffffffffff7f7f", "0.9844"),
("0xffffffffffffffffffffffff7f7f7f7f", "0.9688"),
Expand Down Expand Up @@ -279,6 +278,12 @@ const
"0.5931"),
]

AttestationBitsVectors = [
([("0xff01", Slot(0), 0'u64), ("0xff01", Slot(0), 0'u64)], 8),
([("0xff01", Slot(0), 0'u64), ("0xff01", Slot(1), 0'u64)], 16),
([("0xff01", Slot(0), 0'u64), ("0xff01", Slot(0), 1'u64)], 16)
]

proc init(t: typedesc[Eth2Digest], data: string): Eth2Digest =
let length = len(data)
var dst = Eth2Digest()
Expand All @@ -298,19 +303,21 @@ proc init(t: typedesc[ProduceAttestationDataResponse],
target: Checkpoint(epoch: Epoch(ad.target))
))

proc init(t: typedesc[GetAggregatedAttestationResponse],
bits: string): GetAggregatedAttestationResponse =

proc init(t: typedesc[Attestation], bits: string,
slot: Slot = GENESIS_SLOT, index: uint64 = 0'u64): Attestation =
let
jdata = "{\"data\":\"" & bits & "\"}"
bits =
try:
RestJson.decode(jdata, AttestationBitsObject)
except SerializationError as exc:
raiseAssert "Serialization error from [" & $exc.name & "]: " & $exc.msg
GetAggregatedAttestationResponse(data: Attestation(
aggregation_bits: bits.data
))
Attestation(aggregation_bits: bits.data,
data: AttestationData(slot: slot, index: index))

proc init(t: typedesc[GetAggregatedAttestationResponse],
bits: string): GetAggregatedAttestationResponse =
GetAggregatedAttestationResponse(data: Attestation.init(bits))

proc init(t: typedesc[ProduceSyncCommitteeContributionResponse],
bits: string): ProduceSyncCommitteeContributionResponse =
Expand Down Expand Up @@ -380,6 +387,15 @@ suite "Validator Client test suite":
check:
score == vector[5]

test "getUniqueVotes() test vectors":
var data = CommitteeValidatorsBits.init(16)

for vector in AttestationBitsVectors:
let
a1 = Attestation.init(vector[0][0][0], vector[0][0][1], vector[0][0][2])
a2 = Attestation.init(vector[0][1][0], vector[0][1][1], vector[0][1][2])
check getUniqueVotes([a1, a2]) == vector[1]

asyncTest "firstSuccessParallel() API timeout test":
let
uri = parseUri("http://127.0.0.1/")
Expand Down

0 comments on commit 4774db1

Please sign in to comment.