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

Commit 7a91dd3

Browse files
authored
Return null if userOpHash is valid but cannot be found on-chain (#362)
1 parent 2b27eee commit 7a91dd3

File tree

5 files changed

+102
-15
lines changed

5 files changed

+102
-15
lines changed

pkg/client/utils.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package client
22

33
import (
4-
"errors"
54
"math/big"
65

76
"github.com/ethereum/go-ethereum/common"
@@ -20,8 +19,7 @@ type GetUserOpReceiptFunc = func(hash string, ep common.Address) (*filter.UserOp
2019

2120
func getUserOpReceiptNoop() GetUserOpReceiptFunc {
2221
return func(hash string, ep common.Address) (*filter.UserOperationReceipt, error) {
23-
//lint:ignore ST1005 This needs to match the bundler test spec.
24-
return nil, errors.New("Missing/invalid userOpHash")
22+
return nil, nil
2523
}
2624
}
2725

@@ -67,8 +65,7 @@ func getGasEstimateNoop() GetGasEstimateFunc {
6765
op *userop.UserOperation,
6866
sos state.OverrideSet,
6967
) (verificationGas uint64, callGas uint64, err error) {
70-
//lint:ignore ST1005 This needs to match the bundler test spec.
71-
return 0, 0, errors.New("Missing/invalid userOpHash")
68+
return 0, 0, nil
7269
}
7370
}
7471

@@ -103,8 +100,7 @@ type GetUserOpByHashFunc func(hash string, ep common.Address, chain *big.Int) (*
103100

104101
func getUserOpByHashNoop() GetUserOpByHashFunc {
105102
return func(hash string, ep common.Address, chain *big.Int) (*filter.HashLookupResult, error) {
106-
//lint:ignore ST1005 This needs to match the bundler test spec.
107-
return nil, errors.New("Missing/invalid userOpHash")
103+
return nil, nil
108104
}
109105
}
110106

pkg/entrypoint/filter/hash.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package filter
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
)
8+
9+
var (
10+
userOpHashStrLen = 64
11+
userOpHashRegex = regexp.MustCompile(fmt.Sprintf("(?i)0x[0-9a-f]{%d}", userOpHashStrLen))
12+
)
13+
14+
func IsValidUserOpHash(userOpHash string) bool {
15+
return len(strings.TrimPrefix(strings.ToLower(userOpHash), "0x")) == userOpHashStrLen &&
16+
userOpHashRegex.MatchString(userOpHash)
17+
}

pkg/entrypoint/filter/hash_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package filter
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
"github.com/stackup-wallet/stackup-bundler/internal/testutils"
8+
)
9+
10+
func TestIsValidUserOpHash(t *testing.T) {
11+
if ok := IsValidUserOpHash(testutils.MockHash); !ok {
12+
t.Fatalf("%s: got false, want true", testutils.MockHash)
13+
}
14+
15+
allNumHash := strings.ReplaceAll(testutils.MockHash, "dead", "0101")
16+
if ok := IsValidUserOpHash(allNumHash); !ok {
17+
t.Fatalf("%s: got false, want true", allNumHash)
18+
}
19+
}
20+
21+
func TestIsValidUserOpHashAllCaps(t *testing.T) {
22+
hash := strings.ToUpper(testutils.MockHash)
23+
if ok := IsValidUserOpHash(hash); !ok {
24+
t.Fatalf("%s: got false, want true", hash)
25+
}
26+
}
27+
28+
func TestIsValidUserOpHashEmptyString(t *testing.T) {
29+
hash := ""
30+
if ok := IsValidUserOpHash(hash); ok {
31+
t.Fatalf("%s: got true, want false", hash)
32+
}
33+
}
34+
35+
func TestIsValidUserOpHashEmptyHexString(t *testing.T) {
36+
hash := "0x"
37+
if ok := IsValidUserOpHash(hash); ok {
38+
t.Fatalf("%s: got true, want false", hash)
39+
}
40+
}
41+
42+
func TestIsValidUserOpHashNoPrefix(t *testing.T) {
43+
hash := strings.TrimPrefix(testutils.MockHash, "0x")
44+
if ok := IsValidUserOpHash(hash); ok {
45+
t.Fatalf("%s: got true, want false", hash)
46+
}
47+
}
48+
49+
func TestIsValidUserOpHashTooShort(t *testing.T) {
50+
hash := "0xdead"
51+
if ok := IsValidUserOpHash(hash); ok {
52+
t.Fatalf("%s: got true, want false", hash)
53+
}
54+
}
55+
56+
func TestIsValidUserOpHashTooLong(t *testing.T) {
57+
hash := testutils.MockHash + "dead"
58+
if ok := IsValidUserOpHash(hash); ok {
59+
t.Fatalf("%s: got true, want false", hash)
60+
}
61+
}
62+
63+
func TestIsValidUserOpHashInvalidChar(t *testing.T) {
64+
hash := strings.ReplaceAll(testutils.MockHash, "dead", "zzzz")
65+
if ok := IsValidUserOpHash(hash); ok {
66+
t.Fatalf("%s: got true, want false", hash)
67+
}
68+
}

pkg/entrypoint/filter/opbyhash.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ func GetUserOperationByHash(
3131
entryPoint common.Address,
3232
chainID *big.Int,
3333
) (*HashLookupResult, error) {
34+
if !IsValidUserOpHash(userOpHash) {
35+
//lint:ignore ST1005 This needs to match the bundler test spec.
36+
return nil, errors.New("Missing/invalid userOpHash")
37+
}
38+
3439
it, err := filterUserOperationEvent(eth, userOpHash, entryPoint)
3540
if err != nil {
3641
return nil, err
@@ -45,8 +50,7 @@ func GetUserOperationByHash(
4550
if err != nil {
4651
return nil, err
4752
} else if isPending {
48-
//lint:ignore ST1005 This needs to match the bundler test spec.
49-
return nil, errors.New("Missing/invalid userOpHash")
53+
return nil, nil
5054
}
5155

5256
hex := hexutil.Encode(tx.Data())
@@ -106,6 +110,5 @@ func GetUserOperationByHash(
106110

107111
}
108112

109-
//lint:ignore ST1005 This needs to match the bundler test spec.
110-
return nil, errors.New("Missing/invalid userOpHash")
113+
return nil, nil
111114
}

pkg/entrypoint/filter/receipt.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ func GetUserOperationReceipt(
4444
userOpHash string,
4545
entryPoint common.Address,
4646
) (*UserOperationReceipt, error) {
47+
if !IsValidUserOpHash(userOpHash) {
48+
//lint:ignore ST1005 This needs to match the bundler test spec.
49+
return nil, errors.New("Missing/invalid userOpHash")
50+
}
51+
4752
it, err := filterUserOperationEvent(eth, userOpHash, entryPoint)
4853
if err != nil {
4954
return nil, err
@@ -58,8 +63,7 @@ func GetUserOperationReceipt(
5863
if err != nil {
5964
return nil, err
6065
} else if isPending {
61-
//lint:ignore ST1005 This needs to match the bundler test spec.
62-
return nil, errors.New("Missing/invalid userOpHash")
66+
return nil, nil
6367
}
6468
from, err := types.Sender(types.LatestSignerForChainID(tx.ChainId()), tx)
6569
if err != nil {
@@ -92,6 +96,5 @@ func GetUserOperationReceipt(
9296
}, nil
9397
}
9498

95-
//lint:ignore ST1005 This needs to match the bundler test spec.
96-
return nil, errors.New("Missing/invalid userOpHash")
99+
return nil, nil
97100
}

0 commit comments

Comments
 (0)