How to configure the Data Availability Committee (DAC) in your chain
AnyTrust chains rely on an external Data Availability Committee (DAC) to store data and provide it on-demand instead of using its parent chain as the Data Availability (DA) layer. The members of the DAC run a Data Availability Server (DAS) to handle these operations. Once the DA servers are running, the chain needs to be configured with their information to effectively store and retrieve data from them.
In this how-to, you'll learn how to configure the DAC in your chain. Refer to the Introduction for the full process of running DA servers and configuring the chain.
This how-to assumes that you're familiar with:
- The DAC's role in the AnyTrust protocol. Refer to Inside AnyTrust for a refresher.
- Kubernetes. The examples in this guide use Kubernetes to containerize your DAS.
- How to deploy a Data Availability Server (DAS). This is needed to understand where the data we'll be handling in this guide comes from.
- The Foundry toolkit
Step 0: Prerequisites
Before starting to generate the keyset and configuring the nodes and chain, you'll need to gather the following information from all the DA servers run by the DAC members:
- Public BLS Key
- URL of the RPC endpoint
- URL(s) of the REST endpoint(s)
You should also make sure that at least one DAS is running as an archive DAS, otherwise the information will not be available after the expiry time.
Step 1: Generate the keyset and keyset hash with all the information from the servers
What is a keyset?
The AnyTrust protocol assumes that for the n members of the DAC, a minimum of h members maintain integrity. So h is then the minimum number of trusted committee members on an AnyTrust chain. In scenarios where k = (n + 1) - h members of the DAC pledge to grant access to a specific piece of information, these k members must sign and attest they have stored the data to be considered successful.
To perform this signing operation, each DAC member must generate their own set of BLS public and private keys. They should do this independently and ensure these keys are random and only used by them. You can find more information about how to generate a BLS pair of keys in Generating BLS Keys.
An Anytrust chain needs to know all DAC members' public keys to validate the integrity of the data being batched and posted. A keyset is a list of all DAC members' RPC endpoint and BLS public key. Additionally, it also contains information about how many signatures are needed to approve a Data Availability Certificate (DACert), via a special assumed-honest parameter (i.e., the h parameter we mentioned above). This design lets the chain owner modify the DAC membership over time, and DAC members change their keys if needed. See Inside AnyTrust for more information.
We use this keyset, and its hash to configure the SequencerInbox contract with the valid keyset, and also the batch poster (to request storing information) and full nodes (to request information already stored).
How to generate a keyset and a keyset hash
Nitro comes with a special tool to generate both the keyset and the keyset hash. To use it, you need to first structure the keyset information in a JSON object with the following structure:
{
"keyset": {
"assumed-honest": h,
"backends": [
{
"url": "https://rpc-endpoint-of-member-1/",
"pubkey":"PUBLIC_KEY_OF_MEMBER_1"
},
{
"url": "https://rpc-endpoint-of-member-2/",
"pubkey":"PUBLIC_KEY_OF_MEMBER_2"
},
...
{
"url": "https://rpc-endpoint-of-member-n/",
"pubkey":"PUBLIC_KEY_OF_MEMBER_N"
}
]
}
}
The JSON fields represent the following:
assumed_honestis the amount of members that we assume are honest from thenmembers of the DAC. This is thehvariable we mentioned in the previous section.backendscontain information about each member of the DAC:urlcontains the RPC endpoint of the DAS run by that memberpubkeycontains the base64-encoded BLS public key used in the DAS run by that member
Once you have the JSON structure, save it into a file, for example, keyset-info.json.
Finally, we'll use Nitro's datool dumpkeyset utility inside Docker to generate the keyset and keyset hash.
docker run -v $(pwd):/data/keyset --entrypoint datool offchainlabs/nitro-node:v3.4.0-d896e9c dumpkeyset --conf.file /data/keyset/keyset-info.json
This command will output two results: Keyset and KeysetHash. Save them to use in the next steps.
Example with mocked-up data
Here's an example that uses mocked-up data:
The JSON file is:
{
"keyset": {
"assumed-honest": 2,
"backends": [
{
"url": "http://example",
"pubkey": "YAbcteVnZLty5qRebeswHKhdjEMVwdou+imSfyrI+yVXHOMdLWA3Nf4DGW9tVry/mhmZqJp01TaYIsREXWdsFe1S5QCNqnddyag5yZ/5Y6GZRqx0BXmHTaxPY5kHrhvGnwxmlJVbUk1xjKRFgxxTdTk3c0AfM3JaeWYTed3avV//KGGdwHC+/Z7XPWmeXCNsGhY75YuoEAK2EwcJvAZK9de6lHEwtyBWvxcmOADxo6siacalEO+OdBL9VtHvG5FqEwbjsdnILAmTcb2YYVgqyq2joW6d/uXQ685hCWWYqC8RLQqTXoyrXEjYLjEEsMe6eRV9rRoBmj5/atB3uOYwixFv7A9YI5YiRjw2MfoB4rQnJAkhW4AJQiwWcV2+3lkJBg=="
},
{
"url": "http://example",
"pubkey": "YAg1+ZXyR48kiS0FDaoon4trnBsYW80oUy+I1hDCZCotxvNQl0AjbTPD4tkTaqsX+BnIxnEpO7ondxd2Lo0cH3usnhfdKNKTmpWbs45QD5wRw4zrvEJuLeqXxAF1plXRdACubHX/SeiEx5RpJJ5wlTJYhUtk+oRFxYWtRdxtxpdVAcavfP9wdCAsaH+Ke/GjrBkmiXVfIyJ1tMhCGxpWaem5BMKaKSzflht4OnwLTOc2kA3k2MY8X4WmXLRK80vvhArO+Eq3X0TEyRN2ELaBB6/zu9zBkRnHqSfBFbe5v7J9hcUA7nfRPsWpejrmv1HTtwpVAuhBbee1646f7uN2QRyjXIp/P1l8dgZXjPlqRxXOWjXPSOOcCh+qLe4i105oGQ=="
}
]
}
}