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) {
agreedClaim: start.Marshal(),
disputedClaim: start.Marshal(),
expectValid: false,
skip: true,
},
{
name: "ClaimDirectToNextTimestamp",
......@@ -304,6 +305,7 @@ func TestInteropFaultProofs(gt *testing.T) {
agreedClaim: start.Marshal(),
disputedClaim: end.Marshal(),
expectValid: false,
skip: true,
},
{
name: "FirstChainOptimisticBlock",
......@@ -361,6 +363,7 @@ func TestInteropFaultProofs(gt *testing.T) {
actors.ChainA.L2Genesis,
chain1End.BlockRef.Number,
checkResult,
fpHelpers.WithInteropEnabled(),
)
})
}
......
......@@ -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) {
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 {
return dfault
}
type OpProgramCfgParam func(p *config.Config)
func NewOpProgramCfg(
t helpers.Testing,
rollupCfg *rollup.Config,
l2Genesis *params.ChainConfig,
fi *FixtureInputs,
params ...OpProgramCfgParam,
) *config.Config {
dfault := config.NewConfig(rollupCfg, l2Genesis, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber)
......@@ -210,9 +213,6 @@ func NewOpProgramCfg(
dfault.DataDir = t.TempDir()
dfault.DataFormat = hostTypes.DataFormatPebble
}
for _, apply := range params {
apply(dfault)
}
dfault.InteropEnabled = fi.InteropEnabled
return dfault
}
......@@ -38,12 +38,13 @@ type TestFixture struct {
}
type FixtureInputs struct {
L2BlockNumber uint64 `toml:"l2-block-number"`
L2Claim common.Hash `toml:"l2-claim"`
L2Head common.Hash `toml:"l2-head"`
L2OutputRoot common.Hash `toml:"l2-output-root"`
L2ChainID uint64 `toml:"l2-chain-id"`
L1Head common.Hash `toml:"l1-head"`
L2BlockNumber uint64 `toml:"l2-block-number"`
L2Claim common.Hash `toml:"l2-claim"`
L2Head common.Hash `toml:"l2-head"`
L2OutputRoot common.Hash `toml:"l2-output-root"`
L2ChainID uint64 `toml:"l2-chain-id"`
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.
......
......@@ -33,11 +33,11 @@ type taskExecutor interface {
l2Oracle l2.Oracle) (tasks.DerivationResult, error)
}
func RunInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOracle l1.Oracle, l2PreimageOracle l2.Oracle, validate bool) error {
return runInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle, validate, &interopTaskExecutor{})
func RunInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOracle l1.Oracle, l2PreimageOracle l2.Oracle, validateClaim bool) error {
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)
// 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
bootInfo.RollupConfig,
bootInfo.L2ChainConfig,
bootInfo.L1Head,
superRoot.Chains[0].Output,
superRoot.Chains[transitionState.Step].Output,
claimedBlockNumber,
l1PreimageOracle,
l2PreimageOracle,
......@@ -88,7 +88,7 @@ func runInteropProgram(logger log.Logger, bootInfo *boot.BootInfo, l1PreimageOra
if err != nil {
return err
}
if !validate {
if !validateClaim {
return nil
}
return claim.ValidateClaim(logger, derivationResult.SafeHead, eth.Bytes32(bootInfo.L2Claim), eth.Bytes32(expected))
......
......@@ -28,12 +28,14 @@ func NewCachingOracle(oracle Oracle) *CachingOracle {
nodeLRU, _ := simplelru.NewLRU[common.Hash, []byte](nodeCacheSize, nil)
codeLRU, _ := simplelru.NewLRU[common.Hash, []byte](codeCacheSize, nil)
outputLRU, _ := simplelru.NewLRU[common.Hash, eth.Output](codeCacheSize, nil)
transitionStates, _ := simplelru.NewLRU[common.Hash, *interopTypes.TransitionState](codeCacheSize, nil)
return &CachingOracle{
oracle: oracle,
blocks: blockLRU,
nodes: nodeLRU,
codes: codeLRU,
outputs: outputLRU,
oracle: oracle,
blocks: blockLRU,
nodes: nodeLRU,
codes: codeLRU,
outputs: outputLRU,
transitionStates: transitionStates,
}
}
......
......@@ -14,12 +14,10 @@ import (
"github.com/ethereum/go-ethereum/log"
)
type RunProgramFlag bool
const (
RunProgramFlagSkipValidation RunProgramFlag = false
RunProgramFlagValidate RunProgramFlag = true
)
type Config struct {
SkipValidation bool
InteropEnabled bool
}
// 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.
......@@ -27,7 +25,10 @@ func Main(logger log.Logger) {
log.Info("Starting fault proof program client")
preimageOracle := preimage.ClientPreimageChannel()
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)
os.Exit(1)
} else if err != nil {
......@@ -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.
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)
hClient := preimage.NewHintWriter(preimageHinter)
l1PreimageOracle := l1.NewCachingOracle(l1.NewPreimageOracle(pClient, hClient))
l2PreimageOracle := l2.NewCachingOracle(l2.NewPreimageOracle(pClient, hClient))
bootInfo := boot.NewBootstrapClient(pClient).BootInfo()
if os.Getenv("OP_PROGRAM_USE_INTEROP") == "true" {
return interop.RunInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle, flags == RunProgramFlagValidate)
if cfg.InteropEnabled {
return interop.RunInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle, !cfg.SkipValidation)
}
return RunPreInteropProgram(logger, bootInfo, l1PreimageOracle, l2PreimageOracle)
}
......@@ -99,6 +99,9 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi
cmd.ExtraFiles[cl.PClientWFd-3] = pClientRW.Writer()
cmd.Stdout = os.Stdout // 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()
if err != nil {
......@@ -110,11 +113,12 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi
logger.Debug("Client program completed successfully")
return nil
} else {
runFlag := cl.RunProgramFlagValidate
var clientCfg cl.Config
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 {
// ServerMode indicates that the program should run in pre-image server mode and wait for requests.
// No client program is run.
ServerMode bool
// InteropEnabled enables interop fault proof rules when running the client in-process
InteropEnabled bool
}
func (c *Config) Check() error {
......
......@@ -60,7 +60,7 @@ func Main(logger log.Logger, cfg *config.Config) error {
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 {
var newopts []hostcommon.ProgramOpt
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