You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/concurrency_design.md
+21-22Lines changed: 21 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ The following is a sequence diagram on the lifecycle of a block, from the moment
7
7
```mermaid
8
8
sequenceDiagram
9
9
10
-
participant port as LibP2P Port <br> (Genserver)
10
+
participant port as LibP2P Port <br> (GenServer)
11
11
participant sub as Subscriber <br> (GenStage)
12
12
participant consumer as GossipConsumer <br> (broadway)
13
13
participant pending as Pending Blocks <br> (GenServer)
@@ -66,7 +66,7 @@ Improvements:
66
66
### Other issues
67
67
68
68
- 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.
70
70
71
71
## State Diagram
72
72
@@ -99,11 +99,11 @@ stateDiagram-v2
99
99
100
100
```mermaid
101
101
sequenceDiagram
102
-
participant port as LibP2P Port <br> (Genserver)
102
+
participant port as LibP2P Port <br> (GenServer)
103
103
participant decoder as Decoder <br> (Supervised task)
104
104
participant tracker as Block Tracker <br> (GenServer)
105
105
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)
107
107
participant state_t as State Transition Task <br> (Supervised task)
108
108
participant DB as KV Store
109
109
@@ -148,7 +148,7 @@ With this strategy in mind, the block won’t need to be passed around during it
148
148
149
149
There are some tasks that, of course, will require interaction with the outside world:
150
150
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.
152
152
- 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.
153
153
- 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.
154
154
@@ -157,9 +157,9 @@ There are some tasks that, of course, will require interaction with the outside
157
157
```mermaid
158
158
sequenceDiagram
159
159
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)
163
163
participant db as Persistent Store <br> (DB/Cache)
164
164
165
165
port ->> bp: gossip(block)
@@ -187,33 +187,32 @@ We can see here that:
187
187
```mermaid
188
188
sequenceDiagram
189
189
190
-
participant bp as Block Processor (Genserver)
190
+
participant bp as Block Processor (GenServer)
191
191
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)
194
193
195
194
bp ->>+ db: parent_present?(block_root)
196
195
activate bp
197
196
db -->>- bp: false
198
-
bp ->>+ dt: spawn(parent_root)
197
+
bp ->>+ bpp: spawn(parent_root)
198
+
bp ->> bp: exit()
199
199
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
203
202
bpp ->> db: store_block_if_not_present(block)
204
203
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)
208
206
bp ->>- bp: validation and state transition
209
207
```
210
208
211
-
This is a simplified sequence diagram highlighting the differences when the parent block is not present. To summarize:
212
209
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.
215
214
- 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`.
217
216
218
217
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.
0 commit comments