Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added missing v2 protobuf documentation. #1082

Merged
merged 23 commits into from
Jan 17, 2025

Conversation

cody-littley
Copy link
Contributor

Why are these changes needed?

Adds missing v2 protobuf documentation.

@cody-littley cody-littley self-assigned this Jan 8, 2025
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
// If any one of the 32 bytes elements is outside the range, the whole request is deemed as invalid, and rejected.
bytes data = 1;
// The header contains metadata about the blob.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do users need to specify all quorums (including required ones), or just custom quorums?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked to Ian. All quorums must be specified. Documentation updated as follows:

  // quorum_numbers is the list of quorum numbers that the blob is part of. 
  // All quorums must be specified (including required quorums).
  repeated uint32 quorum_numbers = 2;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jianoaix please resolve if you are happy with this response.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cody-littley can we add what are required quorums v.s. custom quorums, and the current required quorums (0/ETH, 1/EIGEN)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated comment as follows:

  // quorum_numbers is the list of quorum numbers that the blob is part of.
  // All quorums must be specified (including required quorums).
  // 
  // The following quorums are currently required:
  // - 0: ETH
  // - 1: EIGEN
  repeated uint32 quorum_numbers = 2;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, v2 does not explicitly enforce the required quorums. It only enforces that price for using subset of the required quorums is the same as using all required quorums. So technically, users are free to choose whatever set of quorums as necessary (with custom verification method).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds more complicated than before by giving more choice to users. I would prefer an enforcement and reject requests missing required quorums.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does pricing work here? Are they charged per quorum? Where is the pricing defined?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for payments, reservation allows custom quorum numbers and doesn't enforce required quorums, but on-demand payments is only allowed for on-demand quorums.

To Sam's question, there's no specific logic on pricing per quorum. For on-demand, pricing is currently defined across all required quorums in the contracts, which is a simple fixed price per symbol. For reservation (set by EigenDA governance only), we left pricing to the BD team and is not defined at all.

(Pricing for reservations is in the making for permissionless reservations. Curious to learn what you think makes sense)

Copy link
Contributor Author

@cody-littley cody-littley Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a ticket for adding a check at the API server: https://linear.app/eigenlabs/issue/EGDA-804/add-required-quorums-check-in-api-server

api/proto/disperser/v2/disperser_v2.proto Show resolved Hide resolved
api/proto/disperser/v2/disperser_v2.proto Outdated Show resolved Hide resolved
api/proto/disperser/v2/disperser_v2.proto Outdated Show resolved Hide resolved
api/proto/retriever/v2/retriever.proto Outdated Show resolved Hide resolved
api/proto/disperser/v2/disperser_v2.proto Outdated Show resolved Hide resolved
api/proto/disperser/v2/disperser_v2.proto Outdated Show resolved Hide resolved
message BlobStatusReply {
// The status of the blob.
BlobStatus status = 1;
// The signed batch
SignedBatch signed_batch = 2;
// BlobVerificationInfo is the information needed to verify the inclusion of a blob in a batch.
BlobVerificationInfo blob_verification_info = 3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably be easier to understand if it's named as something like "BlobInclusionInfo"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ian-shim are you ok with this rename? If "yes", let me know and I'll do the refactor.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion on this. Summoning the naming council @samlaf @mooselumph @litt3

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that BlobInclusionInfo is much better. (in a previous chat about naming, we actually came up with the same potential improvement)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeessssssss +10000 to this. @litt3 and I had this name change already proposed in austin's diagram.
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea it's more accurate. I had to have a few turns in mind to comprehend BlobVerficationInfo.

Please note the renaming may affect more than "eigenda" and "eigenda-proxy" repos, e.g. https://github.com/Layr-Labs/hokulea/blob/master/crates/eigenda/src/certificate.rs#L50

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine, that'll teach @bxue-l2 for not using prost to generate his proto structs :P

Copy link
Contributor Author

@cody-littley cody-littley Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

api/proto/disperser/v2/disperser_v2.proto Outdated Show resolved Hide resolved
Signed-off-by: Cody Littley <[email protected]>
@cody-littley cody-littley marked this pull request as ready for review January 10, 2025 20:15
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Copy link
Contributor

@jianoaix jianoaix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

We may iterate further from @samlaf PR

api/proto/common/common.proto Outdated Show resolved Hide resolved
api/proto/common/common.proto Outdated Show resolved Hide resolved
rpc StoreChunks(StoreChunksRequest) returns (StoreChunksReply) {}
// NodeInfo fetches metadata about the node.
rpc NodeInfo(NodeInfoRequest) returns (NodeInfoReply) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: maybe we should rename this to GetNodeInfo (to use a verb which is more consistent naming)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other side note: Why is NodeInfo present on both the Dispersal and Retrieval services? Is it currently possible for a node to run those services separately on different machines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to GetNodeInfo() (both Retrieval and Dispersal services).

I'm unsure why we duplicate this. @ian-shim can you comment?

Copy link
Contributor

@ian-shim ian-shim Jan 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They can technically run those services separately on different machines. I duplicated them so they're consistent with v1 API.

Copy link
Contributor Author

@cody-littley cody-littley Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cody-littley think that's the wrong linear ticket

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't find the original ticket (not sure what happened). Created a new one: https://linear.app/eigenlabs/issue/EGDA-809/getnodeinfo-rpc-appears-twice

message DisperseBlobReply {
// The status of the blob associated with the blob key.
BlobStatus result = 1;
// The unique identifier for the blob. Unique even if blob data is the identical.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the first time the users see blob key. We may probably better document it eg:

  • how long is this key? (32 bytes, length always fixed)
  • how is it defined? (hash of BlobHeader)
    etc

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. I'll suggest the same edit here I suggested for the blob_key in GetChunksRequest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The unique identifier for the blob. Unique even if blob data is the identical.
// The unique 32 bytes identifier for the blob.
// The blob_key is the keccak hash of the rlp serialization of the BlobHeader, as computed here:
// https://github.com/Layr-Labs/eigenda/blob/0f14d1c90b86d29c30ff7e92cbadf2762c47f402/core/v2/serialization.go#L30
// The blob_key must thus be unique for every request, even if the same blob is being disperser.
// Meaning the blob_header must be different for each request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we submit the exact same request to DisperseBlob? Does the Disperser return an error? Or does it just return the blob status of the blob identified by that request?

Copy link
Contributor Author

@cody-littley cody-littley Jan 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've adopted your suggested replacement.

What happens if we submit the exact same request to DisperseBlob?

That's a good question. @jianoaix @jianoaix do you know the answer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the exact same request was made again after a successful initial request (not necessarily successful dispersal, but successful dispersal request), the second request will return AlreadyExists error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh snap that's a good point always trips me that the errors are not represented in the proto file itself... easy to forget about them. This is a good reminder that we should be documenting the grpc errors that the different endpoints can return, and on which conditions.

For eg here @cody-littley can you add a comment saying that if the same blob_header is submitted, a grpc AlreadyExists error is returned.

For reference the error is returned here.

Copy link
Contributor Author

@cody-littley cody-littley Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the following comment:

  // Note that attempting to disperse a blob with the same blob key as a previously dispersed blob may cause
  // the disperser to reject the blob (DisperseBlob() RPC will return an error).
  bytes blob_key = 2;

8facb9c

Copy link
Contributor Author

@cody-littley cody-littley Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scheduled follow up discussion

api/proto/common/v2/common_v2.proto Outdated Show resolved Hide resolved
api/proto/common/v2/common_v2.proto Show resolved Hide resolved
api/proto/common/v2/common_v2.proto Outdated Show resolved Hide resolved
api/proto/common/v2/common_v2.proto Outdated Show resolved Hide resolved
api/proto/common/v2/common_v2.proto Outdated Show resolved Hide resolved
api/proto/disperser/v2/disperser_v2.proto Outdated Show resolved Hide resolved
// If any one of the 32 bytes elements is outside the range, the whole request is deemed as invalid, and rejected.
bytes data = 1;
// The header contains metadata about the blob.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jianoaix please resolve if you are happy with this response.

message DisperseBlobReply {
// The status of the blob associated with the blob key.
BlobStatus result = 1;
// The unique identifier for the blob. Unique even if blob data is the identical.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. I'll suggest the same edit here I suggested for the blob_key in GetChunksRequest

message DisperseBlobReply {
// The status of the blob associated with the blob key.
BlobStatus result = 1;
// The unique identifier for the blob. Unique even if blob data is the identical.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The unique identifier for the blob. Unique even if blob data is the identical.
// The unique 32 bytes identifier for the blob.
// The blob_key is the keccak hash of the rlp serialization of the BlobHeader, as computed here:
// https://github.com/Layr-Labs/eigenda/blob/0f14d1c90b86d29c30ff7e92cbadf2762c47f402/core/v2/serialization.go#L30
// The blob_key must thus be unique for every request, even if the same blob is being disperser.
// Meaning the blob_header must be different for each request.

message DisperseBlobReply {
// The status of the blob associated with the blob key.
BlobStatus result = 1;
// The unique identifier for the blob. Unique even if blob data is the identical.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we submit the exact same request to DisperseBlob? Does the Disperser return an error? Or does it just return the blob status of the blob identified by that request?

Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
api/grpc/common/v2/common_v2.pb.go Show resolved Hide resolved
api/grpc/common/v2/common_v2.pb.go Outdated Show resolved Hide resolved
message BlobStatusReply {
// The status of the blob.
BlobStatus status = 1;
// The signed batch
SignedBatch signed_batch = 2;
// BlobVerificationInfo is the information needed to verify the inclusion of a blob in a batch.
BlobVerificationInfo blob_verification_info = 3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that BlobInclusionInfo is much better. (in a previous chat about naming, we actually came up with the same potential improvement)

api/grpc/common/v2/common_v2.pb.go Outdated Show resolved Hide resolved
api/grpc/common/common.pb.go Show resolved Hide resolved
api/grpc/disperser/v2/disperser_v2.pb.go Show resolved Hide resolved
api/grpc/disperser/v2/disperser_v2.pb.go Outdated Show resolved Hide resolved
api/grpc/node/v2/node_v2_grpc.pb.go Outdated Show resolved Hide resolved
api/grpc/node/v2/node_v2_grpc.pb.go Outdated Show resolved Hide resolved
api/proto/node/v2/node_v2.proto Outdated Show resolved Hide resolved
api/proto/node/v2/node_v2.proto Outdated Show resolved Hide resolved
api/proto/node/v2/node_v2.proto Outdated Show resolved Hide resolved
api/proto/node/v2/node_v2.proto Outdated Show resolved Hide resolved
api/proto/common/v2/common_v2.proto Outdated Show resolved Hide resolved
api/proto/common/v2/common_v2.proto Outdated Show resolved Hide resolved
@@ -3,21 +3,39 @@ package common.v2;
import "common/common.proto";
option go_package = "github.com/Layr-Labs/eigenda/api/grpc/common/v2";


// BlobHeader contains the information needed to disperse a blob to the EigenDA network.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this one-liner could be more about what does BlobHeader describe (definitive properties of a blob), rather than where it's used

Copy link
Contributor Author

@cody-littley cody-littley Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to the following:

// BlobHeader contains the information describing a blob and the way it is to be dispersed.

b5734f3

@@ -3,21 +3,39 @@ package common.v2;
import "common/common.proto";
option go_package = "github.com/Layr-Labs/eigenda/api/grpc/common/v2";


// BlobHeader contains the information needed to disperse a blob to the EigenDA network.
// It can be thought of as an "eigenDA tx", in that it plays a purpose similar to an eth_tx to disperse a 4844 blob.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"It" means BlobHeader? I think Blob (which is different than BlobHeader) is analogous to a txn

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No the blob is the payload. the blobheader is the tx, specifying price, commitment, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I don't know what is blob/blobheader/payload/txn... https://en.wikipedia.org/wiki/Semantic_satiation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched the wording as follows. Note that this paragraph moved into DisperseBlobRequest (as requested by a prior comment).

  // This header can be thought of as an "eigenDA tx", in that it plays a purpose similar to an eth_tx to disperse a
  // 4844 blob. Note that a call to DisperseBlob requires the blob and the blobHeader, which is similar to how
  // dispersing a blob to ethereum requires sending a tx whose data contains the hash of the kzg commit of the blob,
  // which is dispersed separately.

Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Comment on lines 8 to 9
// Blob version
uint32 version = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to describe what this version is, and that it's linked to

struct VersionedBlobParams {

@0x0aa0 can you add some description explaining how this version is used wrt the onchain thresholds and params?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blob versions are pushed onchain by EigenDA governance in an append only fashion and store the maximum number of operators, number of chunks, and coding rate for a blob. On blob verification, these values are checked against supplied or default security thresholds to validate the security assumptions of the blobs availability.

Copy link
Contributor Author

@cody-littley cody-littley Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've added this paragraph to the field's documentation.

b5eee20

Signed-off-by: Cody Littley <[email protected]>
// BlobCertificate contains a full description of a blob and how it is dispersed. Part of the certificate
// is provided by the blob submitter (i.e. the blob header), and part is provided by the disperser (i.e. the relays).
// Validator nodes eventually sign the blob certificate once they are in custody of the required chunks
// (note that the signature is indirect; validators sign the hash of a Batch, which contains the blob certificate).
message BlobCertificate {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are re-evaluating the naming, I think we may consider this name as well. It may be something like TBSBlobCertificate, TBS stands for "To Be Signed".

It's a practice seen in https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1
Where a actual certificate is like:

Certificate ::= SEQUENCE {
    tbsCertificate          TBSCertificate,
    signatureAlgorithm      AlgorithmIdentifier,
    signature               BIT STRING
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created a ticket to revisit this. I'd prefer not to rename any additional things as a part of this PR. https://linear.app/eigenlabs/issue/EGDA-808/rename-blobcertificate

Signed-off-by: Cody Littley <[email protected]>
Copy link
Contributor

@samlaf samlaf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with the state of this PR. In favor of merging and then having follow-up PRs. Big thanks @cody-littley !

@cody-littley cody-littley merged commit 9a4bdc0 into Layr-Labs:master Jan 17, 2025
8 checks passed
@cody-littley cody-littley deleted the v2-proto-docs branch January 17, 2025 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants