Skip to content

Commit 6415bd1

Browse files
authored
docs: add section for validators in architecture document (#1201)
1 parent 4b6ab7f commit 6415bd1

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

docs/architecture.md

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ PendingBlocks -->|penalize/get<br>on downloading|Peerbook
105105
Libp2pPort -->|new_request| IncomingRequests
106106
```
107107

108-
## Sequences
108+
## P2P Events
109109

110110
This section contains sequence diagrams representing the interaction of processes through time in response to a stimulus. The main entry point for new events is through gossip and request-response protocols, which is how nodes communicates between each other.
111111

@@ -115,7 +115,7 @@ Gossip allows clients to subscribe to different topics (hence the name "gossipsu
115115

116116
We use the `go-libp2p` library for the networking primitives, which is an implementation of the `libp2p` networking stack. We use ports to communicate with a go application and Broadway to process notifications. This port has a GenServer owner called `Libp2pPort`.
117117

118-
# Gossipsub
118+
## Gossipsub
119119

120120
### Subscribing
121121

@@ -296,10 +296,61 @@ Explained, a process that wants to request something from Libp2pPort sends a req
296296

297297
The specific kind of command (a request) is specified, but there's nothing identifying this is a response vs any other kind of result, or the specific kind of response (e.g. a block download vs a blob download). Currently the only way this is handled differentially is because the pid is waiting for a specific kind of response and for nothing else at a time.
298298

299-
### Checkpoint sync
299+
## Checkpoint sync
300300

301301
**TO DO**: document checkpoint sync.
302302

303+
## Validators
304+
305+
Validators are separate processes. They react to:
306+
307+
- Clock ticks: this allows them to compute their duties for different sections of the slot:
308+
- First third: producing a block and sending it to the general gossip channel.
309+
- Second third: Attesting for a block and sending it to a subnet.
310+
- Last third: aggregating attestations from a subnet and sending them over the general gossip network.
311+
- Fork choice results (head updates): these are needed by the validators to build the blocks accordingly when proposing, as they will get the head state, create a block on top of it and apply a state transition.
312+
313+
### Attester duty calculation
314+
315+
Duties are calculated by the `LambdaEthereumConsensus.Validator.Duties` module. This should be done once every epoch. In the current implementation it's done when:
316+
317+
- A new head appears for the same current slot.
318+
- There's an epoch change.
319+
320+
A validator must attest once per epoch, in one committee. There are multiple committees per slot. In the current design, all attestation committees are calculated for every slot of the epoch, and then the one containing the validator is returned, thus obtaining the slot and committee index within the slot for that validator.
321+
322+
There's some room for optimizations here:
323+
324+
- We should calculate the committees only once for all validators.
325+
- We should not calculate the full committees, we should only shuffle the validators that we are handling to know in which slot and committee they are in an epoch.
326+
327+
### Proposing duties
328+
329+
There's only one block proposer per slot and there are about 1 million validators in mainnet. That means that a block will be chosen approximately once every 12 million seconds (a slot is 12 seconds), which is roughly 4 months and 19 days.
330+
331+
Each proposer index is calculated for the whole epoch, using the hash of the epoch's randao mix + metadata as a seed.
332+
333+
This too could be calculated only once for all validators, but it's not as big as a task compared to calculating all committees.
334+
335+
### Building blocks
336+
337+
When proposing a block, the "block builder" is used.
338+
339+
In the previous block to proposing, the payload build starts:
340+
341+
- The head block and state are fetched from the db.
342+
- The block metadata is obtained from the blocks execution payload.
343+
- Slots are processed if necessary.
344+
- The execution client is notified of the fork choice update.
345+
346+
In the proposing slot:
347+
348+
- The process of getting the pre-state, processing slots, etc. is repeated (this could be optimized).
349+
- The execution payload and blob bundle are requested directly to the execution client for the corresponding payload_id.
350+
- The operations (slashings, attestations voluntary exits) that were collected from gossip are added to the block.
351+
- The deposits and eth1_vote are fetched from `ExecutionChain`.
352+
- The block is signed.
353+
303354
## Next document
304355

305356
Let's go over [Fork Choice](fork_choice.md) to see a theoretical explanation of LMD GHOST.

0 commit comments

Comments
 (0)