Commit 320e11db authored by clabby's avatar clabby Committed by GitHub

feat: Helper for dumping `fp-tests` fixtures in `op-program` action tests (#11855)

* feat: Helper for dumping `fp-tests` fixtures in `op-program` action tests

* adrian review
parent bd3955a6
...@@ -2,14 +2,22 @@ package actions ...@@ -2,14 +2,22 @@ package actions
import ( import (
"context" "context"
"encoding/json"
"errors"
"io/fs"
"math/rand" "math/rand"
"os" "os"
"os/exec"
"path/filepath"
"testing" "testing"
"github.com/BurntSushi/toml"
batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-program/client/claim"
"github.com/ethereum-optimism/optimism/op-program/host" "github.com/ethereum-optimism/optimism/op-program/host"
"github.com/ethereum-optimism/optimism/op-program/host/config" "github.com/ethereum-optimism/optimism/op-program/host/config"
hostTypes "github.com/ethereum-optimism/optimism/op-program/host/types"
"github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -19,10 +27,14 @@ import ( ...@@ -19,10 +27,14 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var dumpFixtures = false var (
dumpFixtures = false
fixtureDir string
)
func init() { func init() {
if os.Getenv("OP_E2E_DUMP_FIXTURES") == "1" { fixtureDir = os.Getenv("OP_E2E_FPP_FIXTURE_DIR")
if fixtureDir != "" {
dumpFixtures = true dumpFixtures = true
} }
} }
...@@ -137,6 +149,11 @@ func NewOpProgramCfg( ...@@ -137,6 +149,11 @@ func NewOpProgramCfg(
l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
dfault.L2ProcessSource = l2DebugCl dfault.L2ProcessSource = l2DebugCl
if dumpFixtures {
dfault.DataDir = t.TempDir()
dfault.DataFormat = hostTypes.DataFormatPebble
}
for _, apply := range params { for _, apply := range params {
apply(dfault) apply(dfault)
} }
...@@ -205,6 +222,8 @@ func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) { ...@@ -205,6 +222,8 @@ func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) {
) )
err = host.FaultProofProgram(context.Background(), env.log, programCfg) err = host.FaultProofProgram(context.Background(), env.log, programCfg)
require.NoError(t, err) require.NoError(t, err)
tryDumpTestFixture(gt, err, "simple-empty-chain-honest-claim-granite", env, programCfg)
} }
func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) {
...@@ -267,4 +286,100 @@ func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) { ...@@ -267,4 +286,100 @@ func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) {
) )
err = host.FaultProofProgram(context.Background(), env.log, programCfg) err = host.FaultProofProgram(context.Background(), env.log, programCfg)
require.Error(t, err) require.Error(t, err)
tryDumpTestFixture(gt, err, "simple-empty-chain-junk-claim-granite", env, programCfg)
}
////////////////////////////////////////////////////////////////
// Fixture Generation utils //
////////////////////////////////////////////////////////////////
type TestFixture struct {
Name string `toml:"name"`
ExpectedStatus uint8 `toml:"expected-status"`
Inputs FixtureInputs `toml:"inputs"`
}
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"`
}
// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set.
//
// [fp-tests]: https://github.com/ethereum-optimism/fp-tests
func tryDumpTestFixture(t *testing.T, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) {
if !dumpFixtures {
return
}
rollupCfg := env.sequencer.rollupCfg
l2Genesis := env.sd.L2Cfg
var expectedStatus uint8
if result == nil {
expectedStatus = 0
} else if errors.Is(result, claim.ErrClaimNotValid) {
expectedStatus = 1
} else {
expectedStatus = 2
}
fixture := TestFixture{
Name: name,
ExpectedStatus: expectedStatus,
Inputs: FixtureInputs{
L2BlockNumber: programCfg.L2ClaimBlockNumber,
L2Claim: programCfg.L2Claim,
L2Head: programCfg.L2Head,
L2OutputRoot: programCfg.L2OutputRoot,
L2ChainID: env.sd.RollupCfg.L2ChainID.Uint64(),
L1Head: programCfg.L1Head,
},
}
fixturePath := filepath.Join(fixtureDir, name)
err := os.MkdirAll(filepath.Join(fixturePath), fs.ModePerm)
require.NoError(t, err, "failed to create fixture dir")
fixtureFilePath := filepath.Join(fixturePath, "fixture.toml")
serFixture, err := toml.Marshal(fixture)
require.NoError(t, err, "failed to serialize fixture")
require.NoError(t, os.WriteFile(fixtureFilePath, serFixture, fs.ModePerm), "failed to write fixture")
genesisPath := filepath.Join(fixturePath, "genesis.json")
serGenesis, err := l2Genesis.MarshalJSON()
require.NoError(t, err, "failed to serialize genesis")
require.NoError(t, os.WriteFile(genesisPath, serGenesis, fs.ModePerm), "failed to write genesis")
rollupPath := filepath.Join(fixturePath, "rollup.json")
serRollup, err := json.Marshal(rollupCfg)
require.NoError(t, err, "failed to serialize rollup")
require.NoError(t, os.WriteFile(rollupPath, serRollup, fs.ModePerm), "failed to write rollup")
// Copy the witness database into the fixture directory.
cmd := exec.Command("cp", "-r", programCfg.DataDir, filepath.Join(fixturePath, "witness-db"))
require.NoError(t, cmd.Run(), "Failed to copy witness DB")
// Compress the genesis file.
cmd = exec.Command("zstd", genesisPath)
_ = cmd.Run()
require.NoError(t, os.Remove(genesisPath), "Failed to remove uncompressed genesis file")
// Compress the witness database.
cmd = exec.Command(
"tar",
"--zstd",
"-cf",
filepath.Join(fixturePath, "witness-db.tar.zst"),
filepath.Join(fixturePath, "witness-db"),
)
cmd.Dir = filepath.Join(fixturePath)
require.NoError(t, cmd.Run(), "Failed to compress witness DB")
require.NoError(t, os.RemoveAll(filepath.Join(fixturePath, "witness-db")), "Failed to remove uncompressed witness DB")
} }
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