Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added RegisterOperatorWithChurn #514

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e3e6909
feat: prefix registration parameters with type
MegaRedHand Jan 27, 2025
a741bd2
feat: make encoding function public
MegaRedHand Jan 27, 2025
4a10928
feat: add registration type prefix to registration
MegaRedHand Jan 27, 2025
a7b90f5
test: add test for abi encoding
MegaRedHand Jan 27, 2025
9ead4b5
refactor: move new type to types module
MegaRedHand Jan 27, 2025
14b1c1c
chore: lint
MegaRedHand Jan 27, 2025
bd21097
chore: re-add imports
MegaRedHand Jan 27, 2025
b15c586
feat: update middleware reference to v1.0.3
MegaRedHand Jan 28, 2025
b527bf2
chore: format contracts
MegaRedHand Jan 28, 2025
5564687
chore: update SDK contracts
MegaRedHand Jan 28, 2025
4a22a66
feat: update bindings list
MegaRedHand Jan 28, 2025
331ef2d
chore: regenerate bindings
MegaRedHand Jan 28, 2025
d893423
fix: update initialize calls
MegaRedHand Jan 28, 2025
485bbc1
chore: regenerate anvil state dump
MegaRedHand Jan 28, 2025
94581cc
fix: update types to use new Types interfaces
MegaRedHand Jan 28, 2025
1ada8d8
fix: use correct path when cleaning bindings
MegaRedHand Jan 28, 2025
8ad2301
chore: regenerate bindings
MegaRedHand Jan 28, 2025
3b7510a
chore: re-add MockAvsServiceManager
MegaRedHand Jan 28, 2025
d4e3e91
fix: update contracts
MegaRedHand Jan 28, 2025
f6b52e6
chore: regenerate bindings
MegaRedHand Jan 28, 2025
2507e8b
fix: update types to new interface
MegaRedHand Jan 28, 2025
527fb4d
feat: set permissions on deploy script
MegaRedHand Jan 28, 2025
f4a08d9
chore: regenerate state dump
MegaRedHand Jan 28, 2025
9f81a7f
fix: make serviceManager field optional
MegaRedHand Jan 29, 2025
fb06a7f
refactor: change name of new function
MegaRedHand Jan 29, 2025
821f5d1
fix: move service manager address to Config
MegaRedHand Jan 29, 2025
eeddc01
fix: use cfg address and set in test
MegaRedHand Jan 29, 2025
94b2951
feat: add new config to builder
MegaRedHand Jan 29, 2025
67671f4
feat: add log message when service manager address is missing
MegaRedHand Jan 29, 2025
c41b4dd
revert: use RegistryCoordinator instead of Slashing one
MegaRedHand Jan 29, 2025
6e12b49
test: change deployed coordinator to RegistryCoordinator
MegaRedHand Jan 29, 2025
bacb663
chore: regenerate state dump
MegaRedHand Jan 29, 2025
a6e5901
feat: add LegacyRegistryCoordinator
MegaRedHand Jan 29, 2025
7d7344f
feat: return to M2 expected state for RegistryCoordinator
MegaRedHand Jan 29, 2025
a3ee1c6
chore: regenerate state dump
MegaRedHand Jan 29, 2025
80179de
Merge branch 'dev' into registration-params-prefix
MegaRedHand Jan 29, 2025
05d0c8a
fix: add service manager to config
MegaRedHand Jan 29, 2025
f342358
fix: set the service manager as AVS address
MegaRedHand Jan 30, 2025
957067d
fix: remove unused variable
MegaRedHand Jan 30, 2025
10d4b8e
fix: add service manager address to the config
MegaRedHand Jan 30, 2025
436390e
chore: regenerate state dump
MegaRedHand Jan 30, 2025
ad36295
chore: revert license change on contract
MegaRedHand Jan 30, 2025
dc8b031
chore: remove commented code
MegaRedHand Jan 30, 2025
83391c4
Merge branch 'dev' into registration-params-prefix
MegaRedHand Jan 30, 2025
4bcbde7
Merge branch 'dev' into registration-params-prefix
MegaRedHand Feb 3, 2025
5feb7d1
Merge branch 'dev' into registration-params-prefix
MegaRedHand Feb 4, 2025
daa3c5b
added RegisterOperatorWithChurn
Sidu28 Feb 5, 2025
7691a09
removed CalculateOperatorChurnApprovalDigestHash
Sidu28 Feb 6, 2025
4994869
added tx.Send
Sidu28 Feb 6, 2025
4457624
gethcommon to common
Sidu28 Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ core_default := "DelegationManager IRewardsCoordinator StrategyManager EigenPod
core_location := "./lib/eigenlayer-middleware/lib/eigenlayer-contracts"
core_bindings_location := "../../../../bindings"

middleware_default := "RegistryCoordinator IndexRegistry OperatorStateRetriever StakeRegistry BLSApkRegistry IBLSSignatureChecker ServiceManagerBase IERC20"
middleware_default := "RegistryCoordinator SlashingRegistryCoordinator IndexRegistry OperatorStateRetriever StakeRegistry BLSApkRegistry SocketRegistry IBLSSignatureChecker ServiceManagerBase IERC20"
middleware_location := "./lib/eigenlayer-middleware"
middleware_bindings_location := "../../bindings"

Expand Down Expand Up @@ -113,7 +113,7 @@ eigenpod-bindings: ## generates contract bindings for eigenpod

.PHONY: bindings
bindings: ## generates all contract bindings
rm -rf bindings/* && make core-bindings middleware-bindings sdk-bindings eigenpod-bindings
rm -rf contracts/bindings/* && make core-bindings middleware-bindings sdk-bindings eigenpod-bindings


___CONTRACTS___: ##
Expand Down
36 changes: 18 additions & 18 deletions chainio/clients/avsregistry/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ func NewBindingsFromConfig(
var (
err error

serviceManagerAddr gethcommon.Address
stakeRegistryAddr gethcommon.Address
blsApkRegistryAddr gethcommon.Address
indexRegistryAddr gethcommon.Address
Expand All @@ -74,18 +73,6 @@ func NewBindingsFromConfig(
return nil, utils.WrapError("Failed to create BLSRegistryCoordinator contract", err)
}

serviceManagerAddr, err = contractBlsRegistryCoordinator.ServiceManager(&bind.CallOpts{})
if err != nil {
return nil, utils.WrapError("Failed to fetch ServiceManager address", err)
}
contractServiceManager, err = servicemanager.NewContractServiceManagerBase(
serviceManagerAddr,
client,
)
if err != nil {
return nil, utils.WrapError("Failed to create ServiceManager contract", err)
}

stakeRegistryAddr, err = contractBlsRegistryCoordinator.StakeRegistry(&bind.CallOpts{})
if err != nil {
return nil, utils.WrapError("Failed to fetch StakeRegistry address", err)
Expand Down Expand Up @@ -123,10 +110,6 @@ func NewBindingsFromConfig(
if err != nil {
return nil, utils.WrapError("Failed to get DelegationManager address", err)
}
avsDirectoryAddr, err = contractServiceManager.AvsDirectory(&bind.CallOpts{})
if err != nil {
return nil, utils.WrapError("Failed to get AvsDirectory address", err)
}

delegationManager, err := contractDelegationManager.NewContractDelegationManager(
delegationManagerAddr,
Expand All @@ -140,6 +123,23 @@ func NewBindingsFromConfig(
}
}

if isZeroAddress(cfg.ServiceManagerAddress) {
logger.Debug("ServiceManager address not provided, the calls to the contract will not work")
} else {
contractServiceManager, err = servicemanager.NewContractServiceManagerBase(
cfg.ServiceManagerAddress,
client,
)
if err != nil {
return nil, utils.WrapError("Failed to create ServiceManager contract", err)
}

avsDirectoryAddr, err = contractServiceManager.AvsDirectory(&bind.CallOpts{})
if err != nil {
return nil, utils.WrapError("Failed to get AvsDirectory address", err)
}
}

if isZeroAddress(cfg.OperatorStateRetrieverAddress) {
logger.Debug("OperatorStateRetriever address not provided, the calls to the contract will not work")
} else {
Expand All @@ -154,7 +154,7 @@ func NewBindingsFromConfig(
}

return &ContractBindings{
ServiceManagerAddr: serviceManagerAddr,
ServiceManagerAddr: cfg.ServiceManagerAddress,
RegistryCoordinatorAddr: cfg.RegistryCoordinatorAddress,
StakeRegistryAddr: stakeRegistryAddr,
BlsApkRegistryAddr: blsApkRegistryAddr,
Expand Down
3 changes: 3 additions & 0 deletions chainio/clients/avsregistry/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ var DefaultQueryBlockRange = big.NewInt(10_000)
type Config struct {
RegistryCoordinatorAddress common.Address
OperatorStateRetrieverAddress common.Address

/// The address of the ServiceManager contract.
ServiceManagerAddress common.Address
}

// The ChainReader provides methods to call the
Expand Down
174 changes: 162 additions & 12 deletions chainio/clients/avsregistry/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
gethcommon "github.com/ethereum/go-ethereum/common"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
Expand Down Expand Up @@ -157,7 +158,7 @@ func (w *ChainWriter) RegisterOperatorInQuorumWithAVSRegistryCoordinator(
)
G1pubkeyBN254 := chainioutils.ConvertToBN254G1Point(blsKeyPair.GetPubKeyG1())
G2pubkeyBN254 := chainioutils.ConvertToBN254G2Point(blsKeyPair.GetPubKeyG2())
pubkeyRegParams := regcoord.IBLSApkRegistryPubkeyRegistrationParams{
pubkeyRegParams := regcoord.IBLSApkRegistryTypesPubkeyRegistrationParams{
PubkeyRegistrationSignature: signedMsg,
PubkeyG1: G1pubkeyBN254,
PubkeyG2: G2pubkeyBN254,
Expand Down Expand Up @@ -259,15 +260,15 @@ func (w *ChainWriter) RegisterOperator(
)
G1pubkeyBN254 := chainioutils.ConvertToBN254G1Point(blsKeyPair.GetPubKeyG1())
G2pubkeyBN254 := chainioutils.ConvertToBN254G2Point(blsKeyPair.GetPubKeyG2())
pubkeyRegParams := regcoord.IBLSApkRegistryPubkeyRegistrationParams{
pubkeyRegParams := regcoord.IBLSApkRegistryTypesPubkeyRegistrationParams{
PubkeyRegistrationSignature: signedMsg,
PubkeyG1: G1pubkeyBN254,
PubkeyG2: G2pubkeyBN254,
}

// generate a random salt and 1 hour expiry for the signature
var operatorToAvsRegistrationSigSalt [32]byte
_, err = rand.Read(operatorToAvsRegistrationSigSalt[:])
var signatureSalt [32]byte
_, err = rand.Read(signatureSalt[:])
if err != nil {
return nil, err
}
Expand All @@ -281,17 +282,17 @@ func (w *ChainWriter) RegisterOperator(
return nil, err
}
sigValidForSeconds := int64(60 * 60) // 1 hour
operatorToAvsRegistrationSigExpiry := new(
big.Int,
).Add(new(big.Int).SetUint64(curBlock.Time()), big.NewInt(sigValidForSeconds))

curTime := new(big.Int).SetUint64(curBlock.Time())
signatureExpiry := new(big.Int).Add(curTime, big.NewInt(sigValidForSeconds))

// params to register operator in delegation manager's operator-avs mapping
msgToSign, err := w.elReader.CalculateOperatorAVSRegistrationDigestHash(
ctx,
operatorAddr,
w.serviceManagerAddr,
operatorToAvsRegistrationSigSalt,
operatorToAvsRegistrationSigExpiry,
signatureSalt,
signatureExpiry,
)
if err != nil {
return nil, err
Expand All @@ -306,8 +307,8 @@ func (w *ChainWriter) RegisterOperator(
operatorSignature[64] += 27
operatorSignatureWithSaltAndExpiry := regcoord.ISignatureUtilsSignatureWithSaltAndExpiry{
Signature: operatorSignature,
Salt: operatorToAvsRegistrationSigSalt,
Expiry: operatorToAvsRegistrationSigExpiry,
Salt: signatureSalt,
Expiry: signatureExpiry,
}

noSendTxOpts, err := w.txMgr.GetNoSendTxOpts()
Expand Down Expand Up @@ -383,11 +384,160 @@ func (w *ChainWriter) UpdateStakesOfEntireOperatorSetForQuorums(

}

func (w *ChainWriter) RegisterOperatorWithChurn(
ctx context.Context,
operatorEcdsaPrivateKey *ecdsa.PrivateKey,
churnApprovalEcdsaPrivateKey *ecdsa.PrivateKey,
blsKeyPair *bls.KeyPair,
quorumNumbers types.QuorumNums,
quorumNumbersToKick types.QuorumNums,
operatorsToKick []gethcommon.Address,
socket string,
waitForReceipt bool,
) (*gethtypes.Receipt, error) {
operatorAddr := crypto.PubkeyToAddress(operatorEcdsaPrivateKey.PublicKey)
g1HashedMsgToSign, err := w.registryCoordinator.PubkeyRegistrationMessageHash(&bind.CallOpts{}, operatorAddr)
if err != nil {
return nil, err
}
signedMsg := chainioutils.ConvertToBN254G1Point(
blsKeyPair.SignHashedToCurveMessage(chainioutils.ConvertBn254GethToGnark(g1HashedMsgToSign)).G1Point,
)
G1pubkeyBN254 := chainioutils.ConvertToBN254G1Point(blsKeyPair.GetPubKeyG1())
G2pubkeyBN254 := chainioutils.ConvertToBN254G2Point(blsKeyPair.GetPubKeyG2())
pubkeyRegParams := regcoord.IBLSApkRegistryTypesPubkeyRegistrationParams{
PubkeyRegistrationSignature: signedMsg,
PubkeyG1: G1pubkeyBN254,
PubkeyG2: G2pubkeyBN254,
}

// generate a random salt and 1 hour expiry for the signature
var signatureSalt [32]byte
_, err = rand.Read(signatureSalt[:])
if err != nil {
return nil, err
}

curBlockNum, err := w.ethClient.BlockNumber(context.Background())
if err != nil {
return nil, err
}
curBlock, err := w.ethClient.BlockByNumber(context.Background(), new(big.Int).SetUint64(curBlockNum))
if err != nil {
return nil, err
}
sigValidForSeconds := int64(60 * 60) // 1 hour

curTime := new(big.Int).SetUint64(curBlock.Time())
signatureExpiry := new(big.Int).Add(curTime, big.NewInt(sigValidForSeconds))

// params to register operator in delegation manager's operator-avs mapping
msgToSign, err := w.elReader.CalculateOperatorAVSRegistrationDigestHash(
ctx,
operatorAddr,
w.serviceManagerAddr,
signatureSalt,
signatureExpiry,
)
if err != nil {
return nil, err
}
operatorSignature, err := crypto.Sign(msgToSign[:], operatorEcdsaPrivateKey)
if err != nil {
return nil, err
}
// the crypto library is low level and deals with 0/1 v values, whereas ethereum expects 27/28, so we add 27
// see https://github.com/ethereum/go-ethereum/issues/28757#issuecomment-1874525854
// and https://twitter.com/pcaversaccio/status/1671488928262529031
operatorSignature[64] += 27
operatorSignatureWithSaltAndExpiry := regcoord.ISignatureUtilsSignatureWithSaltAndExpiry{
Signature: operatorSignature,
Salt: signatureSalt,
Expiry: signatureExpiry,
}

var operatorKickParams []regcoord.ISlashingRegistryCoordinatorTypesOperatorKickParam
for i, operatorToKick := range operatorsToKick {
operatorKickParams = append(operatorKickParams, regcoord.ISlashingRegistryCoordinatorTypesOperatorKickParam{
Operator: operatorToKick,
QuorumNumber: quorumNumbersToKick[i].UnderlyingType(),
})
}
var churnSignatureSalt [32]byte
_, err = rand.Read(churnSignatureSalt[:])
if err != nil {
return nil, err
}

operatorId, err := w.registryCoordinator.GetOperatorId(&bind.CallOpts{}, operatorAddr)
if err != nil {
return nil, err
}
churnMsgToSign, err := w.registryCoordinator.CalculateOperatorChurnApprovalDigestHash(
&bind.CallOpts{},
operatorAddr,
operatorId,
operatorKickParams,
churnSignatureSalt,
signatureExpiry,
)
if err != nil {
return nil, err
}
churnApprovalSignature, err := crypto.Sign(churnMsgToSign[:], churnApprovalEcdsaPrivateKey)
if err != nil {
return nil, err
}
// the crypto library is low level and deals with 0/1 v values, whereas ethereum expects 27/28, so we add 27
// see https://github.com/ethereum/go-ethereum/issues/28757#issuecomment-1874525854
// and https://twitter.com/pcaversaccio/status/1671488928262529031
churnApprovalSignature[64] += 27
churnApproverSignatureWithSaltAndExpiry := regcoord.ISignatureUtilsSignatureWithSaltAndExpiry{
Signature: churnApprovalSignature,
Salt: signatureSalt,
Expiry: signatureExpiry,
}

noSendTxOpts, err := w.txMgr.GetNoSendTxOpts()
if err != nil {
return nil, err
}

tx, err := w.registryCoordinator.RegisterOperatorWithChurn(
noSendTxOpts,
quorumNumbers.UnderlyingType(),
socket,
pubkeyRegParams,
operatorKickParams,
operatorSignatureWithSaltAndExpiry,
churnApproverSignatureWithSaltAndExpiry,
)
if err != nil {
return nil, err
}
receipt, err := w.txMgr.Send(ctx, tx, waitForReceipt)
if err != nil {
return nil, utils.WrapError("failed to send tx with err", err.Error())
}
w.logger.Info(
"successfully registered operator with AVS registry coordinator",
"txHash",
receipt.TxHash.String(),
"avs-service-manager",
w.serviceManagerAddr,
"operator",
operatorAddr,
"quorumNumbers",
quorumNumbers,
)
return receipt, nil
}

// Updates the stakes of a the given `operators` for all the quorums.
// On success, returns the receipt of the transaction.
func (w *ChainWriter) UpdateStakesOfOperatorSubsetForAllQuorums(
ctx context.Context,
operators []gethcommon.Address,
operators []common.Address,
waitForReceipt bool,
) (*gethtypes.Receipt, error) {
w.logger.Info("updating stakes of operator subset for all quorums", "operators", operators)
Expand Down
1 change: 1 addition & 0 deletions chainio/clients/avsregistry/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestWriterMethods(t *testing.T) {
config := avsregistry.Config{
RegistryCoordinatorAddress: contractAddrs.RegistryCoordinator,
OperatorStateRetrieverAddress: contractAddrs.OperatorStateRetriever,
ServiceManagerAddress: contractAddrs.ServiceManager,
}

chainWriter, err := testclients.NewTestAvsRegistryWriterFromConfig(anvilHttpEndpoint, operatorPrivateKeyHex, config)
Expand Down
Loading