Skip to content

Commit 0a61560

Browse files
authored
feat(docs): Secure dispersal/retrieval system flows (#1652)
* feat(docs): Secure dispersal/retrieval system flows * feat(docs): Secure dispersal/retrieval system flows - address numbering comment * feat(docs): Secure dispersal/retrieval system flows - rework structuring and move blob header to data-structs section * feat(docs): Secure dispersal/retrieval system flows - add router section to secure integration section * feat(docs): Secure dispersal/retrieval system flows - fix data structs * feat(docs): Secure dispersal/retrieval system flows - address PR comments * feat(docs): Secure dispersal/retrieval system flows - address Sam PR comments * feat(docs): Secure dispersal/retrieval system flows - update fraud proof diagram w/ router * feat(docs): Secure dispersal/retrieval system flows - address pr comments * feat(docs): Secure dispersal/retrieval system flows - address pr comments again
1 parent 319a865 commit 0a61560

File tree

9 files changed

+158
-78
lines changed

9 files changed

+158
-78
lines changed

docs/spec/src/SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Summary
22

33
- [Introduction](./introduction.md)
4+
- [Glossary](./glossary.md)
45
- [Core Protocol](./protocol.md)
56
- [Architecture](./protocol/architecture.md)
67
- [Encoding](./protocol/architecture/encoding.md)
@@ -12,7 +13,7 @@
1213
- [Spec](./integration/spec.md)
1314
- [APIs](./integration/spec/1-apis.md)
1415
- [Rollup Payload Lifecycle](./integration/spec/2-rollup-payload-lifecycle.md)
15-
- [DataStructs](./integration/spec/3-datastructs.md)
16+
- [Data Structs](./integration/spec/3-data-structs.md)
1617
- [Contracts](./integration/spec/4-contracts.md)
1718
- [Lifecycle Phases](./integration/spec/5-lifecycle-phases.md)
1819
- [Secure Integration](./integration/spec/6-secure-integration.md)
84.1 KB
Loading
200 KB
Loading
81.7 KB
Loading

docs/spec/src/glossary.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Glossary
2+
3+
## Rollup Batcher
4+
5+
Sequencer rollup node component responsible for constructing and submitting to the settlement chain user transaction batches
6+
7+
## Rollup Nodes
8+
9+
Refers to any rollup node (e,g, validator, verifier) which syncs current chain state through an onchain sequencer inbox.
10+
11+
## EigenDA Proxy
12+
13+
Side car server as a part of rollup and used for secure and trustless communication with EigenDA.
14+
15+
## EigenDA Client
16+
17+
Refers to collection of client [modules](https://github.com/Layr-Labs/eigenda/tree/bb91b829995c28e813fce46412a77f9fa428b0af/api/clients/v2) used for securely dispersing and reading EigenDA blobs.

docs/spec/src/integration/spec/2-rollup-payload-lifecycle.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ At a high-level, a rollup sequencer needs to make its `payload` available for do
4949

5050
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 `DACert` 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.
5151

52-
[**Data structs**](./3-datastructs.md)
52+
[**Data structs**](./3-data-structs.md)
5353

5454
- `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.
5555
- `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.

docs/spec/src/integration/spec/3-datastructs.md renamed to docs/spec/src/integration/spec/3-data-structs.md

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,77 @@ A `blob` is a bn254 field elements array that has a power of 2. It is interprete
5555

5656
An `encodedPayload` can thus be transformed into a `blob` by being padded with 0s to a power of 2, with size currently limited to 16MiB. There is no minimum size, but any blob smaller than 128KiB will be charged for 128KiB.
5757

58-
### BlobHeader And BlobCertificate
58+
### BlobHeader
5959

60-
The `blobHeader` is submitted alongside the `blob` as part of the DisperseBlob request, and the hash of its rlp serialization (`blobKey` aka `blobHeaderHash`) is a unique identifier for a blob dispersal. This unique identifier is used to retrieve the blob.
60+
The `blobHeader` is submitted alongside the `blob` as part of the `DisperseBlob` request, and the hash of its ABI encoding (`blobKey`, also known as `blobHeaderHash`) serves as a unique identifier for a blob dispersal. This identifier is used to retrieve the blob.
6161

62-
![image.png](../../assets/integration/blob-certificate.png)
62+
The `BlobHeader` contains four main sections that must be constructed. It is passed into the `DisperseBlobRequest` and is signed over for payment authorization.
6363

6464
Refer to the eigenda [protobufs](https://github.com/Layr-Labs/eigenda/blob/master/api/proto/disperser/v2/disperser_v2.proto) for full details of this struct.
6565

66-
### DACertificate
66+
#### Version
67+
The `blobHeader` version refers to one of the `versionedBlobParams` structs defined in the [`EigenDAThresholdRegistry`](./4-contracts.md#eigendathreshold-registry) contract.
6768

68-
A `DA Certicate` (or short `DACert`) contains all the information needed to retrieve a blob from the EigenDA network, as well as validate it.
69+
#### QuorumNumbers
70+
71+
`QuorumNumbers` represents a list of quorums required to sign and make the blob available. Quorum 0 represents the ETH quorum, quorum 1 represents the EIGEN quorum — both are always required. Custom quorums can also be added to this list.
72+
73+
#### BlobCommitment
74+
75+
The `BlobCommitment` is a binding commitment to an EigenDA Blob. Due to the length field, a `BlobCommitment` uniquely represents a single `Blob`. The length field is added to the kzgCommitment to respect the binding property. It is used by the disperser to prove to EigenDA validators that the chunks they received belong to the original blob (or its Reed-Solomon extension). This commitment can either be computed locally by the *EigenDA Client* from the blob or generated by the disperser via the `GetBlobCommitment` [endpoint](./../../protobufs/generated/disperser_v2.md#disperserv2disperser_v2proto###disperser).
76+
77+
78+
```protobuf
79+
message BlobCommitment {
80+
// A G1 commitment to the blob data.
81+
bytes commitment = 1;
82+
// A G2 commitment to the blob data.
83+
bytes length_commitment = 2;
84+
// Used with length_commitment to assert the correctness of the `length` field below.
85+
bytes length_proof = 3;
86+
// Length in bn254 field elements (32 bytes) of the blob. Must be a power of 2.
87+
uint32 length = 4;
88+
}
89+
```
90+
91+
Unlike Ethereum blobs which are all 128KiB, EigenDA blobs can be any power of 2 length between 32KiB and 16MiB (currently), and so the `commitment` alone is not sufficient to prevent certain attacks:
92+
93+
- Why is a commitment to the length of the blob necessary?
94+
95+
There are different variants of the attack. The basic invariant the system needs to satisfy is that with the chunks from sufficient set of validators, you can get back the full blob. So the total size of the chunks held by these validators needs to exceed the blob size. If I don't know the blob size (or at least an upper bound), there's no way for the system to validate this invariant.
96+
Here’s a simple example. Assume a network of 8 DA nodes, and coding ratio 1/2. For a `blob` containing 128 field elements (FEs), each node gets 128*2/8=32 FEs, meaning that any 4 nodes can join forces and reconstruct the data. Now assume a world without length proof; a malicious disperser receives the same blob, uses the same commitment, but claims that the blob only had length 4 FEs. He sends each node 4*2/8=1 FE. The chunks submitted to the nodes match the commitment, so the nodes accept and sign over the blob’s batch. But now there are only 8 FEs in the system, which is not enough to reconstruct the original blob (need at least 128 for that).
97+
98+
99+
> Note that the length here is the length of the blob (power of 2), which is different from the payload_length encoded as part of the `PayloadHeader` in the `blob` itself (see the [encoding section](#encoding)).
100+
>
101+
102+
**PaymentHeader**
103+
104+
The paymentHeader specifies how the blob dispersal to the network will be paid for. There are 2 modes of payment, the permissionless pay-per-blob model and the permissioned reserved-bandwidth approach. See the [Payments](https://docs.eigenda.xyz/core-concepts/payments#high-level-design) release doc for full details; we will only describe how to set these 3 fields here.
105+
106+
```protobuf
107+
message PaymentHeader {
108+
// The account ID of the disperser client. This should be a hex-encoded string of the ECDSA public key
109+
// corresponding to the key used by the client to sign the BlobHeader.
110+
string account_id = 1;
111+
// UNIX timestamp in nanoseconds at the time of the dispersal request.
112+
// Used to determine the reservation period, for the reserved-bandwidth payment model.
113+
int64 timestamp = 2;
114+
// Total amount of tokens paid by the requesting account, including the current request.
115+
// Used for the pay-per-blob payment model.
116+
bytes cumulative_payment = 3;
117+
}
118+
```
119+
120+
Users who want to pay-per-blob need to set the cumulative_payment. `timestamp` is used by users who have paid for reserved-bandwidth. If both are set, reserved-bandwidth will be used first, and cumulative_payment only used if the entire bandwidth for the current reservation period has been used up.
121+
122+
**NOTE:** There will be a lot of subtleties added to this logic with the new separate-payment-per-quorum model that is actively being worked on.
123+
124+
An RPC call to the Disperser’s `GetPaymentState` method can be made to query the current state of an `account_id`. A client can query for this information on startup, cache it, and then update it manually when making dispersals. In this way, it can keep track of its reserved bandwidth usage and current cumulative_payment and set them correctly for subsequent dispersals.
125+
126+
### EigenDA Certificate (`DACert`)
127+
128+
An `EigenDA Certificate` (or short `DACert`) contains all the information needed to retrieve a blob from the EigenDA network, as well as validate it.
69129

70130
![image.png](../../assets/integration/v2-cert.png)
71131

0 commit comments

Comments
 (0)