Documentation
¶
Index ¶
- Variables
- func CheatAction(readOnly bool, fn func(ctx *cli.Context, ch *cheat.Cheater) error) cli.ActionFunc
- func CheatRawDBAction(readOnly bool, fn func(ctx *cli.Context, db ethdb.Database) error) cli.ActionFunc
- func EngineAction(...) cli.ActionFunc
- func ParseBuildingArgs(ctx *cli.Context) *engine.BlockBuildingSettings
- type Text
- type TextFlag
Constants ¶
This section is empty.
Variables ¶
View Source
var ( GlobalGethLogLvlFlag = &cli.GenericFlag{ Name: "geth-log-level", Usage: "Set the global geth logging level", EnvVars: prefixEnvVars("GETH_LOG_LEVEL"), Value: oplog.NewLevelFlagValue(log.LevelError), } DataDirFlag = &cli.StringFlag{ Name: "data-dir", Usage: "Geth data dir location.", Required: true, TakesFile: true, EnvVars: prefixEnvVars("DATA_DIR"), } EngineEndpoint = &cli.StringFlag{ Name: "engine", Usage: "Authenticated Engine API RPC endpoint, can be HTTP/WS/IPC", Required: true, Value: "http://localhost:8551/", EnvVars: prefixEnvVars("ENGINE"), } EngineJWTPath = &cli.StringFlag{ Name: "engine.jwt-secret", Usage: "Path to JWT secret file used to authenticate Engine API communication with.", Required: true, TakesFile: true, EnvVars: prefixEnvVars("ENGINE_JWT_SECRET"), } EngineOpenEndpoint = &cli.StringFlag{ Name: "engine.open", Usage: "Open Engine API RPC endpoint, can be HTTP/WS/IPC", Value: "http://localhost:8545/", EnvVars: prefixEnvVars("ENGINE_OPEN"), } EngineVersion = &cli.IntFlag{ Name: "engine.version", Usage: "Engine API version to use for Engine calls (1, 2, or 3)", EnvVars: prefixEnvVars("ENGINE_VERSION"), Action: func(ctx *cli.Context, ev int) error { if ev < 1 || ev > 3 { return fmt.Errorf("invalid Engine API version: %d", ev) } return nil }, } FeeRecipientFlag = &cli.GenericFlag{ Name: "fee-recipient", Usage: "fee-recipient of the block building", EnvVars: prefixEnvVars("FEE_RECIPIENT"), Value: &TextFlag[*common.Address]{Value: &common.Address{1: 0x13, 2: 0x37}}, } RandaoFlag = &cli.GenericFlag{ Name: "randao", Usage: "randao value of the block building", EnvVars: prefixEnvVars("RANDAO"), Value: &TextFlag[*common.Hash]{Value: &common.Hash{1: 0x13, 2: 0x37}}, } BlockTimeFlag = &cli.Uint64Flag{ Name: "block-time", Usage: "block time, interval of timestamps between blocks to build, in seconds", EnvVars: prefixEnvVars("BLOCK_TIME"), Value: 12, } BuildingTime = &cli.DurationFlag{ Name: "building-time", Usage: "duration of of block building, this should be set to something lower than the block time.", EnvVars: prefixEnvVars("BUILDING_TIME"), Value: time.Second * 6, } AllowGaps = &cli.BoolFlag{ Name: "allow-gaps", Usage: "allow gaps in block building, like missed slots on the beacon chain.", EnvVars: prefixEnvVars("ALLOW_GAPS"), } )
View Source
var ( CheatStorageGetCmd = &cli.Command{ Name: "get", Aliases: []string{"read"}, Flags: []cli.Flag{ DataDirFlag, addrFlag("address", "Address to read storage of"), hashFlag("key", "key in storage of address to read value"), }, Action: CheatAction(true, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.StorageGet(addrFlagValue("address", ctx), hashFlagValue("key", ctx), ctx.App.Writer)) }), } CheatStorageSetCmd = &cli.Command{ Name: "set", Aliases: []string{"write"}, Flags: []cli.Flag{ DataDirFlag, addrFlag("address", "Address to write storage of"), hashFlag("key", "key in storage of address to set value of"), hashFlag("value", "the value to write"), }, Action: CheatAction(false, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.StorageSet(addrFlagValue("address", ctx), hashFlagValue("key", ctx), hashFlagValue("value", ctx))) }), } CheatStorageReadAll = &cli.Command{ Name: "read-all", Aliases: []string{"get-all"}, Usage: "Read all storage of the given account", Flags: []cli.Flag{DataDirFlag, addrFlag("address", "Address to read all storage of")}, Action: CheatAction(true, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.StorageReadAll(addrFlagValue("address", ctx), ctx.App.Writer)) }), } CheatStorageDiffCmd = &cli.Command{ Name: "diff", Usage: "Diff the storage of accounts A and B", Flags: []cli.Flag{DataDirFlag, hashFlag("a", "address of account A"), hashFlag("b", "address of account B")}, Action: CheatAction(true, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.StorageDiff(ctx.App.Writer, addrFlagValue("a", ctx), addrFlagValue("b", ctx))) }), } CheatStoragePatchCmd = &cli.Command{ Name: "patch", Usage: "Apply storage patch from STDIN to the given account address", Flags: []cli.Flag{DataDirFlag, addrFlag("address", "Address to patch storage of")}, Action: CheatAction(false, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.StoragePatch(os.Stdin, addrFlagValue("address", ctx))) }), } CheatStorageCmd = &cli.Command{ Name: "storage", Subcommands: []*cli.Command{ CheatStorageGetCmd, CheatStorageSetCmd, CheatStorageReadAll, CheatStorageDiffCmd, CheatStoragePatchCmd, }, } CheatSetBalanceCmd = &cli.Command{ Name: "balance", Flags: []cli.Flag{ DataDirFlag, addrFlag("address", "Address to change balance of"), bigFlag("balance", "New balance of the account"), }, Action: CheatAction(false, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.SetBalance(addrFlagValue("address", ctx), bigFlagValue("balance", ctx))) }), } CheatSetCodeCmd = &cli.Command{ Name: "code", Flags: []cli.Flag{ DataDirFlag, addrFlag("address", "Address to change code of"), bytesFlag("code", "New code of the account"), }, Action: CheatAction(false, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.SetCode(addrFlagValue("address", ctx), bytesFlagValue("code", ctx))) }), } CheatSetNonceCmd = &cli.Command{ Name: "nonce", Flags: []cli.Flag{ DataDirFlag, addrFlag("address", "Address to change nonce of"), bigFlag("nonce", "New nonce of the account"), }, Action: CheatAction(false, func(ctx *cli.Context, ch *cheat.Cheater) error { return ch.RunAndClose(cheat.SetNonce(addrFlagValue("address", ctx), bigFlagValue("balance", ctx).Uint64())) }), } CheatPrintHeadBlock = &cli.Command{ Name: "head-block", Usage: "dump head block as JSON", Flags: []cli.Flag{ DataDirFlag, }, Action: CheatRawDBAction(true, func(c *cli.Context, db ethdb.Database) error { enc := json.NewEncoder(c.App.Writer) enc.SetIndent(" ", " ") block := rawdb.ReadHeadBlock(db) if block == nil { return enc.Encode(nil) } return enc.Encode(engine.RPCBlock{ Header: *block.Header(), Transactions: block.Transactions(), }) }), } CheatPrintHeadHeader = &cli.Command{ Name: "head-header", Usage: "dump head header as JSON", Flags: []cli.Flag{ DataDirFlag, }, Action: CheatRawDBAction(true, func(c *cli.Context, db ethdb.Database) error { enc := json.NewEncoder(c.App.Writer) enc.SetIndent(" ", " ") return enc.Encode(rawdb.ReadHeadHeader(db)) }), } EngineBlockCmd = &cli.Command{ Name: "block", Usage: "build the next block using the Engine API", Flags: withEngineFlags( FeeRecipientFlag, RandaoFlag, BlockTimeFlag, BuildingTime, AllowGaps, ), Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { settings := ParseBuildingArgs(ctx) status, err := engine.Status(context.Background(), client.RPC) if err != nil { return err } payloadEnv, err := engine.BuildBlock(context.Background(), client, status, settings) if err != nil { return err } fmt.Fprintln(ctx.App.Writer, payloadEnv.ExecutionPayload.BlockHash) return nil }), } EngineAutoCmd = &cli.Command{ Name: "auto", Usage: "Run a proof-of-nothing chain with fixed block time.", Description: "The block time can be changed. The execution engine must be synced to a post-Merge state first.", Flags: append(withEngineFlags( FeeRecipientFlag, RandaoFlag, BlockTimeFlag, BuildingTime, AllowGaps), opmetrics.CLIFlags(envVarPrefix)...), Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, l log.Logger) error { settings := ParseBuildingArgs(ctx) metricsCfg := opmetrics.ReadCLIConfig(ctx) return opservice.CloseAction(func(ctx context.Context, shutdown <-chan struct{}) error { registry := opmetrics.NewRegistry() metrics := engine.NewMetrics("wheel", registry) if metricsCfg.Enabled { l.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort) metricsSrv, err := opmetrics.StartServer(registry, metricsCfg.ListenAddr, metricsCfg.ListenPort) if err != nil { return fmt.Errorf("failed to start metrics server: %w", err) } defer func() { if err := metricsSrv.Stop(context.Background()); err != nil { l.Error("failed to stop metrics server: %w", err) } }() } return engine.Auto(ctx, metrics, client, l, shutdown, settings) }) }), } EngineStatusCmd = &cli.Command{ Name: "status", Flags: withEngineFlags(), Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { stat, err := engine.Status(context.Background(), client.RPC) if err != nil { return err } enc := json.NewEncoder(ctx.App.Writer) enc.SetIndent("", " ") return enc.Encode(stat) }), } EngineCopyCmd = &cli.Command{ Name: "copy", Flags: withEngineFlags( &cli.StringFlag{ Name: "source", Usage: "Unauthenticated regular eth JSON RPC to pull block data from, can be HTTP/WS/IPC.", Required: true, EnvVars: prefixEnvVars("SOURCE"), }, ), Action: EngineAction(func(ctx *cli.Context, dest *sources.EngineAPIClient, _ log.Logger) error { rpcClient, err := rpc.DialOptions(context.Background(), ctx.String("source")) if err != nil { return fmt.Errorf("failed to dial engine source endpoint: %w", err) } source := client.NewBaseRPCClient(rpcClient) return engine.Copy(context.Background(), source, dest) }), } EngineCopyPayloadCmd = &cli.Command{ Name: "copy-payload", Description: "Take the block by number from source and insert it to the engine with NewPayload. No other calls are made.", Flags: withEngineFlags( &cli.StringFlag{ Name: "source", Usage: "Unauthenticated regular eth JSON RPC to pull block data from, can be HTTP/WS/IPC.", Required: true, EnvVars: prefixEnvVars("SOURCE"), }, &cli.Uint64Flag{ Name: "number", Usage: "Block number to copy from the source", Required: true, EnvVars: prefixEnvVars("NUMBER"), }, ), Action: EngineAction(func(ctx *cli.Context, dest *sources.EngineAPIClient, _ log.Logger) error { rpcClient, err := rpc.DialOptions(context.Background(), ctx.String("source")) if err != nil { return fmt.Errorf("failed to dial engine source endpoint: %w", err) } source := client.NewBaseRPCClient(rpcClient) return engine.CopyPayload(context.Background(), ctx.Uint64("number"), source, dest) }), } EngineSetForkchoiceCmd = &cli.Command{ Name: "set-forkchoice", Description: "Set forkchoice, specify unsafe, safe and finalized blocks by number", Flags: withEngineFlags( &cli.Uint64Flag{ Name: "unsafe", Usage: "Block number of block to set as latest block", Required: true, EnvVars: prefixEnvVars("UNSAFE"), }, &cli.Uint64Flag{ Name: "safe", Usage: "Block number of block to set as safe block", Required: true, EnvVars: prefixEnvVars("SAFE"), }, &cli.Uint64Flag{ Name: "finalized", Usage: "Block number of block to set as finalized block", Required: true, EnvVars: prefixEnvVars("FINALIZED"), }, ), Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { return engine.SetForkchoice(ctx.Context, client, ctx.Uint64("finalized"), ctx.Uint64("safe"), ctx.Uint64("unsafe")) }), } EngineSetForkchoiceHashCmd = &cli.Command{ Name: "set-forkchoice-by-hash", Description: "Set forkchoice, specify unsafe, safe and finalized blocks by hash", Flags: withEngineFlags( &cli.StringFlag{ Name: "unsafe", Usage: "Block hash of block to set as latest block", Required: true, EnvVars: prefixEnvVars("UNSAFE"), }, &cli.StringFlag{ Name: "safe", Usage: "Block hash of block to set as safe block", Required: true, EnvVars: prefixEnvVars("SAFE"), }, &cli.StringFlag{ Name: "finalized", Usage: "Block hash of block to set as finalized block", Required: true, EnvVars: prefixEnvVars("FINALIZED"), }, ), Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { finalized := common.HexToHash(ctx.String("finalized")) safe := common.HexToHash(ctx.String("safe")) unsafe := common.HexToHash(ctx.String("unsafe")) return engine.SetForkchoiceByHash(ctx.Context, client, finalized, safe, unsafe) }), } EngineRewindCmd = &cli.Command{ Name: "rewind", Description: "Rewind chain by number (destructive!)", Flags: withEngineFlags( &cli.Uint64Flag{ Name: "to", Usage: "Block number to rewind chain to", Required: true, EnvVars: prefixEnvVars("REWIND_TO"), }, &cli.BoolFlag{ Name: "set-head", Usage: "Whether to also call debug_setHead when rewinding", EnvVars: prefixEnvVars("REWIND_SET_HEAD"), }, ), Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, lgr log.Logger) error { open, err := initOpenEngineRPC(ctx, lgr) if err != nil { return fmt.Errorf("failed to dial open RPC endpoint: %w", err) } return engine.Rewind(ctx.Context, lgr, client, open, ctx.Uint64("to"), ctx.Bool("set-head")) }), } EngineJSONCmd = &cli.Command{ Name: "json", Description: "read json values from remaining args, or STDIN, and use them as RPC params to call the engine RPC method (first arg)", Flags: withEngineFlags( &cli.BoolFlag{ Name: "stdin", Usage: "Read params from stdin instead", Required: false, EnvVars: prefixEnvVars("STDIN"), }, ), ArgsUsage: "<rpc-method-name> [params...]", Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { if ctx.NArg() == 0 { return fmt.Errorf("expected at least 1 argument: RPC method name") } var r io.Reader var args []string if ctx.Bool("stdin") { r = ctx.App.Reader } else { args = ctx.Args().Tail() } return engine.RawJSONInteraction(ctx.Context, client.RPC, ctx.Args().Get(0), args, r, ctx.App.Writer) }), } )
View Source
var CheatCmd = &cli.Command{ Name: "cheat", Usage: "Cheating commands to modify a Geth database.", Description: "Each sub-command opens a Geth database, applies the cheat, and then saves and closes the database." + "The Geth node will live in its own false reality, other nodes cannot sync the cheated state if they process the blocks.", Subcommands: []*cli.Command{ CheatStorageCmd, CheatSetBalanceCmd, CheatSetCodeCmd, CheatSetNonceCmd, CheatPrintHeadBlock, CheatPrintHeadHeader, }, }
View Source
var EngineCmd = &cli.Command{ Name: "engine", Usage: "Engine API commands to build/reorg/rewind/finalize/copy blocks.", Description: "Each sub-command dials the engine API endpoint (with provided JWT secret) and then runs the action", Subcommands: []*cli.Command{ EngineBlockCmd, EngineAutoCmd, EngineStatusCmd, EngineCopyCmd, EngineCopyPayloadCmd, EngineSetForkchoiceCmd, EngineSetForkchoiceHashCmd, EngineRewindCmd, EngineJSONCmd, }, }
Functions ¶
func CheatAction ¶
func CheatRawDBAction ¶
func EngineAction ¶
func EngineAction(fn func(ctx *cli.Context, client *sources.EngineAPIClient, lgr log.Logger) error) cli.ActionFunc
func ParseBuildingArgs ¶
func ParseBuildingArgs(ctx *cli.Context) *engine.BlockBuildingSettings
Types ¶
type Text ¶
type Text interface { encoding.TextUnmarshaler fmt.Stringer comparable }
Click to show internal directories.
Click to hide internal directories.