digraph architecture{ node [shape = invhouse]; Eth2RPC GossipSub WeakSubjectivitySync; node [shape = octagon]; SyncManager SyncProtocol RequestManager; SyncManager [label="SyncManager (Sync in)"]; node [shape = doubleoctagon] SharedBlockQueue; {rank = same; SyncManager RequestManager;} {rank = same; Eth2RPC GossipSub WeakSubjectivitySync;} WeakSubjectivitySync [label="WeakSubjectivitySync (impl TBD)"]; node [shape = octagon]; Eth2Processor RequestManager; node [shape = octagon]; ChainDAG Quarantine Clearance; Eth2RPC -> SyncProtocol [dir=both] SyncProtocol -> SyncManager [dir=both, label="beaconBlocksByRange() (mixin)"] GossipSub -> Eth2Processor [label="node.topicBeaconBlocks: blockValidator->validateBeaconBlock (no transition or signature check yet)\nthen enqueued in blockQueue"]; GossipSub -> Eth2Processor [dir=back, label="node.topicBeaconBlocks: blockValidator()->ValidationResult.Accept->libp2p/gossipsub.nim\nvalidate() in rpcHandler()"]; Eth2Processor -> Clearance [label="storeBlock(): enqueue in clearance/quarantine and callback to fork choice"]; SyncProtocol -> RequestManager [dir=both, label="fetchAncestorBlocksFromNetwork()"]; SyncManager -> SharedBlockQueue [dir=both, label="Eth2Processor.blockQueue\n== SyncManager.outQueue (shared state!)"]; Eth2Processor -> SharedBlockQueue [dir=both, label="Eth2Processor.blockQueue\n== RequestManager.outQueue (shared state!)"]; SharedBlockQueue -> RequestManager [dir=both, label="SyncManager.outQueue\n== RequestManager.outQueue (shared state!)"]; LocalValidatorDuties -> Clearance RequestManager -> Quarantine [dir=back, label="Retrieve missing ancestors"] Clearance -> Quarantine Clearance -> ChainDAG Eth2Processor -> ForkChoice LocalValidatorDuties -> ForkChoice node [shape = cylinder]; BeaconChainDB; ChainDAG -> BeaconChainDB [dir=both] SyncProtocol -> ChainDAG [dir=back, label="Sync out: getBlockRange()\nbeaconBlocksByRoot()\n"] }