-
Notifications
You must be signed in to change notification settings - Fork 32
Reorganize our documentation #1542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Update the README to reflect the new structure. - Update the frontpage to reflect the contents of the documentation. - Delete all the content. It'll be gradually reintroduced and redistributed when appropriate.
Most of the information was taken from https://ouroboros-consensus.cardano.intersectmbo.org/docs/for-developers/QueryVersioning/
@@ -55,7 +55,7 @@ Custom implementations of the Cardano node client are free to bypass this check | |||
|
|||
Our code does not use the negotiated [`NodeToClientVersion`][n2c] directly, but translates them first to a [`CardanoNodeToClientVersion`][cardano-n2c] and then to [`ShelleyNodeToClientVersion`][shelley-n2c]. | |||
|
|||
- The [`querySupportedVersion`][query-supported-version] function assigns a [`ShelleyNodeToClientVersion`][shelley-n2c] to each Shelley-based query. | |||
- The [`querySupportedVersion`][query-supported-version] function assigns a [`ShelleyNodeToClientVersion`][shelley-n2c] to each Shelley-based query, indicating the minimum *Shelley* version that supports the query. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
querySupportedVersion
was removed (or rather, generalized) in ExposequerySupportedVersions
#1437, so it makes sense to link to that one instead. -
In general, it might not just be a minimum version, but also a maximum version, or even any subset of versions. Concrete example:
Line 536 in 6ac1c9e
GetProposedPParamsUpdates -> (< v12)
with an explanation of `querySupportedVersions`.
... and a subsection that explains the `ConsensusProtocol` class.
The added text looks good and nice to me. |
... explaining the checks that are performed.
|
||
The [`blockForgingController`](https://github.com/intersectmbo/ouroboros-consensus/blob/6c1f0e293b50b898e69116df0355595004432077/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/NodeKernel.hs#L375) function uses [`BlockChainTime`](https://github.com/intersectmbo/ouroboros-consensus/blob/6c1f0e293b50b898e69116df0355595004432077/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/BlockchainTime/API.hs#L23) to monitor the current slot. | ||
|
||
Block forging invokes `forecastFor` on the `LedgerView`. If this operation takes too long, it can delay block production. Note that if it’s not possible to forecast to the current slot, then forging a block is not possible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Block forging invokes `forecastFor` on the `LedgerView`. If this operation takes too long, it can delay block production. Note that if it’s not possible to forecast to the current slot, then forging a block is not possible. | |
Block forging invokes `forecastFor` for the current slot on the `LedgerView`. If this operation takes too long, it can delay block production. Note that if it’s not possible to forecast to the current slot, then forging a block is not possible. |
|
||
Block forging invokes `forecastFor` on the `LedgerView`. If this operation takes too long, it can delay block production. Note that if it’s not possible to forecast to the current slot, then forging a block is not possible. | ||
|
||
If `checkLeader` confirms the node is a leader, a block is forged, extending the current [selected chain](#chain-selection). Transactions are selected from a [mempool snapshot](TODO-ref!), which is a sequence of valid transactions consistent with the ledger state upon which the block will be built. For the purposes of block forging and the consensus protocol, these transactions are irrelevant as long as they are _valid_. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If `checkLeader` confirms the node is a leader, a block is forged, extending the current [selected chain](#chain-selection). Transactions are selected from a [mempool snapshot](TODO-ref!), which is a sequence of valid transactions consistent with the ledger state upon which the block will be built. For the purposes of block forging and the consensus protocol, these transactions are irrelevant as long as they are _valid_. | |
If `checkLeader` confirms the node is a leader, a block is forged, extending the current [selected chain](#chain-selection). Transactions are selected from a [mempool snapshot](TODO-ref!), which is a sequence of valid transactions consistent with the ledger state upon which the block will be built. For the purposes of block forging and the consensus protocol, these transactions are irrelevant as long as they are _valid from the Ledger point of view_. |
|
||
The `k` parameter, often referred to as the security parameter, is a fundamental constant in the Ouroboros consensus protocols. On Cardano mainnet, `k` is set to 2160 blocks. This parameter underpins various aspects of a Cardano node's operation, from chain selection and storage to security guarantees and performance. | ||
|
||
For Ouroboros Praos, used in Shelley-based eras, theoretical proofs guarantee that within `3k/f` slots, the chain will grow by at least `k` blocks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention or link the Chain Growth Property
|
||
### Chain Selection and Rollbacks | ||
|
||
The `ouroboros-consensus` implementation enforces a strict rule: a node will never switch to a chain that forks more than `k` blocks deep from its current tip. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention again the CP property
|
||
When a node is [caught up](TODO-ref), any candidate chains requiring a rollback exceeding `k` blocks are excluded from consideration. This constraint limits the number of ledger states that need to be retained to evaluate forks. Additionally, it prevents arbitrary-length rollbacks thus protecting against potential [attacks](#network-security-and-performance) that rely on this. | ||
|
||
When a node is [syncing](TODO-ref) with the chain, an adversary may present it with an alternative chain that forks more than `k` blocks from the current tip. However, the [Genesis](TODO-ref) syncing protocol ensures that a node joining the network does not switch to an adversarial chain. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a node is [syncing](TODO-ref) with the chain, an adversary may present it with an alternative chain that forks more than `k` blocks from the current tip. However, the [Genesis](TODO-ref) syncing protocol ensures that a node joining the network does not switch to an adversarial chain. | |
When a node is [syncing](TODO-ref) with the chain, an adversary may present it with an alternative chain that forks more than `k` blocks from the server's current tip, which would be rejected by a caught up node. However, the [Genesis](TODO-ref) syncing protocol ensures that a node joining the network does not switch to an adversarial chain. |
or something similar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all the documentation changes look good (modulo typos), I've also left a comment on ChainOrder
but that's more of an aside and changing that probably shouldn't be considered as part of this PR
However, Ouroboros involves short forks and potentially invalid blocks. | ||
On the other hand, even for a single chain, the Consensus Layer would forecast across the same slots multiple times: it does it each time the wall clock enters a new slot as part of the leadership check, and it does so each time any peer sends it a header. | ||
|
||
Ideally all ticks would be inexpensive, but the occasional spike is managable, since short forks are short lived. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"manageable"
## Bounding Ticking and Forecasting Computations | ||
|
||
On a single valid chain, the Consensus Layer will never tick across the same slots multiple times. | ||
However, Ouroboros involves short forks and potentially invalid blocks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, Ouroboros necessarily involves both short forks and potentially invalid blocks, and even for a single chain, [...]
However, Ouroboros involves short forks and potentially invalid blocks. | ||
On the other hand, even for a single chain, the Consensus Layer would forecast across the same slots multiple times: it does it each time the wall clock enters a new slot as part of the leadership check, and it does so each time any peer sends it a header. | ||
|
||
Ideally all ticks would be inexpensive, but the occasional spike is managable, since short forks are short lived. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comma after "ideally"
It could plausibly cause problems within the ledger rules if an entire epoch has no blocks, for example, so there's definitely no guarantee that the resulting ledger state would actually be useful. | ||
But again: the Consensus Layer will never request such a tick. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note
can these lines be moved into a [!note]
block?
## Query versioning | ||
|
||
Queries are versioned to ensure compatibility between nodes and clients running different software versions. | ||
As the ledger gets more features and new use cases are explored, teams will add new queries that allow to get the necessary data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"that allow getting the necessary data" or (probably better) "allow the client to get the necessary data"
@@ -0,0 +1,37 @@ | |||
# How to version a new query | |||
|
|||
1. Determine whether the query is supposed to be experimental. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"should be experimental" or "is intended to be experimental"
|
||
-- | The 'ChainOrder' type class's 'preferCandidate' function | ||
-- consumes both the 'SelectView's of competing chain tips and the | ||
-- 'ChainOrderConfig' to make the final decision on which chain is | ||
-- strictly preferred. This design allows for flexible and | ||
-- protocol-specific tie-breaking rules that go beyond simple chain | ||
-- length comparisons. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this extra comment is good but it's made me unsure about whether the design of the ChainOrder
class makes sense -- should it instead have projectBlockNo
and tiebreakCandidates
functions, and preferCandidates
could be removed from the class and separately enforce the "longer chains are always preferred" property?
(this is a bit unrelated to the actual documentation changes, so it might be better discussed somewhere else)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think this has come up in the past; I think everyone agreed that this would be neat (I don't remember why we didn't follow through with it; probably because it was relatively minor and SelectView
containing the BlockNo
has been the case forever). Eg concretely
data SelectView proto = SelectView {
svBlockNo :: BlockNo
, svTiebreaker :: TiebreakerView proto
}
where TiebreakerView
is an associated type family of ConsensusProtocol
with ChainOrder (TiebreakerView proto)
as a superclass constraint, and instances
Ord (TiebreakerView proto) => Ord (SelectView proto)
.ChainOrder (TiebreakerView proto) => ChainOrder (SelectView proto)
.
I was actually considering doing sth like this in the context of Peras, as doing weighted comparisons between chains is naturally modeled by adding the additional weight to the BlockNo
component, and it is a bit weird that it currently isn't directly accessible.
EDIT: #1591
Ensuring the thorough testability of the consensus layer is a critical design goal. | ||
As a core component of the Cardano Node, which manages the cryptocurrency, the consensus layer must adhere to strict correctness standards. | ||
Currently, we extensively employ property-based testing. | ||
Whenever possible, we should abstract over IO, enabling simulations of various failures (such as disk or network errors) to verify system recovery capabilities. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably worth mentioning IOSim
and io-classes
here specifically
This PR does not change any behavior; most of the diff is purely mechanical. Previously, the `SelectView`s of all `ConsensusProtocol`s contained the `BlockNo` as the most important criterion for comparing chains, with only tiebreaking behavior (among chains of equal length) being different across different protocols. This PR makes this explicit: `SelectView` is now longer an associated type family of `ConsensusProtocol`, but rather an ordinary data type ```haskell data SelectView p = SelectView { svBlockNo :: !BlockNo , svTiebreakerView :: !(TiebreakerView p) } ``` where `TiebreakerView` is now an associated type family of `ConsensusProtocol`. This PR also removes the `WithBlockNo` type that the HFC was already using to always attach a `BlockNo` to its `HardForkSelectView`. The code can be simpler now that `SelectView`s always automatically contain an explicit `BlockNo`. Also see #1542 (comment) ## Primary motivation The main motivation for this is to enable weighted chain selection in Peras (tweag/cardano-peras#62), which can now be easily modeled by adding the weight of a chain to the block number component, at least morally; we probably want to eventually have more type safety here to make it hard to "forget" to account for the weight, such as defining ```haskell data WeightedSelectView p = WeightedSelectView { wsvWeight :: !PerasWeight , wsvTiebreakerView :: !(TiebreakerView p) } ``` If the only goal were to minimize the diff, then it would also be possible to add a function `(BlockNo -> BlockNo) -> SelectView p -> SelectView p`, but it seems more honest to "properly" extract out the block number.
- The Lightweight Checkpointing Component - The Genesis State Machine Component - The Limit on Eagerness Component
... that fork before the immutable tip.
This section refers to the more extensive Genesis design.
This PR reorganizes the Consensus documentation, integrating information from various sources such as the Consensus report, Haddock comments, and existing documentation. The documentation is structured using the Diátaxis framework. Implementation-specific concepts will be moved to the Cardano Blueprints.