Skip to content

Commit

Permalink
feat: set operator split command
Browse files Browse the repository at this point in the history
  • Loading branch information
gpabst committed Dec 9, 2024
1 parent 3c0907f commit 8207781
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 7 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/Layr-Labs/eigenlayer-contracts v0.3.2-mainnet-rewards
github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241121204729-7d2cd162ffe8
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241209163655-6b1cbb153ef6
github.com/blang/semver/v4 v4.0.0
github.com/consensys/gnark-crypto v0.12.1
github.com/ethereum/go-ethereum v1.14.5
Expand All @@ -19,6 +19,7 @@ require (
github.com/tyler-smith/go-bip39 v1.1.0
github.com/urfave/cli/v2 v2.27.2
github.com/wagslane/go-password-validator v0.3.0
github.com/wealdtech/go-merkletree/v2 v2.5.2-0.20240302222400-69219c450662
github.com/wk8/go-ordered-map/v2 v2.1.8
go.uber.org/mock v0.4.0
gopkg.in/yaml.v2 v2.4.0
Expand Down Expand Up @@ -100,7 +101,6 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/wealdtech/go-merkletree/v2 v2.5.2-0.20240302222400-69219c450662 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12 h1:G5Q1SnLmFbEjhOkky3vIHk
github.com/Layr-Labs/eigenlayer-rewards-proofs v0.2.12/go.mod h1:OlJd1QjqEW53wfWG/lJyPCGvrXwWVEjPQsP4TV+gttQ=
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e h1:DvW0/kWHV9mZsbH2KOjEHKTSIONNPUj6X05FJvUohy4=
github.com/Layr-Labs/eigenpod-proofs-generation v0.0.14-stable.0.20240730152248-5c11a259293e/go.mod h1:T7tYN8bTdca2pkMnz9G2+ZwXYWw5gWqQUIu4KLgC/vM=
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20241023200243-565bb4438918 h1:Itl141PoMFzq58ZTo4Nu/CyH+x8f4BH6OmBNhZ6Z2/I=
github.com/Layr-Labs/eigensdk-go v0.1.13-0.20241023200243-565bb4438918/go.mod h1:aYdNURUhaqeYOS+Cq12TfSdPbjFfiLaHkxPdR4Exq/s=
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241121204729-7d2cd162ffe8 h1:6wuVq+Elto+yF7bQ3QYqD2psxGXR3wcJh2koNcUjIQM=
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241121204729-7d2cd162ffe8/go.mod h1:aYdNURUhaqeYOS+Cq12TfSdPbjFfiLaHkxPdR4Exq/s=
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241209163655-6b1cbb153ef6 h1:qQk3QJ+I+ffHOpZvaEC1NULxl3Hfzi+ojpniBAmUdWg=
github.com/Layr-Labs/eigensdk-go v0.1.14-0.20241209163655-6b1cbb153ef6/go.mod h1:aYdNURUhaqeYOS+Cq12TfSdPbjFfiLaHkxPdR4Exq/s=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
Expand Down
1 change: 1 addition & 0 deletions pkg/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func RewardsCmd(p utils.Prompter) *cli.Command {
rewards.ClaimCmd(p),
rewards.SetClaimerCmd(p),
rewards.ShowCmd(p),
rewards.OperatorSplitCmd(p),
},
}

Expand Down
18 changes: 17 additions & 1 deletion pkg/rewards/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ var (

AVSAddressesFlag = cli.StringFlag{
Name: "avs-addresses",
Aliases: []string{"a"},
Aliases: []string{"aa"},
Usage: "Comma seperated addresses of the AVS",
EnvVars: []string{"AVS_ADDRESSES"},
}
Expand All @@ -91,4 +91,20 @@ var (
Value: "all",
EnvVars: []string{"REWARDS_CLAIM_TYPE"},
}

OperatorAddressFlag = cli.StringFlag{
Name: "operator-address",
Aliases: []string{"a"},
Usage: "Address of the operator",
Required: false,
EnvVars: []string{"REWARDS_OPERATOR_ADDRESS"},
}

OperatorSplitFlag = cli.IntFlag{
Name: "operator-split",
Aliases: []string{"os"},
Usage: "Split for the operator",
Required: false,
EnvVars: []string{"REWARDS_OPERATOR_SPLIT"},
}
)
170 changes: 170 additions & 0 deletions pkg/rewards/operator_split.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package rewards

import (
"errors"
"sort"

"github.com/Layr-Labs/eigenlayer-cli/pkg/internal/common"
"github.com/Layr-Labs/eigenlayer-cli/pkg/internal/common/flags"
"github.com/Layr-Labs/eigenlayer-cli/pkg/telemetry"
"github.com/Layr-Labs/eigenlayer-cli/pkg/utils"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts"
"github.com/Layr-Labs/eigensdk-go/logging"
eigenSdkUtils "github.com/Layr-Labs/eigensdk-go/utils"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/urfave/cli/v2"
)

func OperatorSplitCmd(p utils.Prompter) *cli.Command {
var operatorSplitCmd = &cli.Command{
Name: "set-operator-split",
Usage: "Set operator split",
Action: func(cCtx *cli.Context) error {
return OperatorSplit(cCtx, p)
},
After: telemetry.AfterRunAction(),
Flags: getOperatorSplitFlags(),
}

return operatorSplitCmd
}

func OperatorSplit(cCtx *cli.Context, p utils.Prompter) error {
ctx := cCtx.Context
logger := common.GetLogger(cCtx)

config, err := readAndValidateOperatorSplitConfig(cCtx, logger)
if err != nil {
return eigenSdkUtils.WrapError("failed to read and validate claim config", err)
}

cCtx.App.Metadata["network"] = config.ChainID.String()

ethClient, err := ethclient.Dial(config.RPCUrl)
if err != nil {
return eigenSdkUtils.WrapError("failed to create new eth client", err)
}

eLWriter, err := common.GetELWriter(
config.OperatorAddress,
config.SignerConfig,
ethClient,
elcontracts.Config{
RewardsCoordinatorAddress: config.RewardsCoordinatorAddress,
},
p,
config.ChainID,
logger,
)

if err != nil {
return eigenSdkUtils.WrapError("failed to get EL writer", err)
}

logger.Infof("Broadcasting set operator transaction...")

var receipt *types.Receipt

receipt, err = eLWriter.SetOperatorAVSSplit(ctx, config.OperatorAddress, config.AVSAddress, config.Split, true)

if err != nil {
return eigenSdkUtils.WrapError("failed to process claim", err)
}

logger.Infof("Set operator transaction submitted successfully")
common.PrintTransactionInfo(receipt.TxHash.String(), config.ChainID)

return nil
}

func readAndValidateOperatorSplitConfig(cCtx *cli.Context, logger logging.Logger) (*SetOperatorAVSSplitConfig, error) {
network := cCtx.String(flags.NetworkFlag.Name)
environment := cCtx.String(EnvironmentFlag.Name)
rpcUrl := cCtx.String(flags.ETHRpcUrlFlag.Name)
broadcast := cCtx.Bool(flags.BroadcastFlag.Name)
split := cCtx.Int(OperatorSplitFlag.Name)
rewardsCoordinatorAddress := cCtx.String(RewardsCoordinatorAddressFlag.Name)

var err error
if common.IsEmptyString(rewardsCoordinatorAddress) {
rewardsCoordinatorAddress, err = common.GetRewardCoordinatorAddress(utils.NetworkNameToChainId(network))
if err != nil {
return nil, err
}
}
logger.Debugf("Using Rewards Coordinator address: %s", rewardsCoordinatorAddress)

claimTimestamp := cCtx.String(ClaimTimestampFlag.Name)
logger.Debugf("Using claim timestamp from user: %s", claimTimestamp)

operatorAddress := gethcommon.HexToAddress(cCtx.String(OperatorAddressFlag.Name))
logger.Infof("Using operator address: %s", operatorAddress.String())

avsAddress := gethcommon.HexToAddress(cCtx.String(AVSAddressesFlag.Name))
logger.Infof("Using AVS address: %s", avsAddress.String())

chainID := utils.NetworkNameToChainId(network)
logger.Debugf("Using chain ID: %s", chainID.String())

proofStoreBaseURL := cCtx.String(ProofStoreBaseURLFlag.Name)

// If empty get from utils
if common.IsEmptyString(proofStoreBaseURL) {
proofStoreBaseURL = getProofStoreBaseURL(network)

// If still empty return error
if common.IsEmptyString(proofStoreBaseURL) {
return nil, errors.New("proof store base URL not provided")
}
}
logger.Debugf("Using Proof store base URL: %s", proofStoreBaseURL)

if common.IsEmptyString(environment) {
environment = getEnvFromNetwork(network)
}
logger.Debugf("Using network %s and environment: %s", network, environment)

// Get SignerConfig
signerConfig, err := common.GetSignerConfig(cCtx, logger)
if err != nil {
// We don't want to throw error since people can still use it to generate the claim
// without broadcasting it
logger.Debugf("Failed to get signer config: %s", err)
}

// TODO(shrimalmadhur): Fix to make sure correct S3 bucket is used. Clean up later
if network == utils.MainnetNetworkName {
network = "ethereum"
}

return &SetOperatorAVSSplitConfig{
Network: network,
RPCUrl: rpcUrl,
Broadcast: broadcast,
RewardsCoordinatorAddress: gethcommon.HexToAddress(rewardsCoordinatorAddress),
ChainID: chainID,
SignerConfig: signerConfig,
OperatorAddress: operatorAddress,
AVSAddress: avsAddress,
Split: uint16(split),
}, nil
}

func getOperatorSplitFlags() []cli.Flag {
baseFlags := []cli.Flag{
&flags.NetworkFlag,
&flags.ETHRpcUrlFlag,
&flags.OutputFileFlag,
&OperatorAddressFlag,
&OperatorSplitFlag,
&RewardsCoordinatorAddressFlag,
&ClaimTimestampFlag,
&AVSAddressesFlag,
}

allFlags := append(baseFlags, flags.GetSignerFlags()...)
sort.Sort(cli.FlagsByName(allFlags))
return allFlags
}
12 changes: 12 additions & 0 deletions pkg/rewards/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ type rewardsJson struct {

type allRewardsJson []rewardsJson

type SetOperatorAVSSplitConfig struct {
Network string
RPCUrl string
Broadcast bool
RewardsCoordinatorAddress gethcommon.Address
ChainID *big.Int
SignerConfig *types.SignerConfig

OperatorAddress gethcommon.Address
AVSAddress gethcommon.Address
Split uint16
}
type ClaimConfig struct {
Network string
RPCUrl string
Expand Down

0 comments on commit 8207781

Please sign in to comment.