digraph architecture{ node [shape = invhouse]; Eth2RPC GossipSub; node [shape = octagon]; AttestationPool Eth2Processor DoppelgangerDetection; node [shape = doubleoctagon]; AsyncQueueAttestationEntry AsyncQueueAggregateEntry; node [shape = octagon]; ForkChoice Quarantine; {rank = same; Eth2RPC GossipSub;} AsyncQueueAttestationEntry [label="AsyncQueue[AttestationEntry]"]; AsyncQueueAggregateEntry [label="AsyncQueue[AggregateEntry]"]; GossipSub -> Eth2Processor [label="getAttestationTopic: attestationValidator->attestationPool.validateAttestation()"]; GossipSub -> Eth2Processor [label="node.topicAggregateAndProofs: aggregateValidator->attestationPool.validateAggregate()"]; Eth2Processor -> AttestationAggregation [label="validateAttestation() validateAggregate()"]; Eth2Processor -> AttestationPool [label="attestation_pool.selectHead()"]; Eth2Processor -> DoppelgangerDetection Eth2Processor -> AsyncQueueAttestationEntry [label="Move to queue after P2P validation via validateAttestation()"]; Eth2Processor -> AsyncQueueAggregateEntry [label="Move to queue after P2P validation via validateAggregate()"]; AsyncQueueAttestationEntry -> AttestationPool [label="runQueueProcessingLoop() -> processAttestation()\n->addAttestation (to fork choice)"]; AsyncQueueAggregateEntry -> AttestationPool [label="runQueueProcessingLoop() -> processAggregate()\n->addAttestation (to fork choice)"]; AttestationPool -> Quarantine [label="Missing block targets"]; AttestationPool -> ForkChoice [label="addAttestation(), prune(), selectHead()"]; Eth2RPC -> AttestationPool [dir="back" label="get_v1_beacon_pool_attestations() -> attestations iterator"] LocalValidatorDuties -> AttestationPool [label="Vote for head\nMake a block (with local validators attestations)"]; LocalValidatorDuties -> AttestationAggregation [label="aggregate_attestations()"]; AttestationAggregation -> AttestationPool }