From 19bd71fe1aca28f422ab92c0ba295763423f40a3 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Thu, 14 Dec 2023 13:44:03 -0600 Subject: [PATCH] faster iteration through integration test --- assertions/scanner_test.go | 2 +- challenge-manager/BUILD.bazel | 12 +- challenge-manager/edge-tracker/tracker.go | 4 +- .../manager_full_challenge_test.go | 312 ++++++++++++++++++ testing/endtoend/BUILD.bazel | 4 +- .../{internal => }/backend/BUILD.bazel | 2 +- .../{internal => }/backend/anvil_local.go | 0 .../backend/anvil_local_test.go | 0 .../{internal => }/backend/backend.go | 0 testing/endtoend/basic_local_test.go | 2 +- testing/endtoend/expect.go | 2 +- testing/endtoend/helpers.go | 2 +- tools/fund-weth/BUILD.bazel | 28 -- tools/fund-weth/main.go | 127 ------- 14 files changed, 332 insertions(+), 165 deletions(-) create mode 100644 challenge-manager/manager_full_challenge_test.go rename testing/endtoend/{internal => }/backend/BUILD.bazel (98%) rename testing/endtoend/{internal => }/backend/anvil_local.go (100%) rename testing/endtoend/{internal => }/backend/anvil_local_test.go (100%) rename testing/endtoend/{internal => }/backend/backend.go (100%) delete mode 100644 tools/fund-weth/BUILD.bazel delete mode 100644 tools/fund-weth/main.go diff --git a/assertions/scanner_test.go b/assertions/scanner_test.go index ce765acd8..6006bdb78 100644 --- a/assertions/scanner_test.go +++ b/assertions/scanner_test.go @@ -32,7 +32,6 @@ func TestComplexAssertionForkScenario(t *testing.T) { // // and then we have another validator that disagrees with 4, so Charlie // should open a 4' that branches off 3. - ctx := context.Background() setup, err := setup.ChainsWithEdgeChallengeManager( setup.WithMockBridge(), setup.WithMockOneStepProver(), @@ -62,6 +61,7 @@ func TestComplexAssertionForkScenario(t *testing.T) { aliceChain := setup.Chains[0] bobChain := setup.Chains[1] + ctx := context.Background() genesisHash, err := setup.Chains[1].GenesisAssertionHash(ctx) require.NoError(t, err) genesisCreationInfo, err := setup.Chains[1].ReadAssertionCreationInfo(ctx, protocol.AssertionHash{Hash: genesisHash}) diff --git a/challenge-manager/BUILD.bazel b/challenge-manager/BUILD.bazel index 5c6749c8f..a5706ca0e 100644 --- a/challenge-manager/BUILD.bazel +++ b/challenge-manager/BUILD.bazel @@ -33,23 +33,33 @@ go_library( go_test( name = "challenge-manager_test", - srcs = ["manager_test.go"], + srcs = [ + "manager_full_challenge_test.go", + "manager_test.go", + ], embed = [":challenge-manager"], deps = [ + "//assertions", "//chain-abstraction:protocol", + "//chain-abstraction/sol-implementation", "//challenge-manager/chain-watcher", "//challenge-manager/edge-tracker", "//challenge-manager/types", "//containers/option", "//layer2-state-provider", + "//runtime", "//solgen/go/challengeV2gen", + "//solgen/go/mocksgen", "//solgen/go/rollupgen", + "//testing", "//testing/mocks", + "//testing/mocks/state-provider", "//testing/setup:setup_lib", "//time", "@com_github_ethereum_go_ethereum//accounts/abi/bind", "@com_github_ethereum_go_ethereum//common", "@com_github_ethereum_go_ethereum//rpc", "@com_github_stretchr_testify//require", + "@org_golang_x_sync//errgroup", ], ) diff --git a/challenge-manager/edge-tracker/tracker.go b/challenge-manager/edge-tracker/tracker.go index aef135815..114380d48 100644 --- a/challenge-manager/edge-tracker/tracker.go +++ b/challenge-manager/edge-tracker/tracker.go @@ -260,7 +260,7 @@ func (et *Tracker) Act(ctx context.Context) error { case EdgeAtOneStepProof: if err := et.submitOneStepProof(ctx); err != nil { fields["err"] = err - srvlog.Trace("Could not submit one step proof", fields) + //srvlog.Trace("Could not submit one step proof", fields) return et.fsm.Do(edgeBackToStart{}) } return et.fsm.Do(edgeConfirm{}) @@ -913,7 +913,7 @@ func (et *Tracker) openSubchallengeLeaf(ctx context.Context) error { func (et *Tracker) submitOneStepProof(ctx context.Context) error { fields := et.uniqueTrackerLogFields() - srvlog.Info("Submitting one-step-proof to protocol", fields) + //srvlog.Info("Submitting one-step-proof to protocol", fields) originHeights, err := et.edge.TopLevelClaimHeight(ctx) if err != nil { return errors.Wrap(err, "could not get top level claim height") diff --git a/challenge-manager/manager_full_challenge_test.go b/challenge-manager/manager_full_challenge_test.go new file mode 100644 index 000000000..35717a684 --- /dev/null +++ b/challenge-manager/manager_full_challenge_test.go @@ -0,0 +1,312 @@ +package challengemanager + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/OffchainLabs/bold/assertions" + protocol "github.com/OffchainLabs/bold/chain-abstraction" + solimpl "github.com/OffchainLabs/bold/chain-abstraction/sol-implementation" + "github.com/OffchainLabs/bold/challenge-manager/types" + l2stateprovider "github.com/OffchainLabs/bold/layer2-state-provider" + retry "github.com/OffchainLabs/bold/runtime" + "github.com/OffchainLabs/bold/solgen/go/mocksgen" + "github.com/OffchainLabs/bold/solgen/go/rollupgen" + challenge_testing "github.com/OffchainLabs/bold/testing" + statemanager "github.com/OffchainLabs/bold/testing/mocks/state-provider" + "github.com/OffchainLabs/bold/testing/setup" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" +) + +func TestFullChallenge_IntegrationTest(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + setup, err := setup.ChainsWithEdgeChallengeManager( + setup.WithMockBridge(), + setup.WithMockOneStepProver(), + setup.WithChallengeTestingOpts( + challenge_testing.WithConfirmPeriodBlocks(25), + challenge_testing.WithLayerZeroHeights(&protocol.LayerZeroHeights{ + BlockChallengeHeight: 64, + BigStepChallengeHeight: 32, + SmallStepChallengeHeight: 32, + }), + ), + ) + require.NoError(t, err) + + bridgeBindings, err := mocksgen.NewBridgeStub(setup.Addrs.Bridge, setup.Backend) + require.NoError(t, err) + + rollupAdminBindings, err := rollupgen.NewRollupAdminLogic(setup.Addrs.Rollup, setup.Backend) + require.NoError(t, err) + _, err = rollupAdminBindings.SetMinimumAssertionPeriod(setup.Accounts[0].TxOpts, big.NewInt(1)) + require.NoError(t, err) + setup.Backend.Commit() + + msgCount, err := bridgeBindings.SequencerMessageCount(&bind.CallOpts{}) + require.NoError(t, err) + require.Equal(t, uint64(1), msgCount.Uint64()) + + genesisHash, err := setup.Chains[1].GenesisAssertionHash(ctx) + require.NoError(t, err) + genesisCreationInfo, err := setup.Chains[1].ReadAssertionCreationInfo(ctx, protocol.AssertionHash{Hash: genesisHash}) + require.NoError(t, err) + _ = genesisCreationInfo + + stateManagerOpts := []statemanager.Opt{ + statemanager.WithNumBatchesRead(5), + } + honestStateManager, err := statemanager.NewForSimpleMachine(stateManagerOpts...) + require.NoError(t, err) + + // Bob diverges from Alice at batch 1. + // assertionDivergenceHeight := uint64(4) + // assertionBlockHeightDifference := int64(4) + stateManagerOpts = append( + stateManagerOpts, + statemanager.WithBlockDivergenceHeight(1), + statemanager.WithMachineDivergenceStep(1), + // statemanager.WithMachineDivergenceStep(machineDivergenceStep), + // statemanager.WithBlockDivergenceHeight(assertionDivergenceHeight), + // statemanager.WithDivergentBlockHeightOffset(assertionBlockHeightDifference), + ) + evilStateManager, err := statemanager.NewForSimpleMachine(stateManagerOpts...) + require.NoError(t, err) + + honestPostState, err := honestStateManager.ExecutionStateAfterBatchCount(ctx, 1) + require.NoError(t, err) + + t.Logf("New stake from alice at post state %+v\n", honestPostState) + honestManager, honestChain := setupChallengeManager( + t, ctx, setup.Backend, setup.Addrs.Rollup, honestStateManager, setup.Accounts[1].TxOpts, "honest", + ) + evilManager, evilChain := setupChallengeManager( + t, ctx, setup.Backend, setup.Addrs.Rollup, evilStateManager, setup.Accounts[2].TxOpts, "evil", + ) + + honestPoster, err := assertions.NewManager( + honestChain, + honestStateManager, + setup.Backend, + honestManager, + setup.Addrs.Rollup, + "honest", + time.Second, + time.Second, + honestStateManager, + time.Second, + time.Millisecond, + ) + require.NoError(t, err) + + evilPoster, err := assertions.NewManager( + evilChain, + evilStateManager, + setup.Backend, + evilManager, + setup.Addrs.Rollup, + "evil", + time.Second, + time.Second, + evilStateManager, + time.Second, + time.Millisecond, + ) + require.NoError(t, err) + + honestAssertion, err := honestPoster.PostAssertion(ctx) + require.NoError(t, err) + + evilAssertion, err := evilPoster.PostAssertion(ctx) + require.NoError(t, err) + _ = honestAssertion + _ = evilAssertion + + err = honestPoster.ProcessAssertionCreationEvent(ctx, honestAssertion.Unwrap().Id()) + require.NoError(t, err) + err = evilPoster.ProcessAssertionCreationEvent(ctx, evilAssertion.Unwrap().Id()) + require.NoError(t, err) + // _ = evilAssertion + + honestManager.Start(ctx) + evilManager.Start(ctx) + + //time.Sleep(time.Minute * 10) + + // Advance the blockchain in the background. + blockTime := time.Millisecond * 100 + go func() { + ticker := time.NewTicker(blockTime) + defer ticker.Stop() + for { + select { + case <-ticker.C: + setup.Backend.Commit() + case <-ctx.Done(): + return + } + } + }() + + expectations := []expect{ + expectAssertionConfirmedByChallengeWin, + } + g, ctx := errgroup.WithContext(ctx) + for _, e := range expectations { + fn := e // loop closure + g.Go(func() error { + return fn(t, ctx, setup.Addrs, setup.Backend) + }) + } + + if err := g.Wait(); err != nil { + t.Fatal(err) + } + + // trackedBackend, ok := aChain.Backend().(*solimpl.TrackedContractBackend) + // if !ok { + // t.Fatal("Not a tracked contract backend") + // } + // t.Log("Printing Alice's ethclient metrics at the end of a challenge") + // trackedBackend.PrintMetrics() +} + +// setupValidator initializes a validator with the minimum required configuration. +func setupChallengeManager( + t *testing.T, + ctx context.Context, + backend protocol.ChainBackend, + rollup common.Address, + sm l2stateprovider.Provider, + txOpts *bind.TransactOpts, + name string, +) (*Manager, protocol.Protocol) { + chain, err := solimpl.NewAssertionChain( + ctx, + rollup, + txOpts, + backend, + //solimpl.WithTrackedContractBackend(), + ) + require.NoError(t, err) + + v, err := New( + ctx, + chain, + backend, + sm, + rollup, + WithAddress(txOpts.From), + WithName(name), + WithEdgeTrackerWakeInterval(time.Millisecond*250), + WithMode(types.MakeMode), + ) + require.NoError(t, err) + return v, chain +} + +func totalWasmOpcodes(heights *protocol.LayerZeroHeights, numBigSteps uint8) uint64 { + totalWasmOpcodes := uint64(1) + for i := uint8(0); i < numBigSteps; i++ { + totalWasmOpcodes *= heights.BigStepChallengeHeight + } + totalWasmOpcodes *= heights.SmallStepChallengeHeight + return totalWasmOpcodes +} + +// expect is a function that will be called asynchronously to verify some success criteria +// for the given scenario. +type expect func(t *testing.T, ctx context.Context, addresses *setup.RollupAddresses, be protocol.ChainBackend) error + +// Expects that an assertion is confirmed by challenge win. +func expectAssertionConfirmedByChallengeWin( + t *testing.T, + ctx context.Context, + addresses *setup.RollupAddresses, + backend protocol.ChainBackend, +) error { + t.Run("assertion confirmed by challenge win", func(t *testing.T) { + rc, err := rollupgen.NewRollupCore(addresses.Rollup, backend) + require.NoError(t, err) + + var confirmed bool + for ctx.Err() == nil && !confirmed { + i, err := retry.UntilSucceeds(ctx, func() (*rollupgen.RollupCoreAssertionConfirmedIterator, error) { + return rc.FilterAssertionConfirmed(nil, nil) + }) + require.NoError(t, err) + for i.Next() { + assertionNode, err := retry.UntilSucceeds(ctx, func() (rollupgen.AssertionNode, error) { + return rc.GetAssertion(&bind.CallOpts{Context: ctx}, i.Event.AssertionHash) + }) + require.NoError(t, err) + if assertionNode.Status != uint8(protocol.AssertionConfirmed) { + t.Fatal("Confirmed assertion with unfinished state") + } + confirmed = true + break + } + time.Sleep(500 * time.Millisecond) // Don't spam the backend. + } + + if !confirmed { + t.Fatal("assertion was not confirmed") + } + }) + return nil +} + +// // expectAliceAndBobStaked monitors EdgeAdded events until Alice and Bob are observed adding edges +// // with a stake. +// func expectAliceAndBobStaked(t *testing.T, ctx context.Context, be backend.Backend) error { +// t.Run("alice and bob staked", func(t *testing.T) { +// ecm, err := retry.UntilSucceeds(ctx, func() (*challengeV2gen.EdgeChallengeManager, error) { +// return edgeManager(be) +// }) +// if err != nil { +// t.Fatal(err) +// } + +// var aliceStaked, bobStaked bool +// for ctx.Err() == nil && (!aliceStaked || !bobStaked) { +// i, err := retry.UntilSucceeds(ctx, func() (*challengeV2gen.EdgeChallengeManagerEdgeAddedIterator, error) { +// return ecm.FilterEdgeAdded(nil, nil, nil, nil) +// }) +// if err != nil { +// t.Fatal(err) +// } +// for i.Next() { +// e, err := retry.UntilSucceeds(ctx, func() (challengeV2gen.ChallengeEdge, error) { +// return ecm.GetEdge(nil, i.Event.EdgeId) +// }) +// if err != nil { +// t.Fatal(err) +// } + +// switch e.Staker { +// case be.Alice().From: +// aliceStaked = true +// case be.Bob().From: +// bobStaked = true +// } + +// time.Sleep(500 * time.Millisecond) // Don't spam the backend. +// } +// } + +// if !aliceStaked { +// t.Error("alice did not stake") +// } +// if !bobStaked { +// t.Error("bob did not stake") +// } +// }) + +// return nil +// } diff --git a/testing/endtoend/BUILD.bazel b/testing/endtoend/BUILD.bazel index 26a723bda..f9b32964d 100644 --- a/testing/endtoend/BUILD.bazel +++ b/testing/endtoend/BUILD.bazel @@ -28,7 +28,7 @@ go_test( "//layer2-state-provider", "//runtime", "//testing", - "//testing/endtoend/internal/backend", + "//testing/endtoend/backend", "//testing/mocks/state-provider", "@com_github_ethereum_go_ethereum//:go-ethereum", "@com_github_ethereum_go_ethereum//accounts/abi/bind", @@ -54,7 +54,7 @@ go_library( "//runtime", "//solgen/go/challengeV2gen", "//solgen/go/rollupgen", - "//testing/endtoend/internal/backend", + "//testing/endtoend/backend", "@com_github_ethereum_go_ethereum//accounts/abi/bind", "@com_github_stretchr_testify//require", ], diff --git a/testing/endtoend/internal/backend/BUILD.bazel b/testing/endtoend/backend/BUILD.bazel similarity index 98% rename from testing/endtoend/internal/backend/BUILD.bazel rename to testing/endtoend/backend/BUILD.bazel index f88a72165..6a5f8890c 100644 --- a/testing/endtoend/internal/backend/BUILD.bazel +++ b/testing/endtoend/backend/BUILD.bazel @@ -7,7 +7,7 @@ go_library( "anvil_local.go", "backend.go", ], - importpath = "github.com/OffchainLabs/bold/testing/endtoend/internal/backend", + importpath = "github.com/OffchainLabs/bold/testing/endtoend/backend", visibility = ["//testing/endtoend:__subpackages__"], deps = [ "//solgen/go/mocksgen", diff --git a/testing/endtoend/internal/backend/anvil_local.go b/testing/endtoend/backend/anvil_local.go similarity index 100% rename from testing/endtoend/internal/backend/anvil_local.go rename to testing/endtoend/backend/anvil_local.go diff --git a/testing/endtoend/internal/backend/anvil_local_test.go b/testing/endtoend/backend/anvil_local_test.go similarity index 100% rename from testing/endtoend/internal/backend/anvil_local_test.go rename to testing/endtoend/backend/anvil_local_test.go diff --git a/testing/endtoend/internal/backend/backend.go b/testing/endtoend/backend/backend.go similarity index 100% rename from testing/endtoend/internal/backend/backend.go rename to testing/endtoend/backend/backend.go diff --git a/testing/endtoend/basic_local_test.go b/testing/endtoend/basic_local_test.go index a27928f16..3cbfb5d0c 100644 --- a/testing/endtoend/basic_local_test.go +++ b/testing/endtoend/basic_local_test.go @@ -17,7 +17,7 @@ import ( l2stateprovider "github.com/OffchainLabs/bold/layer2-state-provider" retry "github.com/OffchainLabs/bold/runtime" challenge_testing "github.com/OffchainLabs/bold/testing" - "github.com/OffchainLabs/bold/testing/endtoend/internal/backend" + "github.com/OffchainLabs/bold/testing/endtoend/backend" statemanager "github.com/OffchainLabs/bold/testing/mocks/state-provider" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" diff --git a/testing/endtoend/expect.go b/testing/endtoend/expect.go index 54a517243..21912b289 100644 --- a/testing/endtoend/expect.go +++ b/testing/endtoend/expect.go @@ -12,7 +12,7 @@ import ( retry "github.com/OffchainLabs/bold/runtime" "github.com/OffchainLabs/bold/solgen/go/challengeV2gen" "github.com/OffchainLabs/bold/solgen/go/rollupgen" - "github.com/OffchainLabs/bold/testing/endtoend/internal/backend" + "github.com/OffchainLabs/bold/testing/endtoend/backend" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" ) diff --git a/testing/endtoend/helpers.go b/testing/endtoend/helpers.go index 3e4eaf974..bac324196 100644 --- a/testing/endtoend/helpers.go +++ b/testing/endtoend/helpers.go @@ -7,7 +7,7 @@ package endtoend import ( "github.com/OffchainLabs/bold/solgen/go/challengeV2gen" "github.com/OffchainLabs/bold/solgen/go/rollupgen" - "github.com/OffchainLabs/bold/testing/endtoend/internal/backend" + "github.com/OffchainLabs/bold/testing/endtoend/backend" ) // edgeManager fetches the challenge manager contract address from the rollup contract and returns diff --git a/tools/fund-weth/BUILD.bazel b/tools/fund-weth/BUILD.bazel deleted file mode 100644 index 160804d3d..000000000 --- a/tools/fund-weth/BUILD.bazel +++ /dev/null @@ -1,28 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") - -go_library( - name = "fund-weth_lib", - srcs = ["main.go"], - testonly = True, - importpath = "github.com/OffchainLabs/bold/tools/fund-weth", - visibility = ["//visibility:private"], - deps = [ - "//runtime", - "//solgen/go/mocksgen", - "//solgen/go/rollupgen", - "//testing", - "@com_github_ethereum_go_ethereum//accounts/abi/bind", - "@com_github_ethereum_go_ethereum//common", - "@com_github_ethereum_go_ethereum//crypto", - "@com_github_ethereum_go_ethereum//ethclient", - "@com_github_ethereum_go_ethereum//params", - "@com_github_ethereum_go_ethereum//rpc", - ], -) - -go_binary( - name = "fund-weth", - testonly = True, - embed = [":fund-weth_lib"], - visibility = ["//visibility:public"], -) diff --git a/tools/fund-weth/main.go b/tools/fund-weth/main.go deleted file mode 100644 index 4a5911201..000000000 --- a/tools/fund-weth/main.go +++ /dev/null @@ -1,127 +0,0 @@ -package main - -import ( - "context" - "flag" - "fmt" - "math/big" - "strings" - - retry "github.com/OffchainLabs/bold/runtime" - "github.com/OffchainLabs/bold/solgen/go/mocksgen" - "github.com/OffchainLabs/bold/solgen/go/rollupgen" - challenge_testing "github.com/OffchainLabs/bold/testing" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rpc" -) - -var ( - valPrivKeys = flag.String("validator-priv-keys", "", "comma-separated, validator private keys to fund and approve mock ERC20 stake token") - l1ChainIdStr = flag.String("l1-chain-id", "11155111", "l1 chain id (sepolia default)") - l1EndpointUrl = flag.String("l1-endpoint", "", "l1 endpoint") - rollupAddrStr = flag.String("rollup-address", "", "rollup address") - stakeTokenAddrStr = flag.String("stake-token-address", "", "rollup address") - gweiToDeposit = flag.Uint64("gwei-to-deposit", 10_000, "tokens to deposit") -) - -func main() { - flag.Parse() - ctx := context.Background() - endpoint, err := rpc.DialContext(ctx, *l1EndpointUrl) - if err != nil { - panic(err) - } - client := ethclient.NewClient(endpoint) - l1ChainId, ok := new(big.Int).SetString(*l1ChainIdStr, 10) - if !ok { - panic("not big int") - } - if *valPrivKeys == "" { - panic("no validator private keys set") - } - privKeyStrings := strings.Split(*valPrivKeys, ",") - for _, privKeyStr := range privKeyStrings { - validatorPrivateKey, err := crypto.HexToECDSA(privKeyStr) - if err != nil { - panic(err) - } - txOpts, err := bind.NewKeyedTransactorWithChainID(validatorPrivateKey, l1ChainId) - if err != nil { - panic(err) - } - - rollupAddr := common.HexToAddress(*rollupAddrStr) - rollupBindings, err := rollupgen.NewRollupUserLogicCaller(rollupAddr, client) - if err != nil { - panic(err) - } - chalManagerAddr, err := rollupBindings.ChallengeManager(&bind.CallOpts{}) - if err != nil { - panic(err) - } - stakeTokenAddr := common.HexToAddress(*stakeTokenAddrStr) - - tokenBindings, err := mocksgen.NewTestWETH9(stakeTokenAddr, client) - if err != nil { - panic(err) - } - allow, err := tokenBindings.Allowance(&bind.CallOpts{}, txOpts.From, rollupAddr) - if err != nil { - panic(err) - } - fmt.Printf("Addr %#x gave rollup %#x allowance of %#x\n", txOpts.From, rollupAddr, allow.Bytes()) - - allow, err = tokenBindings.Allowance(&bind.CallOpts{}, txOpts.From, chalManagerAddr) - if err != nil { - panic(err) - } - fmt.Printf("Addr %#x gave chal manager addr %#x allowance of %#x\n", txOpts.From, chalManagerAddr, allow.Bytes()) - - depositAmount := new(big.Int).SetUint64(*gweiToDeposit * params.GWei) - txOpts.Value = depositAmount - if _, err = retry.UntilSucceeds[bool](ctx, func() (bool, error) { - tx, err2 := tokenBindings.Deposit(txOpts) - if err2 != nil { - return false, err2 - } - if err2 = challenge_testing.WaitForTx(ctx, client, tx); err2 != nil { - return false, err2 - } - return true, nil - }); err != nil { - panic(err) - } - txOpts.Value = big.NewInt(0) - maxUint256 := new(big.Int) - maxUint256.Exp(big.NewInt(2), big.NewInt(256), nil).Sub(maxUint256, big.NewInt(1)) - if _, err = retry.UntilSucceeds[bool](ctx, func() (bool, error) { - tx, err2 := tokenBindings.Approve(txOpts, rollupAddr, maxUint256) - if err2 != nil { - return false, err2 - } - if err2 = challenge_testing.WaitForTx(ctx, client, tx); err2 != nil { - return false, err2 - } - return true, nil - }); err != nil { - panic(err) - } - if _, err = retry.UntilSucceeds[bool](ctx, func() (bool, error) { - tx, err2 := tokenBindings.Approve(txOpts, chalManagerAddr, maxUint256) - if err2 != nil { - return false, err2 - } - if err2 = challenge_testing.WaitForTx(ctx, client, tx); err2 != nil { - return false, err2 - } - return true, nil - }); err != nil { - panic(err) - } - - } -}