-
Notifications
You must be signed in to change notification settings - Fork 191
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
Sign get chunks #1022
Sign get chunks #1022
Changes from 5 commits
8bf1fa0
5ce2082
73583d8
7309c0e
c818bee
a073a28
8bf552b
cb1e42c
4743516
4c12228
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ package clients | |
import ( | ||
"context" | ||
"fmt" | ||
"github.com/Layr-Labs/eigenda/core" | ||
"github.com/Layr-Labs/eigenda/relay/auth" | ||
"sync" | ||
|
||
relaygrpc "github.com/Layr-Labs/eigenda/api/grpc/relay" | ||
|
@@ -12,9 +14,14 @@ import ( | |
"google.golang.org/grpc" | ||
) | ||
|
||
// MessageSigner is a function that signs a message with a private BLS key. | ||
type MessageSigner func(ctx context.Context, data [32]byte) (*core.Signature, error) | ||
|
||
type RelayClientConfig struct { | ||
Sockets map[corev2.RelayKey]string | ||
UseSecureGrpcFlag bool | ||
OperatorID *core.OperatorID | ||
MessageSigner MessageSigner | ||
} | ||
|
||
type ChunkRequestByRange struct { | ||
|
@@ -62,8 +69,8 @@ var _ RelayClient = (*relayClient)(nil) | |
|
||
// NewRelayClient creates a new RelayClient that connects to the relays specified in the config. | ||
// It keeps a connection to each relay and reuses it for subsequent requests, and the connection is lazily instantiated. | ||
func NewRelayClient(config *RelayClientConfig, logger logging.Logger) (*relayClient, error) { | ||
if config == nil || len(config.Sockets) <= 0 { | ||
func NewRelayClient(config *RelayClientConfig, logger logging.Logger) (RelayClient, error) { | ||
if config == nil || len(config.Sockets) <= 0 || config.OperatorID == nil || config.MessageSigner == nil { | ||
return nil, fmt.Errorf("invalid config: %v", config) | ||
} | ||
|
||
|
@@ -97,7 +104,25 @@ func (c *relayClient) GetBlob(ctx context.Context, relayKey corev2.RelayKey, blo | |
return res.GetBlob(), nil | ||
} | ||
|
||
func (c *relayClient) GetChunksByRange(ctx context.Context, relayKey corev2.RelayKey, requests []*ChunkRequestByRange) ([][]byte, error) { | ||
// signGetChunksRequest signs the GetChunksRequest with the operator's private key | ||
// and sets the signature in the request. | ||
func (c *relayClient) signGetChunksRequest(ctx context.Context, request *relaygrpc.GetChunksRequest) error { | ||
hash := auth.HashGetChunksRequest(request) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To confirm, all the values of the request are being hashed right ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, as long as I didn't make a mistake when coding the hashing function. Makes me nervous writing these types of things by hand due to the possibility of human error. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems good area to focus for auditors |
||
hashArray := [32]byte{} | ||
copy(hashArray[:], hash) | ||
signature, err := c.config.MessageSigner(ctx, hashArray) | ||
if err != nil { | ||
return fmt.Errorf("failed to sign get chunks request: %v", err) | ||
} | ||
request.OperatorSignature = signature.Serialize() | ||
return nil | ||
} | ||
|
||
func (c *relayClient) GetChunksByRange( | ||
ctx context.Context, | ||
relayKey corev2.RelayKey, | ||
requests []*ChunkRequestByRange) ([][]byte, error) { | ||
|
||
if len(requests) == 0 { | ||
return nil, fmt.Errorf("no requests") | ||
} | ||
|
@@ -118,18 +143,29 @@ func (c *relayClient) GetChunksByRange(ctx context.Context, relayKey corev2.Rela | |
}, | ||
} | ||
} | ||
res, err := client.GetChunks(ctx, &relaygrpc.GetChunksRequest{ | ||
|
||
request := &relaygrpc.GetChunksRequest{ | ||
ChunkRequests: grpcRequests, | ||
}) | ||
OperatorId: c.config.OperatorID[:], | ||
} | ||
err = c.signGetChunksRequest(ctx, request) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res, err := client.GetChunks(ctx, request) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return res.GetData(), nil | ||
} | ||
|
||
func (c *relayClient) GetChunksByIndex(ctx context.Context, relayKey corev2.RelayKey, requests []*ChunkRequestByIndex) ([][]byte, error) { | ||
func (c *relayClient) GetChunksByIndex( | ||
ctx context.Context, | ||
relayKey corev2.RelayKey, | ||
requests []*ChunkRequestByIndex) ([][]byte, error) { | ||
|
||
if len(requests) == 0 { | ||
return nil, fmt.Errorf("no requests") | ||
} | ||
|
@@ -150,9 +186,17 @@ func (c *relayClient) GetChunksByIndex(ctx context.Context, relayKey corev2.Rela | |
}, | ||
} | ||
} | ||
res, err := client.GetChunks(ctx, &relaygrpc.GetChunksRequest{ | ||
|
||
request := &relaygrpc.GetChunksRequest{ | ||
ChunkRequests: grpcRequests, | ||
}) | ||
OperatorId: c.config.OperatorID[:], | ||
} | ||
err = c.signGetChunksRequest(ctx, request) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res, err := client.GetChunks(ctx, request) | ||
|
||
if err != nil { | ||
return nil, err | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -135,9 +135,18 @@ var _ = Describe("Inabox v2 Integration", func() { | |
} | ||
} | ||
|
||
// These values are only used by the relay client to get chunks, which we do not call from the relay | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks just because of missing test coverage, then shall we add a call to test GetChunks? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Talked to @ian-shim about this. He said the calls to |
||
// client below. So ok to use dummy values here. | ||
var dummyOperatorID core.OperatorID | ||
dummySigner := func(ctx context.Context, data [32]byte) (*core.Signature, error) { | ||
return nil, nil | ||
} | ||
|
||
// Test retrieval from relay | ||
relayClient, err := clients.NewRelayClient(&clients.RelayClientConfig{ | ||
Sockets: relays, | ||
Sockets: relays, | ||
OperatorID: &dummyOperatorID, | ||
MessageSigner: dummySigner, | ||
}, logger) | ||
Expect(err).To(BeNil()) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ func defaultConfig() *Config { | |
ChunkCacheSize: 1024 * 1024, | ||
ChunkMaxConcurrency: 32, | ||
MaxKeysPerGetChunksRequest: 1024, | ||
AuthenticationDisabled: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we set this to false, does integration test fail? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Disabling authentication doesn't cause signed requests to be rejected, it just causes signatures to be entirely ignored by the relay. That being said, disabling authentication in the relay tests was a bit of a shortcut (the bad kind). I've modified the code in this test file to properly enable authentication. |
||
RateLimits: limiter.Config{ | ||
MaxGetBlobOpsPerSecond: 1024, | ||
GetBlobOpsBurstiness: 1024, | ||
|
@@ -47,7 +48,6 @@ func defaultConfig() *Config { | |
GetChunkBytesBurstinessClient: 2 * 1024 * 1024, | ||
MaxConcurrentGetChunkOpsClient: 1, | ||
}, | ||
AuthenticationDisabled: true, | ||
Timeouts: TimeoutConfig{ | ||
GetBlobTimeout: 10 * time.Second, | ||
GetChunksTimeout: 10 * time.Second, | ||
|
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.
should we move this check
config.OperatorID == nil || config.MessageSigner == nil
to GetChunks methods?Other methods like
GetBlob
should work with nil operator ID and nil signerThere 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 moved these checks out of the constructor. They will cause the methods that get chunks to return an error if they are not properly configured.