## Arbitrum ALT DA Spec
Arbitrum's ALT DA allows for external data availability providers to plug into the orbit stack without having to maintain exhaustive forks. At a high level, there are two major components which an external DA provider has to provide and manage for seamless integration:
1. [ALT DA Server](#ALT-DA-Server) for dispersing/retrieving rollup payloads and enhancing serialized one step proofs before they're submitted for resolution in the worst case challenge.
2. [A proof validator](#Onchain-Custom-DA-Proof-Validation) contract used for verifying ALTDA certificates and 32 byte preimages.
## ALT DA Server
**Protocol**: JSON-RPC 2.0 over HTTP/HTTPS
**Content-Type**: `application/json`
**Reference Commit**: [949806aefdd7bf3b1359069b3d2443baaa047bf3](https://github.com/OffchainLabs/nitro/tree/949806aefdd7bf3b1359069b3d2443baaa047bf3)
The ALT (Alternative/Custom) Data Availability Server provides an RPC interface for storing, retrieving, and validating data availability certificates for Arbitrum CustomDA implementations. This API enables external data availability providers to integrate with Arbitrum's batch poster, derivation pipeline, & fraud proof system.
---
### API Methods
#### 1. Get Supported Header Bytes
**Method**: `daprovider_getSupportedHeaderBytes`
**Description**: Gets supported header bytes used to distinguish an ALT DA provider
**Client Call Site**: Inbox derivation
**Call Frequency**: Every time an inbox message is processed
##### Parameters
N/A
##### Response
```json
{
"header-bytes": [`0x42`, `0x66`],
}
```
- `HeaderBytes` ([]byte): Identifier header bytes
#### 2. Store Data
**Method**: `daprovider_store`
**Description**: Stores data and returns a certificate for later retrieval
**Client Call Site**: Batch poster
**Call Frequency**: Every batch submission
##### Parameters
- `message` (`bytes`): Hex-encoded message bytes to store
- `timeout` (`integer`): Expiration timeout for server processing in seconds
- `disableFallbackStoreDataOnChain` (`bool`): If `false`, allows the ALT DA server to return a `failover` signal (i.e, `ErrBatchToDasFailed`) to the batch poster which results in the usage of secondary DA
##### Response
```json
{
"serialized-da-cert": "0x<hex_encoded_certificate>",
}
```
- `SerializedDACert` ([]byte): Opaque certificate for data retrieval
#### 3. Retrieve Data
**Method**: `daprovider_recoverPayload`
**Description**: Retrieves underlying batch data from external DA provider using serialized DA Cert bytes
**Client Call Site**: When parsing sequencer message from inbox
**Call Frequency**: For every inbox message when syncing from a confirmed or final chain head
##### Parameters
- `batchNum` (`uint`): The associated global state sequence batch number
- `batchBlockHash` (`bytes[32]`): (only used for 4844 retrieval) The L1 block hash containing the blob carrying tx
- `sequencerMsg` (`bytes`): Opaque sequencer message bytes. Assumed to be >40 bytes with message header prepended to `[0,40)`
##### Response
```json
{
"payload": "0x<hex_encoded_batch_data>",
}
```
- `payload` (`bytes`): The underlying batch data sent over during `daprovider_store`
#### 4. Collect Preimages
**Method**: `daprovider_collectPreimages`
**Description**: Retrieves the underlying batch data from external DA provide and embeds it into the Preimage oracle key/value
mapping for consumption by the downstream validation server.
**Client Call Site**: Stateless block validator
**Call Frequency**: every inbox message when doing defensive validation checks used for either creating, validating, to challenge a bridge assertion
##### Parameters
- `batchNum` (`uint`): The associated global state sequence batch number
- `batchBlockHash` (`bytes[32]`): (only used for 4844 retrieval) The L1 block hash containing the blob carrying tx
- `sequencerMsg` (`bytes`): Opaque sequencer message bytes. Assumed to be >40 bytes with message header prepended to `[0,40)`
##### Response
- `preimages` (`map[arbutil.PreimageType]map[common.Hash][]byte`): SHA256 hash for verification
#### 5. Generate `READPREIMAGE` Proof
**Method**: `daprovider_generateReadPreimageProof`
**Description**: Generates a proof for fraud proof validation. This method is only called during a one step proof by a BoLD validator to *enhance* or *enrich* the existing 32 byte preimage when receiving a `0xDA` marker byte from the Arbitrator's serialized machine state proof.
**Client Call Site**: BoLD Validator when collecting a machine state proof
**Call Frequency**: Worst case one step proof
##### Parameters
- `preimageType` `(uint)`: assumed to be `3` or `CustomDAPreimageType`
- `certHash` `(bytes[32])`: keccak256 hash of the certificate
- `offset` (`uint64`): integer offset of certificate hash in serialized one step proof
- `certificate` (`bytes`): DA Cert bytes
##### Response
```json
{
"proof": "0x01045984059840854"
}
```
- `proof`: extension proof bytes
#### 6. Generate Certificate Validity Proof
**Method**: `daprovider_generateCertificateValidityProof`
**Description:** Generates a DA Cert proof for fraud proof validation. This method is only called during a one step proof by a BoLD validator to enhance or enrich the existing DA Cert when receiving a `0xDB` marker byte from the Arbitrator's serialized machine state proof.
**Client Call Site**: BoLD Validator when collecting a machine state proof
**Call Frequency**: Worst case one step proof
##### Parameters
- `preimageType` `(uint)`: assumed to be `3` or `CustomDAPreimageType`
- `certificate` `(bytes)`: the raw DA Cert bytes
##### Response
```json
{
"proof": "0x01045984059840854"
}
```
* `proof`: extension proof bytes
## Onchain Custom DA Proof Validation
An external DA provider will need to provide a proof validation contract which adheres to the `ICustomDAProofValidator` interface:
```solidity=
interface ICustomDAProofValidator {
/**
* @notice Validates a custom DA proof and returns the preimage chunk
* @param certHash The keccak256 hash of the certificate (from machine's proven state)
* @param offset The offset into the preimage to read from (from machine's proven state)
* @param proof The proof data starting with [certSize(8), certificate, customData...]
* @return preimageChunk The 32-byte chunk of preimage data at the specified offset
*/
function validateReadPreimage(
bytes32 certHash,
uint256 offset,
bytes calldata proof
) external view returns (bytes memory preimageChunk);
/**
* @notice Validates whether a certificate is well-formed and legitimate
* @dev This function MUST NOT revert. It should return false for malformed or invalid certificates.
* The security model requires that the prover's validity claim matches what this function returns.
* If they disagree (e.g., prover claims valid but this returns false), the OSP will revert.
*
* The proof format is: [certSize(8), certificate, claimedValid(1), validityProof...]
* The validityProof section can contain additional verification data such as:
* - Cryptographic signatures
* - Merkle proofs
* - Timestamped attestations
* - Or other authentication mechanisms
* @param proof The proof data starting with [certSize(8), certificate, validityProof...]
* @return isValid True if the certificate is valid, false otherwise
*/
function validateCertificate(
bytes calldata proof
) external view returns (bool isValid);
}
```
where:
- a disputed [*ValidatePreimage*](###Validate-Preimage-Opcode) opcode resolves to a *validateCertificate* call
- a disputed [*ReadPreimage*](###Custom-DA-Preimage-Type) opcode with `CustomDA` type resolves to a `validateReadPreimage` call
The `ICustomProofValidator` is immutably stored in the `OneStepProverHostIo` contract - meaning that any bug fixes in this contract would require publishing a new one step proof machine onchain.
### Custom DA Preimage Type
A new `CustomDAPreimageType` is introduced for ALT DA where the preimage key is the keccak256 hash of the DA Cert read from the sequencer message. This deviates from existing preimage types where the preimage key is a direct output of a commitment function ran over the raw preimage contents (e.g, `Keccak256PreimageType` where `preimage_key = keccak256(raw_preimage)`.
**Replay Script**
A `CustomDAPreimageReader` is used to call the HostIO *ResolveTypedPreimage* function for preimage contents using the `keccak256(certificate_bytes)` as preimage key.
**Arbitrator**
`CustomDA` preimages bypass defensive validation checks performed by the arbitrator when ensuring that an ingested preimage oracle key->value mapping are correct w.r.t to key derivation from preimage contents (e.g, recomputing keccak256 commitment hash of preimage read during execution and enforcing equivalence with existing key).
### Validate Preimage Opcode
A new `ValidatePreimage` opcode has been introduced for `CustomDA` preimage type. This opcode is noop for all other preimage types and with logic only expressable for `CustomDAPreimageType`.
**Replay Script**
A `CustomDAPreimageReader` is used to call the HostIO *ValidatePreimage* function for preimage contents using the `keccak256(certificate_bytes)` as preimage key. In the non-provable golang representation, a simple existence check is performed:
```golang
func ValidatePreimage(ty arbutil.PreimageType, hash common.Hash) bool {
// In stub mode, check if the preimage exists
_, ok := preimages[hash]
return ok
}
```
**Arbitrator**
If the entire preimage is unattainable from the `preimageResolver` then it is considered invalid (`0`). Otherwise it is considered valid (`1`). These validations are assumed to happen during batch processing with an "invalid certificate" criteria determined by the ALT DA server when trying to fetch the batch on a `daprovider_recoverPayloadFromBatch` method.
## One Step Proving ALT DA Certs

1. A BoLD validator executes a `CollectProof` call which requests a one step proof at a specific execution trace position for some arbitrator execution over the disputed block
2. The validation server picks up the `getProof` rpc request, and begins serializing a machine state proof using the arbitrator binary
3. If the arbitrator prover sees the use of an ALTDA opcode expression; i.e:
**a.** `READPREIMAGE` w/ `CustomDAPreimageType`
**b.** `VALIDATEPREIMAGE`
then it proceeds to mark the proof as needing upstream *enhancement* when submitting the proof. Afterwards the raw `proof` bytes are returned to the calling BoLD validator.
4. When recieving the proof bytes from the validation server, the validator checks for the prevalence of a `0x80` enhancement flag. If found, then a "proof enhancer" is referenced which does either a:
- `daprovider_generateProof` call if a `READPREIMAGE` opcode proof
- `daprovider_generateCertificateValidityProof` if a `VALIDATEPREIMAGE` opcode proof
### Proof Composition
**ALT DA Machine State Proof Diagram**

**Enhanced READ Preimage Proof**

**Enhanced VALIDATE PREIMAGE Proof**
