mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-30 03:45:42 +00:00
a30092ab42
* Add markdown linting - add linter default rules - adapt rules to current code - fix the code for linting to pass - add CI check fix #1243 * Fix markdown for Substrate * Fix tooling install * Fix workflow * Add documentation * Remove trailing spaces * Update .github/.markdownlint.yaml Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix mangled markdown/lists * Fix captalization issues on known words
103 lines
5.6 KiB
Markdown
103 lines
5.6 KiB
Markdown
# Architecture Overview
|
|
|
|
This section aims to describe, at a high level, the code architecture and subsystems involved in the implementation of
|
|
an individual Parachain Host. It also illuminates certain subtleties and challenges faced in the design and
|
|
implementation of those subsystems.
|
|
|
|
To recap, Polkadot includes a blockchain known as the relay-chain. A blockchain is a Directed Acyclic Graph (DAG) of
|
|
state transitions, where every block can be considered to be the head of a linked-list (known as a "chain" or "fork")
|
|
with a cumulative state which is determined by applying the state transition of each block in turn. All paths through
|
|
the DAG terminate at the Genesis Block. In fact, the blockchain is a tree, since each block can have only one parent.
|
|
|
|
```dot process
|
|
digraph {
|
|
node [shape=box];
|
|
genesis [label = Genesis]
|
|
b1 [label = "Block 1"]
|
|
b2 [label = "Block 2"]
|
|
b3 [label = "Block 3"]
|
|
b4 [label = "Block 4"]
|
|
b5 [label = "Block 5"]
|
|
|
|
b5 -> b3
|
|
b4 -> b3
|
|
b3 -> b1
|
|
b2 -> genesis
|
|
b1 -> genesis
|
|
}
|
|
```
|
|
|
|
A blockchain network is comprised of nodes. These nodes each have a view of many different forks of a blockchain and
|
|
must decide which forks to follow and what actions to take based on the forks of the chain that they are aware of.
|
|
|
|
So in specifying an architecture to carry out the functionality of a Parachain Host, we have to answer two categories of
|
|
questions:
|
|
|
|
1. What is the state-transition function of the blockchain? What is necessary for a transition to be considered valid,
|
|
and what information is carried within the implicit state of a block?
|
|
1. Being aware of various forks of the blockchain as well as global private state such as a view of the current time,
|
|
what behaviors should a node undertake? What information should a node extract from the state of which forks, and how
|
|
should that information be used?
|
|
|
|
The first category of questions will be addressed by the Runtime, which defines the state-transition logic of the chain.
|
|
Runtime logic only has to focus on the perspective of one chain, as each state has only a single parent state.
|
|
|
|
The second category of questions addressed by Node-side behavior. Node-side behavior defines all activities that a node
|
|
undertakes, given its view of the blockchain/block-DAG. Node-side behavior can take into account all or many of the
|
|
forks of the blockchain, and only conditionally undertake certain activities based on which forks it is aware of, as
|
|
well as the state of the head of those forks.
|
|
|
|
```dot process
|
|
digraph G {
|
|
Runtime [shape=box]
|
|
"Node" [shape=box margin=0.5]
|
|
Transport [shape=rectangle width=5]
|
|
|
|
Runtime -> "Node" [dir=both label="Runtime API"]
|
|
|
|
"Node" -> Transport [penwidth=1]
|
|
}
|
|
|
|
```
|
|
|
|
It is also helpful to divide Node-side behavior into two further categories: Networking and Core. Networking behaviors
|
|
relate to how information is distributed between nodes. Core behaviors relate to internal work that a specific node
|
|
does. These two categories of behavior often interact, but can be heavily abstracted from each other. Core behaviors
|
|
care that information is distributed and received, but not the internal details of how distribution and receipt
|
|
function. Networking behaviors act on requests for distribution or fetching of information, but are not concerned with
|
|
how the information is used afterwards. This allows us to create clean boundaries between Core and Networking
|
|
activities, improving the modularity of the code.
|
|
|
|
```text
|
|
___________________ ____________________
|
|
/ Core \ / Networking \
|
|
| | Send "Hello" | |
|
|
| |- to "foo" --->| |
|
|
| | | |
|
|
| | | |
|
|
| | | |
|
|
| | Got "World" | |
|
|
| |<-- from "bar" --| |
|
|
| | | |
|
|
\___________________/ \____________________/
|
|
______| |______
|
|
___Transport___
|
|
|
|
```
|
|
|
|
Node-side behavior is split up into various subsystems. Subsystems are long-lived workers that perform a particular
|
|
category of work. Subsystems can communicate with each other, and do so via an [Overseer](node/overseer.md) that
|
|
prevents race conditions.
|
|
|
|
Runtime logic is divided up into Modules and APIs. Modules encapsulate particular behavior of the system. Modules
|
|
consist of storage, routines, and entry-points. Routines are invoked by entry points, by other modules, upon block
|
|
initialization or closing. Routines can read and alter the storage of the module. Entry-points are the means by which
|
|
new information is introduced to a module and can limit the origins (user, root, parachain) that they accept being
|
|
called by. Each block in the blockchain contains a set of Extrinsics. Each extrinsic targets a a specific entry point to
|
|
trigger and which data should be passed to it. Runtime APIs provide a means for Node-side behavior to extract meaningful
|
|
information from the state of a single fork.
|
|
|
|
These two aspects of the implementation are heavily dependent on each other. The Runtime depends on Node-side behavior
|
|
to author blocks, and to include Extrinsics which trigger the correct entry points. The Node-side behavior relies on
|
|
Runtime APIs to extract information necessary to determine which actions to take.
|