Skip to content

Commit

Permalink
Blob verification changes (#321)
Browse files Browse the repository at this point in the history
Co-authored-by: Robert Raynor <[email protected]>
  • Loading branch information
0x0aa0 and mooselumph authored Mar 18, 2024
1 parent dfe66cd commit 7bd41f9
Show file tree
Hide file tree
Showing 84 changed files with 3,332 additions and 2,449 deletions.
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

0 comments on commit 7bd41f9

Please sign in to comment.