From bc475497e3aa19bfefb21b059fc824b89c9d206b Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Mon, 11 Nov 2024 17:01:52 -0300 Subject: [PATCH 01/11] add failing test --- services/bls_aggregation/blsagg_test.go | 127 ++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 8 deletions(-) diff --git a/services/bls_aggregation/blsagg_test.go b/services/bls_aggregation/blsagg_test.go index fd10338c..56e00d7e 100644 --- a/services/bls_aggregation/blsagg_test.go +++ b/services/bls_aggregation/blsagg_test.go @@ -14,6 +14,8 @@ import ( "github.com/Layr-Labs/eigensdk-go/chainio/clients" "github.com/Layr-Labs/eigensdk-go/chainio/utils" + avssm "github.com/Layr-Labs/eigensdk-go/contracts/bindings/MockAvsServiceManager" + regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" "github.com/Layr-Labs/eigensdk-go/crypto/bls" "github.com/Layr-Labs/eigensdk-go/logging" "github.com/Layr-Labs/eigensdk-go/services/avsregistry" @@ -23,8 +25,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" - - avssm "github.com/Layr-Labs/eigensdk-go/contracts/bindings/MockAvsServiceManager" ) // TestBlsAgg is a suite of test that tests the main aggregation logic of the aggregation service @@ -202,7 +202,7 @@ func TestBlsAgg(t *testing.T) { require.EqualValues(t, taskIndex, gotAggregationServiceResponse.TaskIndex) }) - t.Run("2 quorums 2 operators 2 correct signatures", func(t *testing.T) { + t.Run("2 quorums 2 operators 2 correct signatures", func(t *testing.T) { // TODO: this should be failing now testOperator1 := types.TestOperator{ OperatorId: types.OperatorId{1}, StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, @@ -263,10 +263,10 @@ func TestBlsAgg(t *testing.T) { NonSignersPubkeysG1: []*bls.G1Point{}, QuorumApksG1: []*bls.G1Point{ bls.NewZeroG1Point(). - Add(testOperator1.BlsKeypair.GetPubKeyG1()). + Add(testOperator1.BlsKeypair.GetPubKeyG1()). // TOOD: add each operator twice? Add(testOperator2.BlsKeypair.GetPubKeyG1()), bls.NewZeroG1Point(). - Add(testOperator1.BlsKeypair.GetPubKeyG1()). + Add(testOperator1.BlsKeypair.GetPubKeyG1()). // TODO: add each operator twice? Add(testOperator2.BlsKeypair.GetPubKeyG1()), }, SignersApkG2: testOperator1.BlsKeypair.GetPubKeyG2().Add(testOperator2.BlsKeypair.GetPubKeyG2()), @@ -1213,6 +1213,7 @@ func TestIntegrationBlsAgg(t *testing.T) { anvilWsEndpoint, err := anvilC.Endpoint(context.Background(), "ws") require.NoError(t, err) contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint) + t.Run("1 quorums 1 operator", func(t *testing.T) { // read input from JSON if available, otherwise use default values var defaultInput = struct { @@ -1240,7 +1241,7 @@ func TestIntegrationBlsAgg(t *testing.T) { logger := logging.NewTextSLogger(os.Stdout, &logging.SLoggerOptions{Level: slog.LevelDebug}) avsClients, err := clients.BuildAll(clients.BuildAllConfig{ EthHttpUrl: anvilHttpEndpoint, - EthWsUrl: anvilWsEndpoint, // not used so doesn't matter that we pass an http url + EthWsUrl: anvilWsEndpoint, RegistryCoordinatorAddr: contractAddrs.RegistryCoordinator.String(), OperatorStateRetrieverAddr: contractAddrs.OperatorStateRetriever.String(), AvsName: "avs", @@ -1319,8 +1320,118 @@ func TestIntegrationBlsAgg(t *testing.T) { require.NoError(t, err) }) - t.Run("2 quorums 1 operator", func(t *testing.T) { - // TODO: Implement this test + t.Run("2 quorums 1 operator staking on both", func(t *testing.T) { + // define operator ecdsa and bls private keys + ecdsaPrivKey, err := crypto.HexToECDSA("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80") + require.NoError(t, err) + blsPrivKeyHex := "0x1" + blsKeyPair := newBlsKeyPairPanics(blsPrivKeyHex) + operatorId := types.OperatorIdFromG1Pubkey(blsKeyPair.GetPubKeyG1()) + + // create avs clients to interact with contracts deployed on anvil + ethHttpClient, err := ethclient.Dial(anvilHttpEndpoint) + require.NoError(t, err) + logger := logging.NewTextSLogger(os.Stdout, &logging.SLoggerOptions{Level: slog.LevelDebug}) + avsClients, err := clients.BuildAll(clients.BuildAllConfig{ + EthHttpUrl: anvilHttpEndpoint, + EthWsUrl: anvilWsEndpoint, + RegistryCoordinatorAddr: contractAddrs.RegistryCoordinator.String(), + OperatorStateRetrieverAddr: contractAddrs.OperatorStateRetriever.String(), + AvsName: "avs", + PromMetricsIpPortAddress: "localhost:9090", + }, ecdsaPrivKey, logger) + require.NoError(t, err) + avsWriter := avsClients.AvsRegistryChainWriter + avsServiceManager, err := avssm.NewContractMockAvsServiceManager(contractAddrs.ServiceManager, ethHttpClient) + require.NoError(t, err) + + // create aggregation service + operatorsInfoService := operatorsinfo.NewOperatorsInfoServiceInMemory( + context.TODO(), + avsClients.AvsRegistryChainSubscriber, + avsClients.AvsRegistryChainReader, + nil, + operatorsinfo.Opts{}, + logger, + ) + avsRegistryService := avsregistry.NewAvsRegistryServiceChainCaller( + avsClients.AvsRegistryChainReader, + operatorsInfoService, + logger, + ) + blsAggServ := NewBlsAggregatorService(avsRegistryService, hashFunction, logger) + + // create quorum + registryCoordinator, _ := regcoord.NewContractRegistryCoordinator(contractAddrs.RegistryCoordinator, ethHttpClient) + operatorSetParam := regcoord.IRegistryCoordinatorOperatorSetParam{ + MaxOperatorCount: 10, + KickBIPsOfOperatorStake: 1, + KickBIPsOfTotalStake: 1, + } + strategyParam := []regcoord.IStakeRegistryStrategyParams{ + { + Strategy: contractAddrs.Erc20MockStrategy, + Multiplier: big.NewInt(1), + }, + } + noSendTxOpts, err := avsClients.TxManager.GetNoSendTxOpts() + require.NoError(t, err) + tx, err := registryCoordinator.CreateQuorum(noSendTxOpts, operatorSetParam, big.NewInt(0), strategyParam) + require.NoError(t, err) + _, err = avsClients.TxManager.Send(context.TODO(), tx, true) + require.NoError(t, err) + + // register operator + quorumNumbers := types.QuorumNums{0, 1} + quorumThresholdPercentages := []types.QuorumThresholdPercentage{100, 100} + + _, err = avsWriter.RegisterOperator( + context.Background(), + ecdsaPrivKey, + blsKeyPair, + quorumNumbers, + "socket", + true, + ) + require.NoError(t, err) + + // create the task related parameters: RBN, quorumThresholdPercentages, taskIndex and taskResponse + curBlockNum, err := ethHttpClient.BlockNumber(context.Background()) + require.NoError(t, err) + referenceBlockNumber := uint32(curBlockNum) + // need to advance chain by 1 block because of the check in signatureChecker where RBN must be < current block + // number + testutils.AdvanceChainByNBlocksExecInContainer(context.TODO(), 1, anvilC) + taskIndex := types.TaskIndex(0) + taskResponse := mockTaskResponse{123} // Initialize with appropriate data + + // initialize the task + err = blsAggServ.InitializeNewTask( + taskIndex, + uint32(referenceBlockNumber), + quorumNumbers, + quorumThresholdPercentages, + tasksTimeToExpiry, + ) + require.Nil(t, err) + + // compute the signature and send it to the aggregation service + taskResponseDigest, err := hashFunction(taskResponse) + require.Nil(t, err) + blsSig := blsKeyPair.SignMessage(taskResponseDigest) + err = blsAggServ.ProcessNewSignature(context.Background(), taskIndex, taskResponse, blsSig, operatorId) + require.Nil(t, err) + + // wait for the response from the aggregation service and check the signature + blsAggServiceResp := <-blsAggServ.aggregatedResponsesC + _, _, err = avsServiceManager.CheckSignatures( + &bind.CallOpts{}, + taskResponseDigest, + quorumNumbers.UnderlyingType(), + uint32(referenceBlockNumber), + blsAggServiceResp.toNonSignerStakesAndSignature(), + ) + require.NoError(t, err) }) } From 3a04dd242a8edee3b608381d0ff128e2ce4a2970 Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Mon, 11 Nov 2024 17:04:52 -0300 Subject: [PATCH 02/11] fmt --- services/bls_aggregation/blsagg_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/bls_aggregation/blsagg_test.go b/services/bls_aggregation/blsagg_test.go index 56e00d7e..42b791c7 100644 --- a/services/bls_aggregation/blsagg_test.go +++ b/services/bls_aggregation/blsagg_test.go @@ -1362,7 +1362,10 @@ func TestIntegrationBlsAgg(t *testing.T) { blsAggServ := NewBlsAggregatorService(avsRegistryService, hashFunction, logger) // create quorum - registryCoordinator, _ := regcoord.NewContractRegistryCoordinator(contractAddrs.RegistryCoordinator, ethHttpClient) + registryCoordinator, _ := regcoord.NewContractRegistryCoordinator( + contractAddrs.RegistryCoordinator, + ethHttpClient, + ) operatorSetParam := regcoord.IRegistryCoordinatorOperatorSetParam{ MaxOperatorCount: 10, KickBIPsOfOperatorStake: 1, From f89e0bbbb5f09eb0a7c84d535ee428b21429f421 Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Tue, 12 Nov 2024 11:54:31 -0300 Subject: [PATCH 03/11] implement initial fix --- services/bls_aggregation/blsagg.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/services/bls_aggregation/blsagg.go b/services/bls_aggregation/blsagg.go index 840b8499..c4e7c820 100644 --- a/services/bls_aggregation/blsagg.go +++ b/services/bls_aggregation/blsagg.go @@ -387,26 +387,32 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc( // after verifying signature we aggregate its sig and pubkey, and update the signed stake amount if !ok { // first operator to sign on this digest + signersApkG2 := bls.NewZeroG2Point() + signersAggSigG1 := bls.NewZeroSignature() + for range operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum { + signersApkG2 = signersApkG2.Add(operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey) + signersAggSigG1 = signersAggSigG1.Add(signedTaskResponseDigest.BlsSignature) + } digestAggregatedOperators = aggregatedOperators{ // we've already verified that the operator is part of the task's quorum, so we don't need checks // here - signersApkG2: bls.NewZeroG2Point(). - Add(operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey), - signersAggSigG1: signedTaskResponseDigest.BlsSignature, + signersApkG2: signersApkG2, + signersAggSigG1: signersAggSigG1, signersOperatorIdsSet: map[types.OperatorId]bool{signedTaskResponseDigest.OperatorId: true}, signersTotalStakePerQuorum: cloneStakePerQuorumMap( operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum, ), } } else { + // The operator has already signed on this digest a.logger.Debug("Task goroutine updating existing aggregated operator signatures", "taskIndex", taskIndex, "taskResponseDigest", taskResponseDigest) - digestAggregatedOperators.signersAggSigG1.Add(signedTaskResponseDigest.BlsSignature) - digestAggregatedOperators.signersApkG2.Add(operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey) digestAggregatedOperators.signersOperatorIdsSet[signedTaskResponseDigest.OperatorId] = true for quorumNum, stake := range operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum { + digestAggregatedOperators.signersAggSigG1.Add(signedTaskResponseDigest.BlsSignature) + digestAggregatedOperators.signersApkG2.Add(operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey) if _, ok := digestAggregatedOperators.signersTotalStakePerQuorum[quorumNum]; !ok { // if we haven't seen this quorum before, initialize its signed stake to 0 // possible if previous operators who sent us signatures were not part of this quorum From 9e25ce2c521016916ed12e2e2b17ba3d24e530df Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Tue, 12 Nov 2024 12:10:56 -0300 Subject: [PATCH 04/11] update test --- services/bls_aggregation/blsagg_test.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/services/bls_aggregation/blsagg_test.go b/services/bls_aggregation/blsagg_test.go index 42b791c7..9a6c065f 100644 --- a/services/bls_aggregation/blsagg_test.go +++ b/services/bls_aggregation/blsagg_test.go @@ -202,7 +202,7 @@ func TestBlsAgg(t *testing.T) { require.EqualValues(t, taskIndex, gotAggregationServiceResponse.TaskIndex) }) - t.Run("2 quorums 2 operators 2 correct signatures", func(t *testing.T) { // TODO: this should be failing now + t.Run("2 quorums 2 operators 2 correct signatures", func(t *testing.T) { testOperator1 := types.TestOperator{ OperatorId: types.OperatorId{1}, StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, @@ -255,6 +255,11 @@ func TestBlsAgg(t *testing.T) { ) require.Nil(t, err) + op1G2Key := testOperator1.BlsKeypair.GetPubKeyG2() + op2G2Key := testOperator2.BlsKeypair.GetPubKeyG2() + op1Signature := testOperator1.BlsKeypair.SignMessage(taskResponseDigest) + op2Signature := testOperator2.BlsKeypair.SignMessage(taskResponseDigest) + wantAggregationServiceResponse := BlsAggregationServiceResponse{ Err: nil, TaskIndex: taskIndex, @@ -263,15 +268,14 @@ func TestBlsAgg(t *testing.T) { NonSignersPubkeysG1: []*bls.G1Point{}, QuorumApksG1: []*bls.G1Point{ bls.NewZeroG1Point(). - Add(testOperator1.BlsKeypair.GetPubKeyG1()). // TOOD: add each operator twice? + Add(testOperator1.BlsKeypair.GetPubKeyG1()). Add(testOperator2.BlsKeypair.GetPubKeyG1()), bls.NewZeroG1Point(). - Add(testOperator1.BlsKeypair.GetPubKeyG1()). // TODO: add each operator twice? + Add(testOperator1.BlsKeypair.GetPubKeyG1()). Add(testOperator2.BlsKeypair.GetPubKeyG1()), }, - SignersApkG2: testOperator1.BlsKeypair.GetPubKeyG2().Add(testOperator2.BlsKeypair.GetPubKeyG2()), - SignersAggSigG1: testOperator1.BlsKeypair.SignMessage(taskResponseDigest). - Add(testOperator2.BlsKeypair.SignMessage(taskResponseDigest)), + SignersApkG2: op1G2Key.Add(op1G2Key).Add(op2G2Key).Add(op2G2Key), + SignersAggSigG1: op1Signature.Add(op1Signature).Add(op2Signature).Add(op2Signature), } gotAggregationServiceResponse := <-blsAggServ.aggregatedResponsesC require.EqualValues(t, wantAggregationServiceResponse, gotAggregationServiceResponse) From b8375a7952f718666fa9df531b469934424dce5d Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Tue, 12 Nov 2024 12:12:40 -0300 Subject: [PATCH 05/11] fmt --- services/bls_aggregation/blsagg.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/bls_aggregation/blsagg.go b/services/bls_aggregation/blsagg.go index c4e7c820..e70e7d06 100644 --- a/services/bls_aggregation/blsagg.go +++ b/services/bls_aggregation/blsagg.go @@ -390,7 +390,9 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc( signersApkG2 := bls.NewZeroG2Point() signersAggSigG1 := bls.NewZeroSignature() for range operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum { - signersApkG2 = signersApkG2.Add(operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey) + signersApkG2 = signersApkG2.Add( + operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey, + ) signersAggSigG1 = signersAggSigG1.Add(signedTaskResponseDigest.BlsSignature) } digestAggregatedOperators = aggregatedOperators{ From c1b1d49a289f5daeb2f38335531881774ac36778 Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Tue, 12 Nov 2024 16:15:18 -0300 Subject: [PATCH 06/11] update unit tests --- services/bls_aggregation/blsagg_test.go | 34 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/services/bls_aggregation/blsagg_test.go b/services/bls_aggregation/blsagg_test.go index 9a6c065f..fe321170 100644 --- a/services/bls_aggregation/blsagg_test.go +++ b/services/bls_aggregation/blsagg_test.go @@ -115,17 +115,17 @@ func TestBlsAgg(t *testing.T) { t.Run("1 quorum 3 operator 3 correct signatures", func(t *testing.T) { testOperator1 := types.TestOperator{ OperatorId: types.OperatorId{1}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x1"), } testOperator2 := types.TestOperator{ OperatorId: types.OperatorId{2}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x2"), } testOperator3 := types.TestOperator{ OperatorId: types.OperatorId{3}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(300), 1: big.NewInt(100)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(300)}, BlsKeypair: newBlsKeyPairPanics("0x3"), } blockNum := uint32(1) @@ -274,7 +274,7 @@ func TestBlsAgg(t *testing.T) { Add(testOperator1.BlsKeypair.GetPubKeyG1()). Add(testOperator2.BlsKeypair.GetPubKeyG1()), }, - SignersApkG2: op1G2Key.Add(op1G2Key).Add(op2G2Key).Add(op2G2Key), + SignersApkG2: op1G2Key.Add(op1G2Key).Add(op2G2Key).Add(op2G2Key), // adding each key twice as they participate in two quorums SignersAggSigG1: op1Signature.Add(op1Signature).Add(op2Signature).Add(op2Signature), } gotAggregationServiceResponse := <-blsAggServ.aggregatedResponsesC @@ -381,8 +381,13 @@ func TestBlsAgg(t *testing.T) { Add(testOperator2.BlsKeypair.GetPubKeyG1()), }, SignersApkG2: bls.NewZeroG2Point(). - Add(testOperator1.BlsKeypair.GetPubKeyG2().Add(testOperator2.BlsKeypair.GetPubKeyG2())), + Add(testOperator1.BlsKeypair.GetPubKeyG2()). + Add(testOperator1.BlsKeypair.GetPubKeyG2()). + Add(testOperator2.BlsKeypair.GetPubKeyG2()). + Add(testOperator2.BlsKeypair.GetPubKeyG2()), SignersAggSigG1: testOperator1.BlsKeypair.SignMessage(task1ResponseDigest). + Add(testOperator1.BlsKeypair.SignMessage(task1ResponseDigest)). + Add(testOperator2.BlsKeypair.SignMessage(task1ResponseDigest)). Add(testOperator2.BlsKeypair.SignMessage(task1ResponseDigest)), } wantAggregationServiceResponseTask2 := BlsAggregationServiceResponse{ @@ -399,8 +404,13 @@ func TestBlsAgg(t *testing.T) { Add(testOperator1.BlsKeypair.GetPubKeyG1()). Add(testOperator2.BlsKeypair.GetPubKeyG1()), }, - SignersApkG2: testOperator1.BlsKeypair.GetPubKeyG2().Add(testOperator2.BlsKeypair.GetPubKeyG2()), + SignersApkG2: testOperator1.BlsKeypair.GetPubKeyG2(). + Add(testOperator1.BlsKeypair.GetPubKeyG2()). + Add(testOperator2.BlsKeypair.GetPubKeyG2()). + Add(testOperator2.BlsKeypair.GetPubKeyG2()), SignersAggSigG1: testOperator1.BlsKeypair.SignMessage(task2ResponseDigest). + Add(testOperator1.BlsKeypair.SignMessage(task2ResponseDigest)). + Add(testOperator2.BlsKeypair.SignMessage(task2ResponseDigest)). Add(testOperator2.BlsKeypair.SignMessage(task2ResponseDigest)), } @@ -545,12 +555,12 @@ func TestBlsAgg(t *testing.T) { t.Run("1 quorum 2 operator 1 correct signature quorumThreshold 50% - verified", func(t *testing.T) { testOperator1 := types.TestOperator{ OperatorId: types.OperatorId{1}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x1"), } testOperator2 := types.TestOperator{ OperatorId: types.OperatorId{2}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x2"), } taskIndex := types.TaskIndex(0) @@ -604,12 +614,12 @@ func TestBlsAgg(t *testing.T) { t.Run("1 quorum 2 operator 1 correct signature quorumThreshold 60% - task expired", func(t *testing.T) { testOperator1 := types.TestOperator{ OperatorId: types.OperatorId{1}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x1"), } testOperator2 := types.TestOperator{ OperatorId: types.OperatorId{2}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x2"), } blockNum := uint32(1) @@ -1017,12 +1027,12 @@ func TestBlsAgg(t *testing.T) { func(t *testing.T) { testOperator1 := types.TestOperator{ OperatorId: types.OperatorId{1}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x1"), } testOperator2 := types.TestOperator{ OperatorId: types.OperatorId{2}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x2"), } blockNum := uint32(1) From 2357f68120e25bc91f87cfa0b42e328ba27ceb66 Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Tue, 12 Nov 2024 17:10:40 -0300 Subject: [PATCH 07/11] fix integration test --- services/bls_aggregation/blsagg_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/services/bls_aggregation/blsagg_test.go b/services/bls_aggregation/blsagg_test.go index fe321170..7741fcea 100644 --- a/services/bls_aggregation/blsagg_test.go +++ b/services/bls_aggregation/blsagg_test.go @@ -274,8 +274,9 @@ func TestBlsAgg(t *testing.T) { Add(testOperator1.BlsKeypair.GetPubKeyG1()). Add(testOperator2.BlsKeypair.GetPubKeyG1()), }, - SignersApkG2: op1G2Key.Add(op1G2Key).Add(op2G2Key).Add(op2G2Key), // adding each key twice as they participate in two quorums + SignersApkG2: op1G2Key.Add(op1G2Key).Add(op2G2Key).Add(op2G2Key), SignersAggSigG1: op1Signature.Add(op1Signature).Add(op2Signature).Add(op2Signature), + // each key is added twice because both operators stake on two quorums } gotAggregationServiceResponse := <-blsAggServ.aggregatedResponsesC require.EqualValues(t, wantAggregationServiceResponse, gotAggregationServiceResponse) @@ -1398,8 +1399,13 @@ func TestIntegrationBlsAgg(t *testing.T) { _, err = avsClients.TxManager.Send(context.TODO(), tx, true) require.NoError(t, err) + tx, err = registryCoordinator.CreateQuorum(noSendTxOpts, operatorSetParam, big.NewInt(0), strategyParam) + require.NoError(t, err) + _, err = avsClients.TxManager.Send(context.TODO(), tx, true) + require.NoError(t, err) + // register operator - quorumNumbers := types.QuorumNums{0, 1} + quorumNumbers := types.QuorumNums{1, 2} quorumThresholdPercentages := []types.QuorumThresholdPercentage{100, 100} _, err = avsWriter.RegisterOperator( From eb2131c05141d21f140c32ff4c70a43d46236e30 Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Tue, 12 Nov 2024 17:12:04 -0300 Subject: [PATCH 08/11] remove comment --- services/bls_aggregation/blsagg.go | 1 - 1 file changed, 1 deletion(-) diff --git a/services/bls_aggregation/blsagg.go b/services/bls_aggregation/blsagg.go index e70e7d06..ca6ada0c 100644 --- a/services/bls_aggregation/blsagg.go +++ b/services/bls_aggregation/blsagg.go @@ -406,7 +406,6 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc( ), } } else { - // The operator has already signed on this digest a.logger.Debug("Task goroutine updating existing aggregated operator signatures", "taskIndex", taskIndex, "taskResponseDigest", taskResponseDigest) From 604a9d950a0c2595e79198d83c1bfd59787ee7a0 Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Tue, 12 Nov 2024 17:20:29 -0300 Subject: [PATCH 09/11] fix test --- services/bls_aggregation/blsagg_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/bls_aggregation/blsagg_test.go b/services/bls_aggregation/blsagg_test.go index 7741fcea..9b42916c 100644 --- a/services/bls_aggregation/blsagg_test.go +++ b/services/bls_aggregation/blsagg_test.go @@ -62,7 +62,7 @@ func TestBlsAgg(t *testing.T) { t.Run("1 quorum 1 operator 1 correct signature", func(t *testing.T) { testOperator1 := types.TestOperator{ OperatorId: types.OperatorId{1}, - StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100), 1: big.NewInt(200)}, + StakePerQuorum: map[types.QuorumNum]types.StakeAmount{0: big.NewInt(100)}, BlsKeypair: newBlsKeyPairPanics("0x1"), } blockNum := uint32(1) From 0ddd61fb9e9488d73411c1b1dca0bc54ff3c3da6 Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Wed, 13 Nov 2024 12:54:51 -0300 Subject: [PATCH 10/11] add comments --- services/bls_aggregation/blsagg.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/bls_aggregation/blsagg.go b/services/bls_aggregation/blsagg.go index ca6ada0c..08d99a15 100644 --- a/services/bls_aggregation/blsagg.go +++ b/services/bls_aggregation/blsagg.go @@ -389,6 +389,8 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc( // first operator to sign on this digest signersApkG2 := bls.NewZeroG2Point() signersAggSigG1 := bls.NewZeroSignature() + // for each quorum the operator has stake in, the signature is aggregated + // see https://github.com/Layr-Labs/eigenlayer-middleware/blob/7d49b5181b09198ed275783453aa082bb3766990/src/BLSSignatureChecker.sol#L161-L168 for range operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum { signersApkG2 = signersApkG2.Add( operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey, @@ -411,6 +413,8 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc( "taskResponseDigest", taskResponseDigest) digestAggregatedOperators.signersOperatorIdsSet[signedTaskResponseDigest.OperatorId] = true + + // for each quorum the operator has stake in, the signature is aggregated for quorumNum, stake := range operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum { digestAggregatedOperators.signersAggSigG1.Add(signedTaskResponseDigest.BlsSignature) digestAggregatedOperators.signersApkG2.Add(operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey) From 3e78bff0e16c260c81e36dfb2525b9a940bfa7ff Mon Sep 17 00:00:00 2001 From: tomasarrachea Date: Wed, 13 Nov 2024 12:58:49 -0300 Subject: [PATCH 11/11] fmt --- services/bls_aggregation/blsagg.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/bls_aggregation/blsagg.go b/services/bls_aggregation/blsagg.go index 08d99a15..af244299 100644 --- a/services/bls_aggregation/blsagg.go +++ b/services/bls_aggregation/blsagg.go @@ -390,7 +390,8 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc( signersApkG2 := bls.NewZeroG2Point() signersAggSigG1 := bls.NewZeroSignature() // for each quorum the operator has stake in, the signature is aggregated - // see https://github.com/Layr-Labs/eigenlayer-middleware/blob/7d49b5181b09198ed275783453aa082bb3766990/src/BLSSignatureChecker.sol#L161-L168 + // see + // https://github.com/Layr-Labs/eigenlayer-middleware/blob/7d49b5181b09198ed275783453aa082bb3766990/src/BLSSignatureChecker.sol#L161-L168 for range operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum { signersApkG2 = signersApkG2.Add( operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].OperatorInfo.Pubkeys.G2Pubkey, @@ -413,7 +414,6 @@ func (a *BlsAggregatorService) singleTaskAggregatorGoroutineFunc( "taskResponseDigest", taskResponseDigest) digestAggregatedOperators.signersOperatorIdsSet[signedTaskResponseDigest.OperatorId] = true - // for each quorum the operator has stake in, the signature is aggregated for quorumNum, stake := range operatorsAvsStateDict[signedTaskResponseDigest.OperatorId].StakePerQuorum { digestAggregatedOperators.signersAggSigG1.Add(signedTaskResponseDigest.BlsSignature)