package integration_test import ( "context" "log" "math/big" "testing" "time" "github.com/scroll-tech/go-ethereum/common" gethTypes "github.com/scroll-tech/go-ethereum/core/types" "github.com/stretchr/testify/assert" "gorm.io/gorm" "scroll-tech/common/testcontainers" "scroll-tech/common/types/encoding" "scroll-tech/common/utils" "scroll-tech/common/version" capp "scroll-tech/coordinator/cmd/api/app" "scroll-tech/database/migrate" "scroll-tech/integration-test/orm" rapp "scroll-tech/prover/cmd/app" bcmd "scroll-tech/rollup/cmd" ) var ( testApps *testcontainers.TestcontainerApps rollupApp *bcmd.MockApp ) func TestMain(m *testing.M) { defer func() { if testApps != nil { testApps.Free() } if rollupApp != nil { rollupApp.Free() } }() m.Run() } func setupEnv(t *testing.T) { testApps = testcontainers.NewTestcontainerApps() assert.NoError(t, testApps.StartPostgresContainer()) assert.NoError(t, testApps.StartL1GethContainer()) assert.NoError(t, testApps.StartL2GethContainer()) rollupApp = bcmd.NewRollupApp(testApps, "../../rollup/conf/config.json") } func TestFunction(t *testing.T) { setupEnv(t) t.Run("TestCoordinatorProverInteraction", testCoordinatorProverInteraction) t.Run("TestProverReLogin", testProverReLogin) t.Run("TestERC20", testERC20) t.Run("TestGreeter", testGreeter) } func setupDB(t *testing.T) *gorm.DB { db, err := testApps.GetGormDBClient() assert.NoError(t, err) sqlDB, err := db.DB() assert.NoError(t, err) assert.NoError(t, migrate.ResetDB(sqlDB)) return db } func testCoordinatorProverInteraction(t *testing.T) { db := setupDB(t) sqlDB, err := db.DB() assert.NoError(t, err) assert.NoError(t, migrate.ResetDB(sqlDB)) batchOrm := orm.NewBatch(db) chunkOrm := orm.NewChunk(db) l2BlockOrm := orm.NewL2Block(db) // Connect to l2geth client l2Client, err := testApps.GetL2GethClient() if err != nil { log.Fatalf("Failed to connect to the l2geth client: %v", err) } var header *gethTypes.Header success := utils.TryTimes(10, func() bool { header, err = l2Client.HeaderByNumber(context.Background(), big.NewInt(1)) if err != nil { log.Printf("Failed to retrieve L2 genesis header: %v. Retrying...", err) return false } return true }) if !success { log.Fatalf("Failed to retrieve L2 genesis header after multiple attempts: %v", err) } block := &encoding.Block{ Header: header, Transactions: nil, WithdrawRoot: common.Hash{}, RowConsumption: &gethTypes.RowConsumption{}, } chunk := &encoding.Chunk{Blocks: []*encoding.Block{block}} batch := &encoding.Batch{ Index: 0, TotalL1MessagePoppedBefore: 0, ParentBatchHash: common.Hash{}, Chunks: []*encoding.Chunk{chunk}, } err = l2BlockOrm.InsertL2Blocks(context.Background(), []*encoding.Block{block}) assert.NoError(t, err) dbChunk, err := chunkOrm.InsertChunk(context.Background(), chunk) assert.NoError(t, err) err = l2BlockOrm.UpdateChunkHashInRange(context.Background(), 0, 100, dbChunk.Hash) assert.NoError(t, err) dbBatch, err := batchOrm.InsertBatch(context.Background(), batch) assert.NoError(t, err) err = chunkOrm.UpdateBatchHashInRange(context.Background(), 0, 0, dbBatch.Hash) assert.NoError(t, err) t.Log(version.Version) coordinatorApp := capp.NewCoordinatorApp(testApps, "../../coordinator/conf/config.json", "./genesis.json") chunkProverApp := rapp.NewProverApp(testApps, utils.ChunkProverApp, "../../prover/config.json", coordinatorApp.HTTPEndpoint()) batchProverApp := rapp.NewProverApp(testApps, utils.BatchProverApp, "../../prover/config.json", coordinatorApp.HTTPEndpoint()) defer coordinatorApp.Free() defer chunkProverApp.Free() defer batchProverApp.Free() // Run coordinator app. coordinatorApp.RunApp(t) // Run prover app. chunkProverApp.ExpectWithTimeout(t, true, time.Second*40, "proof submitted successfully") // chunk prover login -> get task -> submit proof. batchProverApp.ExpectWithTimeout(t, true, time.Second*40, "proof submitted successfully") // batch prover login -> get task -> submit proof. // All task has been proven, coordinator would not return any task. chunkProverApp.ExpectWithTimeout(t, true, 60*time.Second, "get empty prover task") batchProverApp.ExpectWithTimeout(t, true, 60*time.Second, "get empty prover task") chunkProverApp.RunApp(t) batchProverApp.RunApp(t) // Free apps. chunkProverApp.WaitExit() batchProverApp.WaitExit() coordinatorApp.WaitExit() } func testProverReLogin(t *testing.T) { client, err := testApps.GetGormDBClient() assert.NoError(t, err) db, err := client.DB() assert.NoError(t, err) assert.NoError(t, migrate.ResetDB(db)) coordinatorApp := capp.NewCoordinatorApp(testApps, "../../coordinator/conf/config.json", "./genesis.json") chunkProverApp := rapp.NewProverApp(testApps, utils.ChunkProverApp, "../../prover/config.json", coordinatorApp.HTTPEndpoint()) batchProverApp := rapp.NewProverApp(testApps, utils.BatchProverApp, "../../prover/config.json", coordinatorApp.HTTPEndpoint()) defer coordinatorApp.Free() defer chunkProverApp.Free() defer batchProverApp.Free() // Run coordinator app. coordinatorApp.RunApp(t) // login timeout: 1 sec // Run prover app. chunkProverApp.ExpectWithTimeout(t, true, time.Second*40, "re-login success") // chunk prover login. batchProverApp.ExpectWithTimeout(t, true, time.Second*40, "re-login success") // batch prover login. chunkProverApp.RunApp(t) batchProverApp.RunApp(t) // Free apps. chunkProverApp.WaitExit() batchProverApp.WaitExit() coordinatorApp.WaitExit() }