The DAL node#

A DAL node is an executable (called octez-dal-node) whose main roles are to publish, store, and exchange data for the DAL layer. Interacting with a DAL node is done through the command-line interface (CLI) and through RPCs. In what follows, we describe the main components and features of a DAL node, and then present some operational aspects on configuring and running a DAL node.

For system requirements for the DAL node, see Hardware and bandwidth requirements for the Tezos DAL.

Concepts and features#

DAL P2P network#

The octez-dal-node executable runs a node in the DAL’s P2P network. Recall that the DAL’s P2P protocol is based on a gossipsub algorithm for distributing shards, running on top of a networking layer using the same P2P library as L1 nodes.

Actors with various roles run DAL nodes, but they need different views of the network depending on their role:

  • Operators of Smart Rollups care about data on the slots that their Smart Rollups use, but not about the slots used by other rollups.

  • Bakers only care about the shards that they are assigned to attest to, but they must watch all slots because the assigned shards can be in any slot.

  • Bootstrap node operators care about other nodes connecting to peers that are interested in the same messages via the P2P network but don’t care about the content of the messages on the network or any specific slot or shard more than any other.

Non-bootstrap DAL nodes distinguish themselves only in the topics they subscribe to:

  • Operators subscribe to all topics containing some specified slot indexes.

  • Bakers subscribe to all topics containing the attester identities they run for (for all possible slot indexes).

Bootstrap nodes are DAL network entry points that are used for network discovery. A bootstrap node remains connected to a large number of peers and is subscribed to all topics. When a DAL node starts, it gets the URLs of the bootstrap nodes from its layer 1 node and uses these bootstrap nodes to connect to peers. When a DAL node does not have the necessary connections to the P2P network, bootstrap nodes provide connection points with the relevant topics.

Profiles#

Because node operators care about different parts of the DAL network, the DAL node runs in different profiles. You can set these profiles in the node’s configuration file, as CLI arguments to the node’s commands, or via RPC calls.

The DAL node runs in these profiles:

  • The producer profile (soon to be changed to the operator profile) is for users who are running a Smart Rollup and want to publish data to it. To run a DAL node with the producer profile, pass the --producer-profiles argument with the indexes of the slots to accept data for, as in this example:

    octez-dal-node run --endpoint http://127.0.0.1:8732 --producer-profiles=0,1 --data-dir $DATA_DIR
    

    The configuration file for a DAL node running with the producer profile shows the slots that it accepts data for, as in this example:

    {
      "data-dir": "dal-node/",
      "endpoint": "http://127.0.0.1:8732",
      "profiles": {
        "kind": "operator",
        "operator_profiles": [
          {
            "kind": "producer",
            "slot_index": 1
          },
          {
            "kind": "producer",
            "slot_index": 2
          }
        ]
      }
    }
    
  • The attester profile is for bakers who want to attest to data. When an octez-baker daemon with attestation rights connects to a DAL node, it prompts the DAL node to run with the attester profile. The DAL node receives this prompt and runs in the attester profile unless it is running in bootstrap profile. To force the DAL node to run with the attester profile, pass the --attester-profiles argument with the public key hashes of the bakers to attest data for, as in this example:

    octez-dal-node run --endpoint http://127.0.0.1:8732 --attester-profiles=tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx --data-dir $DATA_DIR
    

    The configuration file for a DAL node running with the attester profile shows the public key hashes, as in this example:

    {
      "data-dir": "dal-node/",
      "endpoint": "http://127.0.0.1:8732",
      "profiles": {
        "kind": "operator",
        "operator_profiles": [
          {
            "kind": "attester",
            "public_key_hash": "tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx"
          }
        ]
      }
    }
    
  • The observer profile contributes to the resilience of network by helping distribute data in the specified slots. To run a DAL node with the observer profile, pass the --observer-profiles argument with the indexes of the slots to monitor or an empty string (as in --observer-profiles '') to use a random index, as in this example:

    octez-dal-node run --endpoint http://127.0.0.1:8732 --observer-profiles=0,1 --data-dir $DATA_DIR
    

    The configuration file for a DAL node running with the observer profile shows the slots that it is monitoring, as in this example:

    {
      "data-dir": "dal-node/",
      "endpoint": "http://127.0.0.1:8732",
      "profiles": {
        "kind": "operator",
        "operator_profiles": [
          {
            "kind": "observer",
            "slot_index": 1
          },
          {
            "kind": "observer",
            "slot_index": 2
          }
        ]
      }
    }
    
  • The bootstrap profile is for starting a DAL network and providing entry points for other DAL nodes to become part of the network. To run a DAL node with the bootstrap profile, pass the --bootstrap-profile argument, as in this example:

    octez-dal-node run --endpoint http://127.0.0.1:8732 --bootstrap-profile --data-dir $DATA_DIR
    

    The configuration file for a DAL node running with the bootstrap profile shows only the base information about the node, as in this example:

    {
      "data-dir": "dal-node/",
      "endpoint": "http://127.0.0.1:8732",
      "profiles": {
        "kind": "bootstrap"
      }
    }
    

By default, the DAL node runs in the producer profile without subscribing to any topics.

Currently, the DAL node can use any combination of profiles except that the bootstrap profile is not compatible with any other profile. However, for future-proofing and for production installations, run a DAL node in a single profile.

When a baker starts with the --dal-node argument, it checks the DAL node’s configuration. If the DAL node is not in bootstrap mode and not already set up with the attester profile, the baker configures the DAL node to use the attester profile associated with the keys that it is using.

Storage#

The DAL node essentially stores slots and shards. Slots are injected into the node through an RPC (see details at Lifetime of slots and shards), at which moment the corresponding commitment is computed and stored. Shards and their proofs are computed and stored via another RPC. It is important to also compute the shards’ proofs, because shards can be exchanged over the P2P network only if they are accompanied by their proof. Shards received over the P2P network are also stored. The node also tracks and stores the status of commitments by monitoring the L1 chain, connecting to this end to an L1 node specified at startup.

The amount of storage space a DAL node needs depends on how long it keeps the data, and different profiles keep the data for different amounts of time:

  • Bootstrap nodes store no DAL data and therefore require negligible storage.

  • Attester and observer nodes store data in memory for a few blocks after the attestation delay by default.

  • Producer nodes store data on disk for 3 months by default because the data may be needed for the Smart Rollup refutation game.

You can set how long the node stores data with the --history-mode option.

L1 monitoring#

The DAL node tracks the L1 chain, in particular it monitors the heads of the L1 chain via an RPC. Each time a block becomes final, it retrieves and stores the commitments published in that block, and if its storage contains shards for these commitments, it publishes them on the P2P network. The DAL node also retrieves the slot attestation status from the block’s metadata. Finally, based on this information it updates the status of the stored commitments, where the status of a commitment can be one of the following:

  • waiting for attestation: The commitment was included and applied in a finalized L1 block but the corresponding slot remains to be attested.

  • attested: The commitment was included in an L1 block and the corresponding slot is attested.

  • unattested: The commitment was included in an L1 block but the corresponding slot was not timely attested.

  • not selected: The commitment was included in an L1 block but was not selected for that slot index. This can happen if there is another commitment in the same block for the same slot index that was placed before the commitment in question (in operation order) by the baker.

  • unseen or not finalized: The commitment was not seen in a final L1 block. For instance, this could happen if the RPC PATCH /commitments/<commitment> was called but the corresponding commitment was never included into a block; or the commitment was included in a non-final block. This means that the publish operation was not sent (yet) to L1, or sent but not included (yet) in a block, or included in a not (yet) final block.

RPC server#

The DAL node incorporates an RPC server which answers to RPC queries to update or retrieve information about the node’s state. For instance, one can post slots, ask the node to compute and store shards, to update profiles, or to connect to or disconnect from peers.

The default listening port for RPCs is 10732, but can be changed using option --rpc-addr. The RPC server is started by default, even if this option is not given.

Operational aspects#

DAL node commands#

The DAL node has two commands config init and run.

The command init config creates a new configuration file in the specified data directory or in the default location (ie ~/.tezos-dal-node) with the parameters provided on the command-line by the corresponding arguments, in case no configuration file exists already. If such a file already exists, it overrides it with the provided parameters (old parameters are lost).

The command run runs the DAL node. The CLI arguments take precedence over the configuration file arguments, except for the list of bootstrap peers and of profiles, which are considered in addition to the ones from the configuration file. The configuration file is however not overridden with the new values of the node’s parameters. However, at the end of the execution, the node’s profiles, which may have been given as arguments or set via RPCs, are written to the configuration file.

Both commands have the same arguments, which can be seen by executing, e.g., octez-dal-node config init --help:

OPTIONS
       --attester-profiles=PKH1,PKH2,..., --attester=PKH1,PKH2,...
           The Octez DAL node attester profiles for given public key hashes.

       --bootstrap-profile, --bootstrap
           The Octez DAL node bootstrap node profile. Note that a bootstrap
           node cannot also be an attester or a slot producer

       -d DIR, --data-dir=DIR
           The directory where the Octez DAL node will store all its data.
           Parent directories are created if necessary.

       --endpoint=URI
           The endpoint (an URI) of the Tezos node that the DAL node should
           connect to. The default endpoint is 'http://localhost:8732'.

       --expected-pow=FLOAT
           The expected proof-of-work difficulty level for the peers'
           identity.

       --history-mode=VAL
           The duration for the shards to be kept in the node storage. Either
           a number, the string "full" or the string "auto". A number is
           interpreted as the number of blocks the shards should be kept; the
           string "full" means no shard deletion, the string "auto" means the
           default of the profile: 3 months for an observer or a slot
           producer, twice the attestation lag for an attester and other
           profiles.

       --metrics-addr=ADDR[:PORT]
           The TCP address and optionally the port of the node's metrics
           server. The default address is 0.0.0.0. The default port is 11733.

       --net-addr=ADDR[:PORT]
           The TCP address and optionally the port bound by the DAL node. If
           --public-addr is not provided, this is also the address and port
           at which this instance can be reached by other P2P nodes. The
           default address is 0.0.0.0. The default port is 11732.

       --observer-profiles=INDEX1,INDEX2,..., --observer=INDEX1,INDEX2,...
           The Octez DAL node observer profiles for given slot indexes.

       --peers=ADDR:PORT,...
           An additional peer list to expand the bootstrap peers from the
           Octez node's configuration parameter dal_config.bootstrap_peers.

       --producer-profiles=INDEX1,INDEX2,..., --producer=INDEX1,INDEX2,..., --operator=INDEX1,INDEX2,...
           The Octez DAL node producer profiles for given slot indexes.

       --public-addr=ADDR[:PORT]
           The TCP address and optionally the port at which this instance can
           be reached by other P2P nodes. By default, the point is
           '127.0.0.1:11732'. You can override the port using the syntax
           ':2222'. If the IP address is detected as a special address (such
           as a localhost one) it won't be advertised, only the port will.

       --rpc-addr=ADDR[:PORT]
           The TCP address and optionally the port at which the RPC server of
           this instance can be reached. The default address is 0.0.0.0. The
           default port is 10732.

       --service-name=VAL (absent OTEL_SERVICE_NAME env)
           A name that can be used to identify this node. This name can
           appear in observability data such as traces.

       --service-namespace=VAL (absent OTEL_SERVICE_NAMESPACE env)
           A namespace associated with the node. This namespace can appear in
           observability data such as traces.

       --sqlite3-backend
           Experimental feature, please dont use it unless you know what you
           are doing. Configure the DAL node store to use SQLite3 as a
           storage backend. 

See the DAL node manual for more details.

The concrete operational steps for participating in the DAL network are described in page Running a DAL attester node. In order to run a DAL node with an operator profile, one first needs to install some cryptographic parameters, see the section on Install DAL trusted setup.

DAL configuration of the L1 node#

All DAL nodes should use the same initialization parameters of the cryptographic primitives used by the DAL. These parameters are provided by running the script scripts/install_dal_trusted_setup.sh, which downloads and installs them, and which should be run once by any DAL node operator. However, for simplicity, on some test networks the initialization parameters are mocked-up and built-in.

Also, in order for the nodes to be able to join the P2P network, a set of bootstrap nodes can be provided using the network.dal_config.bootstrap_peers configuration parameter of the L1 node (thus using the same mechanism as for L1 nodes, see Connecting to a Network and P2P parameters).

Monitoring#

As for L1 nodes, to monitor the DAL node, one can inspect the node’s logs, query the node through RPCs, or use the incorporated Octez Metrics server. The usage of metrics is analogous to that for the L1 nodes, and we therefore refer to the L1 node’s documentation for details.

The bootstrap mechanism#

The gossipsub algorithm establishes upper bounds on the size of a topic mesh. Whenever a peer B would like to join the mesh of a peer A, but the peer A cannot add B to its mesh due to the upper bound, peer A responds with a random list of peers it knows are subscribed to the same topic. Peer B will then try to connect to these advertised peers. This peer exchange mechanism is used to bootstrap the P2P network: for bootstrap DAL nodes, the upper bound is set to 0, and thus, while they do not participate in exchanging shards, they keep advertising known peers so that new peers can connect to them and thus enter the P2P network.

If a node is behind a NAT, it is important to make the distinction between its “public address” and its “network address”. It is the public address that is advertised, and this should be the node’s external address, while the network address should be the node’s internal address. In other words, the public address behaves as the --advertised-net-port option of the L1 node, see Listening ports.

Lifetime of slots and shards#

The life cycle of slots and shards is described by the following steps:

  1. The operator posts the slot data to some DAL node of its choice. The node computes the corresponding commitment and adds the association commitment - slot to the store. This is done via the RPC POST /commitments/<slot_data>, which returns the corresponding commitment.

  2. The operator instructs the DAL node to compute and save the shards of the slot associated with the given commitment. It is important to set the query flag with_proof to true to be able to publish the shards on the P2P network. This is done via the RPC PUT /commitments/<commitment>/shards.

  3. The operator instructs the DAL node to compute the proof associated with the commitment. This is done via the RPC GET /commitments/<commitment>/proof, which returns the corresponding commitment proof.

  4. The operator selects a slot index for its slot, and posts the commitment to L1, via the publish_commitment operation. This can be done via RPCs for injecting an operation into L1, or using the Octez client, via the following command:

    octez-client publish dal commitment <commitment> from <pkh> for slot <slot_index> with proof <proof>
    
  5. Once the operation is included in a final block (that is, there are at least two blocks on top of the one including the operation), and the slot is considered published (see DAL overview), all DAL nodes exchange the slot’s shards they have in their store on the P2P network, depending on their profile (see The DAL’s P2P protocol), and they store previously unknown shards.

  6. Attesters check, for all published slots, the availability of the shards they are assigned by interrogating their DAL node, via the RPC GET /profiles/<pkh>/attested_levels/<level>/attestable_slots, where level is the level at which the slot was published plus attestation_lag, and pkh is the attester’s public key hash. (See also Bakers & the DAL)

  7. Attesters attach a DAL payload containing the information received at step 6 to their attestation operation, via their baker binary. (See also Bakers & the DAL)

  8. The protocol aggregates the received attestations, and declares each published slot as available or unavailable, depending on whether some threshold is reached, via the blocks metadata.

  9. Rollups and other users can request stored pages or shards for an attested slot from any DAL node via the RPCs GET /slot/pages/<commitment> or GET /shards/<commitment> respectively. Only nodes that store enough shards to reconstruct the slot can provide the requested pages.

Step 2 can be done in parallel with steps 3-4, but before step 5.