Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/docs/disperser.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/docs/eigenda-protos.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/grpc/disperser/disperser.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/proto/disperser/disperser.proto
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ message DisperseBlobRequest {
// within the same batch.
repeated uint32 custom_quorum_numbers = 2;

// The account ID of the client. This should be a hex-encoded string of the ECSDA public key
// The account ID of the client. This should be a hex-encoded string of the ECDSA public key
// corresponding to the key used by the client to sign the BlobAuthHeader.
string account_id = 3;
}
Expand Down
13 changes: 8 additions & 5 deletions docs/spec/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
- [Retriever](./protobufs/generated/retriever.md)
- [RetrieverV2](./protobufs/generated/retriever_v2.md)
- [Integration](./integration.md)
- [Proxy](./integration/proxy.md)
- [Contracts](./integration/contracts.md)
- [Optimism](./integration/optimism.md)
- [Arbitrum](./integration/arbitrum.md)
- [ZKsync](./integration/ZKsync.md)
- [Spec](./integration/spec.md)
- [APIs](./integration/spec/1-apis.md)
- [Rollup Payload Lifecycle](./integration/spec/2-rollup-payload-lifecycle.md)
- [DataStructs](./integration/spec/3-datastructs.md)
- [Contracts](./integration/spec/4-contracts.md)
- [Lifecycle Phases](./integration/spec/5-lifecycle-phases.md)
- [Secure Integration](./integration/spec/6-secure-integration.md)
- [Rollup Stacks](./integration/rollup-stacks.md)
- [V1](./v1.md)
1 change: 0 additions & 1 deletion docs/spec/src/apis.md

This file was deleted.

Binary file removed docs/spec/src/assets/eigenda-contracts.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/spec/src/assets/integration/image 6.png
Binary file not shown.
Binary file removed docs/spec/src/assets/rollup-contracts.png
Binary file not shown.
622 changes: 4 additions & 618 deletions docs/spec/src/integration.md

Large diffs are not rendered by default.

9 changes: 0 additions & 9 deletions docs/spec/src/integration/arbitrum.md

This file was deleted.

5 changes: 0 additions & 5 deletions docs/spec/src/integration/contracts.md

This file was deleted.

5 changes: 0 additions & 5 deletions docs/spec/src/integration/optimism.md

This file was deleted.

5 changes: 0 additions & 5 deletions docs/spec/src/integration/proxy.md

This file was deleted.

23 changes: 23 additions & 0 deletions docs/spec/src/integration/rollup-stacks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Rollup Stacks

## OP Stack

Links:
- [Our OP Fork](https://github.com/Layr-Labs/optimism)
- [Fork Diff](https://layr-labs.github.io/optimism/)

## Arbitrum Nitro

Our up-to-date Nitro docs are available at [docs.eigenda.xyz](https://docs.eigenda.xyz/integrations-guides/rollup-guides/orbit/overview).

We maintain fork diffs for the different nitro repos that we fork:
- [nitro](https://layr-labs.github.io/nitro/)
- [nitro-contracts](https://layr-labs.github.io/nitro-contracts/)
- [nitro-testnode](https://layr-labs.github.io/nitro-testnode/)
- [nitro-go-ethereum](https://layr-labs.github.io/nitro-go-ethereum/)

## ZKsync ZK Stack

ZKSync-era currently supports and maintains a [validium mode](https://docs.zksync.io/zk-stack/running/validium), which means we don't need to fork ZKSync, unlike the other stacks.

The zksync eigenda client is implemented [here](https://github.com/matter-labs/zksync-era/tree/8ce774d20865a2b5223d26e10e227f0ea7cb3693/core/node/da_clients/src/eigen). It makes use of our [eigenda-client-rs](https://github.com/Layr-Labs/eigenda-client-rs) repo.
85 changes: 85 additions & 0 deletions docs/spec/src/integration/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# EigenDA V2 Integration Spec

# Overview

The [EigenDA V2](https://docs.eigenda.xyz/releases/v2) release documentation describes the architectural changes that allow for important network performance increases. From the point of view of rollup integrations, there are three important new features:

1. Blob batches are no longer bridged to Ethereum with dispersals now being confirmed once a batch has been `CERTIFIED` (i.e, signed over by operator set). This operation takes 10-20 seconds - providing lower confirmation latency and higher throughput for the rollup. Verification of the blobs now needs to be done by the rollup stack.
2. Centralized (accounting done by disperser) payments model
3. A new relay API from which to retrieve blobs (distinct from the disperser API which is now only used to disperse blobs)

# Diagrams

We will refer to the below diagrams throughout the spec.

### High Level Diagram

![image.png](../assets/integration/high-level-diagram.png)

### Sequence Diagram

```mermaid
sequenceDiagram
box Rollup Sequencer
participant B as Batcher
participant SP as Proxy
end
box EigenDA Network
participant D as Disperser
participant R as Relay
participant DA as DA Nodes
end
box Ethereum
participant BI as Batcher Inbox
participant BV as EigenDABlobVerifier
end
box Rollup Validator
participant VP as Proxy
participant V as Validator
end

%% Blob Creation and Dispersal Flow
B->>SP: Send payload
Note over SP: Encode payload into blob
alt
SP->>D: GetBlobCommitment(blob)
D-->>SP: blob_commitment
else
SP->>SP: Compute commitment locally
end
Note over SP: Create blob_header including payment_header
SP->>D: DisperseBlob(blob, blob_header)
D-->>SP: QUEUED status + blob_header_hash

%% Parallel dispersal to Relay and DA nodes
par Dispersal to Storage
R->>D: Pull blob
and Dispersal to DA nodes
D->>DA: Send Headers
DA->>R: Pull Chunks
DA->>D: Signature
end

loop Until CERTIFIED status
SP->>D: GetBlobStatus
D-->>SP: status + signed_batch + blob_verification_info
end
SP->>BV: getNonSignerStakesAndSignature(signed_batch)
SP->>BV: verifyBlobV2(batch_header, blob_verification_info, nonSignerStakesAndSignature)
SP->>BI: Submit cert = (batch_header, blob_verification_info, nonSignerStakesAndSignature)

%% Validation Flow
V->>BI: Read cert
V->>VP: GET /get/{cert} → cert
activate V
Note over VP: Extract relay_key + blob_header_hash from cert
VP->>R: GetBlob(blob_header_hash)
R-->>VP: Return blob
VP->>BV: verifyBlobV2
VP-->>V: Return validated blob
deactivate V
```

### Ultra High Resolution Diagram

![image.png](../assets/integration/ultra-high-res-diagram.png)
60 changes: 60 additions & 0 deletions docs/spec/src/integration/spec/1-apis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# APIs

Below we give a summary of the APIs relevant to understanding the EigenDA high-level diagram

![](../../assets/integration/high-level-diagram.png)

### Proxy

See our gorilla/mux [routes](https://github.com/Layr-Labs/eigenda-proxy/blob/main/server/routing.go) for full detail, but the gist is that proxy presents a REST endpoint based off of the [op da-server spec](https://specs.optimism.io/experimental/alt-da.html#da-server) to rollup batchers:

```
# OP
POST /put body: <preimage_bytes> → <hex_encoded_commitment>
GET /get/{hex_encoded_commitment} → <preimage_bytes>
# NITRO
Same as OP but add a `?commitment_mode=standard` query param
to both POST and GET methods.
```

### Disperser

The disperser presents a [grpc v2 service](https://github.com/Layr-Labs/eigenda/blob/ce89dab18d2f8f55004002e17dd3a18529277845/api/proto/disperser/v2/disperser_v2.proto#L10) endpoint

```bash
$ EIGENDA_DISPERSER_PREPROD=disperser-preprod-holesky.eigenda.xyz:443
$ grpcurl $EIGENDA_DISPERSER_PREPROD list disperser.v2.Disperser
disperser.v2.Disperser.DisperseBlob
disperser.v2.Disperser.GetBlobCommitment
disperser.v2.Disperser.GetBlobStatus
disperser.v2.Disperser.GetPaymentState
```

### Relay

Relays similarly present a [grpc service](https://github.com/Layr-Labs/eigenda/blob/ce89dab18d2f8f55004002e17dd3a18529277845/api/proto/relay/relay.proto#L10) endpoint

```bash
$ EIGENDA_RELAY_PREPROD=relay-1-preprod-holesky.eigenda.xyz:443
$ grpcurl $EIGENDA_RELAY_PREPROD list relay.Relay
relay.Relay.GetBlob
relay.Relay.GetChunks
```

### Contracts

The most important contract for rollups integrations is the EigenDACertVerifier, which presents a [function](https://github.com/Layr-Labs/eigenda/blob/98e21397e3471d170f3131549cdbc7113c0cdfaf/contracts/src/core/EigenDACertVerifier.sol#L86) to validate Certs:

```solidity
/**
* @notice Verifies a blob cert for the specified quorums with the default security thresholds
* @param batchHeader The batch header of the blob
* @param blobInclusionInfo The inclusion proof for the blob cert
* @param nonSignerStakesAndSignature The nonSignerStakesAndSignature to verify the blob cert against
*/
function verifyDACertV2(
BatchHeaderV2 calldata batchHeader,
BlobInclusionInfo calldata blobInclusionInfo,
NonSignerStakesAndSignature calldata nonSignerStakesAndSignature
) external view
```
84 changes: 84 additions & 0 deletions docs/spec/src/integration/spec/2-rollup-payload-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Rollup Payload Lifecycle

How is a rollup’s payload (compressed batches of transactions or state transition diffs) encoded and made available on the EigenDA network?

```mermaid
flowchart TD
subgraph Rollups[Rollup Domain]
RS["Rollup Sequencer<br/>[Software System]<br/>Sequences the rollup; submits rollup payloads to EigenDA for data availability"]
RV["Rollup Validator<br/>[Software System]<br/>Runs a derivation pipeline to validate the rollup"]
Payload[("Rollup Payload<br/>[Data]<br/>Batches of tx data or state transition diffs")]
end

%% Standalone proxy
Proxy["Proxy<br/>[Software System]<br/>Bridges domains by encoding/decoding payloads/blobs"]

subgraph EigenDA[Data Availability Domain]
EN["EigenDA Network<br/>[Software System]<br/>Provides decentralized data availability by storing and serving blobs"]
Blob[("Blob<br/>[Data]<br/>Rollup payload encoded into bn254 field element array")]
Cert[("DA Certificate<br/>[Data]<br/>Proof of Data Availability. Used to retrieve and validate blobs.")]
ETH["Ethereum<br/>[Software System]<br/>Stores EigenDA network properties like operator stakes, etc. Also validates certs."]
end

%% Sequencer Flow
RS -->|"(1) Creates"| Payload
Payload -->|"(2) Sent to"| Proxy
Proxy -->|"(3) Encodes into"| Blob
Blob -->|"(4) Dispersed across"| EN
EN -->|"(5) Verifies signatures according to stakes stored on"| ETH
EN -->|"(6) Returns cert"| Proxy
Proxy -->|"(7) Submits"| Cert
Cert -->|"(8) Posted to"| ETH

%% Validator Flow
RV -->|"(9) Reads certificates"| ETH
RV -->|"(10) Retrieve Compressed Batch from Certificate"| Proxy

%% Styling
classDef system fill:#1168bd,stroke:#0b4884,color:white
classDef container fill:#23a,stroke:#178,color:white
classDef data fill:#f9f,stroke:#c6c,color:black
classDef red fill:#916,stroke:#714,color:white

class RS,RV,EN,ETH,S1,Proxy system
class Rollups,EigenDA container
class Batch,Blob,Cert,D1 data
```

At a high-level, a rollup sequencer needs to make its `payload` available for download from validators of its network. The EigenDA network makes use of cryptographic concepts such as KZG commitments as fundamental building blocks. Because of this, it can only work with `eigenda blobs` (hereafter referred to simply as `blobs`; see technical definition below) of data. The [EigenDA proxy](https://github.com/Layr-Labs/eigenda-proxy) is used to bridge the rollup domain (which deals with payloads) and the EigenDA domain (which deals with blobs).

As an example, an op-stack Ethereum rollup’s `payload` is a compressed batch of txs (called a [frame](https://specs.optimism.io/protocol/derivation.html#frame-format)). This frame gets sent to Ethereum to be made available either as a simple tx, or as a [`4844 blob`](https://eips.ethereum.org/EIPS/eip-4844#type-aliases) (using a [blob tx](https://eips.ethereum.org/EIPS/eip-4844#blob-transaction)). Using EigenDA instead of Ethereum for data availability works similarly: the payloads are encoded into an `eigenda blob` and dispersed to the EigenDA network via an EigenDA disperser. The disperser eventually returns a `DA Certificate` containing signatures of EigenDA operators certifying the availability of the data, which is then posted to Ethereum as the `input` field of a normal tx. Note that due to the rollup settling on Ethereum, Ethereum DA is needed, but only to make the `DACert` available, which is much smaller than the `blob` itself.

[**Data structs**](./3-datastructs.md)

- `Payload`: piece of data that an EigenDA client (rollup, avs, etc.) wants to make available. This is typically compressed batches of transactions or state transition diffs.
- `EncodedPayload`: payload encoded into a list of bn254 field elements (each 32 bytes), typically with a prefixed field element containing the payload length in bytes, such that the payload can be decoded.
- `PayloadPolynomial` : encodedPayload padded with 0s to the next power of 2 (if needed) and interpreted either as evaluations (`PolyCoeff`) or coefficients (`PolyEval`) of a polynomial. Because the EigenDA network interprets blobs as coefficients, a `PolyEval` will need to be IFFT’d into a `PolyCoeff` before being dispersed.
- `(EigenDA) Blob`: array of bn254 field elements of length a power of two. Interpreted by the network as coefficients of a polynomial. Equivalent to `PolyCoeff`.
- `Blob Header`: contains the information necessary to uniquely identify a BlobDispersal request.
- `Blob Certificate`: Signed BlobHeader along with relayKeys, which uniquely identify a relay service for DA Nodes to retrieve chunks from and clients to retrieve full blobs from.
- `Batch`: Batch of blobs whose blob certs are grouped into a merkle tree and dispersed together for better network efficiency.
- `DA Certificate` (or `DACert`): contains the information necessary to retrieve and verify a blob from the EigenDA network, along with a proof of availability.
- `AltDACommitment`: RLP serialized `DACert` prepended with rollup-specific header bytes. This commitment is what gets sent to the rollup’s batcher inbox.

[**Contracts**](./4-contracts.md)

- `EigenDACertVerifier`: contains one main important function verifyCertV2 which is used to verify `DACert`s.
- `EigenDAThresholdRegistry`: contains signature related thresholds and blob→chunks encoding related parameters.
- `EigenDARelayRegistry`: contains an Ethereum address and DNS hostname (or IP address) for each registered Relay.
- `EigenDADisperserRegistry` : contains an Ethereum address network for each registered Disperser.

[**Lifecycle phases**](./5-lifecycle-phases.md)

- Sequencer:
- `Encoding`: Payload → Blob
- `BlobHeader Construction`: Blob → BlobHeader
- `Dispersal`: (Blob, BlobHeader) → Certificate
- Certificate+Blob `Validation`
- Unhappy path: `Failover` to EthDA
- `Posting`: Certificate → Ethereum tx
- Validator (exact reverse of sequencer):
- `Reading`: Ethereum tx → Certificate
- `Retrieval`: Certificate → Blob
- Certificate+Blob `Validation`
- `Decoding`: Blob → Payload
Loading
Loading