-
Notifications
You must be signed in to change notification settings - Fork 195
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
Conversation
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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;
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)?
There was a problem hiding this comment.
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;
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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
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; |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tracking task in this ticket: https://linear.app/eigenlabs/issue/EGDA-804/add-required-quorums-check-in-api-server
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
There was a problem hiding this 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/node/v2/node_v2.proto
Outdated
rpc StoreChunks(StoreChunksRequest) returns (StoreChunksReply) {} | ||
// NodeInfo fetches metadata about the node. | ||
rpc NodeInfo(NodeInfoRequest) returns (NodeInfoReply) {} |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
task tracked in this ticket: https://linear.app/eigenlabs/issue/EGDA-804/add-required-quorums-check-in-api-server
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scheduled follow up discussion
// 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 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. |
There was a problem hiding this comment.
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]>
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; |
There was a problem hiding this comment.
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/proto/common/v2/common_v2.proto
Outdated
@@ -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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
api/proto/common/v2/common_v2.proto
Outdated
@@ -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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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]>
api/proto/common/v2/common_v2.proto
Outdated
// Blob version | ||
uint32 version = 1; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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 { |
There was a problem hiding this comment.
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
}
There was a problem hiding this comment.
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]>
There was a problem hiding this 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 !
Why are these changes needed?
Adds missing v2 protobuf documentation.