2. States and Transitions
2.1. Introduction
Definition 1. Discrete State Machine (DSM)
A Discrete State Machine (DSM) is a state transition system that admits a starting state and whose set of states and set of transitions are countable. Formally, it is a tuple of
where
is the countable set of all possible inputs.
is a countable set of all possible states.
is the initial state.
is the state-transition function, known as Runtime in the Polkadot vocabulary, such that
Definition 2. Path Graph
A path graph or a path of nodes, formally referred to as , is a tree with two nodes of vertex degree 1 and the other n-2 nodes of vertex degree 2. Therefore, can be represented by sequences of where for is the edge which connect and .
Definition 3. Blockchain
A blockchain is a directed path graph. Each node of the graph is called Block and indicated by . The unique sink of is called Genesis Block, and the source is called the of . For any vertex where we say is the parent of , which is the child of , respectively. We indicate that by:
The parent refers to the child by its hash value (Definition 10), making the path graph tamper-proof since any modifications to the child would result in its hash value being changed.
The term "blockchain" can also be used as a way to refer to the network or system that interacts or maintains the directed path graph.
2.1.1. Block Tree
In the course of formation of a (distributed) blockchain, it is possible that the chain forks into multiple subchains in various block positions. We refer to this structure as a block tree:
Definition 4. Block
The block tree of a blockchain, denoted by is the union of all different versions of the blockchain observed by the Polkadot Host such that every block is a node in the graph and is connected to if is a parent of .
When a block in the block tree gets finalized, there is an opportunity to prune the block tree to free up resources into branches of blocks that do not contain all of the finalized blocks or those that can never be finalized in the blockchain (Chapter 6).
Definition 5. Pruned Block Tree
By Pruned Block Tree, denoted by , we refer to a subtree of the block tree obtained by eliminating all branches which do not contain the most recent finalized blocks (Definition 85). By pruning, we refer to the procedure of . When there is no risk of ambiguity and it is safe to prune BT, we use to refer to .
Definition 6 gives the means to highlight various branches of the block tree.
Definition 6. Subchain
Let be the root of the block tree and be one of its nodes. By , we refer to the path graph from to in . Conversely, for a chain , we define the head of to be , formally noted as . We define , the length of as a path graph.
If is another node on , then by we refer to the subgraph of path graph which contains and ends at and by we refer to its length.
Accordingly, is the set of all subchains of rooted at . The set of all chains of , is denoted by or simply , for the sake of brevity.
Definition 7. Longest Chain
We define the following complete order over as follows. For chains we have that if either or .
If we say if and only if the block arrival time (Definition 63) of is less than the block arrival time of , from the subjective perspective of the Host. We define the to be the maximum chain given by this order.
Definition 8. Longest Path
returns the path graph of which is the longest among all paths in and has the earliest block arrival time (Definition 63). returns the head of chain.
Because every block in the blockchain contains a reference to its parent, it is easy to see that the block tree is de facto a tree. A block tree naturally imposes partial order relationships on the blocks as follows:
Definition 9. Descendant and Ancestor
We say is descendant of , formally noted as , if . Respectively, we say that is an ancestor of , formally noted as , if .
2.2. State Replication
Polkadot nodes replicate each other’s state by syncing the history of the extrinsics. This, however, is only practical if a large set of transactions are batched and synced at the time. The structure in which the transactions are journaled and propagated is known as a block of extrinsics (Section 2.2.1.). Like any other replicated state machine, state inconsistency can occur between Polkadot replicas. Section 2.4.5. gives an overview of how a Polkadot Host node manages multiple variants of the state.
2.2.1. Block Format
A Polkadot block consists a block header (Definition 10) and a block body (Definition 13). The block body, in turn, is made up out of extrinsics , which represent the generalization of the concept of transactions. Extrinsics can contain any set of external data the underlying chain wishes to validate and track.
Image 1. Block
Definition 10. Block Header
The header of block B, , is a 5-tuple containing the following elements:
parent_hash: formally indicated as , is the 32-byte Blake2b hash (Section A.1.1.1.) of the SCALE encoded parent block header (Definition 12).
number: formally indicated as , is an integer, which represents the index of the current block in the chain. It is equal to the number of the ancestor blocks. The genesis state has the number 0.
state_root: formally indicated as , is the root of the Merkle trie, whose leaves implement the storage for the system.
extrinsics_root: is the field which is reserved for the Runtime to validate the integrity of the extrinsics composing the block body. For example, it can hold the root hash of the Merkle trie which stores an ordered list of the extrinsics being validated in this block. The extrinsics_root is set by the runtime and its value is opaque to the Polkadot Host. This element is formally referred to as .
digest: this field is used to store any chain-specific auxiliary data, which could help the light clients interact with the block without the need of accessing the full storage as well as consensus-related data including the block signature. This field is indicated as (Definition 11).
Image 2. Block Header
Definition 11. Header Digest
The header digest of block formally referred to by is an array of digest items ’s, known as digest items of varying data type (Definition 178) such that:
where each digest item can hold one of the following type identifiers:
where
is a 4-byte ASCII encoded consensus engine identifier
is a SCALE-encoded byte array containing the message payload
Consensus Message, contains scale-encoded message from the Runtime to the consensus engine. The receiving engine is determined by the id identifier:
- id = BABE: a message to BABE engine (Definition 54)
- id = FRNK: a message to GRANDPA engine (Definition 82)
Seal, is produced by the consensus engine and proves the authorship of the block producer. The engine used for this is provided through id (at the moment, BABE
), while contains the scale-encoded signature (Definition 66) of the block producer. In particular, the Seal digest item must be the last item in the digest array and must be stripped off by the Polkadot Host before the block is submitted to any Runtime function, including for validation. The Seal must be added back to the digest afterward.
Pre-Runtime digest, contains messages from the consensus engines to the runtime. Currently only used by BABE to pass the scale encoded BABE Header (Definition 65) in with id = BABE
.
Runtime Environment Updated digest, indicates that changes regarding the Runtime code or heap pages (Section 2.6.3.1.) occurred. No additional data is provided.
Image 3. Digest
Definition 12. Header Hash
The block header hash of block , , is the hash of the header of block encoded by simple codec:
Definition 13. Block Body
The block body consists of a sequence of extrinsics, each encoded as a byte array. The content of an extrinsic is completely opaque to the Polkadot Host. As such, from the point of the Polkadot Host, and is simply a SCALE encoded array of byte arrays. The body of Block represented as is defined to be:
Where each is a SCALE encoded extrinsic.
Image 4. Block Body
2.3. Extrinsics
The block body consists of an array of extrinsics. In a broad sense, extrinsics are data from outside of the state which can trigger state transitions. This section describes extrinsics and their inclusion into blocks.
2.3.1. Preliminaries
The extrinsics are divided into two main categories defined as follows:
Transaction extrinsics are extrinsics which are signed using either of the key types (Section A.1.4.) and broadcasted between the nodes. Inherent extrinsics are unsigned extrinsics that are generated by Polkadot Host and only included in the blocks produced by the node itself. They are broadcasted as part of the produced blocks rather than being gossiped as individual extrinsics.
The Polkadot Host does not specify or limit the internals of each extrinsics and those are defined and dealt with by the Runtime (Definition 1). From the Polkadot Host point of view, each extrinsics is simply a SCALE-encoded blob (Section A.2.2.).
2.3.2. Transactions
Transaction are submitted and exchanged through Transactions network messages (Section 4.8.5.). Upon receiving a Transactions message, the Polkadot Host decodes the SCALE-encoded blob and splits it into individually SCALE-encoded transactions.
Alternatively, transactions can be submitted to the host by off-chain worker through the Host API (Section B.6.2.).
Any new transaction should be submitted to the Runtime (Section C.7.1.). This will allow the Polkadot Host to check the validity of the received transaction against the current state and if it should be gossiped to other peers. If it considers the submitted transaction as valid, the Polkadot Host should store it for inclusion in future blocks. The whole process of handling new transactions is described in more detail by Validate-Transactions-and-Store.
Additionally, valid transactions that are supposed to be gossiped are propagated to connected peers of the Polkadot Host. While doing so the Polkadot Host should keep track of peers already aware of each transaction. This includes peers which have already gossiped the transaction to the node as well as those to whom the transaction has already been sent. This behavior is mandated to avoid resending duplicates and unnecessarily overloading the network. To that aim, the Polkadot Host should keep a transaction pool and a transaction queue defined as follows:
Definition 14. Transaction Queue
The Transaction Queue of a block producer node, formally referred to as is a data structure which stores the transactions ready to be included in a block sorted according to their priorities (Section 4.8.5.). The Transaction Pool, formally referred to as , is a hash table in which the Polkadot Host keeps the list of all valid transactions not in the transaction queue.
Furthermore, Validate-Transactions-and-Store updates the transaction pool and the transaction queue according to the received message:
Algorithm 1. Validate Transactions and Store
\begin{algorithm} +2. States and Transitions
2.1. Introduction
Definition 1. Discrete State Machine (DSM)
A Discrete State Machine (DSM) is a state transition system that admits a starting state and whose set of states and set of transitions are countable. Formally, it is a tuple of
where
is the countable set of all possible inputs.
is a countable set of all possible states.
is the initial state.
is the state-transition function, known as Runtime in the Polkadot vocabulary, such that
Definition 2. Path Graph
A path graph or a path of nodes, formally referred to as , is a tree with two nodes of vertex degree 1 and the other n-2 nodes of vertex degree 2. Therefore, can be represented by sequences of where for is the edge which connect and .
Definition 3. Blockchain
A blockchain is a directed path graph. Each node of the graph is called Block and indicated by . The unique sink of is called Genesis Block, and the source is called the of . For any vertex where we say is the parent of , which is the child of , respectively. We indicate that by:
The parent refers to the child by its hash value (Definition 10), making the path graph tamper-proof since any modifications to the child would result in its hash value being changed.
infoThe term "blockchain" can also be used as a way to refer to the network or system that interacts or maintains the directed path graph.
2.1.1. Block Tree
In the course of formation of a (distributed) blockchain, it is possible that the chain forks into multiple subchains in various block positions. We refer to this structure as a block tree:
Definition 4. Block
The block tree of a blockchain, denoted by is the union of all different versions of the blockchain observed by the Polkadot Host such that every block is a node in the graph and is connected to if is a parent of .
When a block in the block tree gets finalized, there is an opportunity to prune the block tree to free up resources into branches of blocks that do not contain all of the finalized blocks or those that can never be finalized in the blockchain (Chapter 6).
Definition 5. Pruned Block Tree
By Pruned Block Tree, denoted by , we refer to a subtree of the block tree obtained by eliminating all branches which do not contain the most recent finalized blocks (Definition 85). By pruning, we refer to the procedure of . When there is no risk of ambiguity and it is safe to prune BT, we use to refer to .
Definition 6 gives the means to highlight various branches of the block tree.
Definition 6. Subchain
Let be the root of the block tree and be one of its nodes. By , we refer to the path graph from to in . Conversely, for a chain , we define the head of to be , formally noted as . We define , the length of as a path graph.
If is another node on , then by we refer to the subgraph of path graph which contains and ends at and by we refer to its length.
Accordingly, is the set of all subchains of rooted at . The set of all chains of , is denoted by or simply , for the sake of brevity.
Definition 7. Longest Chain
We define the following complete order over as follows. For chains we have that if either or .
If we say if and only if the block arrival time (Definition 63) of is less than the block arrival time of , from the subjective perspective of the Host. We define the to be the maximum chain given by this order.
Definition 8. Longest Path
returns the path graph of which is the longest among all paths in and has the earliest block arrival time (Definition 63). returns the head of chain.
Because every block in the blockchain contains a reference to its parent, it is easy to see that the block tree is de facto a tree. A block tree naturally imposes partial order relationships on the blocks as follows:
Definition 9. Descendant and Ancestor
We say is descendant of , formally noted as , if . Respectively, we say that is an ancestor of , formally noted as , if .
2.2. State Replication
Polkadot nodes replicate each other’s states by syncing the histories of the extrinsics. This, however, is only practical if a large set of transactions are batched and synced at the same time. The structure in which the transactions are journaled and propagated is known as a block of extrinsics (Section 2.2.1.). Like any other replicated state machine, state inconsistencies can occur between Polkadot replicas. Section 2.4.5. gives an overview of how a Polkadot Host node manages multiple variants of the state.
2.2.1. Block Format
A Polkadot block consists a block header (Definition 10) and a block body (Definition 13). The block body, in turn, is made up out of extrinsics , which represent the generalization of the concept of transactions. Extrinsics can contain any set of external data the underlying chain wishes to validate and track.
Image 1. Block
Definition 10. Block Header
The header of block B, , is a 5-tuple containing the following elements:
parent_hash: formally indicated as , is the 32-byte Blake2b hash (Section A.1.1.1.) of the SCALE encoded parent block header (Definition 12).
number: formally indicated as , is an integer, which represents the index of the current block in the chain. It is equal to the number of the ancestor blocks. The genesis state has the number 0.
state_root: formally indicated as , is the root of the Merkle trie, whose leaves implement the storage for the system.
extrinsics_root: is the field which is reserved for the Runtime to validate the integrity of the extrinsics composing the block body. For example, it can hold the root hash of the Merkle trie which stores an ordered list of the extrinsics being validated in this block. The extrinsics_root is set by the runtime and its value is opaque to the Polkadot Host. This element is formally referred to as .
digest: this field is used to store any chain-specific auxiliary data, which could help the light clients interact with the block without the need of accessing the full storage as well as consensus-related data including the block signature. This field is indicated as (Definition 11).
Image 2. Block Header
Definition 11. Header Digest
The header digest of block formally referred to by is an array of digest items ’s, known as digest items of varying data type (Definition 178) such that:
where each digest item can hold one of the following type identifiers:
where
is a 4-byte ASCII encoded consensus engine identifier
is a SCALE-encoded byte array containing the message payload
Consensus Message, contains scale-encoded message from the Runtime to the consensus engine. The receiving engine is determined by the id identifier:
- id = BABE: a message to BABE engine (Definition 54)
- id = FRNK: a message to GRANDPA engine (Definition 82)
Seal, is produced by the consensus engine and proves the authorship of the block producer. The engine used for this is provided through id (at the moment,
BABE
), while contains the scale-encoded signature (Definition 66) of the block producer. In particular, the Seal digest item must be the last item in the digest array and must be stripped off by the Polkadot Host before the block is submitted to any Runtime function, including for validation. The Seal must be added back to the digest afterward.Pre-Runtime digest, contains messages from the consensus engines to the runtime. Currently only used by BABE to pass the scale encoded BABE Header (Definition 65) in with id =
BABE
.Runtime Environment Updated digest, indicates that changes regarding the Runtime code or heap pages (Section 2.6.3.1.) occurred. No additional data is provided.
Image 3. Digest
Definition 12. Header Hash
The block header hash of block , , is the hash of the header of block encoded by simple codec:
Definition 13. Block Body
The block body consists of a sequence of extrinsics, each encoded as a byte array. The content of an extrinsic is completely opaque to the Polkadot Host. As such, from the point of the Polkadot Host, and is simply a SCALE encoded array of byte arrays. The body of Block represented as is defined to be:
Where each is a SCALE encoded extrinsic.
Image 4. Block Body
2.3. Extrinsics
The block body consists of an array of extrinsics. In a broad sense, extrinsics are data from outside of the state which can trigger state transitions. This section describes extrinsics and their inclusion into blocks.
2.3.1. Preliminaries
The extrinsics are divided into two main categories defined as follows:
Transaction extrinsics are extrinsics which are signed using either of the key types (Section A.1.4.) and broadcasted between the nodes. Inherent extrinsics are unsigned extrinsics that are generated by Polkadot Host and only included in the blocks produced by the node itself. They are broadcasted as part of the produced blocks rather than being gossiped as individual extrinsics.
The Polkadot Host does not specify or limit the internals of each extrinsics and those are defined and dealt with by the Runtime (Definition 1). From the Polkadot Host point of view, each extrinsics is simply a SCALE-encoded blob (Section A.2.2.).
2.3.2. Transactions
Transaction are submitted and exchanged through Transactions network messages (Section 4.8.5.). Upon receiving a Transactions message, the Polkadot Host decodes the SCALE-encoded blob and splits it into individually SCALE-encoded transactions.
Alternatively, transactions can be submitted to the host by off-chain worker through the Host API (Section B.6.2.).
Any new transaction should be submitted to the Runtime (Section C.7.1.). This will allow the Polkadot Host to check the validity of the received transaction against the current state and if it should be gossiped to other peers. If it considers the submitted transaction as valid, the Polkadot Host should store it for inclusion in future blocks. The whole process of handling new transactions is described in more detail by Validate-Transactions-and-Store.
Additionally, valid transactions that are supposed to be gossiped are propagated to connected peers of the Polkadot Host. While doing so the Polkadot Host should keep track of peers already aware of each transaction. This includes peers which have already gossiped the transaction to the node as well as those to whom the transaction has already been sent. This behavior is mandated to avoid resending duplicates and unnecessarily overloading the network. To that aim, the Polkadot Host should keep a transaction pool and a transaction queue defined as follows:
Definition 14. Transaction Queue
The Transaction Queue of a block producer node, formally referred to as is a data structure which stores the transactions ready to be included in a block sorted according to their priorities (Section 4.8.5.). The Transaction Pool, formally referred to as , is a hash table in which the Polkadot Host keeps the list of all valid transactions not in the transaction queue.
Furthermore, Validate-Transactions-and-Store updates the transaction pool and the transaction queue according to the received message:
Algorithm 1. Validate Transactions and Store
diff --git a/part-polkadot-host.html b/part-polkadot-host.html index 5b07b8ab6..ca673f9aa 100644 --- a/part-polkadot-host.html +++ b/part-polkadot-host.html @@ -6,7 +6,7 @@\begin{algorithm} \caption{Validate-Transactions-and-Store} \begin{algorithmic} \state $L \leftarrow Dec_{SC}(M_T)$ diff --git a/chap-sync.html b/chap-sync.html index 39c6db5f8..a044a6be0 100644 --- a/chap-sync.html +++ b/chap-sync.html @@ -6,7 +6,7 @@3. Synchronization | Polkadot Protocol Specification - + diff --git a/chapter-anv.html b/chapter-anv.html index a4ce4ffb1..3d8516d26 100644 --- a/chapter-anv.html +++ b/chapter-anv.html @@ -6,7 +6,7 @@8. Availability & Validity | Polkadot Protocol Specification - + diff --git a/id-consensus.html b/id-consensus.html index 33f1c8ec4..e60742d69 100644 --- a/id-consensus.html +++ b/id-consensus.html @@ -6,7 +6,7 @@11. Consensus | Polkadot Protocol Specification - + diff --git a/id-cryptography-encoding.html b/id-cryptography-encoding.html index 0d7aafd15..24824c7bb 100644 --- a/id-cryptography-encoding.html +++ b/id-cryptography-encoding.html @@ -6,7 +6,7 @@Appendix A: Cryptography & Encoding | Polkadot Protocol Specification - + diff --git a/id-extrinsics.html b/id-extrinsics.html index 6bf295ab4..a9311c709 100644 --- a/id-extrinsics.html +++ b/id-extrinsics.html @@ -6,7 +6,7 @@9. Extrinsics | Polkadot Protocol Specification - + diff --git a/id-glossary.html b/id-glossary.html index 29dc93d17..a26df7dc6 100644 --- a/id-glossary.html +++ b/id-glossary.html @@ -6,7 +6,7 @@Glossary | Polkadot Protocol Specification - + diff --git a/id-polkadot-protocol.html b/id-polkadot-protocol.html index 8f9bcaae8..a43f49881 100644 --- a/id-polkadot-protocol.html +++ b/id-polkadot-protocol.html @@ -6,7 +6,7 @@Polkadot Protocol | Polkadot Protocol Specification - + diff --git a/id-weights.html b/id-weights.html index 71ca74270..c19ecb0bc 100644 --- a/id-weights.html +++ b/id-weights.html @@ -6,7 +6,7 @@10. Weights | Polkadot Protocol Specification - + diff --git a/index.html b/index.html index 05e6e594a..b340a8de1 100644 --- a/index.html +++ b/index.html @@ -6,12 +6,12 @@Polkadot Protocol Specification | Polkadot Protocol Specification - +-+Polkadot
Enabling Implementers - Version 0.2.1
Polkadot
Enabling Implementers - Version 0.2.1
Polkadot Host | Polkadot Protocol Specification - + diff --git a/part-polkadot-runtime.html b/part-polkadot-runtime.html index c1ca47c17..b806fb684 100644 --- a/part-polkadot-runtime.html +++ b/part-polkadot-runtime.html @@ -6,7 +6,7 @@Polkadot Runtime | Polkadot Protocol Specification - + diff --git a/sect-block-production.html b/sect-block-production.html index fad495d83..768cf7bb0 100644 --- a/sect-block-production.html +++ b/sect-block-production.html @@ -6,7 +6,7 @@5. Block Production | Polkadot Protocol Specification - + diff --git a/sect-finality.html b/sect-finality.html index a818bfd42..a6ed7e62e 100644 --- a/sect-finality.html +++ b/sect-finality.html @@ -6,7 +6,7 @@6. Finality | Polkadot Protocol Specification - + diff --git a/sect-lightclient.html b/sect-lightclient.html index fe477c5ba..efbceb01f 100644 --- a/sect-lightclient.html +++ b/sect-lightclient.html @@ -6,7 +6,7 @@7. Light Clients | Polkadot Protocol Specification - + diff --git a/sect-metadata.html b/sect-metadata.html index 9ee6bb660..d7e30a0f5 100644 --- a/sect-metadata.html +++ b/sect-metadata.html @@ -6,7 +6,7 @@12. Metadata | Polkadot Protocol Specification - +