Skip to content

Commit

Permalink
happy path integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
colinlyguo committed Aug 4, 2023
1 parent 7235506 commit e3a49fc
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 45 deletions.
1 change: 1 addition & 0 deletions coordinator/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"os"
"path/filepath"

"scroll-tech/common/database"
)

Expand Down
5 changes: 4 additions & 1 deletion prover/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ type GetTaskResponse struct {

// SubmitProofRequest defines the request structure for the SubmitProof API.
type SubmitProofRequest struct {
Message message.ProofDetail `json:"message"`
TaskID string `json:"task_id"`
TaskType int `json:"task_type"`
Status int `json:"status"`
Proof string `json:"proof"`
}

// SubmitProofResponse defines the response structure for the SubmitProof API.
Expand Down
7 changes: 7 additions & 0 deletions prover/cmd/app/mock_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ func (r *ProverApp) RunApp(t *testing.T, args ...string) {
r.AppAPI.RunApp(func() bool { return r.AppAPI.WaitResult(t, time.Second*40, "prover start successfully") })
}

// RunAppWithExpectedResult runs the prover-test child process with multiple parameters,
// and checks for a specific expected result in the output.
func (r *ProverApp) RunAppWithExpectedResult(t *testing.T, expectedResult string, args ...string) {
r.AppAPI = cmd.NewCmd(r.name, append(r.args, args...)...)
r.AppAPI.RunApp(func() bool { return r.AppAPI.WaitResult(t, time.Second*40, expectedResult) })
}

// Free stop and release prover-test.
func (r *ProverApp) Free() {
if !utils.IsNil(r.AppAPI) {
Expand Down
43 changes: 33 additions & 10 deletions prover/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (r *Prover) proveAndSubmit() error {
}

// Push the new task into the stack
if err := r.stack.Push(task); err != nil {
if err = r.stack.Push(task); err != nil {
return fmt.Errorf("failed to push task into stack: %v", err)
}
}
Expand Down Expand Up @@ -211,12 +211,12 @@ func (r *Prover) fetchTaskFromCoordinator() (*store.ProvingTask, error) {
switch taskMsg.Type {
case message.ProofTypeBatch:
taskMsg.BatchTaskDetail = &message.BatchTaskDetail{}
if err := json.Unmarshal([]byte(resp.Data.TaskData), taskMsg.BatchTaskDetail); err != nil {
if err = json.Unmarshal([]byte(resp.Data.TaskData), taskMsg.BatchTaskDetail); err != nil {
return nil, fmt.Errorf("failed to unmarshal batch task detail: %v", err)
}
case message.ProofTypeChunk:
taskMsg.ChunkTaskDetail = &message.ChunkTaskDetail{}
if err := json.Unmarshal([]byte(resp.Data.TaskData), taskMsg.ChunkTaskDetail); err != nil {
if err = json.Unmarshal([]byte(resp.Data.TaskData), taskMsg.ChunkTaskDetail); err != nil {
return nil, fmt.Errorf("failed to unmarshal chunk task detail: %v", err)
}
default:
Expand All @@ -230,12 +230,12 @@ func (r *Prover) fetchTaskFromCoordinator() (*store.ProvingTask, error) {
}

// marshal the task to a json string for logging
taskJson, err := json.Marshal(provingTask)
taskJSON, err := json.Marshal(provingTask)
if err != nil {
return nil, fmt.Errorf("failed to marshal task to json: %v", err)
}

log.Info("successfully fetched new task from coordinator", "resp", resp, "task", string(taskJson))
log.Info("successfully fetched new task from coordinator", "resp", resp, "task", string(taskJSON))

return provingTask, nil
}
Expand Down Expand Up @@ -280,34 +280,56 @@ func (r *Prover) prove(task *store.ProvingTask) (detail *message.ProofDetail) {

func (r *Prover) proveChunk(task *store.ProvingTask) (*message.ChunkProof, error) {
if task.Task.ChunkTaskDetail == nil {
return nil, errors.New("ChunkTaskDetail is empty")
return nil, fmt.Errorf("ChunkTaskDetail is empty")
}
traces, err := r.getSortedTracesByHashes(task.Task.ChunkTaskDetail.BlockHashes)
if err != nil {
return nil, errors.New("get traces from eth node failed")
return nil, fmt.Errorf("get traces from eth node failed, block hashes: %v", task.Task.ChunkTaskDetail.BlockHashes)
}
return r.proverCore.ProveChunk(task.Task.ID, traces)
}

func (r *Prover) proveBatch(task *store.ProvingTask) (*message.BatchProof, error) {
if task.Task.BatchTaskDetail == nil {
return nil, errors.New("BatchTaskDetail is empty")
return nil, fmt.Errorf("BatchTaskDetail is empty")
}
return r.proverCore.ProveBatch(task.Task.ID, task.Task.BatchTaskDetail.ChunkInfos, task.Task.BatchTaskDetail.ChunkProofs)
}

func (r *Prover) submitProof(msg *message.ProofDetail) error {
// prepare the submit request
req := &client.SubmitProofRequest{
Message: *msg,
TaskID: msg.ID,
TaskType: int(msg.Type),
Status: int(msg.Status),
}

// marshal proof by tasktype
switch msg.Type {
case message.ProofTypeChunk:
if msg.ChunkProof != nil {
proofData, err := json.Marshal(msg.ChunkProof)
if err != nil {
return fmt.Errorf("error marshaling chunk proof: %v", err)
}
req.Proof = string(proofData)
}
case message.ProofTypeBatch:
if msg.BatchProof != nil {
proofData, err := json.Marshal(msg.BatchProof)
if err != nil {
return fmt.Errorf("error marshaling batch proof: %v", err)
}
req.Proof = string(proofData)
}
}

// send the submit request
if err := r.coordinatorClient.SubmitProof(r.ctx, req); err != nil {
return fmt.Errorf("error submitting proof: %v", err)
}

log.Debug("proof submitted successfully", "task-id", msg.ID)
log.Info("proof submitted successfully", "task-id", msg.ID, "task-type", msg.Type, "task-status", msg.Status, "err", msg.Error)
return nil
}

Expand All @@ -324,6 +346,7 @@ func (r *Prover) getSortedTracesByHashes(blockHashes []common.Hash) ([]*types.Bl
}
traces = append(traces, trace)
}

// Sort BlockTraces by header number.
sort.Slice(traces, func(i, j int) bool {
return traces[i].Header.Number.Int64() < traces[j].Header.Number.Int64()
Expand Down
2 changes: 1 addition & 1 deletion prover/store/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (s *Stack) UpdateTimes(task *ProvingTask, updateTimes int) error {
task.Times = updateTimes
byt, err := json.Marshal(task)
if err != nil {
return fmt.Errorf("error marshalling task: %v", err)
return fmt.Errorf("error marshaling task: %v", err)
}
key := []byte(task.Task.ID)
return s.Update(func(tx *bbolt.Tx) error {
Expand Down
3 changes: 3 additions & 0 deletions tests/integration-test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.19
require (
github.com/scroll-tech/go-ethereum v1.10.14-0.20230804022247-26eeb40ea3ca
github.com/stretchr/testify v1.8.3
gorm.io/gorm v1.25.2
)

require (
Expand All @@ -19,6 +20,8 @@ require (
github.com/gorilla/websocket v1.5.0 // indirect
github.com/holiman/uint256 v1.2.3 // indirect
github.com/iden3/go-iden3-crypto v0.0.15 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions tests/integration-test/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4=
github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand Down Expand Up @@ -104,3 +106,4 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
63 changes: 30 additions & 33 deletions tests/integration-test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package integration_test

import (
"context"
"log"
"math/big"
"testing"
"time"
Expand All @@ -11,6 +12,7 @@ import (
"github.com/stretchr/testify/assert"

"scroll-tech/integration-test/orm"

rapp "scroll-tech/prover/cmd/app"

"scroll-tech/database/migrate"
Expand All @@ -21,6 +23,7 @@ import (
"scroll-tech/common/docker"
"scroll-tech/common/types"
"scroll-tech/common/types/message"
"scroll-tech/common/utils"

bcmd "scroll-tech/bridge/cmd"
)
Expand All @@ -47,30 +50,7 @@ func TestMain(m *testing.M) {
base.Free()
}

func TestCoordinatorProverInteractionWithoutData(t *testing.T) {
// Start postgres docker containers.
base.RunL2Geth(t)
base.RunDBImage(t)
// Reset db.
assert.NoError(t, migrate.ResetDB(base.DBClient(t)))

// Run coordinator app.
coordinatorApp.RunApp(t)

// Run prover app.
chunkProverApp.RunApp(t) // chunk prover login.
batchProverApp.RunApp(t) // batch prover login.

chunkProverApp.ExpectWithTimeout(t, true, 60*time.Second, "get empty prover task") // get prover task without data.
batchProverApp.ExpectWithTimeout(t, true, 60*time.Second, "get empty prover task") // get prover task without data.

// Free apps.
chunkProverApp.WaitExit()
batchProverApp.WaitExit()
coordinatorApp.WaitExit()
}

func TestCoordinatorProverInteractionWithData(t *testing.T) {
func TestCoordinatorProverInteraction(t *testing.T) {
// Start postgres docker containers.
base.RunL2Geth(t)
base.RunDBImage(t)
Expand All @@ -94,13 +74,28 @@ func TestCoordinatorProverInteractionWithData(t *testing.T) {
chunkOrm := orm.NewChunk(db)
l2BlockOrm := orm.NewL2Block(db)

// Connect to l2geth client
l2Client, err := base.L2Client()
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)
}

wrappedBlock := &types.WrappedBlock{
Header: &gethTypes.Header{
Number: big.NewInt(1),
ParentHash: common.Hash{},
Difficulty: big.NewInt(0),
BaseFee: big.NewInt(0),
},
Header: header,
Transactions: nil,
WithdrawRoot: common.Hash{},
RowConsumption: &gethTypes.RowConsumption{},
Expand All @@ -122,10 +117,12 @@ func TestCoordinatorProverInteractionWithData(t *testing.T) {
coordinatorApp.RunApp(t)

// Run prover app.
chunkProverApp.RunApp(t) // chunk prover login.
batchProverApp.RunApp(t) // batch prover login.
chunkProverApp.RunAppWithExpectedResult(t, "proof submitted successfully") // chunk prover login -> get task -> submit proof.
batchProverApp.RunAppWithExpectedResult(t, "proof submitted successfully") // batch prover login -> get task -> submit proof.

time.Sleep(60 * time.Second) // TODO(colinlyguo): replace time.Sleep(60 * time.Second) with expected results.
// All task has been proven, coordinator would not return any task.
chunkProverApp.ExpectWithTimeout(t, false, 60*time.Second, "get empty prover task")
batchProverApp.ExpectWithTimeout(t, false, 60*time.Second, "get empty prover task")

// Free apps.
chunkProverApp.WaitExit()
Expand Down

0 comments on commit e3a49fc

Please sign in to comment.