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

Blob verification changes #321

Merged
merged 23 commits into from
Mar 18, 2024
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
4 changes: 0 additions & 4 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
[submodule "contracts/lib/openzeppelin-contracts-upgradeable"]
path = contracts/lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "contracts/lib/eigenlayer-contracts"]
path = contracts/lib/eigenlayer-contracts
url = https://github.com/Layr-Labs/eigenlayer-contracts
branch = m2-mainnet-fixes
[submodule "contracts/lib/eigenlayer-middleware"]
path = contracts/lib/eigenlayer-middleware
url = https://github.com/Layr-Labs/eigenlayer-middleware
Expand Down
535 changes: 212 additions & 323 deletions api/grpc/disperser/disperser.pb.go

Large diffs are not rendered by default.

79 changes: 40 additions & 39 deletions api/grpc/node/node.pb.go

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

50 changes: 10 additions & 40 deletions api/proto/disperser/disperser.proto
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,11 @@ message DisperseBlobRequest {
// The data to be dispersed.
// The size of data must be <= 2MiB.
bytes data = 1;
// Security parameters allowing clients to customize the safety (via adversary threshold)
// and liveness (via quorum threshold).
// Clients can define one SecurityParams per quorum, and specify multiple quorums.
// The 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.
repeated SecurityParams security_params = 2;
repeated uint32 custom_quorum_numbers = 2;

// The 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.
Expand Down Expand Up @@ -124,38 +123,6 @@ message RetrieveBlobReply {

// Data Types

// SecurityParams contains the security parameters for a given quorum.
message SecurityParams {
// The ID of the quorum.
// The quorum must be already registered on EigenLayer. The ID must be
// in range [0, 254].
uint32 quorum_id = 1;
// The max percentage of stake within the quorum that can be held by or delegated
// to adversarial operators.
//
// Clients use this to customize the trust assumption (safety).
//
// Requires: 1 <= adversary_threshold < 100
uint32 adversary_threshold = 2;
// The min percentage of stake that must attest in order to consider
// the dispersal is successful.
//
// Clients use this to customize liveness requirement. The higher this number,
// the more operators may need to be up for attesting the blob, so the chance
// the dispersal request to fail may be higher (liveness for dispersal).
//
// Requires:
// 1 <= quorum_threshld <= 100
// quorum_threshld > adversary_threshold + 10.
//
// Note: The adversary_threshold and quorum_threshold will directly influence the
// cost of encoding for the blob to be dispersed, roughly by a factor of
// 100 / (quorum_threshold - adversary_threshold). See the spec for more details:
// https://github.com/Layr-Labs/eigenda/blob/master/docs/spec/protocol-modules/storage/overview.md
// Currently it's required that the difference must be at least 10.
uint32 quorum_threshold = 3;
}

enum BlobStatus {
UNKNOWN = 0;

Expand All @@ -174,7 +141,7 @@ enum BlobStatus {
FAILED = 3;
// FINALIZED means that the block containing the blob's confirmation transaction has been finalized on Ethereum
FINALIZED = 4;
// INSUFFICIENT_SIGNATURES means that the quorum threshold for the blob was not met
// INSUFFICIENT_SIGNATURES means that the confirmation threshold for the blob was not met
// for at least one quorum.
INSUFFICIENT_SIGNATURES = 5;
}
Expand All @@ -200,10 +167,13 @@ message BlobHeader {
message BlobQuorumParam {
// The ID of the quorum.
uint32 quorum_number = 1;
// Same as SecurityParams.adversary_threshold.
// The 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.
uint32 adversary_threshold_percentage = 2;
// Same as SecurityParams.quorum_threshold.
uint32 quorum_threshold_percentage = 3;
// The min percentage of stake that must attest in order to consider
// the dispersal is successful.
uint32 confirmation_threshold_percentage = 3;
// The length of each chunk.
uint32 chunk_length = 4;
}
Expand Down
2 changes: 1 addition & 1 deletion api/proto/node/node.proto
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ message BlobHeader {
message BlobQuorumInfo {
uint32 quorum_id = 1;
uint32 adversary_threshold = 2;
uint32 quorum_threshold = 3;
uint32 confirmation_threshold = 3;
uint32 chunk_length = 4;
uint32 ratelimit = 5;
}
Expand Down
40 changes: 17 additions & 23 deletions clients/disperser_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func NewConfig(hostname, port string, timeout time.Duration, useSecureGrpcFlag b
}

type DisperserClient interface {
DisperseBlob(ctx context.Context, data []byte, securityParams []*core.SecurityParam) (*disperser.BlobStatus, []byte, error)
DisperseBlobAuthenticated(ctx context.Context, data []byte, securityParams []*core.SecurityParam) (*disperser.BlobStatus, []byte, error)
DisperseBlob(ctx context.Context, data []byte, customQuorums []uint8) (*disperser.BlobStatus, []byte, error)
DisperseBlobAuthenticated(ctx context.Context, data []byte, customQuorums []uint8) (*disperser.BlobStatus, []byte, error)
GetBlobStatus(ctx context.Context, key []byte) (*disperser_rpc.BlobStatusReply, error)
}

Expand All @@ -43,6 +43,8 @@ type disperserClient struct {
signer core.BlobRequestSigner
}

var _ DisperserClient = &disperserClient{}

func NewDisperserClient(config *Config, signer core.BlobRequestSigner) DisperserClient {
return &disperserClient{
config: config,
Expand All @@ -60,7 +62,7 @@ func (c *disperserClient) getDialOptions() []grpc.DialOption {
}
}

func (c *disperserClient) DisperseBlob(ctx context.Context, data []byte, securityParams []*core.SecurityParam) (*disperser.BlobStatus, []byte, error) {
func (c *disperserClient) DisperseBlob(ctx context.Context, data []byte, quorums []uint8) (*disperser.BlobStatus, []byte, error) {
addr := fmt.Sprintf("%v:%v", c.config.Hostname, c.config.Port)

dialOptions := c.getDialOptions()
Expand All @@ -74,18 +76,14 @@ func (c *disperserClient) DisperseBlob(ctx context.Context, data []byte, securit
ctxTimeout, cancel := context.WithTimeout(ctx, c.config.Timeout)
defer cancel()

sp := make([]*disperser_rpc.SecurityParams, len(securityParams))
for i, s := range securityParams {
sp[i] = &disperser_rpc.SecurityParams{
QuorumId: uint32(s.QuorumID),
QuorumThreshold: uint32(s.QuorumThreshold),
AdversaryThreshold: uint32(s.AdversaryThreshold),
}
quorumNumbers := make([]uint32, len(quorums))
for i, q := range quorums {
quorumNumbers[i] = uint32(q)
}

request := &disperser_rpc.DisperseBlobRequest{
Data: data,
SecurityParams: sp,
Data: data,
CustomQuorumNumbers: quorumNumbers,
}

reply, err := disperserClient.DisperseBlob(ctxTimeout, request)
Expand All @@ -101,7 +99,7 @@ func (c *disperserClient) DisperseBlob(ctx context.Context, data []byte, securit
return blobStatus, reply.GetRequestId(), nil
}

func (c *disperserClient) DisperseBlobAuthenticated(ctx context.Context, data []byte, securityParams []*core.SecurityParam) (*disperser.BlobStatus, []byte, error) {
func (c *disperserClient) DisperseBlobAuthenticated(ctx context.Context, data []byte, quorums []uint8) (*disperser.BlobStatus, []byte, error) {

addr := fmt.Sprintf("%v:%v", c.config.Hostname, c.config.Port)

Expand All @@ -122,19 +120,15 @@ func (c *disperserClient) DisperseBlobAuthenticated(ctx context.Context, data []
return nil, nil, fmt.Errorf("frror while calling DisperseBlobAuthenticated: %v", err)
}

sp := make([]*disperser_rpc.SecurityParams, len(securityParams))
for i, s := range securityParams {
sp[i] = &disperser_rpc.SecurityParams{
QuorumId: uint32(s.QuorumID),
QuorumThreshold: uint32(s.QuorumThreshold),
AdversaryThreshold: uint32(s.AdversaryThreshold),
}
quorumNumbers := make([]uint32, len(quorums))
for i, q := range quorums {
quorumNumbers[i] = uint32(q)
}

request := &disperser_rpc.DisperseBlobRequest{
Data: data,
SecurityParams: sp,
AccountId: c.signer.GetAccountID(),
Data: data,
CustomQuorumNumbers: quorumNumbers,
AccountId: c.signer.GetAccountID(),
}

// Send the initial request
Expand Down
9 changes: 4 additions & 5 deletions clients/mock/disperser_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

disperser_rpc "github.com/Layr-Labs/eigenda/api/grpc/disperser"
"github.com/Layr-Labs/eigenda/clients"
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/disperser"
"github.com/stretchr/testify/mock"
)
Expand All @@ -20,8 +19,8 @@ func NewMockDisperserClient() *MockDisperserClient {
return &MockDisperserClient{}
}

func (c *MockDisperserClient) DisperseBlobAuthenticated(ctx context.Context, data []byte, securityParams []*core.SecurityParam) (*disperser.BlobStatus, []byte, error) {
args := c.Called(data, securityParams)
func (c *MockDisperserClient) DisperseBlobAuthenticated(ctx context.Context, data []byte, quorums []uint8) (*disperser.BlobStatus, []byte, error) {
args := c.Called(data, quorums)
var status *disperser.BlobStatus
if args.Get(0) != nil {
status = (args.Get(0)).(*disperser.BlobStatus)
Expand All @@ -37,8 +36,8 @@ func (c *MockDisperserClient) DisperseBlobAuthenticated(ctx context.Context, dat
return status, key, err
}

func (c *MockDisperserClient) DisperseBlob(ctx context.Context, data []byte, securityParams []*core.SecurityParam) (*disperser.BlobStatus, []byte, error) {
args := c.Called(data, securityParams)
func (c *MockDisperserClient) DisperseBlob(ctx context.Context, data []byte, quorums []uint8) (*disperser.BlobStatus, []byte, error) {
args := c.Called(data, quorums)
var status *disperser.BlobStatus
if args.Get(0) != nil {
status = (args.Get(0)).(*disperser.BlobStatus)
Expand Down
12 changes: 6 additions & 6 deletions clients/tests/retrieval_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ func setup(t *testing.T) {
)
securityParams := []*core.SecurityParam{
{
QuorumID: quorumID,
QuorumThreshold: quorumThreshold,
AdversaryThreshold: adversaryThreshold,
QuorumID: quorumID,
ConfirmationThreshold: quorumThreshold,
AdversaryThreshold: adversaryThreshold,
},
}
blob := core.Blob{
Expand All @@ -137,9 +137,9 @@ func setup(t *testing.T) {

quorumHeader := &core.BlobQuorumInfo{
SecurityParam: core.SecurityParam{
QuorumID: quorumID,
AdversaryThreshold: adversaryThreshold,
QuorumThreshold: quorumThreshold,
QuorumID: quorumID,
AdversaryThreshold: adversaryThreshold,
ConfirmationThreshold: quorumThreshold,
},
ChunkLength: chunkLength,
}
Expand Down
6 changes: 3 additions & 3 deletions common/abis/EigenDAServiceManager.json

Large diffs are not rendered by default.

Loading
Loading