diff --git a/chainio/clients/avsregistry/reader.go b/chainio/clients/avsregistry/reader.go index 64120b40..84a8dcc7 100644 --- a/chainio/clients/avsregistry/reader.go +++ b/chainio/clients/avsregistry/reader.go @@ -25,69 +25,6 @@ import ( // 10k is an arbitrary choice that should work for most var DefaultQueryBlockRange = big.NewInt(10_000) -type Reader interface { - GetQuorumCount(opts *bind.CallOpts) (uint8, error) - - GetOperatorsStakeInQuorumsAtCurrentBlock( - opts *bind.CallOpts, - quorumNumbers types.QuorumNums, - ) ([][]opstateretriever.OperatorStateRetrieverOperator, error) - - GetOperatorsStakeInQuorumsAtBlock( - opts *bind.CallOpts, - quorumNumbers types.QuorumNums, - blockNumber uint32, - ) ([][]opstateretriever.OperatorStateRetrieverOperator, error) - - GetOperatorAddrsInQuorumsAtCurrentBlock( - opts *bind.CallOpts, - quorumNumbers types.QuorumNums, - ) ([][]common.Address, error) - - GetOperatorsStakeInQuorumsOfOperatorAtBlock( - opts *bind.CallOpts, - operatorId types.OperatorId, - blockNumber uint32, - ) (types.QuorumNums, [][]opstateretriever.OperatorStateRetrieverOperator, error) - - GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock( - opts *bind.CallOpts, - operatorId types.OperatorId, - ) (types.QuorumNums, [][]opstateretriever.OperatorStateRetrieverOperator, error) - - GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock( - opts *bind.CallOpts, - operatorId types.OperatorId, - ) (map[types.QuorumNum]types.StakeAmount, error) - - GetCheckSignaturesIndices( - opts *bind.CallOpts, - referenceBlockNumber uint32, - quorumNumbers types.QuorumNums, - nonSignerOperatorIds []types.OperatorId, - ) (opstateretriever.OperatorStateRetrieverCheckSignaturesIndices, error) - - GetOperatorId(opts *bind.CallOpts, operatorAddress common.Address) ([32]byte, error) - - GetOperatorFromId(opts *bind.CallOpts, operatorId types.OperatorId) (common.Address, error) - - IsOperatorRegistered(opts *bind.CallOpts, operatorAddress common.Address) (bool, error) - - QueryExistingRegisteredOperatorPubKeys( - ctx context.Context, - startBlock *big.Int, - stopBlock *big.Int, - blockRange *big.Int, - ) ([]types.OperatorAddr, []types.OperatorPubkeys, error) - - QueryExistingRegisteredOperatorSockets( - ctx context.Context, - startBlock *big.Int, - stopBlock *big.Int, - blockRange *big.Int, - ) (map[types.OperatorId]types.Socket, error) -} - type Config struct { RegistryCoordinatorAddress common.Address OperatorStateRetrieverAddress common.Address @@ -103,9 +40,6 @@ type ChainReader struct { ethClient eth.Client } -// forces AvsReader to implement the clients.ReaderInterface interface -var _ Reader = (*ChainReader)(nil) - func NewChainReader( registryCoordinatorAddr common.Address, blsApkRegistryAddr common.Address, diff --git a/chainio/clients/avsregistry/subscriber.go b/chainio/clients/avsregistry/subscriber.go index 26f3dde2..b18ddd80 100644 --- a/chainio/clients/avsregistry/subscriber.go +++ b/chainio/clients/avsregistry/subscriber.go @@ -12,20 +12,12 @@ import ( "github.com/Layr-Labs/eigensdk-go/utils" ) -type Subscriber interface { - SubscribeToNewPubkeyRegistrations() (chan *blsapkreg.ContractBLSApkRegistryNewPubkeyRegistration, event.Subscription, error) - SubscribeToOperatorSocketUpdates() (chan *regcoord.ContractRegistryCoordinatorOperatorSocketUpdate, event.Subscription, error) -} - type ChainSubscriber struct { logger logging.Logger regCoord regcoord.ContractRegistryCoordinatorFilters blsApkRegistry blsapkreg.ContractBLSApkRegistryFilters } -// forces EthSubscriber to implement the chainio.Subscriber interface -var _ Subscriber = (*ChainSubscriber)(nil) - // NewChainSubscriber creates a new instance of ChainSubscriber // The bindings must be created using websocket ETH Client func NewChainSubscriber( diff --git a/chainio/clients/avsregistry/writer.go b/chainio/clients/avsregistry/writer.go index 7fb49477..dbd397ef 100644 --- a/chainio/clients/avsregistry/writer.go +++ b/chainio/clients/avsregistry/writer.go @@ -27,68 +27,7 @@ import ( "github.com/Layr-Labs/eigensdk-go/utils" ) -type Writer interface { - - // RegisterOperatorInQuorumWithAVSRegistryCoordinator - // TODO(samlaf): an operator that is already registered in a quorum can register with another quorum without passing - // signatures perhaps we should add another sdk function for this purpose, that just takes in a quorumNumber and - // socket? RegisterOperatorInQuorumWithAVSRegistryCoordinator is used to register a single operator with the AVS's - // registry coordinator. - operatorEcdsaPrivateKey is the operator's ecdsa private key (used to sign a message to - // register operator in eigenlayer's delegation manager) - // - operatorToAvsRegistrationSigSalt is a random salt used to prevent replay attacks - // - operatorToAvsRegistrationSigExpiry is the expiry time of the signature - // - // Deprecated: use RegisterOperator instead. - // We will only keep high-level functionality such as RegisterOperator, and low level functionality - // such as this function should eventually all be done with bindings directly instead. - RegisterOperatorInQuorumWithAVSRegistryCoordinator( - ctx context.Context, - operatorEcdsaPrivateKey *ecdsa.PrivateKey, - operatorToAvsRegistrationSigSalt [32]byte, - operatorToAvsRegistrationSigExpiry *big.Int, - blsKeyPair *bls.KeyPair, - quorumNumbers types.QuorumNums, - socket string, - ) (*gethtypes.Receipt, error) - - // RegisterOperator is similar to RegisterOperatorInQuorumWithAVSRegistryCoordinator but - // generates a random salt and expiry for the signature. - RegisterOperator( - ctx context.Context, - operatorEcdsaPrivateKey *ecdsa.PrivateKey, - blsKeyPair *bls.KeyPair, - quorumNumbers types.QuorumNums, - socket string, - ) (*gethtypes.Receipt, error) - - // UpdateStakesOfEntireOperatorSetForQuorums is used by avs teams running https://github.com/Layr-Labs/avs-sync - // to updates the stake of their entire operator set. - // Because of high gas costs of this operation, it typically needs to be called for every quorum, or perhaps for a - // small grouping of quorums - // (highly dependent on number of operators per quorum) - UpdateStakesOfEntireOperatorSetForQuorums( - ctx context.Context, - operatorsPerQuorum [][]gethcommon.Address, - quorumNumbers types.QuorumNums, - ) (*gethtypes.Receipt, error) - - // UpdateStakesOfOperatorSubsetForAllQuorums is meant to be used by single operators (or teams of operators, - // possibly running https://github.com/Layr-Labs/avs-sync) to update the stake of their own operator(s). This might - // be needed in the case that they received a lot of new stake delegations, and want this to be reflected - // in the AVS's registry coordinator. - UpdateStakesOfOperatorSubsetForAllQuorums( - ctx context.Context, - operators []gethcommon.Address, - ) (*gethtypes.Receipt, error) - - DeregisterOperator( - ctx context.Context, - quorumNumbers types.QuorumNums, - pubkey regcoord.BN254G1Point, - ) (*gethtypes.Receipt, error) -} - -type ELReader interface { +type eLReader interface { CalculateOperatorAVSRegistrationDigestHash( opts *bind.CallOpts, operatorAddr gethcommon.Address, @@ -104,21 +43,19 @@ type ChainWriter struct { operatorStateRetriever *opstateretriever.ContractOperatorStateRetriever stakeRegistry *stakeregistry.ContractStakeRegistry blsApkRegistry *blsapkregistry.ContractBLSApkRegistry - elReader ELReader + elReader eLReader logger logging.Logger ethClient eth.Client txMgr txmgr.TxManager } -var _ Writer = (*ChainWriter)(nil) - func NewChainWriter( serviceManagerAddr gethcommon.Address, registryCoordinator *regcoord.ContractRegistryCoordinator, operatorStateRetriever *opstateretriever.ContractOperatorStateRetriever, stakeRegistry *stakeregistry.ContractStakeRegistry, blsApkRegistry *blsapkregistry.ContractBLSApkRegistry, - elReader ELReader, + elReader eLReader, logger logging.Logger, ethClient eth.Client, txMgr txmgr.TxManager, @@ -239,6 +176,18 @@ func NewWriterFromConfig( ), nil } +// RegisterOperatorInQuorumWithAVSRegistryCoordinator +// TODO(samlaf): an operator that is already registered in a quorum can register with another quorum without passing +// signatures perhaps we should add another sdk function for this purpose, that just takes in a quorumNumber and +// socket? RegisterOperatorInQuorumWithAVSRegistryCoordinator is used to register a single operator with the AVS's +// registry coordinator. - operatorEcdsaPrivateKey is the operator's ecdsa private key (used to sign a message to +// register operator in eigenlayer's delegation manager) +// - operatorToAvsRegistrationSigSalt is a random salt used to prevent replay attacks +// - operatorToAvsRegistrationSigExpiry is the expiry time of the signature +// +// Deprecated: use RegisterOperator instead. +// We will only keep high-level functionality such as RegisterOperator, and low level functionality +// such as this function should eventually all be done with bindings directly instead. func (w *ChainWriter) RegisterOperatorInQuorumWithAVSRegistryCoordinator( ctx context.Context, // we need to pass the private key explicitly and can't use the signer because registering requires signing a @@ -340,6 +289,8 @@ func (w *ChainWriter) RegisterOperatorInQuorumWithAVSRegistryCoordinator( return receipt, nil } +// RegisterOperator is similar to RegisterOperatorInQuorumWithAVSRegistryCoordinator but +// generates a random salt and expiry for the signature. func (w *ChainWriter) RegisterOperator( ctx context.Context, // we need to pass the private key explicitly and can't use the signer because registering requires signing a @@ -457,6 +408,11 @@ func (w *ChainWriter) RegisterOperator( return receipt, nil } +// UpdateStakesOfEntireOperatorSetForQuorums is used by avs teams running https://github.com/Layr-Labs/avs-sync +// to updates the stake of their entire operator set. +// Because of high gas costs of this operation, it typically needs to be called for every quorum, or perhaps for a +// small grouping of quorums +// (highly dependent on number of operators per quorum) func (w *ChainWriter) UpdateStakesOfEntireOperatorSetForQuorums( ctx context.Context, operatorsPerQuorum [][]gethcommon.Address, diff --git a/chainio/gen.go b/chainio/gen.go index d8f51fc4..8fdfcb5c 100644 --- a/chainio/gen.go +++ b/chainio/gen.go @@ -1,9 +1,5 @@ package chainio -//go:generate mockgen -destination=./mocks/avsRegistryContractsReader.go -package=mocks -mock_names=Reader=MockAVSReader github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry Reader -//go:generate mockgen -destination=./mocks/avsRegistryContractsSubscriber.go -package=mocks -mock_names=Subscriber=MockAVSSubscriber github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry Subscriber -//go:generate mockgen -destination=./mocks/avsRegistryContractsWriter.go -package=mocks -mock_names=Writer=MockAVSWriter github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry Writer //go:generate mockgen -destination=./mocks/ethclient.go -package=mocks -mock_names=Client=MockEthClient github.com/Layr-Labs/eigensdk-go/chainio/clients/eth Client -//go:generate mockgen -destination=./mocks/eventSubscription.go -package=mocks github.com/ethereum/go-ethereum/event Subscription //go:generate mockgen -destination=./clients/mocks/fireblocks.go -package=mocks -mock_names=Client=MockFireblocksClient github.com/Layr-Labs/eigensdk-go/chainio/clients/fireblocks Client //go:generate mockgen -destination=./clients/mocks/wallet.go -package=mocks github.com/Layr-Labs/eigensdk-go/chainio/clients/wallet Wallet diff --git a/chainio/mocks/avsRegistryContractsReader.go b/chainio/mocks/avsRegistryContractsReader.go deleted file mode 100644 index 15305b91..00000000 --- a/chainio/mocks/avsRegistryContractsReader.go +++ /dev/null @@ -1,243 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry (interfaces: Reader) -// -// Generated by this command: -// -// mockgen -destination=./mocks/avsRegistryContractsReader.go -package=mocks -mock_names=Reader=MockAVSReader github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry Reader -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - big "math/big" - reflect "reflect" - - contractOperatorStateRetriever "github.com/Layr-Labs/eigensdk-go/contracts/bindings/OperatorStateRetriever" - types "github.com/Layr-Labs/eigensdk-go/types" - bind "github.com/ethereum/go-ethereum/accounts/abi/bind" - common "github.com/ethereum/go-ethereum/common" - gomock "go.uber.org/mock/gomock" -) - -// MockAVSReader is a mock of Reader interface. -type MockAVSReader struct { - ctrl *gomock.Controller - recorder *MockAVSReaderMockRecorder -} - -// MockAVSReaderMockRecorder is the mock recorder for MockAVSReader. -type MockAVSReaderMockRecorder struct { - mock *MockAVSReader -} - -// NewMockAVSReader creates a new mock instance. -func NewMockAVSReader(ctrl *gomock.Controller) *MockAVSReader { - mock := &MockAVSReader{ctrl: ctrl} - mock.recorder = &MockAVSReaderMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAVSReader) EXPECT() *MockAVSReaderMockRecorder { - return m.recorder -} - -// GetCheckSignaturesIndices mocks base method. -func (m *MockAVSReader) GetCheckSignaturesIndices(arg0 *bind.CallOpts, arg1 uint32, arg2 types.QuorumNums, arg3 []types.Bytes32) (contractOperatorStateRetriever.OperatorStateRetrieverCheckSignaturesIndices, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCheckSignaturesIndices", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(contractOperatorStateRetriever.OperatorStateRetrieverCheckSignaturesIndices) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCheckSignaturesIndices indicates an expected call of GetCheckSignaturesIndices. -func (mr *MockAVSReaderMockRecorder) GetCheckSignaturesIndices(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCheckSignaturesIndices", reflect.TypeOf((*MockAVSReader)(nil).GetCheckSignaturesIndices), arg0, arg1, arg2, arg3) -} - -// GetOperatorAddrsInQuorumsAtCurrentBlock mocks base method. -func (m *MockAVSReader) GetOperatorAddrsInQuorumsAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.QuorumNums) ([][]common.Address, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorAddrsInQuorumsAtCurrentBlock", arg0, arg1) - ret0, _ := ret[0].([][]common.Address) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOperatorAddrsInQuorumsAtCurrentBlock indicates an expected call of GetOperatorAddrsInQuorumsAtCurrentBlock. -func (mr *MockAVSReaderMockRecorder) GetOperatorAddrsInQuorumsAtCurrentBlock(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorAddrsInQuorumsAtCurrentBlock", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorAddrsInQuorumsAtCurrentBlock), arg0, arg1) -} - -// GetOperatorFromId mocks base method. -func (m *MockAVSReader) GetOperatorFromId(arg0 *bind.CallOpts, arg1 types.Bytes32) (common.Address, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorFromId", arg0, arg1) - ret0, _ := ret[0].(common.Address) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOperatorFromId indicates an expected call of GetOperatorFromId. -func (mr *MockAVSReaderMockRecorder) GetOperatorFromId(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorFromId", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorFromId), arg0, arg1) -} - -// GetOperatorId mocks base method. -func (m *MockAVSReader) GetOperatorId(arg0 *bind.CallOpts, arg1 common.Address) ([32]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorId", arg0, arg1) - ret0, _ := ret[0].([32]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOperatorId indicates an expected call of GetOperatorId. -func (mr *MockAVSReaderMockRecorder) GetOperatorId(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorId", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorId), arg0, arg1) -} - -// GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock mocks base method. -func (m *MockAVSReader) GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.Bytes32) (map[types.QuorumNum]*big.Int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock", arg0, arg1) - ret0, _ := ret[0].(map[types.QuorumNum]*big.Int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock indicates an expected call of GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock. -func (mr *MockAVSReaderMockRecorder) GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock), arg0, arg1) -} - -// GetOperatorsStakeInQuorumsAtBlock mocks base method. -func (m *MockAVSReader) GetOperatorsStakeInQuorumsAtBlock(arg0 *bind.CallOpts, arg1 types.QuorumNums, arg2 uint32) ([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsAtBlock", arg0, arg1, arg2) - ret0, _ := ret[0].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOperatorsStakeInQuorumsAtBlock indicates an expected call of GetOperatorsStakeInQuorumsAtBlock. -func (mr *MockAVSReaderMockRecorder) GetOperatorsStakeInQuorumsAtBlock(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsAtBlock", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorsStakeInQuorumsAtBlock), arg0, arg1, arg2) -} - -// GetOperatorsStakeInQuorumsAtCurrentBlock mocks base method. -func (m *MockAVSReader) GetOperatorsStakeInQuorumsAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.QuorumNums) ([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsAtCurrentBlock", arg0, arg1) - ret0, _ := ret[0].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOperatorsStakeInQuorumsAtCurrentBlock indicates an expected call of GetOperatorsStakeInQuorumsAtCurrentBlock. -func (mr *MockAVSReaderMockRecorder) GetOperatorsStakeInQuorumsAtCurrentBlock(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsAtCurrentBlock", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorsStakeInQuorumsAtCurrentBlock), arg0, arg1) -} - -// GetOperatorsStakeInQuorumsOfOperatorAtBlock mocks base method. -func (m *MockAVSReader) GetOperatorsStakeInQuorumsOfOperatorAtBlock(arg0 *bind.CallOpts, arg1 types.Bytes32, arg2 uint32) (types.QuorumNums, [][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsOfOperatorAtBlock", arg0, arg1, arg2) - ret0, _ := ret[0].(types.QuorumNums) - ret1, _ := ret[1].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetOperatorsStakeInQuorumsOfOperatorAtBlock indicates an expected call of GetOperatorsStakeInQuorumsOfOperatorAtBlock. -func (mr *MockAVSReaderMockRecorder) GetOperatorsStakeInQuorumsOfOperatorAtBlock(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsOfOperatorAtBlock", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorsStakeInQuorumsOfOperatorAtBlock), arg0, arg1, arg2) -} - -// GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock mocks base method. -func (m *MockAVSReader) GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.Bytes32) (types.QuorumNums, [][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock", arg0, arg1) - ret0, _ := ret[0].(types.QuorumNums) - ret1, _ := ret[1].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock indicates an expected call of GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock. -func (mr *MockAVSReaderMockRecorder) GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock", reflect.TypeOf((*MockAVSReader)(nil).GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock), arg0, arg1) -} - -// GetQuorumCount mocks base method. -func (m *MockAVSReader) GetQuorumCount(arg0 *bind.CallOpts) (byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetQuorumCount", arg0) - ret0, _ := ret[0].(byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetQuorumCount indicates an expected call of GetQuorumCount. -func (mr *MockAVSReaderMockRecorder) GetQuorumCount(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQuorumCount", reflect.TypeOf((*MockAVSReader)(nil).GetQuorumCount), arg0) -} - -// IsOperatorRegistered mocks base method. -func (m *MockAVSReader) IsOperatorRegistered(arg0 *bind.CallOpts, arg1 common.Address) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsOperatorRegistered", arg0, arg1) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsOperatorRegistered indicates an expected call of IsOperatorRegistered. -func (mr *MockAVSReaderMockRecorder) IsOperatorRegistered(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsOperatorRegistered", reflect.TypeOf((*MockAVSReader)(nil).IsOperatorRegistered), arg0, arg1) -} - -// QueryExistingRegisteredOperatorPubKeys mocks base method. -func (m *MockAVSReader) QueryExistingRegisteredOperatorPubKeys(arg0 context.Context, arg1, arg2, arg3 *big.Int) ([]common.Address, []types.OperatorPubkeys, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryExistingRegisteredOperatorPubKeys", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]common.Address) - ret1, _ := ret[1].([]types.OperatorPubkeys) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// QueryExistingRegisteredOperatorPubKeys indicates an expected call of QueryExistingRegisteredOperatorPubKeys. -func (mr *MockAVSReaderMockRecorder) QueryExistingRegisteredOperatorPubKeys(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryExistingRegisteredOperatorPubKeys", reflect.TypeOf((*MockAVSReader)(nil).QueryExistingRegisteredOperatorPubKeys), arg0, arg1, arg2, arg3) -} - -// QueryExistingRegisteredOperatorSockets mocks base method. -func (m *MockAVSReader) QueryExistingRegisteredOperatorSockets(arg0 context.Context, arg1, arg2, arg3 *big.Int) (map[types.Bytes32]types.Socket, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryExistingRegisteredOperatorSockets", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(map[types.Bytes32]types.Socket) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryExistingRegisteredOperatorSockets indicates an expected call of QueryExistingRegisteredOperatorSockets. -func (mr *MockAVSReaderMockRecorder) QueryExistingRegisteredOperatorSockets(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryExistingRegisteredOperatorSockets", reflect.TypeOf((*MockAVSReader)(nil).QueryExistingRegisteredOperatorSockets), arg0, arg1, arg2, arg3) -} diff --git a/chainio/mocks/avsRegistryContractsSubscriber.go b/chainio/mocks/avsRegistryContractsSubscriber.go deleted file mode 100644 index febfe4ef..00000000 --- a/chainio/mocks/avsRegistryContractsSubscriber.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry (interfaces: Subscriber) -// -// Generated by this command: -// -// mockgen -destination=./mocks/avsRegistryContractsSubscriber.go -package=mocks -mock_names=Subscriber=MockAVSSubscriber github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry Subscriber -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - reflect "reflect" - - contractBLSApkRegistry "github.com/Layr-Labs/eigensdk-go/contracts/bindings/BLSApkRegistry" - contractRegistryCoordinator "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" - event "github.com/ethereum/go-ethereum/event" - gomock "go.uber.org/mock/gomock" -) - -// MockAVSSubscriber is a mock of Subscriber interface. -type MockAVSSubscriber struct { - ctrl *gomock.Controller - recorder *MockAVSSubscriberMockRecorder -} - -// MockAVSSubscriberMockRecorder is the mock recorder for MockAVSSubscriber. -type MockAVSSubscriberMockRecorder struct { - mock *MockAVSSubscriber -} - -// NewMockAVSSubscriber creates a new mock instance. -func NewMockAVSSubscriber(ctrl *gomock.Controller) *MockAVSSubscriber { - mock := &MockAVSSubscriber{ctrl: ctrl} - mock.recorder = &MockAVSSubscriberMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAVSSubscriber) EXPECT() *MockAVSSubscriberMockRecorder { - return m.recorder -} - -// SubscribeToNewPubkeyRegistrations mocks base method. -func (m *MockAVSSubscriber) SubscribeToNewPubkeyRegistrations() (chan *contractBLSApkRegistry.ContractBLSApkRegistryNewPubkeyRegistration, event.Subscription, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SubscribeToNewPubkeyRegistrations") - ret0, _ := ret[0].(chan *contractBLSApkRegistry.ContractBLSApkRegistryNewPubkeyRegistration) - ret1, _ := ret[1].(event.Subscription) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// SubscribeToNewPubkeyRegistrations indicates an expected call of SubscribeToNewPubkeyRegistrations. -func (mr *MockAVSSubscriberMockRecorder) SubscribeToNewPubkeyRegistrations() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeToNewPubkeyRegistrations", reflect.TypeOf((*MockAVSSubscriber)(nil).SubscribeToNewPubkeyRegistrations)) -} - -// SubscribeToOperatorSocketUpdates mocks base method. -func (m *MockAVSSubscriber) SubscribeToOperatorSocketUpdates() (chan *contractRegistryCoordinator.ContractRegistryCoordinatorOperatorSocketUpdate, event.Subscription, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SubscribeToOperatorSocketUpdates") - ret0, _ := ret[0].(chan *contractRegistryCoordinator.ContractRegistryCoordinatorOperatorSocketUpdate) - ret1, _ := ret[1].(event.Subscription) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// SubscribeToOperatorSocketUpdates indicates an expected call of SubscribeToOperatorSocketUpdates. -func (mr *MockAVSSubscriberMockRecorder) SubscribeToOperatorSocketUpdates() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeToOperatorSocketUpdates", reflect.TypeOf((*MockAVSSubscriber)(nil).SubscribeToOperatorSocketUpdates)) -} diff --git a/chainio/mocks/avsRegistryContractsWriter.go b/chainio/mocks/avsRegistryContractsWriter.go deleted file mode 100644 index 7797d777..00000000 --- a/chainio/mocks/avsRegistryContractsWriter.go +++ /dev/null @@ -1,122 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry (interfaces: Writer) -// -// Generated by this command: -// -// mockgen -destination=./mocks/avsRegistryContractsWriter.go -package=mocks -mock_names=Writer=MockAVSWriter github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry Writer -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - ecdsa "crypto/ecdsa" - big "math/big" - reflect "reflect" - - contractRegistryCoordinator "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" - bls "github.com/Layr-Labs/eigensdk-go/crypto/bls" - types "github.com/Layr-Labs/eigensdk-go/types" - common "github.com/ethereum/go-ethereum/common" - types0 "github.com/ethereum/go-ethereum/core/types" - gomock "go.uber.org/mock/gomock" -) - -// MockAVSWriter is a mock of Writer interface. -type MockAVSWriter struct { - ctrl *gomock.Controller - recorder *MockAVSWriterMockRecorder -} - -// MockAVSWriterMockRecorder is the mock recorder for MockAVSWriter. -type MockAVSWriterMockRecorder struct { - mock *MockAVSWriter -} - -// NewMockAVSWriter creates a new mock instance. -func NewMockAVSWriter(ctrl *gomock.Controller) *MockAVSWriter { - mock := &MockAVSWriter{ctrl: ctrl} - mock.recorder = &MockAVSWriterMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAVSWriter) EXPECT() *MockAVSWriterMockRecorder { - return m.recorder -} - -// DeregisterOperator mocks base method. -func (m *MockAVSWriter) DeregisterOperator(arg0 context.Context, arg1 types.QuorumNums, arg2 contractRegistryCoordinator.BN254G1Point) (*types0.Receipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeregisterOperator", arg0, arg1, arg2) - ret0, _ := ret[0].(*types0.Receipt) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DeregisterOperator indicates an expected call of DeregisterOperator. -func (mr *MockAVSWriterMockRecorder) DeregisterOperator(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeregisterOperator", reflect.TypeOf((*MockAVSWriter)(nil).DeregisterOperator), arg0, arg1, arg2) -} - -// RegisterOperator mocks base method. -func (m *MockAVSWriter) RegisterOperator(arg0 context.Context, arg1 *ecdsa.PrivateKey, arg2 *bls.KeyPair, arg3 types.QuorumNums, arg4 string) (*types0.Receipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterOperator", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(*types0.Receipt) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RegisterOperator indicates an expected call of RegisterOperator. -func (mr *MockAVSWriterMockRecorder) RegisterOperator(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterOperator", reflect.TypeOf((*MockAVSWriter)(nil).RegisterOperator), arg0, arg1, arg2, arg3, arg4) -} - -// RegisterOperatorInQuorumWithAVSRegistryCoordinator mocks base method. -func (m *MockAVSWriter) RegisterOperatorInQuorumWithAVSRegistryCoordinator(arg0 context.Context, arg1 *ecdsa.PrivateKey, arg2 [32]byte, arg3 *big.Int, arg4 *bls.KeyPair, arg5 types.QuorumNums, arg6 string) (*types0.Receipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterOperatorInQuorumWithAVSRegistryCoordinator", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(*types0.Receipt) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RegisterOperatorInQuorumWithAVSRegistryCoordinator indicates an expected call of RegisterOperatorInQuorumWithAVSRegistryCoordinator. -func (mr *MockAVSWriterMockRecorder) RegisterOperatorInQuorumWithAVSRegistryCoordinator(arg0, arg1, arg2, arg3, arg4, arg5, arg6 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterOperatorInQuorumWithAVSRegistryCoordinator", reflect.TypeOf((*MockAVSWriter)(nil).RegisterOperatorInQuorumWithAVSRegistryCoordinator), arg0, arg1, arg2, arg3, arg4, arg5, arg6) -} - -// UpdateStakesOfEntireOperatorSetForQuorums mocks base method. -func (m *MockAVSWriter) UpdateStakesOfEntireOperatorSetForQuorums(arg0 context.Context, arg1 [][]common.Address, arg2 types.QuorumNums) (*types0.Receipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateStakesOfEntireOperatorSetForQuorums", arg0, arg1, arg2) - ret0, _ := ret[0].(*types0.Receipt) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UpdateStakesOfEntireOperatorSetForQuorums indicates an expected call of UpdateStakesOfEntireOperatorSetForQuorums. -func (mr *MockAVSWriterMockRecorder) UpdateStakesOfEntireOperatorSetForQuorums(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStakesOfEntireOperatorSetForQuorums", reflect.TypeOf((*MockAVSWriter)(nil).UpdateStakesOfEntireOperatorSetForQuorums), arg0, arg1, arg2) -} - -// UpdateStakesOfOperatorSubsetForAllQuorums mocks base method. -func (m *MockAVSWriter) UpdateStakesOfOperatorSubsetForAllQuorums(arg0 context.Context, arg1 []common.Address) (*types0.Receipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateStakesOfOperatorSubsetForAllQuorums", arg0, arg1) - ret0, _ := ret[0].(*types0.Receipt) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UpdateStakesOfOperatorSubsetForAllQuorums indicates an expected call of UpdateStakesOfOperatorSubsetForAllQuorums. -func (mr *MockAVSWriterMockRecorder) UpdateStakesOfOperatorSubsetForAllQuorums(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStakesOfOperatorSubsetForAllQuorums", reflect.TypeOf((*MockAVSWriter)(nil).UpdateStakesOfOperatorSubsetForAllQuorums), arg0, arg1) -} diff --git a/chainio/mocks/eventSubscription.go b/chainio/mocks/eventSubscription.go deleted file mode 100644 index 953a5aa1..00000000 --- a/chainio/mocks/eventSubscription.go +++ /dev/null @@ -1,65 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ethereum/go-ethereum/event (interfaces: Subscription) -// -// Generated by this command: -// -// mockgen -destination=./mocks/eventSubscription.go -package=mocks github.com/ethereum/go-ethereum/event Subscription -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - reflect "reflect" - - gomock "go.uber.org/mock/gomock" -) - -// MockSubscription is a mock of Subscription interface. -type MockSubscription struct { - ctrl *gomock.Controller - recorder *MockSubscriptionMockRecorder -} - -// MockSubscriptionMockRecorder is the mock recorder for MockSubscription. -type MockSubscriptionMockRecorder struct { - mock *MockSubscription -} - -// NewMockSubscription creates a new mock instance. -func NewMockSubscription(ctrl *gomock.Controller) *MockSubscription { - mock := &MockSubscription{ctrl: ctrl} - mock.recorder = &MockSubscriptionMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSubscription) EXPECT() *MockSubscriptionMockRecorder { - return m.recorder -} - -// Err mocks base method. -func (m *MockSubscription) Err() <-chan error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Err") - ret0, _ := ret[0].(<-chan error) - return ret0 -} - -// Err indicates an expected call of Err. -func (mr *MockSubscriptionMockRecorder) Err() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Err", reflect.TypeOf((*MockSubscription)(nil).Err)) -} - -// Unsubscribe mocks base method. -func (m *MockSubscription) Unsubscribe() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Unsubscribe") -} - -// Unsubscribe indicates an expected call of Unsubscribe. -func (mr *MockSubscriptionMockRecorder) Unsubscribe() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unsubscribe", reflect.TypeOf((*MockSubscription)(nil).Unsubscribe)) -} diff --git a/internal/fakes/avs_registry.go b/internal/fakes/avs_registry.go new file mode 100644 index 00000000..e17ce7f9 --- /dev/null +++ b/internal/fakes/avs_registry.go @@ -0,0 +1,100 @@ +package fakes + +import ( + "context" + "math/big" + + apkregistrybindings "github.com/Layr-Labs/eigensdk-go/contracts/bindings/BLSApkRegistry" + opstateretriever "github.com/Layr-Labs/eigensdk-go/contracts/bindings/OperatorStateRetriever" + "github.com/Layr-Labs/eigensdk-go/types" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" +) + +type TestOperator struct { + OperatorAddr common.Address + OperatorInfo types.OperatorInfo + ContractG1Pubkey apkregistrybindings.BN254G1Point + ContractG2Pubkey apkregistrybindings.BN254G2Point + OperatorId types.OperatorId +} + +type FakeAVSRegistryReader struct { + opAddress []types.OperatorAddr + opPubKeys []types.OperatorPubkeys + operatorId types.OperatorId + socket types.Socket + err error +} + +func NewFakeAVSRegistryReader( + opr *TestOperator, + err error, +) *FakeAVSRegistryReader { + if opr == nil { + return &FakeAVSRegistryReader{} + } + return &FakeAVSRegistryReader{ + opAddress: []common.Address{opr.OperatorAddr}, + opPubKeys: []types.OperatorPubkeys{opr.OperatorInfo.Pubkeys}, + socket: opr.OperatorInfo.Socket, + operatorId: opr.OperatorId, + err: err, + } +} + +func (f *FakeAVSRegistryReader) QueryExistingRegisteredOperatorPubKeys( + ctx context.Context, + startBlock *big.Int, + stopBlock *big.Int, + blockRange *big.Int, +) ([]types.OperatorAddr, []types.OperatorPubkeys, error) { + return f.opAddress, f.opPubKeys, f.err +} + +func (f *FakeAVSRegistryReader) QueryExistingRegisteredOperatorSockets( + ctx context.Context, + startBlock *big.Int, + stopBlock *big.Int, + blockRange *big.Int, +) (map[types.OperatorId]types.Socket, error) { + if len(f.opPubKeys) == 0 { + return nil, nil + } + + return map[types.OperatorId]types.Socket{ + types.OperatorIdFromG1Pubkey(f.opPubKeys[0].G1Pubkey): f.socket, + }, nil +} + +func (f *FakeAVSRegistryReader) GetOperatorFromId( + opts *bind.CallOpts, + operatorId types.OperatorId, +) (common.Address, error) { + return f.opAddress[0], f.err +} + +func (f *FakeAVSRegistryReader) GetOperatorsStakeInQuorumsAtBlock( + opts *bind.CallOpts, + quorumNumbers types.QuorumNums, + blockNumber types.BlockNum, +) ([][]opstateretriever.OperatorStateRetrieverOperator, error) { + return [][]opstateretriever.OperatorStateRetrieverOperator{ + { + { + OperatorId: f.operatorId, + Stake: big.NewInt(123), + }, + }, + }, nil +} + +func (f *FakeAVSRegistryReader) GetCheckSignaturesIndices( + opts *bind.CallOpts, + referenceBlockNumber uint32, + quorumNumbers types.QuorumNums, + nonSignerOperatorIds []types.OperatorId, +) (opstateretriever.OperatorStateRetrieverCheckSignaturesIndices, error) { + return opstateretriever.OperatorStateRetrieverCheckSignaturesIndices{}, nil +} diff --git a/metrics/collectors/economic/economic.go b/metrics/collectors/economic/economic.go index 96d83ffb..5ab8dec5 100644 --- a/metrics/collectors/economic/economic.go +++ b/metrics/collectors/economic/economic.go @@ -5,7 +5,6 @@ import ( "errors" "strconv" - "github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry" "github.com/Layr-Labs/eigensdk-go/logging" "github.com/Layr-Labs/eigensdk-go/types" "github.com/Layr-Labs/eigensdk-go/utils" @@ -14,6 +13,19 @@ import ( "github.com/prometheus/client_golang/prometheus" ) +type eLReader interface { + OperatorIsFrozen(opts *bind.CallOpts, operatorAddr common.Address) (bool, error) +} + +type avsRegistryReader interface { + GetOperatorId(opts *bind.CallOpts, operatorAddr common.Address) ([32]byte, error) + + GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock( + opts *bind.CallOpts, + operatorId types.OperatorId, + ) (map[types.QuorumNum]types.StakeAmount, error) +} + // Collector exports the economic metrics listed at // // https://docs.eigenlayer.xyz/eigenlayer/avs-guides/spec/metrics/metrics-prom-spec#economics-metrics @@ -24,8 +36,8 @@ import ( // so that they are exported on the same port type Collector struct { // TODO(samlaf): we use a chain as the backend for now, but should eventually move to a subgraph - elReader ELReader - avsRegistryReader avsregistry.Reader + elReader eLReader + avsRegistryReader avsRegistryReader logger logging.Logger // params to query the metrics for operatorAddr common.Address @@ -60,14 +72,13 @@ type Collector struct { var _ prometheus.Collector = (*Collector)(nil) -type ELReader interface { - OperatorIsFrozen(opts *bind.CallOpts, operatorAddr common.Address) (bool, error) -} - func NewCollector( - elReader ELReader, avsRegistryReader avsregistry.Reader, - avsName string, logger logging.Logger, - operatorAddr common.Address, quorumNames map[types.QuorumNum]string, + elReader eLReader, + avsRegistryReader avsRegistryReader, + avsName string, + logger logging.Logger, + operatorAddr common.Address, + quorumNames map[types.QuorumNum]string, ) *Collector { return &Collector{ elReader: elReader, diff --git a/metrics/collectors/economic/economic_test.go b/metrics/collectors/economic/economic_test.go index 386779e8..671fb489 100644 --- a/metrics/collectors/economic/economic_test.go +++ b/metrics/collectors/economic/economic_test.go @@ -11,32 +11,58 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" - chainioMocks "github.com/Layr-Labs/eigensdk-go/chainio/mocks" "github.com/Layr-Labs/eigensdk-go/logging" "github.com/Layr-Labs/eigensdk-go/types" ) -const registeredOpAddress = "\"0xb81b18c988bfc7d131fca985a9c531f325e98a2f\"" +const registeredOpAddress = "0xb81b18c988bfc7d131fca985a9c531f325e98a2f" -type FakeELReader struct { +type fakeELReader struct { registeredOperators map[common.Address]bool } -func NewFakeELReader() *FakeELReader { +func newFakeELReader() *fakeELReader { registeredOperators := make(map[common.Address]bool) registeredOperators[common.HexToAddress(registeredOpAddress)] = false - return &FakeELReader{ + return &fakeELReader{ registeredOperators: registeredOperators, } } -func (f *FakeELReader) OperatorIsFrozen(opts *bind.CallOpts, operatorAddr common.Address) (bool, error) { +func (f *fakeELReader) OperatorIsFrozen(opts *bind.CallOpts, operatorAddr common.Address) (bool, error) { return f.registeredOperators[operatorAddr], nil } +type fakeAVSRegistryReader struct { + operatorId types.OperatorId + stakes map[types.QuorumNum]*big.Int +} + +func (f *fakeAVSRegistryReader) GetOperatorId(opts *bind.CallOpts, operatorAddr common.Address) ([32]byte, error) { + return f.operatorId, nil +} + +func (f *fakeAVSRegistryReader) GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock( + opts *bind.CallOpts, + operatorId types.OperatorId, +) (map[types.QuorumNum]*big.Int, error) { + return f.stakes, nil +} + +func newFakeAVSRegistryReader() *fakeAVSRegistryReader { + operatorId := types.OperatorId{1} + stakes := map[types.QuorumNum]*big.Int{ + 0: big.NewInt(1000), + 1: big.NewInt(2000), + } + return &fakeAVSRegistryReader{ + operatorId: operatorId, + stakes: stakes, + } +} + func TestEconomicCollector(t *testing.T) { operatorAddr := common.HexToAddress(registeredOpAddress) - operatorId := types.OperatorId{1} quorumNames := map[types.QuorumNum]string{ 0: "ethQuorum", 1: "someOtherTokenQuorum", @@ -45,16 +71,8 @@ func TestEconomicCollector(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() - elReader := NewFakeELReader() - avsRegistryReader := chainioMocks.NewMockAVSReader(mockCtrl) - avsRegistryReader.EXPECT().GetOperatorId(gomock.Any(), operatorAddr).Return(operatorId, nil) - avsRegistryReader.EXPECT().GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock(gomock.Any(), gomock.Any()).Return( - map[types.QuorumNum]*big.Int{ - 0: big.NewInt(1000), - 1: big.NewInt(2000), - }, - nil, - ) + elReader := newFakeELReader() + avsRegistryReader := newFakeAVSRegistryReader() logger := logging.NewNoopLogger() economicCollector := NewCollector(elReader, avsRegistryReader, "testavs", logger, operatorAddr, quorumNames) diff --git a/services/avsregistry/avsregistry_chaincaller.go b/services/avsregistry/avsregistry_chaincaller.go index 7bdddb5a..7b3601e3 100644 --- a/services/avsregistry/avsregistry_chaincaller.go +++ b/services/avsregistry/avsregistry_chaincaller.go @@ -3,9 +3,10 @@ package avsregistry import ( "context" "fmt" + opstateretriever "github.com/Layr-Labs/eigensdk-go/contracts/bindings/OperatorStateRetriever" + "github.com/ethereum/go-ethereum/common" "math/big" - avsregistry "github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry" "github.com/Layr-Labs/eigensdk-go/crypto/bls" "github.com/Layr-Labs/eigensdk-go/logging" opinfoservice "github.com/Layr-Labs/eigensdk-go/services/operatorsinfo" @@ -14,19 +15,39 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" ) +type avsRegistryReader interface { + GetOperatorsStakeInQuorumsAtBlock( + opts *bind.CallOpts, + quorumNumbers types.QuorumNums, + blockNumber types.BlockNum, + ) ([][]opstateretriever.OperatorStateRetrieverOperator, error) + + GetOperatorFromId( + opts *bind.CallOpts, + operatorId types.OperatorId, + ) (common.Address, error) + + GetCheckSignaturesIndices( + opts *bind.CallOpts, + referenceBlockNumber uint32, + quorumNumbers types.QuorumNums, + nonSignerOperatorIds []types.OperatorId, + ) (opstateretriever.OperatorStateRetrieverCheckSignaturesIndices, error) +} + // AvsRegistryServiceChainCaller is a wrapper around Reader that transforms the data into // nicer golang types that are easier to work with type AvsRegistryServiceChainCaller struct { - avsregistry.Reader + avsRegistryReader operatorInfoService opinfoservice.OperatorsInfoService logger logging.Logger } var _ AvsRegistryService = (*AvsRegistryServiceChainCaller)(nil) -func NewAvsRegistryServiceChainCaller(avsRegistryReader avsregistry.Reader, operatorInfoService opinfoservice.OperatorsInfoService, logger logging.Logger) *AvsRegistryServiceChainCaller { +func NewAvsRegistryServiceChainCaller(reader avsRegistryReader, operatorInfoService opinfoservice.OperatorsInfoService, logger logging.Logger) *AvsRegistryServiceChainCaller { return &AvsRegistryServiceChainCaller{ - Reader: avsRegistryReader, + avsRegistryReader: reader, operatorInfoService: operatorInfoService, logger: logger, } @@ -35,7 +56,7 @@ func NewAvsRegistryServiceChainCaller(avsRegistryReader avsregistry.Reader, oper func (ar *AvsRegistryServiceChainCaller) GetOperatorsAvsStateAtBlock(ctx context.Context, quorumNumbers types.QuorumNums, blockNumber types.BlockNum) (map[types.OperatorId]types.OperatorAvsState, error) { operatorsAvsState := make(map[types.OperatorId]types.OperatorAvsState) // Get operator state for each quorum by querying BLSOperatorStateRetriever (this call is why this service implementation is called ChainCaller) - operatorsStakesInQuorums, err := ar.Reader.GetOperatorsStakeInQuorumsAtBlock(&bind.CallOpts{Context: ctx}, quorumNumbers, blockNumber) + operatorsStakesInQuorums, err := ar.avsRegistryReader.GetOperatorsStakeInQuorumsAtBlock(&bind.CallOpts{Context: ctx}, quorumNumbers, blockNumber) if err != nil { return nil, utils.WrapError("Failed to get operator state", err) } @@ -96,7 +117,7 @@ func (ar *AvsRegistryServiceChainCaller) GetQuorumsAvsStateAtBlock(ctx context.C } func (ar *AvsRegistryServiceChainCaller) getOperatorInfo(ctx context.Context, operatorId types.OperatorId) (types.OperatorInfo, error) { - operatorAddr, err := ar.Reader.GetOperatorFromId(&bind.CallOpts{Context: ctx}, operatorId) + operatorAddr, err := ar.avsRegistryReader.GetOperatorFromId(&bind.CallOpts{Context: ctx}, operatorId) if err != nil { return types.OperatorInfo{}, utils.WrapError("Failed to get operator address from pubkey hash", err) } diff --git a/services/avsregistry/avsregistry_chaincaller_test.go b/services/avsregistry/avsregistry_chaincaller_test.go index 8b2cbde0..a334be73 100644 --- a/services/avsregistry/avsregistry_chaincaller_test.go +++ b/services/avsregistry/avsregistry_chaincaller_test.go @@ -2,32 +2,40 @@ package avsregistry import ( "context" + "errors" + "math/big" "reflect" "testing" - chainiomocks "github.com/Layr-Labs/eigensdk-go/chainio/mocks" - opstateretrievar "github.com/Layr-Labs/eigensdk-go/contracts/bindings/OperatorStateRetriever" "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/eigensdk-go/internal/fakes" "github.com/Layr-Labs/eigensdk-go/logging" - servicemocks "github.com/Layr-Labs/eigensdk-go/services/mocks" "github.com/Layr-Labs/eigensdk-go/types" + "github.com/ethereum/go-ethereum/common" - "go.uber.org/mock/gomock" ) -type testOperator struct { - operatorAddr common.Address - operatorId types.OperatorId +type fakeOperatorInfoService struct { operatorInfo types.OperatorInfo } +func newFakeOperatorInfoService(operatorInfo types.OperatorInfo) *fakeOperatorInfoService { + return &fakeOperatorInfoService{ + operatorInfo: operatorInfo, + } +} + +func (f *fakeOperatorInfoService) GetOperatorInfo(ctx context.Context, operator common.Address) (operatorInfo types.OperatorInfo, operatorFound bool) { + return f.operatorInfo, true +} + func TestAvsRegistryServiceChainCaller_getOperatorPubkeys(t *testing.T) { logger := logging.NewNoopLogger() - testOperator := testOperator{ - operatorAddr: common.HexToAddress("0x1"), - operatorId: types.OperatorId{1}, - operatorInfo: types.OperatorInfo{ + testOperator1 := fakes.TestOperator{ + OperatorAddr: common.HexToAddress("0x1"), + OperatorId: types.OperatorId{1}, + OperatorInfo: types.OperatorInfo{ Pubkeys: types.OperatorPubkeys{ G1Pubkey: bls.NewG1Point(big.NewInt(1), big.NewInt(1)), G2Pubkey: bls.NewG2Point([2]*big.Int{big.NewInt(1), big.NewInt(1)}, [2]*big.Int{big.NewInt(1), big.NewInt(1)}), @@ -38,40 +46,33 @@ func TestAvsRegistryServiceChainCaller_getOperatorPubkeys(t *testing.T) { // TODO(samlaf): add error test cases var tests = []struct { - name string - mocksInitializationFunc func(*chainiomocks.MockAVSReader, *servicemocks.MockOperatorsInfoService) - queryOperatorId types.OperatorId - wantErr error - wantOperatorInfo types.OperatorInfo + name string + operator *fakes.TestOperator + queryOperatorId types.OperatorId + wantErr error + wantOperatorInfo types.OperatorInfo }{ { - name: "should return operator info", - mocksInitializationFunc: func(mockAvsRegistryReader *chainiomocks.MockAVSReader, mockOperatorsInfoService *servicemocks.MockOperatorsInfoService) { - mockAvsRegistryReader.EXPECT().GetOperatorFromId(gomock.Any(), testOperator.operatorId).Return(testOperator.operatorAddr, nil) - mockOperatorsInfoService.EXPECT().GetOperatorInfo(gomock.Any(), testOperator.operatorAddr).Return(testOperator.operatorInfo, true) - }, - queryOperatorId: testOperator.operatorId, + name: "should return operator info", + operator: &testOperator1, + queryOperatorId: testOperator1.OperatorId, wantErr: nil, - wantOperatorInfo: testOperator.operatorInfo, + wantOperatorInfo: testOperator1.OperatorInfo, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create mocks - mockCtrl := gomock.NewController(t) - mockAvsRegistryReader := chainiomocks.NewMockAVSReader(mockCtrl) - mockOperatorsInfoService := servicemocks.NewMockOperatorsInfoService(mockCtrl) + mockAvsRegistryReader := fakes.NewFakeAVSRegistryReader(tt.operator, nil) + mockOperatorsInfoService := newFakeOperatorInfoService(tt.operator.OperatorInfo) - if tt.mocksInitializationFunc != nil { - tt.mocksInitializationFunc(mockAvsRegistryReader, mockOperatorsInfoService) - } // Create a new instance of the avsregistry service service := NewAvsRegistryServiceChainCaller(mockAvsRegistryReader, mockOperatorsInfoService, logger) // Call the GetOperatorPubkeys method with the test operator address gotOperatorInfo, gotErr := service.getOperatorInfo(context.Background(), tt.queryOperatorId) - if tt.wantErr != gotErr { + if !errors.Is(gotErr, tt.wantErr) { t.Fatalf("GetOperatorPubkeys returned wrong error. Got: %v, want: %v.", gotErr, tt.wantErr) } if tt.wantErr == nil && !reflect.DeepEqual(tt.wantOperatorInfo, gotOperatorInfo) { @@ -83,10 +84,10 @@ func TestAvsRegistryServiceChainCaller_getOperatorPubkeys(t *testing.T) { func TestAvsRegistryServiceChainCaller_GetOperatorsAvsState(t *testing.T) { logger := logging.NewNoopLogger() - testOperator := testOperator{ - operatorAddr: common.HexToAddress("0x1"), - operatorId: types.OperatorId{1}, - operatorInfo: types.OperatorInfo{ + testOperator1 := fakes.TestOperator{ + OperatorAddr: common.HexToAddress("0x1"), + OperatorId: types.OperatorId{1}, + OperatorInfo: types.OperatorInfo{ Pubkeys: types.OperatorPubkeys{ G1Pubkey: bls.NewG1Point(big.NewInt(1), big.NewInt(1)), G2Pubkey: bls.NewG2Point([2]*big.Int{big.NewInt(1), big.NewInt(1)}, [2]*big.Int{big.NewInt(1), big.NewInt(1)}), @@ -97,33 +98,22 @@ func TestAvsRegistryServiceChainCaller_GetOperatorsAvsState(t *testing.T) { var tests = []struct { name string - mocksInitializationFunc func(*chainiomocks.MockAVSReader, *servicemocks.MockOperatorsInfoService) queryQuorumNumbers types.QuorumNums queryBlockNum types.BlockNum wantErr error wantOperatorsAvsStateDict map[types.OperatorId]types.OperatorAvsState + operator *fakes.TestOperator }{ { - name: "should return operatorsAvsState", - mocksInitializationFunc: func(mockAvsRegistryReader *chainiomocks.MockAVSReader, mockOperatorsInfoService *servicemocks.MockOperatorsInfoService) { - mockAvsRegistryReader.EXPECT().GetOperatorsStakeInQuorumsAtBlock(gomock.Any(), types.QuorumNums{1}, types.BlockNum(1)).Return([][]opstateretrievar.OperatorStateRetrieverOperator{ - { - { - OperatorId: testOperator.operatorId, - Stake: big.NewInt(123), - }, - }, - }, nil) - mockAvsRegistryReader.EXPECT().GetOperatorFromId(gomock.Any(), testOperator.operatorId).Return(testOperator.operatorAddr, nil) - mockOperatorsInfoService.EXPECT().GetOperatorInfo(gomock.Any(), testOperator.operatorAddr).Return(testOperator.operatorInfo, true) - }, + name: "should return operatorsAvsState", queryQuorumNumbers: types.QuorumNums{1}, + operator: &testOperator1, queryBlockNum: 1, wantErr: nil, wantOperatorsAvsStateDict: map[types.OperatorId]types.OperatorAvsState{ - testOperator.operatorId: { - OperatorId: testOperator.operatorId, - OperatorInfo: testOperator.operatorInfo, + testOperator1.OperatorId: { + OperatorId: testOperator1.OperatorId, + OperatorInfo: testOperator1.OperatorInfo, StakePerQuorum: map[types.QuorumNum]types.StakeAmount{1: big.NewInt(123)}, BlockNumber: 1, }, @@ -134,19 +124,15 @@ func TestAvsRegistryServiceChainCaller_GetOperatorsAvsState(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create mocks - mockCtrl := gomock.NewController(t) - mockAvsRegistryReader := chainiomocks.NewMockAVSReader(mockCtrl) - mockOperatorsInfoService := servicemocks.NewMockOperatorsInfoService(mockCtrl) + mockAvsRegistryReader := fakes.NewFakeAVSRegistryReader(tt.operator, nil) + mockOperatorsInfoService := newFakeOperatorInfoService(tt.operator.OperatorInfo) - if tt.mocksInitializationFunc != nil { - tt.mocksInitializationFunc(mockAvsRegistryReader, mockOperatorsInfoService) - } // Create a new instance of the avsregistry service service := NewAvsRegistryServiceChainCaller(mockAvsRegistryReader, mockOperatorsInfoService, logger) // Call the GetOperatorPubkeys method with the test operator address gotOperatorsAvsStateDict, gotErr := service.GetOperatorsAvsStateAtBlock(context.Background(), tt.queryQuorumNumbers, tt.queryBlockNum) - if tt.wantErr != gotErr { + if !errors.Is(gotErr, tt.wantErr) { t.Fatalf("GetOperatorsAvsState returned wrong error. Got: %v, want: %v.", gotErr, tt.wantErr) } if tt.wantErr == nil && !reflect.DeepEqual(tt.wantOperatorsAvsStateDict, gotOperatorsAvsStateDict) { @@ -158,10 +144,10 @@ func TestAvsRegistryServiceChainCaller_GetOperatorsAvsState(t *testing.T) { func TestAvsRegistryServiceChainCaller_GetQuorumsAvsState(t *testing.T) { logger := logging.NewNoopLogger() - testOperator := testOperator{ - operatorAddr: common.HexToAddress("0x1"), - operatorId: types.OperatorId{1}, - operatorInfo: types.OperatorInfo{ + testOperator1 := fakes.TestOperator{ + OperatorAddr: common.HexToAddress("0x1"), + OperatorId: types.OperatorId{1}, + OperatorInfo: types.OperatorInfo{ Pubkeys: types.OperatorPubkeys{ G1Pubkey: bls.NewG1Point(big.NewInt(1), big.NewInt(1)), G2Pubkey: bls.NewG2Point([2]*big.Int{big.NewInt(1), big.NewInt(1)}, [2]*big.Int{big.NewInt(1), big.NewInt(1)}), @@ -172,27 +158,16 @@ func TestAvsRegistryServiceChainCaller_GetQuorumsAvsState(t *testing.T) { var tests = []struct { name string - mocksInitializationFunc func(*chainiomocks.MockAVSReader, *servicemocks.MockOperatorsInfoService) queryQuorumNumbers types.QuorumNums queryBlockNum types.BlockNum wantErr error wantQuorumsAvsStateDict map[types.QuorumNum]types.QuorumAvsState + operator *fakes.TestOperator }{ { - name: "should return operatorsAvsState", - mocksInitializationFunc: func(mockAvsRegistryReader *chainiomocks.MockAVSReader, mockOperatorsInfoService *servicemocks.MockOperatorsInfoService) { - mockAvsRegistryReader.EXPECT().GetOperatorsStakeInQuorumsAtBlock(gomock.Any(), types.QuorumNums{1}, types.BlockNum(1)).Return([][]opstateretrievar.OperatorStateRetrieverOperator{ - { - { - OperatorId: testOperator.operatorId, - Stake: big.NewInt(123), - }, - }, - }, nil) - mockAvsRegistryReader.EXPECT().GetOperatorFromId(gomock.Any(), testOperator.operatorId).Return(testOperator.operatorAddr, nil) - mockOperatorsInfoService.EXPECT().GetOperatorInfo(gomock.Any(), testOperator.operatorAddr).Return(testOperator.operatorInfo, true) - }, + name: "should return operatorsAvsState", queryQuorumNumbers: types.QuorumNums{1}, + operator: &testOperator1, queryBlockNum: 1, wantErr: nil, wantQuorumsAvsStateDict: map[types.QuorumNum]types.QuorumAvsState{ @@ -209,19 +184,15 @@ func TestAvsRegistryServiceChainCaller_GetQuorumsAvsState(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create mocks - mockCtrl := gomock.NewController(t) - mockAvsRegistryReader := chainiomocks.NewMockAVSReader(mockCtrl) - mockOperatorsInfoService := servicemocks.NewMockOperatorsInfoService(mockCtrl) + mockAvsRegistryReader := fakes.NewFakeAVSRegistryReader(tt.operator, nil) + mockOperatorsInfoService := newFakeOperatorInfoService(tt.operator.OperatorInfo) - if tt.mocksInitializationFunc != nil { - tt.mocksInitializationFunc(mockAvsRegistryReader, mockOperatorsInfoService) - } // Create a new instance of the avsregistry service service := NewAvsRegistryServiceChainCaller(mockAvsRegistryReader, mockOperatorsInfoService, logger) // Call the GetOperatorPubkeys method with the test operator address aggG1PubkeyPerQuorum, gotErr := service.GetQuorumsAvsStateAtBlock(context.Background(), tt.queryQuorumNumbers, tt.queryBlockNum) - if tt.wantErr != gotErr { + if !errors.Is(gotErr, tt.wantErr) { t.Fatalf("GetOperatorsAvsState returned wrong error. Got: %v, want: %v.", gotErr, tt.wantErr) } if tt.wantErr == nil && !reflect.DeepEqual(tt.wantQuorumsAvsStateDict, aggG1PubkeyPerQuorum) { diff --git a/services/gen.go b/services/gen.go deleted file mode 100644 index 6d34428e..00000000 --- a/services/gen.go +++ /dev/null @@ -1,13 +0,0 @@ -package services - -//go:generate mockgen -destination=./mocks/operatorsinfo.go -package=mocks github.com/Layr-Labs/eigensdk-go/services/operatorsinfo OperatorsInfoService -//go:generate mockgen -destination=./mocks/avsregistry.go -package=mocks github.com/Layr-Labs/eigensdk-go/services/avsregistry AvsRegistryService - -// We generate it in ./mocks/blsagg/ instead of ./mocks like the others because otherwise we get a circular dependency -// avsregistry -> mocks -> avsregistry -// because avsregistry_chaincaller_test -> for blsApkRegistry mock -// and blsaggregation mock -> avsregistry interface -// TODO: are there better ways to organize these dependencies? Maybe by using ben johnson -// and having the avs registry interface be in the /avsregistry dir but the avsregistry_chaincaller -// and its test in a subdir? -//go:generate mockgen -destination=./mocks/blsagg/blsaggregation.go -package=mocks github.com/Layr-Labs/eigensdk-go/services/bls_aggregation BlsAggregationService diff --git a/services/mocks/avsregistry.go b/services/mocks/avsregistry.go deleted file mode 100644 index 79e42c8e..00000000 --- a/services/mocks/avsregistry.go +++ /dev/null @@ -1,88 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Layr-Labs/eigensdk-go/services/avsregistry (interfaces: AvsRegistryService) -// -// Generated by this command: -// -// mockgen -destination=./mocks/avsregistry.go -package=mocks github.com/Layr-Labs/eigensdk-go/services/avsregistry AvsRegistryService -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - reflect "reflect" - - contractOperatorStateRetriever "github.com/Layr-Labs/eigensdk-go/contracts/bindings/OperatorStateRetriever" - types "github.com/Layr-Labs/eigensdk-go/types" - bind "github.com/ethereum/go-ethereum/accounts/abi/bind" - gomock "go.uber.org/mock/gomock" -) - -// MockAvsRegistryService is a mock of AvsRegistryService interface. -type MockAvsRegistryService struct { - ctrl *gomock.Controller - recorder *MockAvsRegistryServiceMockRecorder -} - -// MockAvsRegistryServiceMockRecorder is the mock recorder for MockAvsRegistryService. -type MockAvsRegistryServiceMockRecorder struct { - mock *MockAvsRegistryService -} - -// NewMockAvsRegistryService creates a new mock instance. -func NewMockAvsRegistryService(ctrl *gomock.Controller) *MockAvsRegistryService { - mock := &MockAvsRegistryService{ctrl: ctrl} - mock.recorder = &MockAvsRegistryServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAvsRegistryService) EXPECT() *MockAvsRegistryServiceMockRecorder { - return m.recorder -} - -// GetCheckSignaturesIndices mocks base method. -func (m *MockAvsRegistryService) GetCheckSignaturesIndices(arg0 *bind.CallOpts, arg1 uint32, arg2 types.QuorumNums, arg3 []types.Bytes32) (contractOperatorStateRetriever.OperatorStateRetrieverCheckSignaturesIndices, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCheckSignaturesIndices", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(contractOperatorStateRetriever.OperatorStateRetrieverCheckSignaturesIndices) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCheckSignaturesIndices indicates an expected call of GetCheckSignaturesIndices. -func (mr *MockAvsRegistryServiceMockRecorder) GetCheckSignaturesIndices(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCheckSignaturesIndices", reflect.TypeOf((*MockAvsRegistryService)(nil).GetCheckSignaturesIndices), arg0, arg1, arg2, arg3) -} - -// GetOperatorsAvsStateAtBlock mocks base method. -func (m *MockAvsRegistryService) GetOperatorsAvsStateAtBlock(arg0 context.Context, arg1 types.QuorumNums, arg2 uint32) (map[types.Bytes32]types.OperatorAvsState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorsAvsStateAtBlock", arg0, arg1, arg2) - ret0, _ := ret[0].(map[types.Bytes32]types.OperatorAvsState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOperatorsAvsStateAtBlock indicates an expected call of GetOperatorsAvsStateAtBlock. -func (mr *MockAvsRegistryServiceMockRecorder) GetOperatorsAvsStateAtBlock(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsAvsStateAtBlock", reflect.TypeOf((*MockAvsRegistryService)(nil).GetOperatorsAvsStateAtBlock), arg0, arg1, arg2) -} - -// GetQuorumsAvsStateAtBlock mocks base method. -func (m *MockAvsRegistryService) GetQuorumsAvsStateAtBlock(arg0 context.Context, arg1 types.QuorumNums, arg2 uint32) (map[types.QuorumNum]types.QuorumAvsState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetQuorumsAvsStateAtBlock", arg0, arg1, arg2) - ret0, _ := ret[0].(map[types.QuorumNum]types.QuorumAvsState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetQuorumsAvsStateAtBlock indicates an expected call of GetQuorumsAvsStateAtBlock. -func (mr *MockAvsRegistryServiceMockRecorder) GetQuorumsAvsStateAtBlock(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQuorumsAvsStateAtBlock", reflect.TypeOf((*MockAvsRegistryService)(nil).GetQuorumsAvsStateAtBlock), arg0, arg1, arg2) -} diff --git a/services/mocks/blsagg/blsaggregation.go b/services/mocks/blsagg/blsaggregation.go deleted file mode 100644 index 418bf836..00000000 --- a/services/mocks/blsagg/blsaggregation.go +++ /dev/null @@ -1,86 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Layr-Labs/eigensdk-go/services/bls_aggregation (interfaces: BlsAggregationService) -// -// Generated by this command: -// -// mockgen -destination=./mocks/blsagg/blsaggregation.go -package=mocks github.com/Layr-Labs/eigensdk-go/services/bls_aggregation BlsAggregationService -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - reflect "reflect" - time "time" - - bls "github.com/Layr-Labs/eigensdk-go/crypto/bls" - blsagg "github.com/Layr-Labs/eigensdk-go/services/bls_aggregation" - types "github.com/Layr-Labs/eigensdk-go/types" - gomock "go.uber.org/mock/gomock" -) - -// MockBlsAggregationService is a mock of BlsAggregationService interface. -type MockBlsAggregationService struct { - ctrl *gomock.Controller - recorder *MockBlsAggregationServiceMockRecorder -} - -// MockBlsAggregationServiceMockRecorder is the mock recorder for MockBlsAggregationService. -type MockBlsAggregationServiceMockRecorder struct { - mock *MockBlsAggregationService -} - -// NewMockBlsAggregationService creates a new mock instance. -func NewMockBlsAggregationService(ctrl *gomock.Controller) *MockBlsAggregationService { - mock := &MockBlsAggregationService{ctrl: ctrl} - mock.recorder = &MockBlsAggregationServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBlsAggregationService) EXPECT() *MockBlsAggregationServiceMockRecorder { - return m.recorder -} - -// GetResponseChannel mocks base method. -func (m *MockBlsAggregationService) GetResponseChannel() <-chan blsagg.BlsAggregationServiceResponse { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetResponseChannel") - ret0, _ := ret[0].(<-chan blsagg.BlsAggregationServiceResponse) - return ret0 -} - -// GetResponseChannel indicates an expected call of GetResponseChannel. -func (mr *MockBlsAggregationServiceMockRecorder) GetResponseChannel() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResponseChannel", reflect.TypeOf((*MockBlsAggregationService)(nil).GetResponseChannel)) -} - -// InitializeNewTask mocks base method. -func (m *MockBlsAggregationService) InitializeNewTask(arg0, arg1 uint32, arg2 types.QuorumNums, arg3 types.QuorumThresholdPercentages, arg4 time.Duration) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InitializeNewTask", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(error) - return ret0 -} - -// InitializeNewTask indicates an expected call of InitializeNewTask. -func (mr *MockBlsAggregationServiceMockRecorder) InitializeNewTask(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitializeNewTask", reflect.TypeOf((*MockBlsAggregationService)(nil).InitializeNewTask), arg0, arg1, arg2, arg3, arg4) -} - -// ProcessNewSignature mocks base method. -func (m *MockBlsAggregationService) ProcessNewSignature(arg0 context.Context, arg1 uint32, arg2 any, arg3 *bls.Signature, arg4 types.Bytes32) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ProcessNewSignature", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(error) - return ret0 -} - -// ProcessNewSignature indicates an expected call of ProcessNewSignature. -func (mr *MockBlsAggregationServiceMockRecorder) ProcessNewSignature(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProcessNewSignature", reflect.TypeOf((*MockBlsAggregationService)(nil).ProcessNewSignature), arg0, arg1, arg2, arg3, arg4) -} diff --git a/services/mocks/operatorsinfo.go b/services/mocks/operatorsinfo.go deleted file mode 100644 index 3f0b06d9..00000000 --- a/services/mocks/operatorsinfo.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Layr-Labs/eigensdk-go/services/operatorsinfo (interfaces: OperatorsInfoService) -// -// Generated by this command: -// -// mockgen -destination=./mocks/operatorsinfo.go -package=mocks github.com/Layr-Labs/eigensdk-go/services/operatorsinfo OperatorsInfoService -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - reflect "reflect" - - types "github.com/Layr-Labs/eigensdk-go/types" - common "github.com/ethereum/go-ethereum/common" - gomock "go.uber.org/mock/gomock" -) - -// MockOperatorsInfoService is a mock of OperatorsInfoService interface. -type MockOperatorsInfoService struct { - ctrl *gomock.Controller - recorder *MockOperatorsInfoServiceMockRecorder -} - -// MockOperatorsInfoServiceMockRecorder is the mock recorder for MockOperatorsInfoService. -type MockOperatorsInfoServiceMockRecorder struct { - mock *MockOperatorsInfoService -} - -// NewMockOperatorsInfoService creates a new mock instance. -func NewMockOperatorsInfoService(ctrl *gomock.Controller) *MockOperatorsInfoService { - mock := &MockOperatorsInfoService{ctrl: ctrl} - mock.recorder = &MockOperatorsInfoServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockOperatorsInfoService) EXPECT() *MockOperatorsInfoServiceMockRecorder { - return m.recorder -} - -// GetOperatorInfo mocks base method. -func (m *MockOperatorsInfoService) GetOperatorInfo(arg0 context.Context, arg1 common.Address) (types.OperatorInfo, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOperatorInfo", arg0, arg1) - ret0, _ := ret[0].(types.OperatorInfo) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetOperatorInfo indicates an expected call of GetOperatorInfo. -func (mr *MockOperatorsInfoServiceMockRecorder) GetOperatorInfo(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorInfo", reflect.TypeOf((*MockOperatorsInfoService)(nil).GetOperatorInfo), arg0, arg1) -} diff --git a/services/operatorsinfo/operatorsinfo_inmemory.go b/services/operatorsinfo/operatorsinfo_inmemory.go index 72254a63..9e289680 100644 --- a/services/operatorsinfo/operatorsinfo_inmemory.go +++ b/services/operatorsinfo/operatorsinfo_inmemory.go @@ -3,10 +3,12 @@ package operatorsinfo import ( "context" "errors" + blsapkreg "github.com/Layr-Labs/eigensdk-go/contracts/bindings/BLSApkRegistry" + regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" + "github.com/ethereum/go-ethereum/event" "math/big" "sync" - "github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry" "github.com/Layr-Labs/eigensdk-go/crypto/bls" "github.com/Layr-Labs/eigensdk-go/logging" "github.com/Layr-Labs/eigensdk-go/types" @@ -16,6 +18,27 @@ import ( var defaultLogFilterQueryBlockRange = big.NewInt(10_000) +type avsRegistryReader interface { + QueryExistingRegisteredOperatorSockets( + ctx context.Context, + startBlock *big.Int, + stopBlock *big.Int, + blockRange *big.Int, + ) (map[types.OperatorId]types.Socket, error) + + QueryExistingRegisteredOperatorPubKeys( + ctx context.Context, + startBlock *big.Int, + stopBlock *big.Int, + blockRange *big.Int, + ) ([]types.OperatorAddr, []types.OperatorPubkeys, error) +} + +type avsRegistrySubscriber interface { + SubscribeToNewPubkeyRegistrations() (chan *blsapkreg.ContractBLSApkRegistryNewPubkeyRegistration, event.Subscription, error) + SubscribeToOperatorSocketUpdates() (chan *regcoord.ContractRegistryCoordinatorOperatorSocketUpdate, event.Subscription, error) +} + // OperatorsInfoServiceInMemory is a stateful goroutine (see https://gobyexample.com/stateful-goroutines) // implementation of OperatorsInfoService that listen for the NewPubkeyRegistration and OperatorSocketUpdate events using a websocket connection // to an eth client and stores the pubkeys/sockets in memory. Another possible implementation is using a mutex @@ -29,8 +52,8 @@ var defaultLogFilterQueryBlockRange = big.NewInt(10_000) // to be replicated and load-balanced, so that when it fails traffic can be switched to the other aggregator. type OperatorsInfoServiceInMemory struct { logFilterQueryBlockRange *big.Int - avsRegistrySubscriber avsregistry.Subscriber - avsRegistryReader avsregistry.Reader + avsRegistrySubscriber avsRegistrySubscriber + avsRegistryReader avsRegistryReader logger logging.Logger queryC chan<- query // queried via the queryC channel, so don't need mutex to access @@ -59,8 +82,8 @@ var _ OperatorsInfoService = (*OperatorsInfoServiceInMemory)(nil) // Using a separate initialize() function might lead to some users forgetting to call it and the service not behaving properly. func NewOperatorsInfoServiceInMemory( ctx context.Context, - avsRegistrySubscriber avsregistry.Subscriber, - avsRegistryReader avsregistry.Reader, + avsRegistrySubscriber avsRegistrySubscriber, + avsRegistryReader avsRegistryReader, logFilterQueryBlockRange *big.Int, logger logging.Logger, ) *OperatorsInfoServiceInMemory { diff --git a/services/operatorsinfo/operatorsinfo_inmemory_test.go b/services/operatorsinfo/operatorsinfo_inmemory_test.go index c0322223..200766a0 100644 --- a/services/operatorsinfo/operatorsinfo_inmemory_test.go +++ b/services/operatorsinfo/operatorsinfo_inmemory_test.go @@ -2,6 +2,8 @@ package operatorsinfo import ( "context" + + "github.com/ethereum/go-ethereum/event" "log/slog" "math/big" "os" @@ -9,23 +11,61 @@ import ( "testing" "time" - "github.com/Layr-Labs/eigensdk-go/chainio/mocks" + apkregistrybindings "github.com/Layr-Labs/eigensdk-go/contracts/bindings/BLSApkRegistry" + blsapkreg "github.com/Layr-Labs/eigensdk-go/contracts/bindings/BLSApkRegistry" + regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/eigensdk-go/internal/fakes" "github.com/Layr-Labs/eigensdk-go/logging" "github.com/Layr-Labs/eigensdk-go/types" + "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" - "go.uber.org/mock/gomock" - - apkregistrybindings "github.com/Layr-Labs/eigensdk-go/contracts/bindings/BLSApkRegistry" - regcoordbindings "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" ) -type testOperator struct { - operatorAddr common.Address - operatorInfo types.OperatorInfo - contractG1Pubkey apkregistrybindings.BN254G1Point - contractG2Pubkey apkregistrybindings.BN254G2Point +type fakeAVSRegistrySubscriber struct { + pubkeyRegistrationEventC chan *apkregistrybindings.ContractBLSApkRegistryNewPubkeyRegistration + operatorSocketUpdateEventC chan *regcoord.ContractRegistryCoordinatorOperatorSocketUpdate + eventSubscription *fakeEventSubscription +} + +func newFakeAVSRegistrySubscriber( + eventSubscription *fakeEventSubscription, + pubkeyRegistrationEventC chan *apkregistrybindings.ContractBLSApkRegistryNewPubkeyRegistration, + operatorSocketUpdateEventC chan *regcoord.ContractRegistryCoordinatorOperatorSocketUpdate, +) *fakeAVSRegistrySubscriber { + return &fakeAVSRegistrySubscriber{ + pubkeyRegistrationEventC: pubkeyRegistrationEventC, + operatorSocketUpdateEventC: operatorSocketUpdateEventC, + eventSubscription: eventSubscription, + } +} + +func (f *fakeAVSRegistrySubscriber) SubscribeToNewPubkeyRegistrations() (chan *blsapkreg.ContractBLSApkRegistryNewPubkeyRegistration, event.Subscription, error) { + return f.pubkeyRegistrationEventC, f.eventSubscription, nil +} + +func (f *fakeAVSRegistrySubscriber) SubscribeToOperatorSocketUpdates() (chan *regcoord.ContractRegistryCoordinatorOperatorSocketUpdate, event.Subscription, error) { + return f.operatorSocketUpdateEventC, f.eventSubscription, nil +} + +type fakeEventSubscription struct { + errC chan error +} + +func newFakeEventSubscription( + errC chan error) *fakeEventSubscription { + return &fakeEventSubscription{ + errC: errC, + } +} + +func (f *fakeEventSubscription) Err() <-chan error { + return f.errC +} + +func (f *fakeEventSubscription) Unsubscribe() { + } func TestGetOperatorInfo(t *testing.T) { @@ -35,99 +75,73 @@ func TestGetOperatorInfo(t *testing.T) { G2Pubkey: bls.NewG2Point([2]*big.Int{big.NewInt(1), big.NewInt(1)}, [2]*big.Int{big.NewInt(1), big.NewInt(1)}), } contractG1Pubkey, contractG2Pubkey := operator1Pubkeys.ToContractPubkeys() - testOperator1 := testOperator{ - operatorAddr: common.HexToAddress("0x1"), - operatorInfo: types.OperatorInfo{ + testOperator1 := fakes.TestOperator{ + OperatorAddr: common.HexToAddress("0x1"), + OperatorInfo: types.OperatorInfo{ Pubkeys: operator1Pubkeys, Socket: "localhost:8080", }, - contractG1Pubkey: contractG1Pubkey, - contractG2Pubkey: contractG2Pubkey, + ContractG1Pubkey: contractG1Pubkey, + ContractG2Pubkey: contractG2Pubkey, + } + + pubkeyRegistrationEventC := make(chan *apkregistrybindings.ContractBLSApkRegistryNewPubkeyRegistration, 1) + pubkeyRegistrationEvent := &apkregistrybindings.ContractBLSApkRegistryNewPubkeyRegistration{ + Operator: testOperator1.OperatorAddr, + PubkeyG1: testOperator1.ContractG1Pubkey, + PubkeyG2: testOperator1.ContractG2Pubkey, + Raw: gethtypes.Log{}, } + pubkeyRegistrationEventC <- pubkeyRegistrationEvent + operatorSocketUpdateEventC := make(chan *regcoord.ContractRegistryCoordinatorOperatorSocketUpdate, 1) + operatorSocketUpdateEvent := ®coord.ContractRegistryCoordinatorOperatorSocketUpdate{ + OperatorId: types.OperatorIdFromG1Pubkey(testOperator1.OperatorInfo.Pubkeys.G1Pubkey), + Socket: string(testOperator1.OperatorInfo.Socket), + Raw: gethtypes.Log{}, + } + operatorSocketUpdateEventC <- operatorSocketUpdateEvent // Define tests var tests = []struct { - name string - mocksInitializationFunc func(*mocks.MockAVSSubscriber, *mocks.MockAVSReader, *mocks.MockSubscription) - queryOperatorAddr common.Address - wantOperatorFound bool - wantOperatorInfo types.OperatorInfo + name string + operator *fakes.TestOperator + pubkeyRegistrationEventC chan *apkregistrybindings.ContractBLSApkRegistryNewPubkeyRegistration + operatorSocketUpdateEventC chan *regcoord.ContractRegistryCoordinatorOperatorSocketUpdate + eventErrC chan error + queryOperatorAddr common.Address + wantOperatorFound bool + wantOperatorInfo types.OperatorInfo }{ { - name: "should return false if operator not found", - mocksInitializationFunc: func(mockAvsRegistrySubscriber *mocks.MockAVSSubscriber, mockAvsReader *mocks.MockAVSReader, mockSubscription *mocks.MockSubscription) { - errC := make(chan error) - mockSubscription.EXPECT().Err().AnyTimes().Return(errC) - mockAvsRegistrySubscriber.EXPECT().SubscribeToNewPubkeyRegistrations().Return(nil, mockSubscription, nil) - mockAvsReader.EXPECT().QueryExistingRegisteredOperatorPubKeys(gomock.Any(), nil, nil, defaultLogFilterQueryBlockRange).Return(nil, nil, nil) - mockAvsRegistrySubscriber.EXPECT().SubscribeToOperatorSocketUpdates().Return(nil, mockSubscription, nil) - mockAvsReader.EXPECT().QueryExistingRegisteredOperatorSockets(gomock.Any(), nil, nil, defaultLogFilterQueryBlockRange).Return(nil, nil) - }, - queryOperatorAddr: testOperator1.operatorAddr, + name: "should return false if operator not found", + queryOperatorAddr: testOperator1.OperatorAddr, wantOperatorFound: false, wantOperatorInfo: types.OperatorInfo{}, }, { - name: "should return operator info found via query", - mocksInitializationFunc: func(mockAvsRegistrySubscriber *mocks.MockAVSSubscriber, mockAvsReader *mocks.MockAVSReader, mockSubscription *mocks.MockSubscription) { - errC := make(chan error) - mockSubscription.EXPECT().Err().AnyTimes().Return(errC) - mockAvsRegistrySubscriber.EXPECT().SubscribeToNewPubkeyRegistrations().Return(nil, mockSubscription, nil) - mockAvsReader.EXPECT().QueryExistingRegisteredOperatorPubKeys(gomock.Any(), nil, nil, defaultLogFilterQueryBlockRange). - Return([]common.Address{testOperator1.operatorAddr}, []types.OperatorPubkeys{testOperator1.operatorInfo.Pubkeys}, nil) - mockAvsRegistrySubscriber.EXPECT().SubscribeToOperatorSocketUpdates().Return(nil, mockSubscription, nil) - mockAvsReader.EXPECT().QueryExistingRegisteredOperatorSockets(gomock.Any(), nil, nil, defaultLogFilterQueryBlockRange). - Return(map[types.OperatorId]types.Socket{ - types.OperatorIdFromG1Pubkey(testOperator1.operatorInfo.Pubkeys.G1Pubkey): testOperator1.operatorInfo.Socket, - }, nil) - }, - queryOperatorAddr: testOperator1.operatorAddr, + name: "should return operator info found via query", + operator: &testOperator1, + queryOperatorAddr: testOperator1.OperatorAddr, wantOperatorFound: true, - wantOperatorInfo: testOperator1.operatorInfo, + wantOperatorInfo: testOperator1.OperatorInfo, }, { - name: "should return operator info found via subscription", - mocksInitializationFunc: func(mockAvsRegistrySubscriber *mocks.MockAVSSubscriber, mockAvsReader *mocks.MockAVSReader, mockSubscription *mocks.MockSubscription) { - errC := make(chan error) - pubkeyRegistrationEventC := make(chan *apkregistrybindings.ContractBLSApkRegistryNewPubkeyRegistration, 1) - pubkeyRegistrationEvent := &apkregistrybindings.ContractBLSApkRegistryNewPubkeyRegistration{ - Operator: testOperator1.operatorAddr, - PubkeyG1: testOperator1.contractG1Pubkey, - PubkeyG2: testOperator1.contractG2Pubkey, - Raw: gethtypes.Log{}, - } - pubkeyRegistrationEventC <- pubkeyRegistrationEvent - operatorSocketUpdateEventC := make(chan *regcoordbindings.ContractRegistryCoordinatorOperatorSocketUpdate, 1) - operatorSocketUpdateEvent := ®coordbindings.ContractRegistryCoordinatorOperatorSocketUpdate{ - OperatorId: types.OperatorIdFromG1Pubkey(testOperator1.operatorInfo.Pubkeys.G1Pubkey), - Socket: string(testOperator1.operatorInfo.Socket), - Raw: gethtypes.Log{}, - } - operatorSocketUpdateEventC <- operatorSocketUpdateEvent - mockSubscription.EXPECT().Err().AnyTimes().Return(errC) - mockAvsRegistrySubscriber.EXPECT().SubscribeToNewPubkeyRegistrations().Return(pubkeyRegistrationEventC, mockSubscription, nil) - mockAvsReader.EXPECT().QueryExistingRegisteredOperatorPubKeys(gomock.Any(), nil, nil, defaultLogFilterQueryBlockRange). - Return([]common.Address{}, []types.OperatorPubkeys{}, nil) - mockAvsRegistrySubscriber.EXPECT().SubscribeToOperatorSocketUpdates().Return(operatorSocketUpdateEventC, mockSubscription, nil) - mockAvsReader.EXPECT().QueryExistingRegisteredOperatorSockets(gomock.Any(), nil, nil, defaultLogFilterQueryBlockRange).Return(nil, nil) - }, - queryOperatorAddr: testOperator1.operatorAddr, - wantOperatorFound: true, - wantOperatorInfo: testOperator1.operatorInfo, + name: "should return operator info found via subscription", + queryOperatorAddr: testOperator1.OperatorAddr, + pubkeyRegistrationEventC: pubkeyRegistrationEventC, + operatorSocketUpdateEventC: operatorSocketUpdateEventC, + wantOperatorFound: true, + wantOperatorInfo: testOperator1.OperatorInfo, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create mocks - mockCtrl := gomock.NewController(t) - mockAvsRegistrySubscriber := mocks.NewMockAVSSubscriber(mockCtrl) - mockAvsReader := mocks.NewMockAVSReader(mockCtrl) - mockSubscription := mocks.NewMockSubscription(mockCtrl) + mockSubscription := newFakeEventSubscription(tt.eventErrC) + mockAvsRegistrySubscriber := newFakeAVSRegistrySubscriber(mockSubscription, tt.pubkeyRegistrationEventC, tt.operatorSocketUpdateEventC) + mockAvsReader := fakes.NewFakeAVSRegistryReader(tt.operator, nil) - if tt.mocksInitializationFunc != nil { - tt.mocksInitializationFunc(mockAvsRegistrySubscriber, mockAvsReader, mockSubscription) - } // Create a new instance of the operatorpubkeys service service := NewOperatorsInfoServiceInMemory(context.Background(), mockAvsRegistrySubscriber, mockAvsReader, nil, logger) time.Sleep(2 * time.Second) // need to give it time to process the subscription events.. not sure if there's a better way to do this.