Protocol Documentation

Table of Contents

Top

disperser/disperser.proto

AuthenticatedReply

FieldTypeLabelDescription
blob_auth_headerBlobAuthHeader
disperse_replyDisperseBlobReply

AuthenticatedRequest

FieldTypeLabelDescription
disperse_requestDisperseBlobRequest
authentication_dataAuthenticationData

AuthenticationData

AuthenticationData contains the signature of the BlobAuthHeader.

FieldTypeLabelDescription
authentication_databytes

BatchHeader

FieldTypeLabelDescription
batch_rootbytesThe root of the merkle tree with the hashes of blob headers as leaves.
quorum_numbersbytesAll quorums associated with blobs in this batch. Sorted in ascending order. Ex. [0, 2, 1] => 0x000102
quorum_signed_percentagesbytesThe percentage of stake that has signed for this batch. The quorum_signed_percentages[i] is percentage for the quorum_numbers[i].
reference_block_numberuint32The Ethereum block number at which the batch was created. The Disperser will encode and disperse the blobs based on the onchain info (e.g. operator stakes) at this block number.

BatchMetadata

FieldTypeLabelDescription
batch_headerBatchHeader
signatory_record_hashbytesThe hash of all public keys of the operators that did not sign the batch.
feebytesThe fee payment paid by users for dispersing this batch. It's the bytes representation of a big.Int value.
confirmation_block_numberuint32The Ethereum block number at which the batch is confirmed onchain.
batch_header_hashbytesThis is the hash of the ReducedBatchHeader defined onchain, see: https://github.com/Layr-Labs/eigenda/blob/master/contracts/src/interfaces/IEigenDAServiceManager.sol#L43 The is the message that the operators will sign their signatures on.

BlobAuthHeader

BlobAuthHeader contains information about the blob for the client to verify and sign.

  • Once payments are enabled, the BlobAuthHeader will contain the KZG commitment to the blob, which the client will verify and sign. Having the client verify the KZG commitment instead of calculating it avoids the need for the client to have the KZG structured reference string (SRS), which can be large. The signed KZG commitment prevents the disperser from sending a different blob to the DA Nodes than the one the client sent.
  • In the meantime, the BlobAuthHeader contains a simple challenge parameter is used to prevent replay attacks in the event that a signature is leaked.
FieldTypeLabelDescription
challenge_parameteruint32

BlobHeader

FieldTypeLabelDescription
commitmentcommon.G1CommitmentKZG commitment of the blob.
data_lengthuint32The length of the blob in symbols (each symbol is 32 bytes).
blob_quorum_paramsBlobQuorumParamrepeatedThe params of the quorums that this blob participates in.

BlobInfo

BlobInfo contains information needed to confirm the blob against the EigenDA contracts

FieldTypeLabelDescription
blob_headerBlobHeader
blob_verification_proofBlobVerificationProof

BlobQuorumParam

FieldTypeLabelDescription
quorum_numberuint32The ID of the quorum.
adversary_threshold_percentageuint32The max percentage of stake within the quorum that can be held by or delegated to adversarial operators. Currently, this and the next parameter are standardized across the quorum using values read from the EigenDA contracts.
confirmation_threshold_percentageuint32The min percentage of stake that must attest in order to consider the dispersal is successful.
chunk_lengthuint32The length of each chunk.

BlobStatusReply

FieldTypeLabelDescription
statusBlobStatusThe status of the blob.
infoBlobInfoThe blob info needed for clients to confirm the blob against the EigenDA contracts.

BlobStatusRequest

BlobStatusRequest is used to query the status of a blob.

FieldTypeLabelDescription
request_idbytesRefer to the documentation for DisperseBlobReply.request_id. Note that because the request_id depends on the timestamp at which the disperser received the request, it is not possible to compute it locally from the cert and blob. Clients should thus store this request_id if they plan on requerying the status of the blob in the future.

BlobVerificationProof

FieldTypeLabelDescription
batch_iduint32batch_id is an incremental ID assigned to a batch by EigenDAServiceManager
blob_indexuint32The index of the blob in the batch (which is logically an ordered list of blobs).
batch_metadataBatchMetadata
inclusion_proofbytesinclusion_proof is a merkle proof for a blob header's inclusion in a batch
quorum_indexesbytesindexes of quorums in BatchHeader.quorum_numbers that match the quorums in BlobHeader.blob_quorum_params Ex. BlobHeader.blob_quorum_params = [ { quorum_number = 0, ... }, { quorum_number = 3, ... }, { quorum_number = 5, ... }, ] BatchHeader.quorum_numbers = [0, 5, 3] => 0x000503 Then, quorum_indexes = [0, 2, 1] => 0x000201

DisperseBlobReply

FieldTypeLabelDescription
resultBlobStatusThe status of the blob associated with the request_id. Will always be PROCESSING.
request_idbytesThe request ID generated by the disperser.

Once a request is accepted, a unique request ID is generated. request_id = string(blob_key) = (hash(blob), hash(metadata)) where metadata contains a requestedAt timestamp and the requested quorum numbers and their adversarial thresholds. BlobKey definition: https://github.com/Layr-Labs/eigenda/blob/6b02bf966afa2b9bf2385db8dd01f66f17334e17/disperser/disperser.go#L87 BlobKey computation: https://github.com/Layr-Labs/eigenda/blob/6b02bf966afa2b9bf2385db8dd01f66f17334e17/disperser/common/blobstore/shared_storage.go#L83-L84

Different DisperseBlobRequests have different IDs, including two identical DisperseBlobRequests sent at different times. Clients should thus store this ID and use it to query the processing status of the request via the GetBlobStatus API. |

DisperseBlobRequest

FieldTypeLabelDescription
databytesThe data to be dispersed. The size of data must be <= 16MiB. Every 32 bytes of data is interpreted as an integer in big endian format where the lower address has more significant bits. The integer must stay in the valid range to be interpreted as a field element on the bn254 curve. The valid range is 0 <= x < 21888242871839275222246405745257275088548364400416034343698204186575808495617 If any one of the 32 bytes elements is outside the range, the whole request is deemed as invalid, and rejected.
custom_quorum_numbersuint32repeatedThe quorums to which the blob will be sent, in addition to the required quorums which are configured on the EigenDA smart contract. If required quorums are included here, an error will be returned. The disperser will ensure that the encoded blobs for each quorum are all processed within the same batch.
account_idstringThe account ID of the client. This should be a hex-encoded string of the ECSDA public key corresponding to the key used by the client to sign the BlobAuthHeader.

RetrieveBlobReply

RetrieveBlobReply contains the retrieved blob data

FieldTypeLabelDescription
databytes

RetrieveBlobRequest

RetrieveBlobRequest contains parameters to retrieve the blob.

FieldTypeLabelDescription
batch_header_hashbytes
blob_indexuint32

BlobStatus

BlobStatus represents the status of a blob. The status of a blob is updated as the blob is processed by the disperser. The status of a blob can be queried by the client using the GetBlobStatus API. Intermediate states are states that the blob can be in while being processed, and it can be updated to a different state:

  • PROCESSING
  • DISPERSING
  • CONFIRMED Terminal states are states that will not be updated to a different state:
  • FAILED
  • FINALIZED
  • INSUFFICIENT_SIGNATURES
NameNumberDescription
UNKNOWN0
PROCESSING1PROCESSING means that the blob is currently being processed by the disperser
CONFIRMED2CONFIRMED means that the blob has been dispersed to DA Nodes and the dispersed batch containing the blob has been confirmed onchain
FAILED3FAILED means that the blob has failed permanently (for reasons other than insufficient signatures, which is a separate state). This status is somewhat of a catch-all category, containing (but not necessarily exclusively as errors can be added in the future): - blob has expired - internal logic error while requesting encoding - blob retry has exceeded its limit while waiting for blob finalization after confirmation. Most likely triggered by a chain reorg: see https://github.com/Layr-Labs/eigenda/blob/master/disperser/batcher/finalizer.go#L179-L189.
FINALIZED4FINALIZED means that the block containing the blob's confirmation transaction has been finalized on Ethereum
INSUFFICIENT_SIGNATURES5INSUFFICIENT_SIGNATURES means that the confirmation threshold for the blob was not met for at least one quorum.
DISPERSING6The DISPERSING state is comprised of two separate phases: - Dispersing to DA nodes and collecting signature - Submitting the transaction on chain and waiting for tx receipt

Disperser

Disperser defines the public APIs for dispersing blobs.

Method NameRequest TypeResponse TypeDescription
DisperseBlobDisperseBlobRequestDisperseBlobReplyDisperseBlob accepts a single blob to be dispersed. This executes the dispersal async, i.e. it returns once the request is accepted. The client should use GetBlobStatus() API to poll the processing status of the blob.

If DisperseBlob returns the following error codes: INVALID_ARGUMENT (400): request is invalid for a reason specified in the error msg. RESOURCE_EXHAUSTED (429): request is rate limited for the quorum specified in the error msg. user should retry after the specified duration. INTERNAL (500): serious error, user should NOT retry. | | DisperseBlobAuthenticated | AuthenticatedRequest stream | AuthenticatedReply stream | DisperseBlobAuthenticated is similar to DisperseBlob, except that it requires the client to authenticate itself via the AuthenticationData message. The protocol is as follows: 1. The client sends a DisperseBlobAuthenticated request with the DisperseBlobRequest message 2. The Disperser sends back a BlobAuthHeader message containing information for the client to verify and sign. 3. The client verifies the BlobAuthHeader and sends back the signed BlobAuthHeader in an AuthenticationData message. 4. The Disperser verifies the signature and returns a DisperseBlobReply message. | | GetBlobStatus | BlobStatusRequest | BlobStatusReply | This API is meant to be polled for the blob status. | | RetrieveBlob | RetrieveBlobRequest | RetrieveBlobReply | This retrieves the requested blob from the Disperser's backend. This is a more efficient way to retrieve blobs than directly retrieving from the DA Nodes (see detail about this approach in api/proto/retriever/retriever.proto). The blob should have been initially dispersed via this Disperser service for this API to work. |

Scalar Value Types

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)