From dd1bfeeb27475fb7d70db36220d764d142fabc2a Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Thu, 19 Sep 2024 10:18:17 -0700 Subject: [PATCH] add more code --- pkg/internal/common/eth.go | 30 +++++ pkg/operator/allocations/initializedelay.go | 2 +- pkg/operator/allocations/show.go | 122 ++++++++++++-------- pkg/operator/allocations/types.go | 100 +++++++++++----- pkg/operator/allocations/update.go | 4 +- 5 files changed, 184 insertions(+), 74 deletions(-) diff --git a/pkg/internal/common/eth.go b/pkg/internal/common/eth.go index a838944..912b5fc 100644 --- a/pkg/internal/common/eth.go +++ b/pkg/internal/common/eth.go @@ -3,6 +3,7 @@ package common import ( "fmt" "math/big" + "strconv" "strings" "github.com/ethereum/go-ethereum/common" @@ -60,3 +61,32 @@ func ConvertStringSliceToGethAddressSlice(addresses []string) []common.Address { func ShortEthAddress(address common.Address) string { return fmt.Sprintf("%s...%s", address.Hex()[:6], address.Hex()[len(address.Hex())-4:]) } + +func FormatNumberWithUnderscores(n uint64) string { + // Convert the number to a string + numStr := strconv.FormatUint(n, 10) + + // If the number is less than 1000, no formatting is needed + if len(numStr) <= 3 { + return numStr + } + + // Calculate the number of groups of 3 digits + groups := (len(numStr) - 1) / 3 + + // Create a slice to hold the result + result := make([]byte, len(numStr)+groups) + + // Fill the result slice from right to left + resultIndex := len(result) - 1 + for i := len(numStr) - 1; i >= 0; i-- { + if (len(numStr)-i-1)%3 == 0 && i != len(numStr)-1 { + result[resultIndex] = '_' + resultIndex-- + } + result[resultIndex] = numStr[i] + resultIndex-- + } + + return string(result) +} diff --git a/pkg/operator/allocations/initializedelay.go b/pkg/operator/allocations/initializedelay.go index 7f7f34a..f12a687 100644 --- a/pkg/operator/allocations/initializedelay.go +++ b/pkg/operator/allocations/initializedelay.go @@ -51,7 +51,7 @@ func initializeDelayAction(cCtx *cli.Context, p utils.Prompter) error { } // Temp to test modify Allocations - config.delegationManagerAddress = gethcommon.HexToAddress("0xec91e43612896E7D45736cE751bea6dbf1BBEdB5") + config.delegationManagerAddress = gethcommon.HexToAddress("0x1a597729A7dCfeDDD1f6130fBb099892B7623FAd") if config.broadcast { confirm, err := p.Confirm( diff --git a/pkg/operator/allocations/show.go b/pkg/operator/allocations/show.go index 741ba0b..971b66f 100644 --- a/pkg/operator/allocations/show.go +++ b/pkg/operator/allocations/show.go @@ -10,6 +10,7 @@ import ( "github.com/Layr-Labs/eigenlayer-cli/pkg/utils" "github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts" + contractIAllocationManager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IAllocationManager" "github.com/Layr-Labs/eigensdk-go/logging" eigenSdkUtils "github.com/Layr-Labs/eigensdk-go/utils" @@ -52,7 +53,7 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error { } // Temp to test modify allocations - config.delegationManagerAddress = gethcommon.HexToAddress("0xec91e43612896E7D45736cE751bea6dbf1BBEdB5") + config.delegationManagerAddress = gethcommon.HexToAddress("0x1a597729A7dCfeDDD1f6130fBb099892B7623FAd") elReader, err := elcontracts.NewReaderFromConfig( elcontracts.Config{ @@ -75,7 +76,7 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error { if err != nil { return eigenSdkUtils.WrapError("failed to get allocatable magnitude", err) } - logger.Debugf("Allocatable magnitude for strategy %v: %d", strategyAddress, allocatableMagnitude) + logger.Debugf("Allocatable magnitude for strategy %v: %s", strategyAddress, common.FormatNumberWithUnderscores(allocatableMagnitude)) } opSets, slashableMagnitudes, err := elReader.GetCurrentSlashableMagnitudes( @@ -87,21 +88,9 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error { return eigenSdkUtils.WrapError("failed to get slashable magnitude", err) } - slashableMagnitudeHolders := make(SlashableMagnitudeHolders, 0) - for i, strategyAddress := range config.strategyAddresses { - slashableMagnitude := slashableMagnitudes[i] - for j, opSet := range opSets { - slashableMagnitudeHolders = append(slashableMagnitudeHolders, SlashableMagnitudesHolder{ - StrategyAddress: strategyAddress, - AVSAddress: opSet.Avs, - OperatorSetId: opSet.OperatorSetId, - SlashableMagnitude: slashableMagnitude[j], - }) - } - } - // Get Pending allocations - pendingAllocationsDetails := make(AllocationDetailsHolder, 0) + //pendingAllocationsDetails := make(AllocationDetailsHolder, 0) + pendingAllocationMap := make(map[string]AllocDetails) for _, strategyAddress := range config.strategyAddresses { pendingAllocations, timestamps, err := elReader.GetPendingAllocations( &bind.CallOpts{Context: ctx}, @@ -118,17 +107,22 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error { if pendingAllocation == 0 && timestamp == 0 { continue } - pendingAllocationsDetails = append(pendingAllocationsDetails, AllocationDetails{ - StrategyAddress: strategyAddress, - AVSAddress: opSet.Avs, - OperatorSetId: opSet.OperatorSetId, - Allocation: pendingAllocation, - Timestamp: timestamp, - }) + //pendingAllocationsDetails = append(pendingAllocationsDetails, AllocationDetails{ + // StrategyAddress: strategyAddress, + // AVSAddress: opSet.Avs, + // OperatorSetId: opSet.OperatorSetId, + // Allocation: pendingAllocation, + // Timestamp: timestamp, + //}) + pendingAllocationMap[getUniqueKey(strategyAddress, opSet)] = AllocDetails{ + Magnitude: pendingAllocation, + Timestamp: timestamp, + } } } - pendingDeallocationsDetails := make(AllocationDetailsHolder, 0) + //pendingDeallocationsDetails := make(AllocationDetailsHolder, 0) + pendingdeAllocationMap := make(map[string]AllocDetails) for _, strategyAddress := range config.strategyAddresses { pendingDeallocations, err := elReader.GetPendingDeallocations( &bind.CallOpts{Context: ctx}, @@ -144,33 +138,67 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error { if pendingAllocation.MagnitudeDiff == 0 && pendingAllocation.CompletableTimestamp == 0 { continue } - pendingDeallocationsDetails = append(pendingDeallocationsDetails, AllocationDetails{ - StrategyAddress: strategyAddress, - AVSAddress: opSet.Avs, - OperatorSetId: opSet.OperatorSetId, - Allocation: pendingAllocation.MagnitudeDiff, - Timestamp: pendingAllocation.CompletableTimestamp, - }) + //pendingDeallocationsDetails = append(pendingDeallocationsDetails, AllocationDetails{ + // StrategyAddress: strategyAddress, + // AVSAddress: opSet.Avs, + // OperatorSetId: opSet.OperatorSetId, + // Allocation: pendingAllocation.MagnitudeDiff, + // Timestamp: pendingAllocation.CompletableTimestamp, + //}) + pendingdeAllocationMap[getUniqueKey(strategyAddress, opSet)] = AllocDetails{ + Magnitude: pendingAllocation.MagnitudeDiff, + Timestamp: pendingAllocation.CompletableTimestamp, + } } } - fmt.Println() - fmt.Println("------------------Pending Allocations---------------------") - if config.outputType == string(common.OutputType_Json) { - pendingAllocationsDetails.PrintJSON() - } else { - pendingAllocationsDetails.PrintPretty() - } - fmt.Println() + slashableMagnitudeHolders := make(SlashableMagnitudeHolders, 0) + for i, strategyAddress := range config.strategyAddresses { + slashableMagnitude := slashableMagnitudes[i] + for j, opSet := range opSets { + newAllocation := uint64(0) + newTimestamp := uint32(0) + currSlashableMag := slashableMagnitude[j] + someKey := getUniqueKey(strategyAddress, opSet) + if _, ok := pendingAllocationMap[someKey]; ok { + newAllocation = pendingAllocationMap[someKey].Magnitude + newTimestamp = pendingAllocationMap[someKey].Timestamp + } - fmt.Println() - fmt.Println("------------------Pending Deallocations---------------------") - if config.outputType == string(common.OutputType_Json) { - pendingDeallocationsDetails.PrintJSON() - } else { - pendingDeallocationsDetails.PrintPretty() + if _, ok := pendingdeAllocationMap[someKey]; ok { + newAllocationDiff := pendingdeAllocationMap[someKey].Magnitude + newTimestamp = pendingdeAllocationMap[someKey].Timestamp + newAllocation = currSlashableMag + currSlashableMag = currSlashableMag + newAllocationDiff + } + slashableMagnitudeHolders = append(slashableMagnitudeHolders, SlashableMagnitudesHolder{ + StrategyAddress: strategyAddress, + AVSAddress: opSet.Avs, + OperatorSetId: opSet.OperatorSetId, + SlashableMagnitude: currSlashableMag, + NewMagnitude: newAllocation, + NewMagnitudeTimestamp: newTimestamp, + }) + } } + fmt.Println() + //fmt.Println("------------------Pending Allocations---------------------") + //if config.outputType == string(common.OutputType_Json) { + // pendingAllocationsDetails.PrintJSON() + //} else { + // pendingAllocationsDetails.PrintPretty() + //} + //fmt.Println() + // + //fmt.Println() + //fmt.Println("------------------Pending Deallocations---------------------") + //if config.outputType == string(common.OutputType_Json) { + // pendingDeallocationsDetails.PrintJSON() + //} else { + // pendingDeallocationsDetails.PrintPretty() + //} + //fmt.Println() fmt.Println("------------------Current Slashable Magnitudes---------------------") if config.outputType == string(common.OutputType_Json) { @@ -182,6 +210,10 @@ func showAction(cCtx *cli.Context, p utils.Prompter) error { return nil } +func getUniqueKey(strategyAddress gethcommon.Address, opSet contractIAllocationManager.OperatorSet) string { + return fmt.Sprintf("%s-%s-%d", strategyAddress.String(), opSet.Avs.String(), opSet.OperatorSetId) +} + func readAndValidateShowConfig(cCtx *cli.Context, logger *logging.Logger) (*showConfig, error) { network := cCtx.String(flags.NetworkFlag.Name) rpcUrl := cCtx.String(flags.ETHRpcUrlFlag.Name) diff --git a/pkg/operator/allocations/types.go b/pkg/operator/allocations/types.go index aa05151..a00d18e 100644 --- a/pkg/operator/allocations/types.go +++ b/pkg/operator/allocations/types.go @@ -20,24 +20,54 @@ type BulkModifyAllocations struct { AllocatableMagnitudes map[gethcommon.Address]uint64 } -func (b *BulkModifyAllocations) Print() { - for _, a := range b.Allocations { - fmt.Printf( - "Strategy: %s, Expected Total Magnitude: %d, Allocatable Magnitude %d\n", - a.Strategy.Hex(), - a.ExpectedTotalMagnitude, - b.AllocatableMagnitudes[a.Strategy], - ) +func (b *BulkModifyAllocations) PrintPretty() { + + fmt.Println() + fmt.Println("Allocations to be Updated") + allocations := b.Allocations + headers := []string{"Strategy", "Expected Total Magnitude", "Allocatable Magnitude", "Operator Set ID", "AVS", "Magnitude"} + widths := []int{20, 25, 25, 20, 20, 25} + + // print dashes + for _, width := range widths { + fmt.Print("+" + strings.Repeat("-", width+1)) + } + + fmt.Println("+") + + // Print header + for i, header := range headers { + fmt.Printf("| %-*s", widths[i], header) + } + + fmt.Println("|") + + // Print separator + for _, width := range widths { + fmt.Print("|", strings.Repeat("-", width+1)) + } + + fmt.Println("|") + + // Print data rows + for _, a := range allocations { for i, opSet := range a.OperatorSets { - fmt.Printf( - "Operator Set: %d, AVS: %s, Magnitude: %d\n", - opSet.OperatorSetId, - opSet.Avs.Hex(), - a.Magnitudes[i], - ) + fmt.Printf("| %-*s| %-*s| %-*s| %-*d| %-*s| %-*s|\n", + widths[0], common.ShortEthAddress(a.Strategy), + widths[1], common.FormatNumberWithUnderscores(a.ExpectedTotalMagnitude), + widths[2], common.FormatNumberWithUnderscores(b.AllocatableMagnitudes[a.Strategy]), + widths[3], opSet.OperatorSetId, + widths[4], common.ShortEthAddress(opSet.Avs), + widths[5], common.FormatNumberWithUnderscores(a.Magnitudes[i])) } - fmt.Println() } + + // print dashes + for _, width := range widths { + fmt.Print("+" + strings.Repeat("-", width+1)) + } + + fmt.Println("+") } type updateConfig struct { @@ -95,16 +125,18 @@ type showConfig struct { type SlashableMagnitudeHolders []SlashableMagnitudesHolder type SlashableMagnitudesHolder struct { - StrategyAddress gethcommon.Address - AVSAddress gethcommon.Address - OperatorSetId uint32 - SlashableMagnitude uint64 + StrategyAddress gethcommon.Address + AVSAddress gethcommon.Address + OperatorSetId uint32 + SlashableMagnitude uint64 + NewMagnitude uint64 + NewMagnitudeTimestamp uint32 } func (s SlashableMagnitudeHolders) PrintPretty() { // Define column headers and widths - headers := []string{"Strategy Address", "AVS Address", "Operator Set ID", "Slashable Magnitude"} - widths := []int{20, 20, 16, 20} + headers := []string{"Strategy Address", "AVS Address", "Operator Set ID", "Slashable Magnitude", "New Magnitude", "New Magnitude Timestamp"} + widths := []int{20, 20, 16, 25, 25, 25} // print dashes for _, width := range widths { @@ -126,11 +158,22 @@ func (s SlashableMagnitudeHolders) PrintPretty() { // Print data rows for _, holder := range s { - fmt.Printf("| %-*s| %-*s| %-*d| %-*d|\n", + // Example timestamp (Unix timestamp in seconds) + timestamp := int64(holder.NewMagnitudeTimestamp) + + // Convert timestamp to time.Time + t := time.Unix(timestamp, 0) + + // Format the time as a string + formattedTime := t.Format("2006-01-02 15:04:05") + fmt.Printf("| %-*s| %-*s| %-*d| %-*s| %-*s| %-*s|\n", widths[0], common.ShortEthAddress(holder.StrategyAddress), widths[1], common.ShortEthAddress(holder.AVSAddress), widths[2], holder.OperatorSetId, - widths[3], holder.SlashableMagnitude) + widths[3], common.FormatNumberWithUnderscores(holder.SlashableMagnitude), + widths[4], common.FormatNumberWithUnderscores(holder.NewMagnitude), + widths[5], formattedTime, + ) } // print dashes @@ -162,7 +205,7 @@ type AllocationDetails struct { func (a AllocationDetailsHolder) PrintPretty() { // Define column headers and widths headers := []string{"Strategy Address", "AVS Address", "Operator Set ID", "Allocation", "Application Timestamp"} - widths := []int{20, 20, 16, 20, 25} + widths := []int{20, 20, 16, 25, 25} // print dashes for _, width := range widths { @@ -192,11 +235,11 @@ func (a AllocationDetailsHolder) PrintPretty() { // Format the time as a string formattedTime := t.Format("2006-01-02 15:04:05") - fmt.Printf("| %-*s| %-*s| %-*d| %-*d| %-*s|\n", + fmt.Printf("| %-*s| %-*s| %-*d| %-*s| %-*s|\n", widths[0], common.ShortEthAddress(holder.StrategyAddress), widths[1], common.ShortEthAddress(holder.AVSAddress), widths[2], holder.OperatorSetId, - widths[3], holder.Allocation, + widths[3], common.FormatNumberWithUnderscores(holder.Allocation), widths[4], formattedTime) } @@ -215,3 +258,8 @@ func (a AllocationDetailsHolder) PrintJSON() { } fmt.Println(string(obj)) } + +type AllocDetails struct { + Magnitude uint64 + Timestamp uint32 +} diff --git a/pkg/operator/allocations/update.go b/pkg/operator/allocations/update.go index c8465b4..0719e06 100644 --- a/pkg/operator/allocations/update.go +++ b/pkg/operator/allocations/update.go @@ -74,7 +74,7 @@ func updateAllocations(cCtx *cli.Context, p utils.Prompter) error { } // Temp to test modify Allocations - config.delegationManagerAddress = gethcommon.HexToAddress("0xec91e43612896E7D45736cE751bea6dbf1BBEdB5") + config.delegationManagerAddress = gethcommon.HexToAddress("0x1a597729A7dCfeDDD1f6130fBb099892B7623FAd") elReader, err := elcontracts.NewReaderFromConfig( elcontracts.Config{ @@ -170,7 +170,7 @@ func updateAllocations(cCtx *cli.Context, p utils.Prompter) error { fmt.Println("output file not supported for pretty output type") fmt.Println() } - allocationsToUpdate.Print() + allocationsToUpdate.PrintPretty() } txFeeDetails := common.GetTxFeeDetails(unsignedTx) fmt.Println()