Skip to content

Commit

Permalink
format fixes in the docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ines-toupeira committed Apr 15, 2024
1 parent 7cf9857 commit 8018198
Show file tree
Hide file tree
Showing 14 changed files with 62 additions and 33 deletions.
12 changes: 4 additions & 8 deletions learn/protocol/block-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Micro blocks contain user transactions, and each micro block is produced and sig

Note that only one of those is added as justification. The block producer signs the block when the micro block is produced within the expected time. But when the micro block isn't produced in the expected time, a `SkipBlockProof` is added instead.

### Macro Blocks
## Macro Blocks

There are two types of macro blocks: election and checkpoint. A new validator list is elected in every election macro block, and the staking contract is updated accordingly. Macro blocks are produced with Tendermint, where a random validator is chosen to propose the new macro block. User transactions are not included in macro blocks.

Expand Down Expand Up @@ -89,11 +89,7 @@ The following figure demonstrates the connection between a macro block and a mic
## Blockchain format

The blockchain is divided into batches and epochs:
- Batch: The interval between two macro blocks. A batch consists of several micro blocks, closing on a macro block.
- Epoch: The interval between two election macro blocks marks an epoch. It starts with the first micro block after an election macro block and ends at an election macro block, including multiple micro blocks and checkpoint macro blocks in between.

Batch: The interval between two macro blocks. A batch consists of several micro blocks, closing on a macro block.

Epoch: The interval between two election macro blocks marks an epoch. It starts with the first micro block after an election macro block and ends at an election macro block, including multiple micro blocks and checkpoint macro blocks in between.

The following figure illustrates how the blockchain is divided.

![Alt Text](/assets/images/protocol/block-struct-3.png)
![blockchain-structure](/assets/images/protocol/block-struct-3.png)
17 changes: 8 additions & 9 deletions learn/protocol/mempool.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ Every block has a predetermined storage capacity for transactions. Validators ar

Users are encouraged to offer higher fees to accelerate the addition of their transactions to the blockchain. The result of a transaction being added to the mempool is to be then added to the block. The mempool serves the dual purpose of filtering transactions and enabling validators to disregard invalid ones.

---

The blockchain mempool is divided into two groups that hold different types of transactions:

- Transactions from the [staking contract](validators/staking-contract.md) are added to a **control mempool**
Expand All @@ -30,6 +28,8 @@ A verification process filters transactions before they are added to the mempool
- Another scenario involves a transaction *x* being made, received by all validators, and one validator includes it in a block. The transaction *x* is now considered a known transaction, necessitating the other validators to remove it from their individual mempools.
- **Balance:** After verifying all necessary steps, the validator checks the user’s balance and all pending transactions for that user in the mempool. The mempool must ensure that the sender has adequate funds to cover at least the transaction fees.

###

Note that if the first step returns an invalid signature, the transaction is immediately discarded, and verifying the following steps unnecessary as the first was already invalid. This means that if, for example, the signature is not valid, the rest of the steps do not need to be verified, and the transaction is immediately discarded.

After the two mempools are fed with transactions respecting the verification process, they are kept on hold and will be added to a block by the elected block producer in the following way:
Expand All @@ -38,7 +38,7 @@ After the two mempools are fed with transactions respecting the verification pro
- Transactions with higher fees have priority against transactions with lower fees (mind that this is not the rule. While high fees encourage validators to add the transaction to the block, nothing in the protocol prevents the validator from adding a transaction with low fees)
- New transactions have priority over older ones.

![Alt Text](/assets/images/protocol/mempool.png)
![mempool](/assets/images/protocol/mempool.png)

<Callout type='info'>

Expand All @@ -52,9 +52,8 @@ After a transaction is added, the user’s balance is updated, and the validator

Even after the verification process went through and after the transactions have been added to the mempool, transactions may not succeed in being included in a block, as they can become invalid when in the mempool. As transactions are included in the blockchain, validators first verify if:

- There are **expired transactions**. Similar to the verification step of the validity window, when adding a transaction to the mempool, transactions can expire when on hold. In this case, validators must discard the respective transaction.
- There is any **transaction already included** in a block. A validator might have included a transaction in a block that other validators haven’t detected, or a validator might disconnect from the network, and once reconnecting and downloading the history sync, other validators could already have included that transactions; in this case, as soon known a validator notices the respective transaction, he must discard the one already added.
- A **fork occurred** somewhere in the chain. Suppose a malicious validator forks the chain, and the following block producer elected is also malicious and produces on top of the fork. Eventually, a rational validator will be selected, and the blocks produced maliciously must be reverted. Based on this, as soon as a rational validator notices the fork, the blocks produced maliciously are longer valid. There are two ways to fix this:
1. Transactions are adopted by other validators, and they include them in a block in the longest chain; validators with the respective transaction in their mempool can discard it.
2. Transactions are reverted and must be readded to the mempool as they were added in the block produced maliciously.
- The user's **account balance** has changed between the time the transaction was added to the mempool and the time the transaction was about to be added to the block. Identical to verifying the user’s balance made before the transaction is added to the mempool, if the user's balance changes in this period, the transaction becomes invalid as the user's balance is insufficient. Validators must update the user's balance in their mempool.
1. There are **expired transactions**. Similar to the verification step of the validity window, when adding a transaction to the mempool, transactions can expire when on hold. In this case, validators must discard the respective transaction.
2. There is any **transaction already included** in a block. A validator might have included a transaction in a block that other validators haven’t detected, or a validator might disconnect from the network, and once reconnecting and downloading the history sync, other validators could already have included that transactions; in this case, as soon known a validator notices the respective transaction, he must discard the one already added.
3. A **fork occurred** somewhere in the chain. Suppose a malicious validator forks the chain, and the following block producer elected is also malicious and produces on top of the fork. Eventually, a rational validator will be selected, and the blocks produced maliciously must be reverted. Based on this, as soon as a rational validator notices the fork, the blocks produced maliciously are longer valid.
There are two ways to fix this: (1) transactions are adopted by other validators, and they include them in a block in the longest chain;validators with the respective transaction in their mempool can discard it, and (2) transactions are reverted and must be re-added to the mempool as they were added in the block produced maliciously.
4. The user's **account balance** has changed between the time the transaction was added to the mempool and the time the transaction was about to be added to the block. Identical to verifying the user’s balance made before the transaction is added to the mempool, if the user's balance changes in this period, the transaction becomes invalid as the user's balance is insufficient. Validators must update the user's balance in their mempool.
4 changes: 4 additions & 0 deletions learn/protocol/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ To facilitate this process, Nimiq provides a two-mode tool. This tool allows use
- **Validator registration:** The first 6 transactions contain the encoded validator keys. Each transaction must be sent from the account of the registering validator, and have a value of 1 Luna each.
- **Deposit payment and commitment:** The last step is to pay the validator's deposit of 100 000 NIM and commit to the registration. Unlike the other six transactions, this one can be sent from any account, but the data field must include the registered validator's address to identify the validator.

###

The validator generation transactions include the following data:

| Type | Data |
Expand Down Expand Up @@ -56,6 +58,8 @@ Only preregistered validators can participate in this phase. The activation phas
- **Selecting the Transition Block:** Validators target a block with a height corresponding to the next PoS election block as the candidate block for the transition.
- **Executing the Transition:** If, at the candidate block's height, at least 80% of stake is signalling readiness for the transition, the candidate block becomes the transition block. An activation tool takes charge of capturing the state of the PoW chain at the transition block and generating the genesis block for the new PoS chain.

###

During this phase, validators send a transaction signaling their readiness. The readiness transaction is as follows:

| Type | Data |
Expand Down
7 changes: 6 additions & 1 deletion learn/protocol/penalties.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Validators are responsible for ensuring the security and stability of a blockcha

Our blockchain deals with misbehavior based on the nature of the offense:

- A delay in block production constitutes a minor offense. In such cases, the associated slot is deactivated, and the rewards are burned. For more severe offenses like forking, double voting, or double proposals, the validator is jailed. All validator slots are deactivated for a set period, and rewards for these slots are burned.
- A delay in block production constitutes a minor offense. In such cases, the associated slot is deactivated, and the rewards are burned.
- For more severe offenses like forking, double voting, or double proposals, the validator is jailed. All validator slots are deactivated for a set period, and rewards for these slots are burned.

<Callout type='info'>

Expand All @@ -28,6 +29,8 @@ When a validator acts maliciously on purpose, it gets jailed. Getting jailed can
- Making a double proposal on Tendermint
- Casting more than one vote per slot on Tendermint proposals

###

Any rational validator that witnesses one of these behaviors can report it by including a proof in a micro block. Once the proof that attests to the misbehavior is submitted, the validator is immediately jailed.

As these are more severe offenses that interfere with the blockchain, the consequences are also more severe. When a validator is jailed:
Expand All @@ -36,6 +39,8 @@ As these are more severe offenses that interfere with the blockchain, the conseq
- It gets locked for 8 epochs. However, it is required to continue the block production until the end of the current batch and vote for Tendermint blocks until the end of the epoch; from thereafter, it is not considered for block production until the locking period ends. The withdrawal lock takes effect immediately upon getting jailed.
- It loses its rewards for the jail period.

###

The `active_validators` and `punished_slots` sets are updated at every block in the [staking contract](validators/staking-contract.md). However, if a validator shifts from active to inactive or jailed, it is required to produce blocks until the current batch concludes, as it remains included in the validator slot list for that batch. However, it is no longer considered to produce blocks for further batches starting at the next checkpoint block.

In the context of Tendermint votes, a validator that shifts to inactive or jailed mid-epoch must vote until the end of the epoch. This is because there are no mid-epoch elections to replace the slots of the inactive or jailed validator. Thus, it must participate in the entire epoch's voting process to maintain the necessary validator count for consensus.
Expand Down
4 changes: 4 additions & 0 deletions learn/protocol/prover-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ The blockchain uses zero-knowledge proofs to:
- Enable nodes to reconnect with the blockchain faster
- Secure the network

###

Zero-knowledge proofs prove the chain’s integrity from the genesis block to the latest election macro block in a small proof, which makes it easy for the node receiving it to verify. The proof size remains the same regardless of whether the node requests a proof from the genesis block or the latest macro block.

From the verifier side, receiving and verifying a zero-knowledge proof is a fast process, but generating such proof takes significant computational power and space from the prover node side. Generating these proofs takes time but verifying them is a quick process.
Expand Down Expand Up @@ -50,6 +52,8 @@ pub struct ZKProof {
- The `block_number` consists of the most recent election block. This number must be greater than the node's number in the request.
- The `proof` consists of the zero-knowledge proof generated using a construction based on the MNT4-753 and MNT6-753 elliptic curves.

###

In case of a first connection with the network, the node provides the `block_number` 0 as the most recent proof, despite the genesis block having no proof attached to it.

In the case of a node that was synced and had a zero-knowledge proof for election block 43200 in its database, the resync method would differ. If it gets disconnected by chance, when reconnecting again, this node can try to resync with the chain by requesting a zkp more recent than block 43200. However, if this same node hadn't activated the database feature, it would be unable to resync from the same point and have to sync from the genesis block.
Expand Down
1 change: 0 additions & 1 deletion learn/protocol/sync-protocol/block-live-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ The block live sync method applies to both light nodes and history nodes. The sy
After the node has synced with the macro chain, it must begin to sync with the micro blocks from the current epoch by listening for the blocks as they are produced. However, there is a caveat in downloading the micro blocks:

- **Light nodes**, which do not require transaction history, only the headers of the micro blocks are downloaded. This streamlined approach significantly reduces the storage requirements for the light client.

- **History nodes** need all the historical data to download the entire micro block, so they download the entire micro block.

Once the node receives the micro block, it can add and update its copy of the blockchain. Nodes then wait for the next micro block to be produced and repeat the process of applying the micro header or the micro block to the local copy of the blockchain.
8 changes: 4 additions & 4 deletions learn/protocol/sync-protocol/history-macro-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ The node requests batch sets for each epoch using received election block hashes

The syncing node requests and incorporates history chunks from multiple history nodes since the genesis block. Each history chunk, consisting of a set number of history items, is fetched by specifying the epoch number, chunk index, and the closing macro block. The node repeats this request until it reaches the most recent history item.

- Towards receiving as many history chunks as optimally as possible, the node can request the first chunk of an epoch to one node, the second chunk to another, and so on by providing:
1. the epoch number of the epoch the node wants to fetch the history items from
2. a chunk index within the epoch; if the index of the chunk is 0, it receives history items from 0 to 999
3. the closing macro block of the respective chunk; can be either an election or a checkpoint block
Towards receiving as many history chunks as optimally as possible, the node can request the first chunk of an epoch to one node, the second chunk to another, and so on by providing:
1. the epoch number of the epoch the node wants to fetch the history items from
2. a chunk index within the epoch; if the index of the chunk is 0, it receives history items from 0 to 999
3. the closing macro block of the respective chunk; can be either an election or a checkpoint block

As mentioned, this process can be made with many history nodes. History items are aggregated into chunks to avoid the time-consuming process of downloading item by item. Plus, requesting chunks from multiple nodes makes the process practical and accelerated. The syncing node makes this request continuously until it reaches the most recent history item. Mind that as the chain progresses, it might be required for the syncing node to re-request some of the requests mentioned above.

Expand Down
3 changes: 2 additions & 1 deletion learn/protocol/sync-protocol/nodes-and-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ History nodes rely on other history nodes to sync through two mechanisms:
- [History Macro Sync](history-macro-sync.md)
- [Block Live Sync](block-live-sync.md)

###

In addition to the node types outlined, Nimiq PoS also features [prover nodes](/learn/protocol/prover-node.md) and [validator nodes](/learn/protocol/validators/validators-and-stakers.md):

- Prover nodes play a crucial role in blockchain networks by generating zero-knowledge proofs that allow both light and full nodes to sync. While zero-knowledge proofs are small and easy to verify, generating them requires significant computational resources. Prover nodes are, therefore, responsible for generating these proofs and must have the necessary resources.

- Validator nodes are the block producers. Any node in the network that desires to participate in the consensus and produce blocks can propose as a validator, and depending on the amount of NIM staked, they can increase their voting power.
4 changes: 2 additions & 2 deletions learn/protocol/sync-protocol/state-live-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ The Merkle Radix Tree efficiently stores accounts and their corresponding balanc

Hash values are propagated up the tree from lower to higher levels until the state root is reached. The state root serves as the fingerprint of the entire tree, allowing for easy detection of unauthorized modifications and efficient data integrity verification stored in the block’s header. The following accounts tree illustrates how 6 accounts are stored in the state root:

![Alt Text](/assets/images/protocol/merkle.png)
![merkle-tree](/assets/images/protocol/merkle.png)

<Callout type='warning'>
<Callout type='info'>

This figure is merely illustrative as the accounts tree hold multiple accounts.

Expand Down
Loading

0 comments on commit 8018198

Please sign in to comment.