Skip to content
This repository was archived by the owner on Oct 20, 2024. It is now read-only.

Commit 9278227

Browse files
authored
Add CI pipeline for test and lint (#64)
1 parent bf3bdb2 commit 9278227

File tree

7 files changed

+164
-14
lines changed

7 files changed

+164
-14
lines changed

.github/workflows/pipeline.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: CI Pipeline
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v3
16+
17+
- name: Set up Go
18+
uses: actions/setup-go@v3
19+
with:
20+
go-version: 1.19
21+
cache: true
22+
23+
- name: Install dependencies
24+
run: go get .
25+
26+
- name: Build
27+
run: go build -v ./...
28+
29+
- name: Test
30+
run: go test -v ./...
31+
lint:
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@v3
35+
36+
- name: Set up Go
37+
uses: actions/setup-go@v3
38+
with:
39+
go-version: 1.19
40+
cache: true
41+
42+
- name: Lint
43+
uses: golangci/golangci-lint-action@v3

cmd/start.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ var mode string
2828
func init() {
2929
rootCmd.AddCommand(startCmd)
3030
startCmd.Flags().StringVarP(&mode, "mode", "m", "", "Required. See acceptable values above.")
31-
startCmd.MarkFlagRequired("mode")
32-
viper.BindPFlag("mode", startCmd.Flags().Lookup("mode"))
31+
if err := startCmd.MarkFlagRequired("mode"); err != nil {
32+
panic(err)
33+
}
34+
if err := viper.BindPFlag("mode", startCmd.Flags().Lookup("mode")); err != nil {
35+
panic(err)
36+
}
3337
}

internal/config/values.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,30 @@ func GetValues() *Values {
6161
}
6262

6363
// Read in from environment variables
64-
viper.BindEnv("erc4337_bundler_eth_client_url")
65-
viper.BindEnv("erc4337_bundler_private_key")
66-
viper.BindEnv("erc4337_bundler_port")
67-
viper.BindEnv("erc4337_bundler_data_directory")
68-
viper.BindEnv("erc4337_bundler_supported_entry_points")
69-
viper.BindEnv("erc4337_bundler_beneficiary")
70-
viper.BindEnv("erc4337_bundler_max_verification_gas")
71-
viper.BindEnv("erc4337_bundler_gin_mode")
64+
if err := viper.BindEnv("erc4337_bundler_eth_client_url"); err != nil {
65+
panic(err)
66+
}
67+
if err := viper.BindEnv("erc4337_bundler_private_key"); err != nil {
68+
panic(err)
69+
}
70+
if err := viper.BindEnv("erc4337_bundler_port"); err != nil {
71+
panic(err)
72+
}
73+
if err := viper.BindEnv("erc4337_bundler_data_directory"); err != nil {
74+
panic(err)
75+
}
76+
if err := viper.BindEnv("erc4337_bundler_supported_entry_points"); err != nil {
77+
panic(err)
78+
}
79+
if err := viper.BindEnv("erc4337_bundler_beneficiary"); err != nil {
80+
panic(err)
81+
}
82+
if err := viper.BindEnv("erc4337_bundler_max_verification_gas"); err != nil {
83+
panic(err)
84+
}
85+
if err := viper.BindEnv("erc4337_bundler_gin_mode"); err != nil {
86+
panic(err)
87+
}
7288

7389
// Validate required variables
7490
if !viper.IsSet("erc4337_bundler_eth_client_url") || viper.GetString("erc4337_bundler_eth_client_url") == "" {

internal/start/private.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,21 @@ func PrivateMode() {
9999
relayer.SendUserOperation(),
100100
paymaster.IncOpsIncluded(),
101101
)
102-
b.Run()
102+
if err := b.Run(); err != nil {
103+
log.Fatal(err)
104+
}
103105

104106
// Init HTTP server
105107
gin.SetMode(conf.GinMode)
106108
r := gin.New()
109+
if err := r.SetTrustedProxies(nil); err != nil {
110+
log.Fatal(err)
111+
}
107112
r.Use(
108113
cors.Default(),
109114
logger.WithLogr(logr),
110115
gin.Recovery(),
111116
)
112-
r.SetTrustedProxies(nil)
113117
r.GET("/ping", func(g *gin.Context) {
114118
g.Status(http.StatusOK)
115119
})
@@ -119,5 +123,7 @@ func PrivateMode() {
119123
jsonrpc.Controller(client.NewRpcAdapter(c)),
120124
relayer.MapUserOpHashToClientID(),
121125
)
122-
r.Run(fmt.Sprintf(":%d", conf.Port))
126+
if err := r.Run(fmt.Sprintf(":%d", conf.Port)); err != nil {
127+
log.Fatal(err)
128+
}
123129
}

internal/testutils/ethmock.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package testutils
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"net/http/httptest"
8+
)
9+
10+
type mockReq struct {
11+
JsonRpc string `json:"jsonrpc"`
12+
ID float64 `json:"id"`
13+
Method string `json:"method"`
14+
}
15+
16+
type mockRes struct {
17+
JsonRpc string `json:"jsonrpc"`
18+
ID float64 `json:"id"`
19+
Result any `json:"result"`
20+
}
21+
22+
type MethodMocks map[string]any
23+
24+
// EthMock returns a httptest.Server for mocking the return value of a JSON-RPC method call to an Ethereum node.
25+
func EthMock(mocks MethodMocks) *httptest.Server {
26+
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
27+
var req mockReq
28+
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
29+
panic(err)
30+
}
31+
32+
mock, ok := mocks[req.Method]
33+
if !ok {
34+
w.WriteHeader(http.StatusBadRequest)
35+
if _, err := w.Write([]byte(fmt.Sprintf("method not in mocks: %s", req.Method))); err != nil {
36+
panic(err)
37+
}
38+
return
39+
}
40+
41+
res := &mockRes{
42+
JsonRpc: req.JsonRpc,
43+
ID: req.ID,
44+
Result: mock,
45+
}
46+
w.WriteHeader(http.StatusOK)
47+
if err := json.NewEncoder(w).Encode(res); err != nil {
48+
panic(err)
49+
}
50+
}))
51+
}

pkg/mempool/db.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ func getEntryPointAndSenderFromDBKey(key []byte) (common.Address, common.Address
2626

2727
func getUserOpFromDBValue(value []byte) (*userop.UserOperation, error) {
2828
data := make(map[string]any)
29-
json.Unmarshal(value, &data)
29+
if err := json.Unmarshal(value, &data); err != nil {
30+
return nil, err
31+
}
32+
3033
op, err := userop.New(data)
3134
if err != nil {
3235
return nil, err
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package checks
2+
3+
import (
4+
"testing"
5+
6+
"github.com/ethereum/go-ethereum/common"
7+
"github.com/ethereum/go-ethereum/ethclient"
8+
"github.com/stackup-wallet/stackup-bundler/internal/testutils"
9+
"github.com/stackup-wallet/stackup-bundler/pkg/userop"
10+
)
11+
12+
// TestCheckSender calls checks.CheckSender where sender is existing contract and initCode is empty
13+
func TestCheckSender(t *testing.T) {
14+
server := testutils.EthMock(testutils.MethodMocks{
15+
"eth_getCode": "0x1234",
16+
})
17+
defer server.Close()
18+
19+
eth, _ := ethclient.Dial(server.URL)
20+
op := &userop.UserOperation{
21+
Sender: common.HexToAddress("0x"),
22+
InitCode: common.Hex2Bytes("0x"),
23+
}
24+
if err := checkSender(eth, op); err != nil {
25+
t.Fatalf(`got err %v, want nil`, err)
26+
}
27+
}

0 commit comments

Comments
 (0)