-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
541 additions
and
495 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
Oops, something went wrong.