Skip to content

Commit

Permalink
word smithing
Browse files Browse the repository at this point in the history
  • Loading branch information
crocodile-dentist committed Mar 3, 2025
1 parent 4a7f702 commit d53fde4
Showing 1 changed file with 8 additions and 10 deletions.
18 changes: 8 additions & 10 deletions docs/get-started/cardano-node/topology.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ The P2P topology file specifies how to obtain the _root peers_.
These connections are typically kept private.


* _bootstrap peers_: trusted set of peers, only used for syncing. With
`cardano-node-10.2` one can use _Genesis_ instead.
* _bootstrap peers_: trusted set of peers, only used for syncing. Optionally starting with
`cardano-node-10.2`, the operator has the alternative to use Ouroboros Genesis instead.


* _public roots_: publicly known nodes (e.g. IOG relays or ledger nodes).
Expand Down Expand Up @@ -148,7 +148,7 @@ It is a subset of ledger peers which contains 90% of them with the largest stake

### Genesis lite a.k.a Bootstrap Peers

Bootstrap Peers is a pre-Genesis feature that allows a node to connect to a trustable set of peers when its chain falls behind.
Bootstrap Peers is an interim solution to facilitate syncing client nodes in a P2P environment from a pool of dedicated relays belonging to the original founding organizations of the Cardano blockchain. These relays have a priviledged trusted status within the ecosystem until full decentralization is achieved following a successful rollout of the Ouroboros Genesis protocol.

Bootstrap peers can be disabled by setting `bootstrapPeers: null`.
They are enabled by providing a list of addresses.
Expand Down Expand Up @@ -176,15 +176,15 @@ With bootstrap peers enabled, the node will trace the following:

### [Ouroboros Genesis](https://iohk.io/en/blog/posts/2024/05/08/ouroboros-genesis-design-update/)

Ouroboros Genesis is the upcoming mechanism of trustless syncing in P2P environment which is expected to supersede bootstrap peers described in the previous section. This feature is included starting with `cardano-node 10.2`, and at the time of this writing it is disabled by default - refer to config.json file section below on instructions how to enable this by toggling a feature flag. Once enabled, this mode is incompatible with bootstrap peers, and will disable the latter by overriding the configuration, and emit a trace of such occurrence to inform the operator to update topology file. From the perspective of the topology file a new entry must be added:
Ouroboros Genesis is the upcoming mechanism of trustless syncing in a meaningfully decentralized P2P environment which is expected to supersede bootstrap peers described in the previous section. This feature is included starting with `cardano-node 10.2`, and at the time of this writing it is disabled by default - refer to config.json file section below on instructions how to enable this by toggling a feature flag. Until Ouroboros Genesis is officially adopted by the community following a rollout period, one can configure the node to either use it or fall back on the bootstrap peers mechanism. However, if Genesis mode is enabled, it is incompatible with bootstrap peers and will disable the latter by overriding the configuration, and emit a trace of such occurrence to inform the operator to update the topology file. From the perspective of the topology file, a new entry must be added especially if a node is starting to sync from a blank or some arbitrary but significantly out-of-date state:

`"peerSnapshotFile": "path/to/snapshot.json"`

The file contains a snapshot of so-called big ledger peers which are the largest peers registered on the ledger which cumulatively hold 90% of stake at some arbitrary slot number. By virtue of the size of their stake in the system, they are postulated to be a proxy for honest ledger state. When syncing in this mode, these peers are sampled and connected with to bootstrap the process. Such a snapshot file can be created manually apriori with cardano-cli from a synced node, and may be distributed with a node release in the future. For reference,
The file contains a snapshot of so-called big ledger peers which are the relays belonging to the largest pools, by staked ADA, registered on the ledger which cumulatively hold 90% of the total stake at some arbitrary slot number. By virtue of the size of their stake, indicating a level of vested interest in sustaining the network, they are postulated to be a proxy for honest ledger state. These stake pools need not be priviledged in any sense nor even necessarily be members of the founding organizations. When syncing in this mode, these peers are sampled and connected with to jump-start the process. Such a snapshot file can be created manually apriori with cardano-cli from, ideally, a synced node, and may be signed and distributed with a node release in the future. Once provided, this file remains static while a node is running. The relevant cli command to manually generate a snapshot is `cardano-cli query ledger-peer-snapshot --out-file *arbitrary-file-name*`. Finally, the node will ignore this file if it's own ledger state is more recent and hence it is not strictly necessary for ongoing operation. It is however recommended to periodically update the snapshot, manually or from a latest release, as part of regular maintenance schedule.

### Configuring the node to use P2P

The `cardano-node`'s P2P configuration has a variety of options relating to how many connections are to be initiated, and conversely how many incoming connections can be accepted and it is vital to understand what this actually means in practice to operate a well-configured stake pool, but the provided defaults described below do provide a sensible starting point. The smallest practical network in principle is that between two hosts, and if drawn on paper, the two nodes as points, as a simplification the link between them can be viewed as a single concept when considering the network as a whole. However, to understand the P2P network at a lower level that is useful to us as relay operators, it is crucial to be aware that logically a connection should be split into a pair - its outbound and inbound legs - from *each* peer to the other most generally. An outbound from a peer/node/host is the inbound as seen from the other side, and vice versa. At any time, a node can maintain an outbound connection to its upstream peer that is not reciprocated. In such situation, the node initiating the outbound connection is the initiator, and it's upstream node is the responder. Even though the underlying TCP bearer supports bidirectional communication, in this scenario the logical communication is inherently one way where the initiator typically queries the responder, whom provides the requested information. At any time, the responder can decide to initiate its own outbound connection back to its previously downstream-only client, and in this case each one runs its initiator and responder mechanisms independently over a single channel/TCP bearer to conserve system resources. The queries from the initiator of one are served by the responder of the other side - but each side can now query the other at its own pace to get the information it wants. Furthermore in this duplex state, the original initiator can at any time decide to close its outbound leg to the other side, at which point it is now the original responder side that is then running in initiator-only mode, and the original initiator is just the responder. It is only when neither side wants to maintain an initiator/outbound leg to the other for querying that the connection is torn down and system resources are released.
The `cardano-node`'s P2P configuration has a variety of options relating to how many connections are to be initiated, and conversely how many incoming connections can be accepted and it is vital to understand what this actually means in practice to operate a well-configured stake pool, but the provided defaults described below do provide a sensible starting point. The smallest practical network in principle is that between two hosts, and if drawn on paper, the two nodes as points, as a simplification the link between them can be viewed as a single concept when considering the network as a whole. However, to understand the P2P network at a lower level that is useful to us as relay operators, it is crucial to be aware that logically a connection should be split into a pair - its outbound and inbound legs - from *each* peer to the other most generally. An outbound from a peer/node/host is the inbound as seen from the other side, and vice versa. At any time, a node can maintain an outbound connection to its upstream peer that is not reciprocated. In such situation, the node initiating the outbound connection is the initiator, and it's upstream node is the responder. Even though the underlying TCP bearer supports bidirectional communication, in this scenario the logical communication is inherently one way where the initiator typically queries the responder, whom provides the requested information. At any time, the responder can decide to initiate its own outbound connection back to its previously downstream-only client, and in this case each one runs its initiator and responder mechanisms independently over a single channel/TCP bearer to conserve system resources. The queries from the initiator of one are served by the responder of the other side - but each side can now query the other at its own pace to get the information it wants. Furthermore in this duplex state, the original initiator can at any time decide to close its outbound leg to the other side, at which point it is now the original responder side that is merely in initiator-only mode, and the original initiator is just the responder. It is only when neither side wants to maintain an initiator/outbound leg to the other for querying that the connection is torn down and system resources are released.

You can enable P2P from the configuration file; the field `EnableP2P` can be set to either `false` or `true`. When setting it to `true`, you will also need to configure the target number of _active_, _established_ and _known_ peers, together with the target number of _root_ peers. These values control the number of outbound/initiator connections the node will try to maintain in the appropriate mode to what are collectively named our upstream peers. This is important for the node as blocks are downloaded strictly from these peers and we want to maintain sufficiently many outbound connections to both:
- ensure we remain on the current network blockchain tip in a timely fashion to avoid short forks causing height battles and potentially losing rewards
Expand Down Expand Up @@ -216,8 +216,7 @@ The default configuration values are:
}
```

Collectively, these are known as the deadline targets. Prior to Ouroboros Genesis, this was the only set of static P2P targets available to the node. When Genesis is enabled, these deadline targets
are in effect strictly when the node deems itself caught up to its upstream peers, and the network is awaiting for the next block to be produced and diffused.
Collectively, these are known as the deadline targets. Prior to Ouroboros Genesis, this was the only set of static P2P targets available to the node. When Genesis mode is enabled in the configuration file, these deadline targets are in effect strictly when the node deems itself caught up to its upstream peers, and the network is awaiting for the next block to be produced and diffused.

* `TargetNumberOfActivePeers` - the target for active ledger peers (aka hot peers); includes: local roots, ledger peers / public roots, peers from peer-sharing; excludes: big ledger peers. This ordinarily should be least the number of local root peers that are specified as hot in the topology file, otherwise the number of these connections will be clamped below the expected number. However, it is not strictly a misconfiguration and the node will run in such configuration.
* `TargetNumberOfEstablishedPeers` - the target for established connections (the sum of warm & hot peers); includes: local roots roots, ledger peers / public roots, peers from peer-sharing; excludes big ledger peers. Same note as for active peers above applied here as well.
Expand Down Expand Up @@ -252,5 +251,4 @@ These options are available since `cardano-node-10.2` and by default their value
}
```

Collectively, these are known as the sync targets and they are in effect automatically when the node's consensus module detects that the node's chain tip is sufficiently behind its upstream peers. The node then proceeds to download *and validate* blocks in bulk from some of the active big ledger peers to catch up as soon as possible. Optionally, the `SyncTargetNumberOfActivePeers` can be set such that outbound connections are also
opened up to local root peers, if defined, as well as other public relays or nodes we learn about via peer sharing, if enabled. Care must be taken to ensure that these sync targets *by themselves* satisfy the inequality constraints given in the prior section, or the node will fail to start with an appropriate error message. Additionally, this latter option must not exceed `TargetNumberOfEstablishedPeers` from the *deadline* configuration set as the sole exception. Once sufficiently many blocks have been adopted and the node deems itself caught up again, the number of outbound connections will revert to the deadline set described in the previous section. If at any time during the syncing process the number of hot connections to big ledger peers drops below `MinBigLedgerPeersForTrustedState` value (which must not exceed the `SyncTargetNumberOfActivePeers` for obvious reasons), the node will pause and await until sufficiently many active outbound connections are online. This is only but one of the many safeguards in Ouroboros Genesis protocol to avoid adopting a dishonest chain during the syncing process. The blog post link in a prior section heading provides an approachable but technical deep dive for the curious operator or end user.
Collectively, these are known as the sync targets and they are in effect automatically when the node's consensus module detects that the local ledger state is out of date vis-à-vis our upstream peers. The node then proceeds to download *and validate* blocks in bulk from some of its upstream active peers to catch up as soon as possible. As long as there is at least one honest active peer in this set, which need not be the same one(s) for the duration of the process, the Ouroboros Genesis protocol ensures that our node will successfully complete with the honest ledger state. It is important for this reason that the `SyncTargetNumberOfActiveBigLedgerPeers` is not a 'small' number. Optionally, the `SyncTargetNumberOfActivePeers` can be set such that outbound connections are also opened up to local root peers, if defined, as well as other public relays or nodes we learn about via peer sharing, if enabled. Care must be taken to ensure that these sync targets *by themselves* satisfy the inequality constraints given in the prior section, or the node will fail to start with an appropriate error message. Additionally, this latter option must not exceed `TargetNumberOfEstablishedPeers` from the *deadline* configuration set as the sole exception. Once sufficiently many blocks have been adopted and the node deems itself caught up again, the number of outbound connections will revert to the deadline set described in the previous section. If at any time during the syncing process the number of hot connections to big ledger peers drops below `MinBigLedgerPeersForTrustedState` value (which must not exceed the `SyncTargetNumberOfActivePeers` for obvious reasons), the node will pause and await until sufficiently many active outbound connections are online. This is only but one of the many safeguards in Ouroboros Genesis protocol to avoid adopting a dishonest chain during the syncing process. The blog post link in a prior section heading provides an approachable but technical deep dive for the curious operator or end user.

0 comments on commit d53fde4

Please sign in to comment.