rm unused work_pool module (#90)
* rm unused work_pool module * preserve comment from Danny about signature aggregation
This commit is contained in:
parent
2774e5a67a
commit
bc44744acd
|
@ -24,6 +24,18 @@ type
|
|||
# in each epoch, each shard is going to receive attestations exactly once.
|
||||
# Once the epoch is over, we can discard all attestations and start all
|
||||
# over again (no need for `discardHistoryToSlot` too).
|
||||
#
|
||||
# Per Danny as of 2018-12-21:
|
||||
# Yeah, you can do any linear combination of signatures. but you have to
|
||||
# remember the linear combination of pubkeys that constructed
|
||||
# if you have two instances of a signature from pubkey p, then you need 2*p
|
||||
# in the group pubkey because the attestation bitfield is only 1 bit per
|
||||
# pubkey right now, attestations do not support this it could be extended to
|
||||
# support N overlaps up to N times per pubkey if we had N bits per validator
|
||||
# instead of 1
|
||||
# We are shying away from this for the time being. If there end up being
|
||||
# substantial difficulties in network layer aggregation, then adding bits to
|
||||
# aid in supporting overlaps is one potential solution
|
||||
|
||||
proc init*(T: type AttestationPool, startingSlot: int): T =
|
||||
result.attestations = initDeque[array[SHARD_COUNT, Option[Attestation]]]()
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
import
|
||||
sequtils, tables,
|
||||
spec/[datatypes, crypto, digest], ssz
|
||||
|
||||
type
|
||||
# TODO is it better to only key on some subset (e.g., shard+slot+beacon state hash)
|
||||
# of AttestationData? Using whole AttestationData does defend against some attacks.
|
||||
#
|
||||
# Per Danny as of 2018-12-21:
|
||||
# Yeah, you can do any linear combination of signatures. but you have to
|
||||
# remember the linear combination of pubkeys that constructed
|
||||
# if you have two instances of a signature from pubkey p, then you need 2*p
|
||||
# in the group pubkey because the attestation bitfield is only 1 bit per
|
||||
# pubkey right now, attestations do not support this it could be extended to
|
||||
# support N overlaps up to N times per pubkey if we had N bits per validator
|
||||
# instead of 1
|
||||
# We are shying away from this for the time being. If there end up being
|
||||
# substantial difficulties in network layer aggregation, then adding bits to
|
||||
# aid in supporting overlaps is one potential solution
|
||||
|
||||
# TODO replace array[32, byte] with Eth2Digest from hash_tree_root_final from
|
||||
# https://github.com/status-im/nim-beacon-chain/pull/47
|
||||
|
||||
# It would be better to combine these incrementally, pending above.
|
||||
AttestationPool* = object
|
||||
attestations: Table[uint64, Table[array[32, byte], seq[Attestation]]]
|
||||
|
||||
# TODO priority queue or similar to track most-voted-on-AttestationData
|
||||
# per shard
|
||||
|
||||
proc init*(T: type AttestationPool): T =
|
||||
result.attestations = initTable[AttestationData, seq[Attestation]]()
|
||||
|
||||
func getLookupKey(attestationData: AttestationData): array[0..31, byte] =
|
||||
hash_tree_root(attestationData)
|
||||
|
||||
proc add*(pool: var AttestationPool,
|
||||
attestation: Attestation) =
|
||||
# Should be called for local and remote attestations.
|
||||
let key = getLookupKey(attestation.data)
|
||||
var attestations = pool.attestations.getOrDefault(attestation.data.shard).getOrDefault(key)
|
||||
|
||||
# Basic sanity checks should already have been performed on this.
|
||||
# For example, if non-committee attestations shouldn't be included, this
|
||||
# doesn't separately check for that invariant.
|
||||
attestations.add(attestation)
|
||||
pool.attestations[attestation.data.shard][key] = attestations
|
||||
|
||||
func findMostCovering(pool: AttestationPool, shard: uint64): AttestationData =
|
||||
# Just a simple linear scan for now; could use various acceleration
|
||||
# data structures later, depending on tradeoff of how often queried
|
||||
# Might not be perf-sensitive; mostly per-epoch
|
||||
var mostAttestedData: AttestationData
|
||||
var maxLen: int = 0
|
||||
|
||||
for perShardAttestations in values(pool.attestations[shard]):
|
||||
let l = perShardAttestations.len
|
||||
if l > maxLen:
|
||||
# Guaranteed to have at least one element if > 0
|
||||
mostAttestedData = perShardAttestations[0].data
|
||||
maxLen = l
|
||||
|
||||
mostAttestedData
|
||||
|
||||
func getCombined(pool: AttestationPool, attestationData: AttestationData) : ValidatorSig =
|
||||
var signatures : seq[ValidatorSig] = @[]
|
||||
for perShardAttestation in pool.attestations.getOrDefault(attestationData.shard).getOrDefault(attestationData.getLookupKey):
|
||||
signatures.add(perShardAttestation.aggregate_signature)
|
||||
combine(signatures)
|
||||
|
||||
proc bitfieldUnion(accum: var seq[byte], disjunct: seq[byte]) =
|
||||
# TODO replace with nim-ranges
|
||||
doAssert len(accum) == len(disjunct)
|
||||
for i in 0 ..< len(accum):
|
||||
accum[i] = accum[i] or disjunct[i]
|
||||
|
||||
func getAggregatedAttestion*(pool: AttestationPool, shard: uint64) : Attestation =
|
||||
# TODO This might turn out to be a non-assertable condition, per, e.g.,
|
||||
# the recent discussion on error handling elsewhere in Nimbus, but it's
|
||||
# likelier that other code shouldn't be just randomly probing shards so
|
||||
# it's useful to start this way and catch logic errors early.
|
||||
assert shard in pool.attestations, "Attempt to query nonexistent shard"
|
||||
|
||||
let mostCoveringAttestationData = findMostCovering(pool, shard)
|
||||
# TODO error handling where shard either doesn't exist or empty; needs
|
||||
# more holistic approach
|
||||
|
||||
result.data = mostCoveringAttestationData
|
||||
|
||||
let freqAttestations = pool.attestations[shard].getOrDefault(result.data.getLookupKey)
|
||||
# TODO probably this should not assert on failure
|
||||
|
||||
# TODO Ugly, due to leaky seq[byte] non-abstraction. nim-ranges should help.
|
||||
result.participation_bitfield = repeat(0'u8, freqAttestations[0].participation_bitfield.len)
|
||||
for freqAttestation in freqAttestations:
|
||||
bitfieldUnion(result.participation_bitfield, freqAttestation.participation_bitfield)
|
||||
|
||||
# TODO 2018-12-22 ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md
|
||||
# doesn't document semantics.
|
||||
# result.custody_bitfield = bitfieldUnion
|
||||
|
||||
result.aggregate_signature = getCombined(pool, mostCoveringAttestationData)
|
Loading…
Reference in New Issue