-
Notifications
You must be signed in to change notification settings - Fork 175
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
Relay authentication #911
Relay authentication #911
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]>
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]>
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]>
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]>
api/proto/relay/relay.proto
Outdated
@@ -34,7 +34,7 @@ message GetChunksRequest { | |||
|
|||
// If this is an authenticated request, this should hold the ID of the requester. If this | |||
// is an unauthenticated request, this field should be empty. | |||
uint64 requester_id = 2; | |||
bytes requester_id = 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.
From the code below, this is interpreted as operator ID. It'll be helpful to document it here so the users know how to set it.
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 renamed this field to operator_id
. Is that sufficient, or do you think I should add additional documentation?
relay/auth/authenticator.go
Outdated
request *pb.GetChunksRequest, | ||
now time.Time) error { | ||
|
||
if a == nil { |
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 this compare to check the authenticator from outside?
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 way I have it here is wrong (it didn't pass unit tests). I removed this check and instead now make it in the outside context.
relay/auth/authenticator.go
Outdated
operatorID := core.OperatorID(request.RequesterId) | ||
operator, ok := operators[operatorID] | ||
if !ok { | ||
return errors.New("operator not found") |
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'll be helpful to include the block number in error message
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
if err != nil { | ||
return fmt.Errorf("failed to get current block number: %w", err) | ||
} | ||
operators, err := a.ics.GetIndexedOperators(context.Background(), blockNumber) |
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 are 2 RPC calls here, it'd be helpful to cache the operator state
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.
caching added
relay/auth/authenticator.go
Outdated
if !ok { | ||
return errors.New("operator not found") | ||
} | ||
key := operator.PubkeyG2 |
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'd cache operatorID->G2
, this is a mapping that'll not change (hence highly valuable to cache)
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.
Done. This will break if we ever allow operators to change keys, but that's a bridge we can cross in the future.
api/proto/relay/relay.proto
Outdated
@@ -34,7 +34,7 @@ message GetChunksRequest { | |||
|
|||
// If this is an authenticated request, this should hold the ID of the requester. If this | |||
// is an unauthenticated request, this field should be empty. | |||
uint64 requester_id = 2; | |||
bytes requester_id = 2; | |||
|
|||
// If this is an authenticated request, this field will hold a signature by the requester | |||
// on the chunks being requested. |
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.
Document how this signature should be computed
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 this is an authenticated request, this field will hold a BLS signature by the requester
// on the hash of this request. Relays may choose to reject unauthenticated requests.
//
// The following describes the schema for computing the hash of this request
// This algorithm is implemented in golang using relay.auth.HashGetChunksRequest().
//
// All integers are encoded as unsigned 4 byte big endian values.
//
// Perform a keccak256 hash on the following data in the following order:
// 1. the operator id
// 2. for each chunk request:
// a. if the chunk request is a request by index:
// i. the blob key
// ii. the start index
// iii. the end index
// b. if the chunk request is a request by range:
// i. the blob key
// ii. each requested chunk index, in order
bytes operator_signature = 3;
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! few comments
relay/cmd/main.go
Outdated
return nil, fmt.Errorf("failed to create eth writer: %w", err) | ||
} | ||
|
||
idx, err := coreindexer.CreateNewIndexer( |
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.
Is this using a built-in indexer? Should we use a graph indexer instead?
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.
Converted to use a thegraph indexer
relay/auth/authenticator.go
Outdated
} | ||
key := operator.PubkeyG2 | ||
|
||
a.keyCache.Store(operatorID, key) |
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 may just preload the cache by storing all operators's pubkeys returned from GetIndexedOperators. This will reduce num of RPCs from 2*NumOperators to 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.
Good idea. Done.
func (a *requestAuthenticator) PreloadCache() error {
blockNumber, err := a.ics.GetCurrentBlockNumber()
if err != nil {
return fmt.Errorf("failed to get current block number: %w", err)
}
operators, err := a.ics.GetIndexedOperators(context.Background(), blockNumber)
if err != nil {
return fmt.Errorf("failed to get operators: %w", err)
}
for operatorID, operator := range operators {
a.keyCache.Add(operatorID, operator.PubkeyG2)
}
return nil
}
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]>
relay/auth/authenticator.go
Outdated
}, nil | ||
} | ||
|
||
func (a *requestAuthenticator) PreloadCache() 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.
Make it private and run in the the NewRequestAuthenticator?
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.
change made
Signed-off-by: Cody Littley <[email protected]>
@@ -221,6 +264,10 @@ var optionalFlags = []cli.Flag{ | |||
MaxGetChunkBytesPerSecondClientFlag, | |||
GetChunkBytesBurstinessClientFlag, | |||
MaxConcurrentGetChunkOpsClientFlag, | |||
IndexerPullIntervalFlag, |
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 can remove this, right?
Why are these changes needed?
Add authentication for GetChunks() requests.
Checks