-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
document parallel evm funnel delay/confirmationDepth (#39)
* document parallel evm funnel delay/confirmationDepth * refactor common funnel page and add delay guideline * update also the configuration page * Fix broken links --------- Co-authored-by: Enzo Cioppettini <[email protected]> Co-authored-by: Sebastien Guillemot <[email protected]>
- Loading branch information
1 parent
4ea73b5
commit 86e99e1
Showing
13 changed files
with
566 additions
and
392 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
...me/300-react-to-events/3-funnel-types/1-common-concepts/2-parallel-networks.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import Merge from "./parallel-funnel-merge.svg"; | ||
import MergeDelayed from "./parallel-funnel-merge-delayed.svg"; | ||
import ParallelToMain from "./parallel-to-main.svg"; | ||
import DataAddition from "./parallel-data-addition.svg"; | ||
import Finalized from "./parallel-finalized.svg"; | ||
|
||
# Parallel funnels | ||
|
||
## Merging state from multiple chains | ||
|
||
When running a game, there is always a (single) primary EVM network which is | ||
synchronized by the [block funnel](../block-funnel). This is the network that has | ||
the Paima L2 contract deployed, and it's the one that provides the inputs for | ||
the game. In addition to this, there are funnel types that are used for | ||
synchronizing additional networks in parallel: | ||
|
||
- [parallel evm funnel](../parallel-evm-funnel) | ||
- [carp funnel](../carp-funnel) | ||
- [mina funnel](../mina-funnel) | ||
|
||
Conceptually these funnels are independent from each other, so there can be as | ||
many as needed, but they all depend on the block funnel. | ||
|
||
<ParallelToMain className="img-full" style={{ height: "200px" }} /> | ||
|
||
The reason for this is | ||
that the engine makes it _appear_ as if events happened in a single network by | ||
_merging_ the events from the parallel chains into the blocks from the block | ||
funnel. This provides a single interface where adding an extension in an extra | ||
network is no different than adding an extension in a single network. | ||
|
||
<DataAddition className="img-full" style={{ marginTop: "8px" }} /> | ||
|
||
### Determinism | ||
|
||
Merging of data is done in a way to ensure that the state transition is deterministic. | ||
|
||
For example,<br /> | ||
if on the main chain we have blocks with timestamps <span style={{ color: "red" }}>3</span> and <span style={{ color: "red" }}>5</span>,<br/> | ||
and on the parallel chain we have blocks with timestamps <span style={{ color: "green" }}>4</span> and <span style={{ color: "green" }}>5</span>,<br /> | ||
the events in the parallel chain will <span style={{ color: "lightblue" }}>look as if</span> they happened in the main chain's block that has timestamp <span style={{ color: "red" }}>5</span>. | ||
And this is always the same regardless of the time of the sync, since the chains are always processed in tandem. | ||
Note that it is possible that there are no blocks to merge at a certain point (if no events we're monitoring occur in these blocks). | ||
|
||
Visually: | ||
|
||
<Merge className="img-full" style={{ height: "auto" }} /> | ||
|
||
## Finalizing blocks | ||
|
||
We cannot go back in time to add information to old blocks that have already been parsed by the game's state machine. | ||
Therefore, it means that a block can only be considered finalized and ready to be given to the state machine once we're certain we have all the information for all chains being monitored. | ||
The only way for us to know that we have all the information for a block is if the _latest_ [**confirmed**](#confirmation-depth) timestamp of all networks we're monitoring is more recent *or* equal ( depending on whether the network can have multiple blocks with the same timestamp), than the timestamp of the main chain block timestamp we're looking at. | ||
|
||
*Note*: this behavior helps protect apps built with Paima from getting in a bad state. If an RPC you're connecting to for a network gets stuck, it should stop block production for the entire application. | ||
Otherwise, it can break determinism because your node (that is missing events from the parallel chain RPC that is stuck) will see a different block history from somebody else running a node connecting to a properly functioning RPC for that parallel chain. | ||
|
||
<Finalized className="img-full" style={{ height: "auto" }} /> | ||
|
||
## Delayed state | ||
|
||
When getting information from a chain with probabilistic finality, it's | ||
necessary to have a setup that can avoid rollbacks, since there is no way in for | ||
the engine to handle that otherwise. Because of this, the parallel funnels have | ||
the ability to run in a delayed state. This involves two different variables: | ||
|
||
``` | ||
confirmationDepth: number | ||
delay: number | ||
``` | ||
|
||
### Confirmation depth | ||
|
||
`confirmationDepth` is a parameter that is based on blocks. A | ||
`confirmationDepth` of 0 would be proper for a network with instant finality. | ||
Increasing the argument depends on the underlying network, and the amount of | ||
confidence desired. | ||
|
||
### Delay | ||
|
||
If the `delay` setting is used, the parallel chain is delayed by this amount of | ||
seconds. This is equivalent to either subtracting the delay for the timestamps | ||
of the main network before merging (without changing the result), or to adding | ||
the delay to the parallel network timestamps. In that case the merge process | ||
changes in the following way (with a delay of 60 seconds). | ||
|
||
<MergeDelayed className="img-full" style={{ height: "auto" }} /> | ||
|
||
This has the effect that no events newer than `current time - delay` will be | ||
processed by the funnel (relative to the main chain's latest synced block). | ||
|
||
### Guidelines | ||
|
||
In general both of these are needed for the funnel to properly function, and a | ||
good guideline is to set `delay` to a value greater or equal than | ||
`confirmationDepth * block_production_speed`. Having a greater value adds | ||
latency for the engine to react to events, but decreases the chances of the | ||
funnel needing to wait for block production in order to get a confirmed block | ||
(see [finalizing blocks](#finalizing-blocks)). This is particularly problematic | ||
because a single network may stall all of the other ones. | ||
|
||
Considering the above, setting up a `confirmationDepth` without `delay` it's not | ||
really advised, since the funnel will stall with every block. On the other hand, | ||
it's possible to set a `delay` without a `confirmationDepth`, but if the | ||
underlying network stops producing blocks for some reason, it may lead to | ||
eventually finalizing a block that it's not stable, unless the underlying | ||
network has some extra guarantees based exclusively on timings. | ||
|
||
## Performance implications | ||
|
||
Leveraging parallel funnels has multiple performance implications. In some cases the performance impact can be mitigated by [emulated blocks](./400-stable-tick-rate-funnel.mdx), | ||
but we will cover all performance implications in this section | ||
|
||
### Networking overhead | ||
|
||
From Paima's perspective, a block can only be considered complete and ready to send to the game's state machine after it's fetched all necessary information. | ||
That means that fetching blocks is only as fast as your slowest connection when fetching the latest block. | ||
|
||
If you're connecting to a public node for a network and receiving data from that node is slow (ex: geographically far from you, running on cheap hardware, etc.), | ||
the delay in fetching data from that node will delay the final block creation process and cause slowdowns in your game node. |
3 changes: 3 additions & 0 deletions
3
docs/home/300-react-to-events/3-funnel-types/1-common-concepts/_category_.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"label": "Common concepts" | ||
} |
File renamed without changes
File renamed without changes
327 changes: 327 additions & 0 deletions
327
...ct-to-events/3-funnel-types/1-common-concepts/parallel-funnel-merge-delayed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Oops, something went wrong.