- blockchains: the current blockchain and possibly different known forks.
- clock: general time tracking to know the time in blockchain unit (epoch/slot)
- tip: the current fork that is considered the correct one, related to consensus algorithm.
Each node runs several tasks. Task is a process with a clearly defined interface that abstracts a particular task.
Network task: handle new connections, and perform lowlevel queries. It does queries parsing and routing them to the other tasks: block, client or transaction tasks.
Block task: handles blocks reception from other nodes and the leadership thread. The blocks can be external and internal. External block (…), and internal block (…). When the task receives an external block it validates the block. If validation succeeds then the task appends blocks to the blockchain and checks if the tip needs any changes. When the task receives an internal block it does the same actions except for block validation. And then broadcasts the change of the tip to the network thread.
Leadership task: waits for each new slot, evaluates if this node is a slot leader. In case if it is, the task creates a new block (with a set of known transactions) referencing the latest known and agreed block in the blockchain. Then the task sends it to the block thread for processing.
Client task: receives block header/body queries. This task is in charge of in accord [!!!] with the blockchains, reply to the client.
Transaction task: receives new transactions from the network, validates transaction and handle duplicates. Also the broadcast to other nodes new (valid) transaction received.
blockchain module is responsible to maintaining the blockchain (i.e.) the blocks,
the current working branches (we will come back to it in a bit), the different states
associated to every blocks, the epoch’s data (the parameters, the stake active distribution
and the leadership schedule).
It is fairly easy to maintain the blocks of a blockchain. They all have the identifier of the parent block. Storing them is another story though and is not covered here.
blockx.yare blocks of the blockchain. They
linkto the parent block except for the
block0which may not have parents here (there is a special case where we could set a parent pointing to the block of a previously known state of the blockchain);
ledgerx.yare states of the blockchain at a given
epoch x parametersare the blockchain parameters that are valid for all the epoch
epoch N stake distributionare the stake distribution as extracted from epoch
epoch x leadershipis the leadership schedule for the epoch
This may seem a bit overwhelming. Let’s follow the flow of block creations and validation on this blockchain:
Let’s start with first initializing the blockchain from the
The first block, the
block0, is the block that contains the initial data of the blockchain.
From the block0 we can construct the first ledger: the
From the ledger0 we can extract two objects:
epoch 1 parameterswhich will contains the fee setting to apply during the epoch 1;
epoch 0 stake distribution. This is the stake distribution at the end of the epoch 0 (and before the following epoch starts);
And now from the
epoch 0 stake distribution we can determine the leadership schedules for the
epoch 1 and the epoch 2.
The view from the point of view of a block
k at an epoch
block N.k) looks like the following:
It links to the parent block:
block N.(k - 1). This is important because it allows us to retrieve the
ledger state at the block
N.(k - 1). In order to accept the block
N.k in the blockchain we need to
validate a couple of things:
- the block N.k is correctly referring to the block N.(k - 1):
- the block date is increasing;
- the block number is strictly monotonically increasing;
- the schedule is correct: the block has been created by the right stake pool at the right time;
block N.kis updating the parent’s ledger state (
ledger N.(k - 1)) and is producing a valid new ledger:
Epoch transition happen when we switch to an epoch to the following one.