Cardano SL Updater Implementation Overview
Implementation of the update system can be found in the Pos.Update family of modules. The general approach to implementation is the same as in other subsystems of CSL, such as Txp, Ssc and Delegation. The update system has the global state, stored in the database. The global state can be unambiguously derived from the information that is in the blockchain. The local state, sometimes referred to as “mempool”, is stored in the memory. The mempool is used for data transfer and inclusion of transferred data into blocks. The network protocol (built with standard Inv/Req/Data pattern) is described in Application-level document with the binary protocol described in Binary protocols document.
Currently, everything is ready to add hard fork functionality via software update and then perform a hard fork as described in research section; soft forks (or software updates) are fully implemented.
Fields Updatable with a Soft Fork
contains fields for changing some parameters used by Cardano SL (for instance,
slot duration). Specifically,
upBlockVersion is used to signify that a
proposal performs such changes; if
upBlockVersion is greater than the last
used block version, the changes from
upBlockVersionData will be applied.
upBlockVersionData has the type
Its fields are described below:
bvdScriptVersion– a script language version used to validate script transactions. If the proposal increases
upBlockVersion, it must also increase
bvdScriptVersionby 1 (and can’t leave it unchanged).
bvdSlotDuration– slot duration (in milliseconds).
bvdMaxBlockSize– block size limit (in bytes). A proposal can’t increase the block size limit more than twofold compared to the previous limit.
bvdMaxHeaderSize- block header size limit (in bytes).
bvdMaxTxSize– transaction size limit (in bytes, currently 4096), limits size of TxAux
The checks described above are made in verifyNextBVData.
In addition, there are some fields that are unused right now, but will be used in the future. Their meaning is briefly described below:
bvdMpcThd– eligibility threshold for MPC.
bvdHeavyDelThd– threshold for heavyweight delegation.
bvdUpdateVoteThd– portion of total stake necessary to vote for or against an update.
bvdUpdateProposalThd– portion of total stake such that block containing
UpdateProposalmust contain positive votes for this proposal from stakeholders owning at least this amount of stake.
bvdUpdateImplicit– number of slots after which an update is implicitly approved (unless it has more negative votes than positive).
bvdUpdateSoftforkThd– portion of total stake such that if total stake of issuers of blocks with some block version is bigger than this portion, this block version is adopted.
MemPool consists of votes and proposals. Apart from that
tip, slot and
PollModifier corresponding to
MemPool (and to current
GState, i. e. to application of
GState). No matter whether a
change in proposal state comes from the network/mempool, or from loading the
PollModifier represents modification of global state which will be
made if one applies mempool.
Updating the Mempool
MemPool is updated in three cases:
- When a new proposal/vote is received. In this case, one of the
functions is called, which in turn calls
verifyAndApplyUSPayloadand then updates current
- When a new slot starts. In this case some data in
MemPoolmay become invalid. In fact, it happens only when epoch changes. That can happen because stable stake distribution changes and some votes may have not enough stake for inclusion. It’s done in the
GStateis updated. It is called
usNormalize. Some data may become invalid as a result of block(s) application or rollback. For instance, we have a proposal in memory, apply block with this proposal and it becomes invalid (because it’s already in block). We should drop such proposals. Or we have a vote for proposal from some block, then rollback of this block happens and vote is no longer valid. It is implemented by applying all local data to empty state, ignoring all data which is no longer valid.
Proposal and Votes Accumulation
To vote for a proposal, nodes should send their votes. Proposals and votes are stored in mempool (even if proposals don’t have enough votes for inclusion into blocks, this way votes can be collected automatically) or gathered from the blockchain in order to figure out which proposal is adopted.
Interaction With the Database
In order to verify update system data, we have to get this data from the global
state (database). To provide such interface, a well-documented type class
is presented. This type class is used not only for DB interaction, but also to
take mempool into account when the data received from the network are processed.
It is important that its implementation relies on functions found in
Core types are mentioned in the Binary Protocols document. Those types reflect the concepts from the research section in a straightforward way. Please refer to the core types module for more information.
Update Proposal Approval
A very important part of implementation of the update mechanism is the part that
works with genesis blocks for epochs. This logic resides in
The terminology related to this process is explained below.
Suppose there is a block version
X. And there are blocks with version
created in slots
S is a set of slots). If total relative stake of
leaders of all slots in
S is ≥
softforkResolutionThreshold (referred to as
«threshold» in the code), then
X becomes adopted. See the more detailed
description in research overview.
Update proposal can be in one of the states described below.
It means that update proposal is contained in one of the blocks, but it doesn’t
50% votes for/against it (here
50% means total stake of voters who are
for/against proposal relative to total stake of all stakeholders in system) and
implicit agreement rule hasn’t been triggered yet.
It means that proposal has more than
50% votes for it or it was added to block
long ago (according to implicit agreement rule) and it has more positive votes
than negative (comparison by stake of course).
A proposal is called rejected if that proposal has more than
against it or it was added to block long ago (according to implicit agreement
rule) and it has more negative votes than positive (again, comparison by stake).
An approved proposal is called confirmed if at least
k blocks ago
proposal became Approved. At this point we can be sure that proposal won’t
become rejected, because rollbacks with depth more than
k aren’t possible.
A rejected proposal is called discarded, if at least
k blocks ago that
proposal became rejected. At this point we can be sure that proposal won’t
be approved, because rollbacks with depth more than
k aren’t possible.
Download New Version
Download Confirmed Update
To download a confirmed update, we extract the update hash from
ConfirmedProposalState. It is extracted depending on whether or not we’re
using an installer on given platform. If the update hash is extracted
successfully, the “Download Update by Hash” algorithm is invoked to download and
save the confirmed update.
Download Update by Hash
To download an update by hash, we loop through known update servers trying to
download the update with given hash using
httpLBS from HTTP. It’s simple: in
the end, we will either have the update completely downloaded or server list
exhausted and an error reported. URIs of the known update servers are defined
--update-server argument of the