Skip to content

Commit

Permalink
clean up the cli
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrower95 committed Aug 14, 2024
1 parent dd69d47 commit 574ac8f
Show file tree
Hide file tree
Showing 8 changed files with 541 additions and 495 deletions.
75 changes: 75 additions & 0 deletions cli/commands/assignSubmitter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package commands

import (
"context"
"fmt"

"github.com/Layr-Labs/eigenpod-proofs-generation/cli/core"
"github.com/Layr-Labs/eigenpod-proofs-generation/cli/core/onchain"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/fatih/color"
)

type TAssignSubmitterArgs struct {
Node string
TargetAddress string
Sender string
EigenpodAddress string
NoPrompt bool
Verbose bool
}

func AssignSubmitterCommand(args TAssignSubmitterArgs) error {
ctx := context.Background()

if len(args.TargetAddress) == 0 {
return fmt.Errorf("usage: `assign-submitter <0xsubmitter>`")
} else if !common.IsHexAddress(args.TargetAddress) {
return fmt.Errorf("invalid address for 0xsubmitter: %s", args.TargetAddress)
}

eth, err := ethclient.Dial(args.Node)
if err != nil {
return fmt.Errorf("failed to reach eth --node: %w", err)
}

chainId, err := eth.ChainID(ctx)
if err != nil {
return fmt.Errorf("failed to reach eth node for chain id: %w", err)
}

ownerAccount, err := core.PrepareAccount(&args.Sender, chainId, false /* noSend */)
if err != nil {
return fmt.Errorf("failed to parse --sender: %w", err)
}

pod, err := onchain.NewEigenPod(common.HexToAddress(args.EigenpodAddress), eth)
if err != nil {
return fmt.Errorf("error contacting eigenpod: %w", err)
}

// Check that the existing submitter is not the current submitter
newSubmitter := common.HexToAddress(args.TargetAddress)
currentSubmitter, err := pod.ProofSubmitter(nil)
if err != nil {
return fmt.Errorf("error fetching current proof submitter: %w", err)
} else if currentSubmitter.Cmp(newSubmitter) == 0 {
return fmt.Errorf("error: new proof submitter is existing proof submitter (%s)", currentSubmitter)
}

if !args.NoPrompt {
fmt.Printf("Your pod's current proof submitter is %s.\n", currentSubmitter)
core.PanicIfNoConsent(fmt.Sprintf("This will update your EigenPod to allow %s to submit proofs on its behalf. As the EigenPod's owner, you can always change this later.", newSubmitter))
}

txn, err := pod.SetProofSubmitter(ownerAccount.TransactionOptions, newSubmitter)
if err != nil {
return fmt.Errorf("error updating submitter role: %w", err)
}

color.Green("submitted txn: %s", txn.Hash())
color.Green("updated!")

return nil
}
110 changes: 110 additions & 0 deletions cli/commands/checkpoint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package commands

import (
"context"

"github.com/Layr-Labs/eigenpod-proofs-generation/cli/core"
"github.com/Layr-Labs/eigenpod-proofs-generation/cli/core/onchain"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/fatih/color"
"github.com/pkg/errors"
)

type TCheckpointCommandArgs struct {
EigenpodAddress string
Node string
BeaconNode string
Sender string
DisableColor bool
NoPrompt bool
SimulateTransaction bool
BatchSize uint64
ForceCheckpoint bool
Verbose bool
}

func CheckpointCommand(args TCheckpointCommandArgs) error {
ctx := context.Background()

if args.DisableColor {
color.NoColor = true
}

isVerbose := !args.SimulateTransaction || args.Verbose

if args.SimulateTransaction && len(args.Sender) > 0 {
core.Panic("if using `--print-calldata`, please do not specify a sender.")
return nil
}

eth, beaconClient, chainId, err := core.GetClients(ctx, args.Node, args.BeaconNode, isVerbose)
core.PanicOnError("failed to reach ethereum clients", err)

currentCheckpoint, err := core.GetCurrentCheckpoint(args.EigenpodAddress, eth)
core.PanicOnError("failed to load checkpoint", err)

eigenpod, err := onchain.NewEigenPod(common.HexToAddress(args.EigenpodAddress), eth)
core.PanicOnError("failed to connect to eigenpod", err)

if currentCheckpoint == 0 {
if len(args.Sender) > 0 || args.SimulateTransaction {
if !args.NoPrompt && !args.SimulateTransaction {
core.PanicIfNoConsent(core.StartCheckpointProofConsent())
}

txn, err := core.StartCheckpoint(ctx, args.EigenpodAddress, args.Sender, chainId, eth, args.ForceCheckpoint, args.SimulateTransaction)
core.PanicOnError("failed to start checkpoint", err)

if !args.SimulateTransaction {
color.Green("starting checkpoint: %s.. (waiting for txn to be mined)", txn.Hash().Hex())
bind.WaitMined(ctx, eth, txn)
color.Green("started checkpoint! txn: %s", txn.Hash().Hex())
} else {
printProofs([]Transaction{
{
Type: "checkpoint_start",
To: txn.To().Hex(),
CallData: common.Bytes2Hex(txn.Data()),
},
})

return nil
}

newCheckpoint, err := eigenpod.CurrentCheckpointTimestamp(nil)
core.PanicOnError("failed to fetch current checkpoint", err)

currentCheckpoint = newCheckpoint
} else {
core.PanicOnError("no checkpoint active and no private key provided to start one", errors.New("no checkpoint"))
}
}

if isVerbose {
color.Green("pod has active checkpoint! checkpoint timestamp: %d", currentCheckpoint)
}

proof, err := core.GenerateCheckpointProof(ctx, args.EigenpodAddress, eth, chainId, beaconClient)
core.PanicOnError("failed to generate checkpoint proof", err)

txns, err := core.SubmitCheckpointProof(ctx, args.Sender, args.EigenpodAddress, chainId, proof, eth, args.BatchSize, args.NoPrompt, args.SimulateTransaction)
if args.SimulateTransaction {
printableTxns := aMap(txns, func(txn *types.Transaction) Transaction {
return Transaction{
To: txn.To().Hex(),
CallData: common.Bytes2Hex(txn.Data()),
Type: "checkpoint_proof",
}
})
printProofs(printableTxns)
} else {
for i, txn := range txns {
color.Green("transaction(%d): %s", i, txn.Hash().Hex())
}
}
core.PanicOnError("an error occurred while submitting your checkpoint proofs", err)

return nil
}
94 changes: 94 additions & 0 deletions cli/commands/credentials.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package commands

import (
"context"
"fmt"
"math"
"math/big"

"github.com/Layr-Labs/eigenpod-proofs-generation/cli/core"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/fatih/color"
)

type TCredentialCommandArgs struct {
EigenpodAddress string

DisableColor bool
UseJSON bool
SimulateTransaction bool
Node string
BeaconNode string
Sender string
SpecificValidator uint64
BatchSize uint64
NoPrompt bool
Verbose bool
}

func CredentialsCommand(args TCredentialCommandArgs) error {
ctx := context.Background()
if args.DisableColor {
color.NoColor = true
}

isVerbose := (!args.UseJSON && !args.SimulateTransaction) || args.Verbose

eth, beaconClient, chainId, err := core.GetClients(ctx, args.Node, args.BeaconNode, isVerbose)
core.PanicOnError("failed to reach ethereum clients", err)

if args.SimulateTransaction && len(args.Sender) > 0 {
core.Panic("if using --print-calldata, please do not specify a --sender.")
return nil
}

var specificValidatorIndex *big.Int = nil
if args.SpecificValidator != math.MaxUint64 && args.SpecificValidator != 0 {
specificValidatorIndex = new(big.Int).SetUint64(args.SpecificValidator)
if isVerbose {
fmt.Printf("Using specific validator: %d", args.SpecificValidator)
}
}

validatorProofs, oracleBeaconTimestamp, err := core.GenerateValidatorProof(ctx, args.EigenpodAddress, eth, chainId, beaconClient, specificValidatorIndex, isVerbose)

if err != nil || validatorProofs == nil {
core.PanicOnError("Failed to generate validator proof", err)
core.Panic("no inactive validators")
}

if len(args.Sender) != 0 || args.SimulateTransaction {
txns, indices, err := core.SubmitValidatorProof(ctx, args.Sender, args.EigenpodAddress, chainId, eth, args.BatchSize, validatorProofs, oracleBeaconTimestamp, args.NoPrompt, args.SimulateTransaction, isVerbose)
core.PanicOnError(fmt.Sprintf("failed to %s validator proof", func() string {
if args.SimulateTransaction {
return "simulate"
} else {
return "submit"
}
}()), err)

if args.SimulateTransaction {
out := aMap(txns, func(txn *types.Transaction) CredentialProofTransaction {
return CredentialProofTransaction{
Transaction: Transaction{
Type: "credential_proof",
To: txn.To().Hex(),
CallData: common.Bytes2Hex(txn.Data()),
},
ValidatorIndices: aMap(aFlatten(indices), func(index *big.Int) uint64 {
return index.Uint64()
}),
}
})
printProofs(out)
} else {
for i, txn := range txns {
color.Green("transaction(%d): %s", i, txn.Hash().Hex())
}
}

core.PanicOnError("failed to invoke verifyWithdrawalCredentials", err)
}
return nil
}
Loading

0 comments on commit 574ac8f

Please sign in to comment.