When deploying the rollup, by default it is set to rollup mode: all transactions are sent to L1. If we want to change that behavior,
we specify these fields in the deploy-config of our rollup contracts:
"enableDAC": true,
"dacPublicKeys": [
"10c36f69c5f73a0ae95fa1768e68a58973d0a3a61f1e9bf889050217388ebb24c57341fb5528b8f2b6138d5149d88c611003f241a22da86d76e15cdfdc06d6ea86845d5f662e3209044716add654d98aa6a9c99632b2d647ac280e36d9da5756",
"1866562f34d7339fc7831b4b6a47defe714007f4720d03849f2e90b0ee8330d56d76e0957f500fe76f24e6a730016bcf091e3ba87744ceefd90503b120550eb9554f5683b739fb1cbdd6e56ac7b89288e9f35ce7e32d40008f347b21e036602c",
"1830f58c42f446a5659c08a5c39a2734cdbca673007076612384387d3f79e6c44c2427012cac0b011c698b9c0d5834920a7ec51884e4f7b43d73a683d1038c1b940dd4c1aa69bd097419b8ed69ff9447e44c9da1e8ea38ac916655260a42b14e"
],
"dacHonnestMembersAssumption": 2
This will generate a rollup configuration that embeds these information.
In the rollup.json
, we add a data_availability_committee
field that describes the properties of the DAC. This means that the DAC is part of the rollup configuration :
"data_availability_committee": {
"public_keys": [
"07e23eb4be09609d92e73a4660f6b543ba26777d53db3e1ef64ef934177a82fe090f3bf31bb0fd0adb9ee7a2e4cf3260184ea695cfbb36ffeb1bc6183268c3ff0799699cdfa067b6aea70e908b3b8b31e924fa70fc105fda531b80f9ccbb528e",
"0f630b04de66c7a4120344dba4e46954bf48f9faa7b9085ee1fdb3a2880af43ae8c7dac640d2ad7d93ff38f5737c3d1000070a64414e9607dd75ca886f52cfdb4745d3f443332e69c5f73ee23fcff62593b24504b29b65f3fb5aaa2a6516d729",
"0bf160cda8786d5c50ef3841a1412fce870f718cc838dce3bd1ef1ef2e3a6a8141d374ceb45f17b7dcd0d628782549110295a32173312d888a6a75c9b5ed917624cd81c70cde56fe8cea304cb537f5cf6ea0dd74ea00996a36640cd8ae38a37f"
],
"honnest_members_assumption": 2
},
type BatchRef interface {
ToTx() (Tx, error)
}
type Client interface {
PostBatch(data []byte) (BatchRef, error)
GetBatch(ref []byte) ([]byte, error)
}
We propose a simple implementation of a Data Availability Client. A DA client should be able to
When we instanciate a node. The only thing we now need to do is create the correct DA client. By default we provide a rollup mode.
If the rollup configuration specifies a Data Availability Committee, we enter DAC mode.
// by default use rollup mode
daClient := rollupda.NewClient(rollupConfig.BatchInboxAddress)
daURL := ctx.GlobalString(flags.CentralizedDAApiFlag.Name)
if rollupConfig.DataAvailabilityComittee != nil {
log.Info("initializing DAC da client", "url", daURL)
log.Info("public keys", "public_keys", rollupConfig.DataAvailabilityComittee.PublicKeys)
keyset, err := dac.NewKeySetFromString(rollupConfig.DataAvailabilityComittee.PublicKeys)
if err != nil {
return nil, fmt.Errorf("could not create DAC keyset: %w", err)
}
daClient = dac.NewClient(daURL, rollupConfig.BatchInboxAddress, keyset)
}
We modified op-batcher to make it publish batch references. It will let the DA client implementation chose what to post or not to post. The DA client will also make relevant calls it needs to do to store the given payload.
// delegate DA posting logic to the client
batchRef, err := l.DA.PostBatch(data)
if err != nil {
l.log.Error("unable to publish data to DA", "err", err, "data_size", len(data))
return
}
tx, err := batchRef.ToTx()
if err != nil {
l.log.Error("unable to construct tx from batch ref", "err")
}
At the derivation step, each transaction contains a batch reference. Since the DA mode is described in the rollup configuration, we can safely pass the batch reference to the DA client implementation that will do what it needs to do to fetch the correct payload.
// delegate getting batch data to the DA client
ref := tx.Data()
data, err := daClient.GetBatch(ref)
if err != nil {
return nil, fmt.Errorf("could not retrieve batch from ref: %w", err)
}
To make a new implementation, one needs to :
We provide an implementation of a DAC in our optimism fork.