Commit f8e20bea authored by Adrian Sutton's avatar Adrian Sutton

op-program: Specify client program to run as an executable

Removes the env var approach to toggling between the host and client executables.
parent 6d77414f
package op_e2e
import (
"context"
"os"
"os/exec"
"testing"
"time"
"github.com/stretchr/testify/require"
)
// BuildOpProgramClient builds the `op-program` client executable and returns the path to the resulting executable
func BuildOpProgramClient(t *testing.T) string {
t.Log("Building op-program-client")
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
cmd := exec.CommandContext(ctx, "make", "op-program-client")
cmd.Dir = "../op-program"
cmd.Stdout = os.Stdout // for debugging
cmd.Stderr = os.Stderr // for debugging
require.NoError(t, cmd.Run(), "Failed to build op-program-client")
t.Log("Built op-program-client successfully")
return "../op-program/bin/op-program-client"
}
......@@ -9,11 +9,9 @@ import (
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-node/testlog"
oppcl "github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/client/driver"
opp "github.com/ethereum-optimism/optimism/op-program/host"
oppconf "github.com/ethereum-optimism/optimism/op-program/host/config"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
......@@ -21,18 +19,6 @@ import (
"github.com/stretchr/testify/require"
)
// bypass the test runnner if running client to execute the fpp directly
func init() {
if !opp.RunningProgramInClient() {
return
}
logger := oplog.NewLogger(oplog.CLIConfig{
Level: "debug",
Format: "text",
})
oppcl.Main(logger)
}
func TestVerifyL2OutputRoot(t *testing.T) {
testVerifyL2OutputRoot(t, false)
}
......@@ -115,7 +101,10 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool) {
fppConfig.L1URL = sys.NodeEndpoint("l1")
fppConfig.L2URL = sys.NodeEndpoint("sequencer")
fppConfig.DataDir = preimageDir
fppConfig.Detached = detached
if detached {
// When running in detached mode we need to compile the client executable since it will be called directly.
fppConfig.ExecCmd = BuildOpProgramClient(t)
}
// Check the FPP confirms the expected output
t.Log("Running fault proof in fetching mode")
......
......@@ -5,7 +5,6 @@ import (
"fmt"
"os"
cl "github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/client/driver"
"github.com/ethereum-optimism/optimism/op-program/host"
"github.com/ethereum-optimism/optimism/op-program/host/config"
......@@ -37,11 +36,6 @@ var VersionWithMeta = func() string {
}()
func main() {
if host.RunningProgramInClient() {
logger := oplog.NewLogger(oplog.DefaultCLIConfig())
cl.Main(logger)
panic("Client main should have exited process")
}
args := os.Args
if err := run(args, host.FaultProofProgram); errors.Is(err, driver.ErrClaimNotValid) {
log.Crit("Claim is invalid", "err", err)
......
......@@ -220,22 +220,15 @@ func TestL2BlockNumber(t *testing.T) {
})
}
func TestDetached(t *testing.T) {
t.Run("DefaultFalse", func(t *testing.T) {
func TestExec(t *testing.T) {
t.Run("DefaultEmpty", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs())
require.False(t, cfg.Detached)
})
t.Run("Enabled", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs("--detached"))
require.True(t, cfg.Detached)
require.Equal(t, "", cfg.ExecCmd)
})
t.Run("EnabledWithArg", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs("--detached=true"))
require.True(t, cfg.Detached)
})
t.Run("Disabled", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs("--detached=false"))
require.False(t, cfg.Detached)
t.Run("Set", func(t *testing.T) {
cmd := "/bin/echo"
cfg := configForArgs(t, addRequiredArgs("--exec", cmd))
require.Equal(t, cmd, cfg.ExecCmd)
})
}
......
......@@ -49,8 +49,9 @@ type Config struct {
L2ClaimBlockNumber uint64
// L2ChainConfig is the op-geth chain config for the L2 execution engine
L2ChainConfig *params.ChainConfig
// Detached indicates that the program runs as a separate process
Detached bool
// ExecCmd specifies the client program to execute in a separate process.
// If unset, the fault proof client is run in the same process.
ExecCmd string
}
func (c *Config) Check() error {
......@@ -148,7 +149,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
L1URL: ctx.GlobalString(flags.L1NodeAddr.Name),
L1TrustRPC: ctx.GlobalBool(flags.L1TrustRPC.Name),
L1RPCKind: sources.RPCProviderKind(ctx.GlobalString(flags.L1RPCProviderKind.Name)),
Detached: ctx.GlobalBool(flags.Detached.Name),
ExecCmd: ctx.String(flags.Exec.Name),
}, nil
}
......
......@@ -81,10 +81,10 @@ var (
return &out
}(),
}
Detached = cli.BoolFlag{
Name: "detached",
Usage: "Run the program as a separate process detached from the host",
EnvVar: service.PrefixEnvVar(envVarPrefix, "DETACHED"),
Exec = cli.StringFlag{
Name: "exec",
Usage: "Run the specified client program as a separate process detached from the host. Default is to run the client program in the host process.",
EnvVar: service.PrefixEnvVar(envVarPrefix, "EXEC"),
}
)
......@@ -106,7 +106,7 @@ var programFlags = []cli.Flag{
L1NodeAddr,
L1TrustRPC,
L1RPCProviderKind,
Detached,
Exec,
}
func init() {
......
......@@ -27,13 +27,6 @@ type L2Source struct {
*sources.DebugClient
}
const opProgramChildEnvName = "OP_PROGRAM_CHILD"
func RunningProgramInClient() bool {
value, _ := os.LookupEnv(opProgramChildEnvName)
return value == "true"
}
// FaultProofProgram is the programmatic entry-point for the fault proof program
func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
if err := cfg.Check(); err != nil {
......@@ -96,8 +89,8 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
routeHints(logger, hHost, hinter)
var cmd *exec.Cmd
if cfg.Detached {
cmd = exec.CommandContext(ctx, os.Args[0])
if cfg.ExecCmd != "" {
cmd = exec.CommandContext(ctx, cfg.ExecCmd)
cmd.ExtraFiles = make([]*os.File, cl.MaxFd-3) // not including stdin, stdout and stderr
cmd.ExtraFiles[cl.HClientRFd-3] = hClientRW.Reader()
cmd.ExtraFiles[cl.HClientWFd-3] = hClientRW.Writer()
......@@ -105,7 +98,6 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
cmd.ExtraFiles[cl.PClientWFd-3] = pClientRW.Writer()
cmd.Stdout = os.Stdout // for debugging
cmd.Stderr = os.Stderr // for debugging
cmd.Env = append(os.Environ(), fmt.Sprintf("%s=true", opProgramChildEnvName))
err := cmd.Start()
if err != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment