CDK DA Integration
The purpose of this document is to explain how a 3rd Party Data Availability (DA) solution can integrate with CDK.
Considerations
The code outlined in this document is under development, and while we’re confident that it will be ready for production in a few weeks, it is currently under heavy development.
For the first iteration of integrations, on-chain verification is not expected. Although this document shows how this could be done at the contract level (doing such a thing on the ZKPs is out of the scope right now). In any case, Agglayer will assert that the data is actually available before settling ZKPs.
Smart Contracts
The versions of the smart contracts that are being targeted for the DA integrations are found in zkevm-contracts @ feature/banana. This new version of the contracts allow for multiple “consensus” implementations but there are two that are included by default:
- zkEVM to implement a rollup.
- Validium to implement a validium.
- Adding a custom solution.
This document only considers the first approach, reusing the PolygonValidium
consensus. That being said, the PolygonValidium
implementation allows a custom smart contract to be used in the relevant interaction. This could be used by DAs to add custom on-chain verification logic. While verifying the DA integrity is optional, any new protocol will need to develop a custom smart contract in order to be successfully integrated (more details bellow)
This is by far the most relevant part of the contract for DAs:
function sequenceBatchesValidium(
ValidiumBatchData[] calldata batches,
uint32 indexL1InfoRoot,
uint64 maxSequenceTimestamp,
bytes32 expectedFinalAccInputHash,
address l2Coinbase,
bytes calldata dataAvailabilityMessage
) external onlyTrustedSequencer {
And in particular this piece of code:
// Validate that the data availability protocol accepts the dataAvailabilityMessage
// note This is a view function, so there's not much risk even if this contract was vulnerable to reentrant attacks
dataAvailabilityProtocol.verifyMessage(
accumulatedNonForcedTransactionsHash,
dataAvailabilityMessage
);
It's expected that any protocol build their own contract that follows this interface, in the same way that the PolygonDataCommittee
does. The implementation of verifyMessage
is dependant on each protocol, and in a first iteration could be "dummy", since the AggLayer will ensure that the DA is actually available anyway. That being said we expect protocol integrations to evolve towards "trustless verification"
Setup the Node
In order to integrate a DA solution into CDK, the most fundamental part is for the node to be able to post and retrieve data from the DA backend.
Up until now, DAs would fork the cdk-validium-node
repo to make such an integration. But maintaining forks can be really painful, so the team is proposing this solution that will allow the different DAs to be 1st class citizens and live on the official cdk
repo.
These items would need to be implemented to have a successful integration:
- Create a repository that will host the package that implements this interface. You can check how is done for the DAC case as an example.
- Add a new entry on the supported backend strings
- [OPTIONAL] Add a config struct in the new package, and add the struct inside the main data availability config struct, this way your package will be able to receive custom configuration using the main config file of the node.
go get
and instantiate your package and use it to create the main data availability instance, as done in the Polygon implementation.
tip
By default all E2E tests will run using the DAC. It’s possible to run the E2E test using other DA backends changing the test config file.
Test the integration
- Create an E2E test that uses your protocol by following the test/e2e/datacommittee_test.go example.
- Follow the instructions on Local Debug to run Kurtosis enviroment for local testing
- Deploy the new contract contract to L1 running in Kurtosis
- Call
setDataAvailabilityProtocol
in validium consensus contract to use the newly deployed contract. - Modify the
Makefile
to be able to run your test, take the case of the DAC test as an example here
Example flow
- Sequencer groups N batches of arbitrary size into a sequence
- Sequencer calls
PostSequence
- The DA BAckend implementation decides to split the N batches into M chunks, so they fit as good as possible to the size of the DA blobs of the protocol (or other considerations that the protocol may have)
- The DA BAckend crafts the
dataAvailabilityMessage
, this is optional but could be used to:- Verify the existance of the data on the DA backend on L1 (this message will be passed down to the DA smart contract, and it could include merkle proofs, ...). Realisitcally speaking, we don't expect to be implemented on a first iteration
- Help the data retrival process, for instance by including the block height or root of the blobs used to store the data. If many DA blobs are used to store a single sequence, one interesting trick would be to post some metadata in another blob, or the lates used blob, that points to the other used blobs. This way only the pointer to the metadata is needed to include into the
dataAvailabilityMessage
(since this message will be posted as part of the calldata, it's interesting to minimize it's size)
- The sequencer posts the sequence on L1, including the
dataAvailabilityMessage
. On that call, the DA smart contract will be called. This can be used to validate that the DA protocol has been used as expected (optional) - After that happens, any node synchronizing the network will realise of it through an event of the smart contract, and will be able to retrieve the hashes of each batch and the
dataAvailabilityMessage
- And so it will be able to call
GetSequence(hashes common.Hash, dataAvailabilityMessage []byte)
to the DA Backend - The DA BAckend will then retrieve the data, and return it