Skip to content

Commit 692da2a

Browse files
ArkenanMegaRedHand
andauthored
docs: refine per-block-process design (#702)
Co-authored-by: Tomás Grüner <47506558+MegaRedHand@users.noreply.github.com>
1 parent f54ba61 commit 692da2a

File tree

1 file changed

+21
-22
lines changed

1 file changed

+21
-22
lines changed

docs/concurrency_design.md

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The following is a sequence diagram on the lifecycle of a block, from the moment
77
```mermaid
88
sequenceDiagram
99
10-
participant port as LibP2P Port <br> (Genserver)
10+
participant port as LibP2P Port <br> (GenServer)
1111
participant sub as Subscriber <br> (GenStage)
1212
participant consumer as GossipConsumer <br> (broadway)
1313
participant pending as Pending Blocks <br> (GenServer)
@@ -66,7 +66,7 @@ Improvements:
6666
### Other issues
6767

6868
- States aren't ever stored in the DB. This is not a concurrency issue, but we should fix it.
69-
- Low priority, but we should evaluate dropping the Subscriber genserver and broadway, and have one task per message under a supervisor.
69+
- Low priority, but we should evaluate dropping the Subscriber GenServer and Broadway, and have one task per message under a supervisor.
7070

7171
## State Diagram
7272

@@ -99,11 +99,11 @@ stateDiagram-v2
9999

100100
```mermaid
101101
sequenceDiagram
102-
participant port as LibP2P Port <br> (Genserver)
102+
participant port as LibP2P Port <br> (GenServer)
103103
participant decoder as Decoder <br> (Supervised task)
104104
participant tracker as Block Tracker <br> (GenServer)
105105
participant down as Downloader <br> (Supervised task)
106-
participant store as Fork Choice Store <br> (Genserver)
106+
participant store as Fork Choice Store <br> (GenServer)
107107
participant state_t as State Transition Task <br> (Supervised task)
108108
participant DB as KV Store
109109
@@ -148,7 +148,7 @@ With this strategy in mind, the block won’t need to be passed around during it
148148

149149
There are some tasks that, of course, will require interaction with the outside world:
150150

151-
- When a parent is missing, we need to download it. The block processor may pause until it receives a notification that the parent was downloaded and transitioned. After that, it may continue with its own state transition.
151+
- When a parent is missing, we need to download it. The block processor may exit and be re-spawned after the parent is downloaded and transitioned. After that, it may continue with its own state transition.
152152
- When validating it will need to interact with the global fork choice store. This just requires validating a few parameters like the epoch/slot, which is a fast process, so it’s a relatively simple call without passing the full block and without changing the store state.
153153
- The final step is updating the store/beacon chain state, which still doesn’t need to pass around big state and is fast. If additional validations are performed or repeated, it doesn’t represent a big performance hit.
154154

@@ -157,9 +157,9 @@ There are some tasks that, of course, will require interaction with the outside
157157
```mermaid
158158
sequenceDiagram
159159
160-
participant port as LibP2P Port <br> (Genserver)
161-
participant bp as Block Processor (Genserver)
162-
participant store as Fork Choice <br> (Genserver)
160+
participant port as LibP2P Port <br> (GenServer)
161+
participant bp as Block Processor (GenServer)
162+
participant store as Fork Choice <br> (GenServer)
163163
participant db as Persistent Store <br> (DB/Cache)
164164
165165
port ->> bp: gossip(block)
@@ -187,33 +187,32 @@ We can see here that:
187187
```mermaid
188188
sequenceDiagram
189189
190-
participant bp as Block Processor (Genserver)
190+
participant bp as Block Processor (GenServer)
191191
participant db as Persistent Store <br> (DB/Cache)
192-
participant dt as Download Task
193-
participant bpp as Parent Block Processor (Genserver)
192+
participant bpp as Parent Block Processor (GenServer)
194193
195194
bp ->>+ db: parent_present?(block_root)
196195
activate bp
197196
db -->>- bp: false
198-
bp ->>+ dt: spawn(parent_root)
197+
bp ->>+ bpp: spawn(parent_root)
198+
bp ->> bp: exit()
199199
deactivate bp
200-
dt ->> dt: download(parent_root)
201-
dt ->>- bpp: spawn(parent)
202-
activate bpp
200+
bpp ->> bpp: download(parent_root)
201+
bpp ->> bpp: decompress <br> ssz decode
203202
bpp ->> db: store_block_if_not_present(block)
204203
bpp ->> bpp: validation and state transition
205-
bpp ->> db: put_state(new_parent_state)
206-
deactivate bpp
207-
db ->>+ bp: parent_ready()
204+
bpp ->>- db: put_state(new_parent_state)
205+
bpp ->>+ bp: spawn(block_root)
208206
bp ->>- bp: validation and state transition
209207
```
210208

211-
This is a simplified sequence diagram highlighting the differences when the parent block is not present. To summarize:
212209

213-
- The block processor spawns a download task under a download supervisor.
214-
- When the download finishes it will start a block processor for the parent, repeating the whole process for the parent.
210+
This is a simplified sequence diagram highlighting the differences when the parent block is not present, so it omits the interaction with fork choice GenServer. To summarize:
211+
212+
- The block processor spawns another processor for the parent, at a `download stage` and exits.
213+
- When the download finishes, the parent processor will do as a normal one, decoding, deserializing, interacting with the db, etc.
215214
- When the parent finishes the state transition, it will have saved both the block and the state to the persistent store.
216-
- The store will then notify the child block processor that it can now proceed with its own state transition.
215+
- The parent process will then spawn a new block processor for the child, at a `transition stage`.
217216

218217
Note that the persistent store here is a simplified structure. Internally, it will contain the fork tree and the cache. The fork tree will contain the relationship between blocks (the tree structure), which will enable to get a block’s children without iterating through the DB.
219218

0 commit comments

Comments
 (0)