feat: initialize Kurdistan SDK - independent fork of Polkadot SDK
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# Architecture Overview
|
||||
|
||||
This section aims to describe, at a high level, the code architecture and subsystems involved in the implementation of
|
||||
an individual Teyrchain Host. It also illuminates certain subtleties and challenges faced in the design and
|
||||
implementation of those subsystems.
|
||||
|
||||
To recap, Pezkuwi 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 Teyrchain 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, teyrchain) that they accept being
|
||||
called by. Each block in the blockchain contains a set of Extrinsics. Each extrinsic targets 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.
|
||||
Reference in New Issue
Block a user