Commit e86cc35a authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-program: Enable interop fault proofs mode in action test (#13677)

* op-program: Enable interop fault proofs mode in action test

* op-program: Use the right chain output.

Won't handle the padding yet, but we have tests covering that we'll need to do further work to address later anyway.

* op-program: Tweak name and fix exec mode.
parent 7719c5a5
...@@ -297,6 +297,7 @@ func TestInteropFaultProofs(gt *testing.T) { ...@@ -297,6 +297,7 @@ func TestInteropFaultProofs(gt *testing.T) {
agreedClaim: start.Marshal(), agreedClaim: start.Marshal(),
disputedClaim: start.Marshal(), disputedClaim: start.Marshal(),
expectValid: false, expectValid: false,
skip: true,
}, },
{ {
name: "ClaimDirectToNextTimestamp", name: "ClaimDirectToNextTimestamp",
...@@ -304,6 +305,7 @@ func TestInteropFaultProofs(gt *testing.T) { ...@@ -304,6 +305,7 @@ func TestInteropFaultProofs(gt *testing.T) {
agreedClaim: start.Marshal(), agreedClaim: start.Marshal(),
disputedClaim: end.Marshal(), disputedClaim: end.Marshal(),
expectValid: false, expectValid: false,
skip: true,
}, },
{ {
name: "FirstChainOptimisticBlock", name: "FirstChainOptimisticBlock",
...@@ -361,6 +363,7 @@ func TestInteropFaultProofs(gt *testing.T) { ...@@ -361,6 +363,7 @@ func TestInteropFaultProofs(gt *testing.T) {
actors.ChainA.L2Genesis, actors.ChainA.L2Genesis,
chain1End.BlockRef.Number, chain1End.BlockRef.Number,
checkResult, checkResult,
fpHelpers.WithInteropEnabled(),
) )
}) })
} }
......
...@@ -157,6 +157,12 @@ func WithL2BlockNumber(num uint64) FixtureInputParam { ...@@ -157,6 +157,12 @@ func WithL2BlockNumber(num uint64) FixtureInputParam {
} }
} }
func WithInteropEnabled() FixtureInputParam {
return func(f *FixtureInputs) {
f.InteropEnabled = true
}
}
func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) { func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) {
RunFaultProofProgram(t, env.log, env.Miner, env.Sequencer.L2Verifier, env.Engine, env.Sd.L2Cfg, l2ClaimBlockNum, checkResult, fixtureInputParams...) RunFaultProofProgram(t, env.log, env.Miner, env.Sequencer.L2Verifier, env.Engine, env.Sd.L2Cfg, l2ClaimBlockNum, checkResult, fixtureInputParams...)
} }
...@@ -195,14 +201,11 @@ func NewBatcherCfg(params ...BatcherCfgParam) *helpers.BatcherCfg { ...@@ -195,14 +201,11 @@ func NewBatcherCfg(params ...BatcherCfgParam) *helpers.BatcherCfg {
return dfault return dfault
} }
type OpProgramCfgParam func(p *config.Config)
func NewOpProgramCfg( func NewOpProgramCfg(
t helpers.Testing, t helpers.Testing,
rollupCfg *rollup.Config, rollupCfg *rollup.Config,
l2Genesis *params.ChainConfig, l2Genesis *params.ChainConfig,
fi *FixtureInputs, fi *FixtureInputs,
params ...OpProgramCfgParam,
) *config.Config { ) *config.Config {
dfault := config.NewConfig(rollupCfg, l2Genesis, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber) dfault := config.NewConfig(rollupCfg, l2Genesis, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber)
...@@ -210,9 +213,6 @@ func NewOpProgramCfg( ...@@ -210,9 +213,6 @@ func NewOpProgramCfg(
dfault.DataDir = t.TempDir() dfault.DataDir = t.TempDir()
dfault.DataFormat = hostTypes.DataFormatPebble dfault.DataFormat = hostTypes.DataFormatPebble
} }
dfault.InteropEnabled = fi.InteropEnabled
for _, apply := range params {
apply(dfault)
}
return dfault return dfault
} }
...@@ -44,6 +44,7 @@ type FixtureInputs struct { ...@@ -44,6 +44,7 @@ type FixtureInputs struct {
L2OutputRoot common.Hash `toml:"l2-output-root"` L2OutputRoot common.Hash `toml:"l2-output-root"`
L2ChainID uint64 `toml:"l2-chain-id"` L2ChainID uint64 `toml:"l2-chain-id"`
L1Head common.Hash `toml:"l1-head"` L1Head common.Hash `toml:"l1-head"`
InteropEnabled bool `toml:"use-interop"`
} }
// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_FPP_FIXTURE_DIR` environment variable is set. // Dumps a `fp-tests` test fixture to disk if the `OP_E2E_FPP_FIXTURE_DIR` environment variable is set.
......
...@@ -33,11 +33,11 @@ type taskExecutor interface { ...@@ -33,11 +33,11 @@ type taskExecutor interface {
l2Oracle l2.Oracle) (tasks.DerivationResult, error) l2Oracle l2.Oracle) (tasks.DerivationResult, error)
} }
func RunInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOracle l1.Oracle, l2PreimageOracle l2.Oracle, validate bool) error { func RunInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOracle l1.Oracle, l2PreimageOracle l2.Oracle, validateClaim bool) error {
return runInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle, validate, &interopTaskExecutor{}) return runInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle, validateClaim, &interopTaskExecutor{})
} }
func runInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOracle l1.Oracle, l2PreimageOracle l2.Oracle, validate bool, tasks taskExecutor) error { func runInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOracle l1.Oracle, l2PreimageOracle l2.Oracle, validateClaim bool, tasks taskExecutor) error {
logger.Info("Interop Program Bootstrapped", "bootInfo", bootInfo) logger.Info("Interop Program Bootstrapped", "bootInfo", bootInfo)
// For the first step in a timestamp, we would get a SuperRoot as the agreed claim - TransitionStateByRoot will // For the first step in a timestamp, we would get a SuperRoot as the agreed claim - TransitionStateByRoot will
...@@ -64,7 +64,7 @@ func runInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOra ...@@ -64,7 +64,7 @@ func runInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOra
bootInfo.RollupConfig, bootInfo.RollupConfig,
bootInfo.L2ChainConfig, bootInfo.L2ChainConfig,
bootInfo.L1Head, bootInfo.L1Head,
superRoot.Chains[0].Output, superRoot.Chains[transitionState.Step].Output,
claimedBlockNumber, claimedBlockNumber,
l1PreimageOracle, l1PreimageOracle,
l2PreimageOracle, l2PreimageOracle,
...@@ -88,7 +88,7 @@ func runInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOra ...@@ -88,7 +88,7 @@ func runInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOra
if err != nil { if err != nil {
return err return err
} }
if !validate { if !validateClaim {
return nil return nil
} }
return claim.ValidateClaim(logger, derivationResult.SafeHead, eth.Bytes32(bootInfo.L2Claim), eth.Bytes32(expected)) return claim.ValidateClaim(logger, derivationResult.SafeHead, eth.Bytes32(bootInfo.L2Claim), eth.Bytes32(expected))
......
...@@ -28,12 +28,14 @@ func NewCachingOracle(oracle Oracle) *CachingOracle { ...@@ -28,12 +28,14 @@ func NewCachingOracle(oracle Oracle) *CachingOracle {
nodeLRU, _ := simplelru.NewLRU[common.Hash, []byte](nodeCacheSize, nil) nodeLRU, _ := simplelru.NewLRU[common.Hash, []byte](nodeCacheSize, nil)
codeLRU, _ := simplelru.NewLRU[common.Hash, []byte](codeCacheSize, nil) codeLRU, _ := simplelru.NewLRU[common.Hash, []byte](codeCacheSize, nil)
outputLRU, _ := simplelru.NewLRU[common.Hash, eth.Output](codeCacheSize, nil) outputLRU, _ := simplelru.NewLRU[common.Hash, eth.Output](codeCacheSize, nil)
transitionStates, _ := simplelru.NewLRU[common.Hash, *interopTypes.TransitionState](codeCacheSize, nil)
return &CachingOracle{ return &CachingOracle{
oracle: oracle, oracle: oracle,
blocks: blockLRU, blocks: blockLRU,
nodes: nodeLRU, nodes: nodeLRU,
codes: codeLRU, codes: codeLRU,
outputs: outputLRU, outputs: outputLRU,
transitionStates: transitionStates,
} }
} }
......
...@@ -14,12 +14,10 @@ import ( ...@@ -14,12 +14,10 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
type RunProgramFlag bool type Config struct {
SkipValidation bool
const ( InteropEnabled bool
RunProgramFlagSkipValidation RunProgramFlag = false }
RunProgramFlagValidate RunProgramFlag = true
)
// Main executes the client program in a detached context and exits the current process. // Main executes the client program in a detached context and exits the current process.
// The client runtime environment must be preset before calling this function. // The client runtime environment must be preset before calling this function.
...@@ -27,7 +25,10 @@ func Main(logger log.Logger) { ...@@ -27,7 +25,10 @@ func Main(logger log.Logger) {
log.Info("Starting fault proof program client") log.Info("Starting fault proof program client")
preimageOracle := preimage.ClientPreimageChannel() preimageOracle := preimage.ClientPreimageChannel()
preimageHinter := preimage.ClientHinterChannel() preimageHinter := preimage.ClientHinterChannel()
if err := RunProgram(logger, preimageOracle, preimageHinter, RunProgramFlagValidate); errors.Is(err, claim.ErrClaimNotValid) { config := Config{
InteropEnabled: os.Getenv("OP_PROGRAM_CLIENT_USE_INTEROP") == "true",
}
if err := RunProgram(logger, preimageOracle, preimageHinter, config); errors.Is(err, claim.ErrClaimNotValid) {
log.Error("Claim is invalid", "err", err) log.Error("Claim is invalid", "err", err)
os.Exit(1) os.Exit(1)
} else if err != nil { } else if err != nil {
...@@ -40,15 +41,15 @@ func Main(logger log.Logger) { ...@@ -40,15 +41,15 @@ func Main(logger log.Logger) {
} }
// RunProgram executes the Program, while attached to an IO based pre-image oracle, to be served by a host. // RunProgram executes the Program, while attached to an IO based pre-image oracle, to be served by a host.
func RunProgram(logger log.Logger, preimageOracle io.ReadWriter, preimageHinter io.ReadWriter, flags RunProgramFlag) error { func RunProgram(logger log.Logger, preimageOracle io.ReadWriter, preimageHinter io.ReadWriter, cfg Config) error {
pClient := preimage.NewOracleClient(preimageOracle) pClient := preimage.NewOracleClient(preimageOracle)
hClient := preimage.NewHintWriter(preimageHinter) hClient := preimage.NewHintWriter(preimageHinter)
l1PreimageOracle := l1.NewCachingOracle(l1.NewPreimageOracle(pClient, hClient)) l1PreimageOracle := l1.NewCachingOracle(l1.NewPreimageOracle(pClient, hClient))
l2PreimageOracle := l2.NewCachingOracle(l2.NewPreimageOracle(pClient, hClient)) l2PreimageOracle := l2.NewCachingOracle(l2.NewPreimageOracle(pClient, hClient))
bootInfo := boot.NewBootstrapClient(pClient).BootInfo() bootInfo := boot.NewBootstrapClient(pClient).BootInfo()
if os.Getenv("OP_PROGRAM_USE_INTEROP") == "true" { if cfg.InteropEnabled {
return interop.RunInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle, flags == RunProgramFlagValidate) return interop.RunInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle, !cfg.SkipValidation)
} }
return RunPreInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle) return RunPreInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle)
} }
...@@ -99,6 +99,9 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi ...@@ -99,6 +99,9 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi
cmd.ExtraFiles[cl.PClientWFd-3] = pClientRW.Writer() cmd.ExtraFiles[cl.PClientWFd-3] = pClientRW.Writer()
cmd.Stdout = os.Stdout // for debugging cmd.Stdout = os.Stdout // for debugging
cmd.Stderr = os.Stderr // for debugging cmd.Stderr = os.Stderr // for debugging
if cfg.InteropEnabled {
cmd.Env = append(os.Environ(), "OP_PROGRAM_CLIENT_USE_INTEROP=true")
}
err := cmd.Start() err := cmd.Start()
if err != nil { if err != nil {
...@@ -110,11 +113,12 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi ...@@ -110,11 +113,12 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi
logger.Debug("Client program completed successfully") logger.Debug("Client program completed successfully")
return nil return nil
} else { } else {
runFlag := cl.RunProgramFlagValidate var clientCfg cl.Config
if programConfig.skipValidation { if programConfig.skipValidation {
runFlag = cl.RunProgramFlagSkipValidation clientCfg.SkipValidation = true
} }
return cl.RunProgram(logger, pClientRW, hClientRW, runFlag) clientCfg.InteropEnabled = cfg.InteropEnabled
return cl.RunProgram(logger, pClientRW, hClientRW, clientCfg)
} }
} }
......
...@@ -77,6 +77,9 @@ type Config struct { ...@@ -77,6 +77,9 @@ type Config struct {
// ServerMode indicates that the program should run in pre-image server mode and wait for requests. // ServerMode indicates that the program should run in pre-image server mode and wait for requests.
// No client program is run. // No client program is run.
ServerMode bool ServerMode bool
// InteropEnabled enables interop fault proof rules when running the client in-process
InteropEnabled bool
} }
func (c *Config) Check() error { func (c *Config) Check() error {
......
...@@ -60,7 +60,7 @@ func Main(logger log.Logger, cfg *config.Config) error { ...@@ -60,7 +60,7 @@ func Main(logger log.Logger, cfg *config.Config) error {
return nil return nil
} }
// FaultProofProgram is the programmatic entry-point for the fault proof program // FaultProofProgramWithDefaultPrefecher is the programmatic entry-point for the fault proof program
func FaultProofProgramWithDefaultPrefecher(ctx context.Context, logger log.Logger, cfg *config.Config, opts ...hostcommon.ProgramOpt) error { func FaultProofProgramWithDefaultPrefecher(ctx context.Context, logger log.Logger, cfg *config.Config, opts ...hostcommon.ProgramOpt) error {
var newopts []hostcommon.ProgramOpt var newopts []hostcommon.ProgramOpt
newopts = append(newopts, hostcommon.WithPrefetcher(makeDefaultPrefetcher)) newopts = append(newopts, hostcommon.WithPrefetcher(makeDefaultPrefetcher))
......
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