diff --git a/op-acceptance-tests/tests/interop/proofs/challenger_test.go b/op-acceptance-tests/tests/interop/proofs/challenger_test.go index 83ee70bd88871..ed981747381aa 100644 --- a/op-acceptance-tests/tests/interop/proofs/challenger_test.go +++ b/op-acceptance-tests/tests/interop/proofs/challenger_test.go @@ -15,6 +15,7 @@ import ( ) func TestChallengerPlaysGame(gt *testing.T) { + gt.Skip("Skipping until super node is available from the interop system") t := devtest.ParallelT(gt) sys := presets.NewSimpleInterop(t) dsl.CheckAll(t, diff --git a/op-devstack/dsl/proofs/dispute_game_factory.go b/op-devstack/dsl/proofs/dispute_game_factory.go index 4d11047ee24fe..253f7aa7a141b 100644 --- a/op-devstack/dsl/proofs/dispute_game_factory.go +++ b/op-devstack/dsl/proofs/dispute_game_factory.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum-optimism/optimism/op-devstack/devtest" "github.com/ethereum-optimism/optimism/op-devstack/dsl" "github.com/ethereum-optimism/optimism/op-devstack/dsl/contract" + "github.com/ethereum-optimism/optimism/op-devstack/stack" "github.com/ethereum-optimism/optimism/op-service/apis" "github.com/ethereum-optimism/optimism/op-service/bigs" "github.com/ethereum-optimism/optimism/op-service/txintent/bindings" @@ -43,7 +44,7 @@ type DisputeGameFactory struct { addr common.Address l2CL *dsl.L2CLNode l2EL *dsl.L2ELNode - superRoots SuperRootsSource + superNode stack.Supernode gameHelper *GameHelper challengerCfg *challengerConfig.Config @@ -57,7 +58,7 @@ func NewDisputeGameFactory( dgfAddr common.Address, l2CL *dsl.L2CLNode, l2EL *dsl.L2ELNode, - superRoots SuperRootsSource, + superNode stack.Supernode, challengerCfg *challengerConfig.Config, ) *DisputeGameFactory { dgf := bindings.NewDisputeGameFactory(bindings.WithClient(ethClient), bindings.WithTo(dgfAddr), bindings.WithTest(t)) @@ -71,7 +72,7 @@ func NewDisputeGameFactory( addr: dgfAddr, l2CL: l2CL, l2EL: l2EL, - superRoots: superRoots, + superNode: superNode, ethClient: ethClient, challengerCfg: challengerCfg, @@ -185,7 +186,7 @@ func (f *DisputeGameFactory) WaitForGame() *FaultDisputeGame { } func (f *DisputeGameFactory) StartSuperCannonGame(eoa *dsl.EOA, opts ...GameOpt) *SuperFaultDisputeGame { - f.require.NotNil(f.superRoots, "super roots source is required to start super games") + f.require.NotNil(f.superNode, "super node is required to start super games") return f.startSuperCannonGameOfType(eoa, gameTypes.SuperCannonGameType, opts...) } @@ -198,7 +199,8 @@ func (f *DisputeGameFactory) startSuperCannonGameOfType(eoa *dsl.EOA, gameType g } timestamp := cfg.l2SequenceNumber if !cfg.l2SequenceNumberSet { - timestamp = f.superRoots.SafeTimestamp() + f.t.Error("Can't retrieve safe timestamp from super node yet") + f.t.FailNow() } extraData := f.createSuperGameExtraData(timestamp, cfg) rootClaim := cfg.rootClaim @@ -211,11 +213,15 @@ func (f *DisputeGameFactory) startSuperCannonGameOfType(eoa *dsl.EOA, gameType g } func (f *DisputeGameFactory) createSuperGameExtraData(timestamp uint64, cfg *GameCfg) []byte { - f.require.NotNil(f.superRoots, "super roots is required create super games") + f.require.NotNil(f.superNode, "super node is required create super games") if !cfg.allowFuture { - f.superRoots.AwaitMinVerifiedTimestamp(timestamp) + f.awaitMinVerifiedTimestamp(timestamp) } - superV1 := f.superRoots.SuperV1AtTimestamp(timestamp) + resp, err := f.superNode.QueryAPI().SuperRootAtTimestamp(f.t.Ctx(), timestamp) + f.require.NoError(err, "Failed to fetch super root at timestamp") + f.require.NotNil(resp.Data, "Super root data must be present at timestamp %v", timestamp) + superV1, ok := resp.Data.Super.(*eth.SuperV1) + f.require.Truef(ok, "unsupported super type %T", resp.Data.Super) if len(cfg.superOutputRoots) != 0 { f.require.Len(cfg.superOutputRoots, len(superV1.Chains), "Super output roots length mismatch") for i := range superV1.Chains { @@ -226,6 +232,14 @@ func (f *DisputeGameFactory) createSuperGameExtraData(timestamp uint64, cfg *Gam return extraData } +func (f *DisputeGameFactory) awaitMinVerifiedTimestamp(timestamp uint64) { + f.t.Require().Eventually(func() bool { + resp, err := f.superNode.QueryAPI().SuperRootAtTimestamp(f.t.Ctx(), timestamp) + f.require.NoError(err, "Failed to fetch supernode status (superroot_atTimestamp)") + return resp.Data != nil + }, 2*time.Minute, 1*time.Second) +} + func (f *DisputeGameFactory) StartCannonGame(eoa *dsl.EOA, opts ...GameOpt) *FaultDisputeGame { return f.startOutputRootGameOfType(eoa, gameTypes.CannonGameType, f.honestTraceForGame, opts...) } diff --git a/op-devstack/dsl/proofs/super_roots_source.go b/op-devstack/dsl/proofs/super_roots_source.go deleted file mode 100644 index e0d37185f8510..0000000000000 --- a/op-devstack/dsl/proofs/super_roots_source.go +++ /dev/null @@ -1,90 +0,0 @@ -package proofs - -import ( - "time" - - "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/dsl" - "github.com/ethereum-optimism/optimism/op-devstack/stack" - "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/stretchr/testify/require" -) - -// SuperRootsSource is a minimal abstraction for "super-roots" needed by the proofs DSL. -// It can be backed by either an op-supervisor (legacy) or an op-supernode (replacement). -type SuperRootsSource interface { - // SafeTimestamp retrieves the current safe timestamp from the source - SafeTimestamp() uint64 - // AwaitMinVerifiedTimestamp blocks until the source has verified at least up to the given timestamp - AwaitMinVerifiedTimestamp(timestamp uint64) - // SuperV1AtTimestamp retrieves the super root at the given timestamp - SuperV1AtTimestamp(timestamp uint64) *eth.SuperV1 -} - -func NewSuperRootsFromSupervisor(supervisor *dsl.Supervisor) SuperRootsSource { - return &supervisorSuperRootsSource{supervisor: supervisor} -} - -func NewSuperRootsFromSupernode(t devtest.T, supernode stack.Supernode) SuperRootsSource { - return &supernodeSuperRootsSource{ - t: t, - require: require.New(t), - supernode: supernode, - } -} - -type supervisorSuperRootsSource struct { - supervisor *dsl.Supervisor -} - -func (s *supervisorSuperRootsSource) SafeTimestamp() uint64 { - return s.supervisor.FetchSyncStatus().SafeTimestamp -} - -func (s *supervisorSuperRootsSource) AwaitMinVerifiedTimestamp(timestamp uint64) { - s.supervisor.AwaitMinCrossSafeTimestamp(timestamp) -} - -func (s *supervisorSuperRootsSource) SuperV1AtTimestamp(timestamp uint64) *eth.SuperV1 { - super, err := s.supervisor.FetchSuperRootAtTimestamp(timestamp).ToSuper() - s.supervisor.Escape().T().Require().NoError(err, "Failed to parse super root at timestamp %v", timestamp) - superV1, ok := super.(*eth.SuperV1) - s.supervisor.Escape().T().Require().Truef(ok, "Unsupported super type %T", super) - return superV1 -} - -type supernodeSuperRootsSource struct { - t devtest.T - require *require.Assertions - supernode stack.Supernode -} - -func (s *supernodeSuperRootsSource) SafeTimestamp() uint64 { - s.t.Error("not yet implemented: supernodeSuperRootsSource.SafeTimestamp") - s.t.FailNow() - return 0 -} - -func (s *supernodeSuperRootsSource) AwaitMinVerifiedTimestamp(timestamp uint64) { - s.t.Require().Eventually(func() bool { - resp, err := s.supernode.QueryAPI().SuperRootAtTimestamp(s.t.Ctx(), timestamp) - s.require.NoError(err, "Failed to fetch supernode status (superroot_atTimestamp)") - return resp.Data != nil - }, 2*time.Minute, 1*time.Second) -} - -func (s *supernodeSuperRootsSource) SuperV1AtTimestamp(timestamp uint64) *eth.SuperV1 { - var resp eth.SuperRootAtTimestampResponse - s.t.Require().Eventually(func() bool { - r, err := s.supernode.QueryAPI().SuperRootAtTimestamp(s.t.Ctx(), timestamp) - if err != nil { - return false - } - resp = r - return resp.Data != nil - }, 2*time.Minute, 1*time.Second) - s.require.NotNil(resp.Data, "Super root data must be present at timestamp %v", timestamp) - superV1, ok := resp.Data.Super.(*eth.SuperV1) - s.require.Truef(ok, "Unsupported super type %T", resp.Data.Super) - return superV1 -} diff --git a/op-devstack/presets/interop.go b/op-devstack/presets/interop.go index c0943c7d47852..02695d68aaad3 100644 --- a/op-devstack/presets/interop.go +++ b/op-devstack/presets/interop.go @@ -114,7 +114,8 @@ func (s *SimpleInterop) L2Networks() []*dsl.L2Network { } func (s *SimpleInterop) DisputeGameFactory() *proofs.DisputeGameFactory { - return proofs.NewDisputeGameFactory(s.T, s.L1Network, s.L1EL.EthClient(), s.L2ChainA.DisputeGameFactoryProxyAddr(), nil, nil, proofs.NewSuperRootsFromSupervisor(s.Supervisor), nil) + var superNode stack.Supernode // System doesn't currently track super nodes so we can't get one. + return proofs.NewDisputeGameFactory(s.T, s.L1Network, s.L1EL.EthClient(), s.L2ChainA.DisputeGameFactoryProxyAddr(), nil, nil, superNode, nil) } func (s *SingleChainInterop) StandardBridge(l2Chain *dsl.L2Network) *dsl.StandardBridge {