Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/go_modules/github.com/aws/aws-s…
Browse files Browse the repository at this point in the history
…dk-go-v2/config-1.27.16
  • Loading branch information
NimaVaziri authored Jun 7, 2024
2 parents edbb686 + 4a204d0 commit bd3a760
Show file tree
Hide file tree
Showing 17 changed files with 516 additions and 96 deletions.
19 changes: 19 additions & 0 deletions chainio/clients/avsregistry/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,22 @@ func (w *AvsRegistryChainWriter) DeregisterOperator(
)
return receipt, nil
}

func (w *AvsRegistryChainWriter) UpdateSocket(
ctx context.Context,
socket types.Socket,
) (*gethtypes.Receipt, error) {
noSendTxOpts, err := w.txMgr.GetNoSendTxOpts()
if err != nil {
return nil, err
}
tx, err := w.registryCoordinator.UpdateSocket(noSendTxOpts, socket.String())
if err != nil {
return nil, err
}
receipt, err := w.txMgr.Send(ctx, tx)
if err != nil {
return nil, errors.New("failed to send UpdateSocket tx with err: " + err.Error())
}
return receipt, nil
}
4 changes: 2 additions & 2 deletions cmd/egnkey/generate.go → cmd/egnkey/generate/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package generate

import (
"encoding/hex"
Expand Down Expand Up @@ -42,7 +42,7 @@ var (
}
)

var commandGenerate = &cli.Command{
var Command = &cli.Command{
Name: "generate",
Aliases: []string{"g"},
Description: `Generate keys for testing purpose.
Expand Down
8 changes: 6 additions & 2 deletions cmd/egnkey/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"fmt"
"os"

"github.com/Layr-Labs/eigensdk-go/cmd/egnkey/operatorid"
"github.com/Layr-Labs/eigensdk-go/cmd/egnkey/generate"
"github.com/Layr-Labs/eigensdk-go/cmd/egnkey/store"
"github.com/urfave/cli/v2"
)

Expand All @@ -12,8 +15,9 @@ func main() {
app.Name = "egnkey"
app.Description = "Eigenlayer batch keys manager"
app.Commands = []*cli.Command{
commandGenerate,
commandStore,
generate.Command,
store.Command,
operatorid.Command,
}

app.Usage = "Used to manage batch keys for testing"
Expand Down
39 changes: 39 additions & 0 deletions cmd/egnkey/operatorid/operatorid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package operatorid

import (
"encoding/hex"
"fmt"

"github.com/Layr-Labs/eigensdk-go/crypto/bls"
"github.com/Layr-Labs/eigensdk-go/types"
"github.com/urfave/cli/v2"
)

var (
PrivateKey = &cli.StringFlag{
Name: "private-key",
Usage: "(bn254) private key from which to derive operatorId from",
Required: true,
}
)

var Command = &cli.Command{
Name: "derive-operator-id",
Aliases: []string{"d"},
Description: `Given a private key, output its associated operatorId (hash of bn254 G1 pubkey).`,
Action: derive,
Flags: []cli.Flag{
PrivateKey,
},
}

func derive(c *cli.Context) error {
sk := c.String(PrivateKey.Name)
keypair, err := bls.NewKeyPairFromString(sk)
if err != nil {
return err
}
operatorId := types.OperatorIdFromKeyPair(keypair)
fmt.Println("0x" + hex.EncodeToString(operatorId[:]))
return nil
}
4 changes: 2 additions & 2 deletions cmd/egnkey/store.go → cmd/egnkey/store/store.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package store

import (
"github.com/Layr-Labs/eigensdk-go/crypto/ecdsa"
Expand All @@ -25,7 +25,7 @@ var (
}
)

var commandStore = &cli.Command{
var Command = &cli.Command{
Name: "convert",
Aliases: []string{"c"},
Description: `Stores an ecdsa key to a file, in web3 secret storage format.`,
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/moby/sys/user v0.1.0 // indirect
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFt
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 h1:17JxqqJY66GmZVHkmAsGEkcIu0oCe3AM420QDgGwZx0=
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466/go.mod h1:9dIRpgIY7hVhoqfe0/FcYp0bpInZaT7dc3BYOprrIUE=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA=
Expand Down
61 changes: 47 additions & 14 deletions services/bls_aggregation/blsagg.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ var (
OperatorNotPartOfTaskQuorumErrorFn = func(operatorId types.OperatorId, taskIndex types.TaskIndex) error {
return fmt.Errorf("operator %x not part of task %d's quorum", operatorId, taskIndex)
}
HashFunctionError = func(err error) error {
return fmt.Errorf("Failed to hash task response: %w", err)
}
SignatureVerificationError = func(err error) error {
return fmt.Errorf("Failed to verify signature: %w", err)
}
Expand All @@ -45,6 +48,7 @@ var (
type BlsAggregationServiceResponse struct {
Err error // if Err is not nil, the other fields are not valid
TaskIndex types.TaskIndex // unique identifier of the task
TaskResponse types.TaskResponse // the task response that was signed
TaskResponseDigest types.TaskResponseDigest // digest of the task response that was signed
// The below 8 fields are the data needed to build the IBLSSignatureChecker.NonSignerStakesAndSignature struct
// users of this service will need to build the struct themselves by converting the bls points
Expand Down Expand Up @@ -97,7 +101,7 @@ type BlsAggregationService interface {
ProcessNewSignature(
ctx context.Context,
taskIndex types.TaskIndex,
taskResponseDigest types.TaskResponseDigest,
taskResponse types.TaskResponse,
blsSignature *bls.Signature,
operatorId types.OperatorId,
) error
Expand Down Expand Up @@ -134,17 +138,20 @@ type BlsAggregatorService struct {
taskChansMutex sync.RWMutex
avsRegistryService avsregistry.AvsRegistryService
logger logging.Logger

hashFunction types.TaskResponseHashFunction
}

var _ BlsAggregationService = (*BlsAggregatorService)(nil)

func NewBlsAggregatorService(avsRegistryService avsregistry.AvsRegistryService, logger logging.Logger) *BlsAggregatorService {
func NewBlsAggregatorService(avsRegistryService avsregistry.AvsRegistryService, hashFunction types.TaskResponseHashFunction, logger logging.Logger) *BlsAggregatorService {
return &BlsAggregatorService{
aggregatedResponsesC: make(chan BlsAggregationServiceResponse),
signedTaskRespsCs: make(map[types.TaskIndex]chan types.SignedTaskResponseDigest),
taskChansMutex: sync.RWMutex{},
avsRegistryService: avsRegistryService,
logger: logger,
hashFunction: hashFunction,
}
}

Expand Down Expand Up @@ -179,7 +186,7 @@ func (a *BlsAggregatorService) InitializeNewTask(
func (a *BlsAggregatorService) ProcessNewSignature(
ctx context.Context,
taskIndex types.TaskIndex,
taskResponseDigest types.TaskResponseDigest,
taskResponse types.TaskResponse,
blsSignature *bls.Signature,
operatorId types.OperatorId,
) error {
Expand All @@ -189,14 +196,16 @@ func (a *BlsAggregatorService) ProcessNewSignature(
if !taskInitialized {
return TaskNotFoundErrorFn(taskIndex)
}

signatureVerificationErrorC := make(chan error)
// send the task to the goroutine processing this task
// and return the error (if any) returned by the signature verification routine

select {
// we need to send this as part of select because if the goroutine is processing another SignedTaskResponseDigest
// and cannot receive this one, we want the context to be able to cancel the request
case taskC <- types.SignedTaskResponseDigest{
TaskResponseDigest: taskResponseDigest,
TaskResponse: taskResponse,
BlsSignature: blsSignature,
OperatorId: operatorId,
SignatureVerificationErrorC: signatureVerificationErrorC,
Expand Down Expand Up @@ -226,14 +235,16 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc(
operatorsAvsStateDict, err := a.avsRegistryService.GetOperatorsAvsStateAtBlock(context.Background(), quorumNumbers, taskCreatedBlock)
if err != nil {
a.aggregatedResponsesC <- BlsAggregationServiceResponse{
Err: TaskInitializationErrorFn(fmt.Errorf("AggregatorService failed to get operators state from avs registry at blockNum %d: %w", taskCreatedBlock, err), taskIndex),
Err: TaskInitializationErrorFn(fmt.Errorf("AggregatorService failed to get operators state from avs registry at blockNum %d: %w", taskCreatedBlock, err), taskIndex),
TaskIndex: taskIndex,
}
return
}
quorumsAvsStakeDict, err := a.avsRegistryService.GetQuorumsAvsStateAtBlock(context.Background(), quorumNumbers, taskCreatedBlock)
if err != nil {
a.aggregatedResponsesC <- BlsAggregationServiceResponse{
Err: TaskInitializationErrorFn(fmt.Errorf("Aggregator failed to get quorums state from avs registry: %w", err), taskIndex),
Err: TaskInitializationErrorFn(fmt.Errorf("Aggregator failed to get quorums state from avs registry: %w", err), taskIndex),
TaskIndex: taskIndex,
}
return
}
Expand All @@ -255,13 +266,22 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc(
select {
case signedTaskResponseDigest := <-signedTaskRespsC:
a.logger.Debug("Task goroutine received new signed task response digest", "taskIndex", taskIndex, "signedTaskResponseDigest", signedTaskResponseDigest)

err := a.verifySignature(taskIndex, signedTaskResponseDigest, operatorsAvsStateDict)
signedTaskResponseDigest.SignatureVerificationErrorC <- err
if err != nil {
continue
}

// compute the taskResponseDigest using the hash function
taskResponseDigest, err := a.hashFunction(signedTaskResponseDigest.TaskResponse)
if err != nil {
// this error should never happen, because we've already hashed the taskResponse in verifySignature,
// but keeping here in case the verifySignature implementation ever changes or some catastrophic bug happens..
continue
}
// after verifying signature we aggregate its sig and pubkey, and update the signed stake amount
digestAggregatedOperators, ok := aggregatedOperatorsDict[signedTaskResponseDigest.TaskResponseDigest]
digestAggregatedOperators, ok := aggregatedOperatorsDict[taskResponseDigest]
if !ok {
// first operator to sign on this digest
digestAggregatedOperators = aggregatedOperators{
Expand All @@ -286,7 +306,7 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc(
}
// update the aggregatedOperatorsDict. Note that we need to assign the whole struct value at once,
// because of https://github.com/golang/go/issues/3117
aggregatedOperatorsDict[signedTaskResponseDigest.TaskResponseDigest] = digestAggregatedOperators
aggregatedOperatorsDict[taskResponseDigest] = digestAggregatedOperators

if checkIfStakeThresholdsMet(a.logger, digestAggregatedOperators.signersTotalStakePerQuorum, totalStakePerQuorum, quorumThresholdPercentagesMap) {
nonSignersOperatorIds := []types.OperatorId{}
Expand All @@ -312,14 +332,17 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc(
indices, err := a.avsRegistryService.GetCheckSignaturesIndices(&bind.CallOpts{}, taskCreatedBlock, quorumNumbers, nonSignersOperatorIds)
if err != nil {
a.aggregatedResponsesC <- BlsAggregationServiceResponse{
Err: utils.WrapError(errors.New("Failed to get check signatures indices"), err),
Err: utils.WrapError(errors.New("Failed to get check signatures indices"), err),
TaskIndex: taskIndex,
}
return
}

blsAggregationServiceResponse := BlsAggregationServiceResponse{
Err: nil,
TaskIndex: taskIndex,
TaskResponseDigest: signedTaskResponseDigest.TaskResponseDigest,
TaskResponse: signedTaskResponseDigest.TaskResponse,
TaskResponseDigest: taskResponseDigest,
NonSignersPubkeysG1: nonSignersG1Pubkeys,
QuorumApksG1: quorumApksG1,
SignersApkG2: digestAggregatedOperators.signersApkG2,
Expand All @@ -335,7 +358,8 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc(
}
case <-taskExpiredTimer.C:
a.aggregatedResponsesC <- BlsAggregationServiceResponse{
Err: TaskExpiredErrorFn(taskIndex),
Err: TaskExpiredErrorFn(taskIndex),
TaskIndex: taskIndex,
}
return
}
Expand Down Expand Up @@ -371,18 +395,27 @@ func (a *BlsAggregatorService) verifySignature(
return OperatorNotPartOfTaskQuorumErrorFn(signedTaskResponseDigest.OperatorId, taskIndex)
}

// 0. verify that the msg actually came from the correct operator
taskResponseDigest, err := a.hashFunction(signedTaskResponseDigest.TaskResponse)
if err != nil {
a.logger.Error("Failed to hash task response, skipping.", "taskIndex", taskIndex, "signedTaskResponseDigest", signedTaskResponseDigest, "err", err)
return HashFunctionError(err)
}

// verify that the msg actually came from the correct operator
operatorG2Pubkey := operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey
if operatorG2Pubkey == nil {
a.logger.Error("Operator G2 pubkey not found", "operatorId", signedTaskResponseDigest.OperatorId, "taskId", taskIndex)
return fmt.Errorf("taskId %d: Operator G2 pubkey not found (operatorId: %x)", taskIndex, signedTaskResponseDigest.OperatorId)
}
a.logger.Debug("Verifying signed task response digest signature",
"operatorG2Pubkey", operatorG2Pubkey,
"taskResponseDigest", signedTaskResponseDigest.TaskResponseDigest,
"taskResponseDigest", taskResponseDigest,
"blsSignature", signedTaskResponseDigest.BlsSignature,
)
signatureVerified, err := signedTaskResponseDigest.BlsSignature.Verify(operatorG2Pubkey, signedTaskResponseDigest.TaskResponseDigest)

// if the operator signs a digest that is not the digest of the TaskResponse submitted in ProcessNewTask
// then the signature will not be verified
signatureVerified, err := signedTaskResponseDigest.BlsSignature.Verify(operatorG2Pubkey, taskResponseDigest)
if err != nil {
return SignatureVerificationError(err)
}
Expand Down
Loading

0 comments on commit bd3a760

Please sign in to comment.