github.com/status-im/status-go@v1.1.0/rpc/client_test.go (about) 1 package rpc 2 3 import ( 4 "context" 5 "database/sql" 6 "encoding/base64" 7 "fmt" 8 "math/big" 9 "net/http" 10 "net/http/httptest" 11 "sync" 12 "testing" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 17 "github.com/status-im/status-go/appdatabase" 18 "github.com/status-im/status-go/params" 19 "github.com/status-im/status-go/t/helpers" 20 21 "github.com/ethereum/go-ethereum/common" 22 gethrpc "github.com/ethereum/go-ethereum/rpc" 23 ) 24 25 func setupTestNetworkDB(t *testing.T) (*sql.DB, func()) { 26 db, cleanup, err := helpers.SetupTestSQLDB(appdatabase.DbInitializer{}, "rpc-network-tests") 27 require.NoError(t, err) 28 return db, func() { require.NoError(t, cleanup()) } 29 } 30 31 func TestBlockedRoutesCall(t *testing.T) { 32 db, close := setupTestNetworkDB(t) 33 defer close() 34 35 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 36 fmt.Fprintln(w, `{ 37 "id": 1, 38 "jsonrpc": "2.0", 39 "result": "0x234234e22b9ffc2387e18636e0534534a3d0c56b0243567432453264c16e78a2adc" 40 }`) 41 })) 42 defer ts.Close() 43 44 gethRPCClient, err := gethrpc.Dial(ts.URL) 45 require.NoError(t, err) 46 47 c, err := NewClient(gethRPCClient, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db, nil) 48 require.NoError(t, err) 49 50 for _, m := range blockedMethods { 51 var ( 52 result interface{} 53 err error 54 ) 55 56 err = c.Call(&result, 1, m) 57 require.EqualError(t, err, ErrMethodNotFound.Error()) 58 require.Nil(t, result) 59 60 err = c.CallContext(context.Background(), &result, 1, m) 61 require.EqualError(t, err, ErrMethodNotFound.Error()) 62 require.Nil(t, result) 63 64 err = c.CallContextIgnoringLocalHandlers(context.Background(), &result, 1, m) 65 require.EqualError(t, err, ErrMethodNotFound.Error()) 66 require.Nil(t, result) 67 } 68 } 69 70 func TestBlockedRoutesRawCall(t *testing.T) { 71 db, close := setupTestNetworkDB(t) 72 defer close() 73 74 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 75 fmt.Fprintln(w, `{ 76 "id": 1, 77 "jsonrpc": "2.0", 78 "result": "0x234234e22b9ffc2387e18636e0534534a3d0c56b0243567432453264c16e78a2adc" 79 }`) 80 })) 81 defer ts.Close() 82 83 gethRPCClient, err := gethrpc.Dial(ts.URL) 84 require.NoError(t, err) 85 86 c, err := NewClient(gethRPCClient, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db, nil) 87 require.NoError(t, err) 88 89 for _, m := range blockedMethods { 90 rawResult := c.CallRaw(fmt.Sprintf(`{ 91 "jsonrpc": "2.0", 92 "id": 1, 93 "method": "%s", 94 "params": ["0xc862bf3cf4565d46abcbadaf4712a8940bfea729a91b9b0e338eab5166341ab5"] 95 }`, m)) 96 require.Contains(t, rawResult, fmt.Sprintf(`{"code":-32700,"message":"%s"}`, ErrMethodNotFound)) 97 } 98 } 99 100 func TestUpdateUpstreamURL(t *testing.T) { 101 db, close := setupTestNetworkDB(t) 102 defer close() 103 104 ts := createTestServer("") 105 defer ts.Close() 106 107 updatedUpstreamTs := createTestServer("") 108 defer updatedUpstreamTs.Close() 109 110 gethRPCClient, err := gethrpc.Dial(ts.URL) 111 require.NoError(t, err) 112 113 c, err := NewClient(gethRPCClient, 1, params.UpstreamRPCConfig{Enabled: true, URL: ts.URL}, []params.Network{}, db, nil) 114 require.NoError(t, err) 115 require.Equal(t, ts.URL, c.upstreamURL) 116 117 // cache the original upstream client 118 originalUpstreamClient := c.upstream 119 120 err = c.UpdateUpstreamURL(updatedUpstreamTs.URL) 121 require.NoError(t, err) 122 // the upstream cleint instance should change 123 require.NotEqual(t, originalUpstreamClient, c.upstream) 124 require.Equal(t, updatedUpstreamTs.URL, c.upstreamURL) 125 } 126 127 func createTestServer(resp string) *httptest.Server { 128 if resp == "" { 129 resp = `{ 130 "id": 1, 131 "jsonrpc": "2.0", 132 "result": "0x234234e22b9ffc2387e18636e0534534a3d0c56b0243567432453264c16e78a2adc" 133 }` 134 } 135 136 return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 137 fmt.Fprintln(w, resp) 138 })) 139 } 140 141 func TestGetClientsUsingCache(t *testing.T) { 142 db, close := setupTestNetworkDB(t) 143 defer close() 144 145 providerConfig := params.ProviderConfig{ 146 Enabled: true, 147 Name: ProviderStatusProxy, 148 User: "user1", 149 Password: "pass1", 150 } 151 providerConfigs := []params.ProviderConfig{providerConfig} 152 153 var wg sync.WaitGroup 154 wg.Add(2) // 2 providers 155 156 // Create a new ServeMux 157 mux := http.NewServeMux() 158 159 path1 := "/foo" 160 path2 := "/bar" 161 // Register handlers for different URL paths 162 mux.HandleFunc(path1, func(w http.ResponseWriter, r *http.Request) { 163 authToken := base64.StdEncoding.EncodeToString([]byte(providerConfig.User + ":" + providerConfig.Password)) 164 require.Equal(t, fmt.Sprintf("Basic %s", authToken), r.Header.Get("Authorization")) 165 wg.Done() 166 }) 167 168 mux.HandleFunc(path2, func(w http.ResponseWriter, r *http.Request) { 169 authToken := base64.StdEncoding.EncodeToString([]byte(providerConfig.User + ":" + providerConfig.Password)) 170 require.Equal(t, fmt.Sprintf("Basic %s", authToken), r.Header.Get("Authorization")) 171 wg.Done() 172 }) 173 174 // Create a new server with the mux as the handler 175 server := httptest.NewServer(mux) 176 defer server.Close() 177 178 networks := []params.Network{ 179 { 180 ChainID: 1, 181 DefaultRPCURL: server.URL + path1, 182 DefaultFallbackURL: server.URL + path2, 183 }, 184 } 185 c, err := NewClient(nil, 1, params.UpstreamRPCConfig{}, networks, db, providerConfigs) 186 require.NoError(t, err) 187 188 // Networks from DB must pick up DefaultRPCURL and DefaultFallbackURL 189 chainClient, err := c.getClientUsingCache(networks[0].ChainID) 190 require.NoError(t, err) 191 require.NotNil(t, chainClient) 192 193 // Make any call to provider. If test finishes, then all handlers were called and asserts inside them passed 194 balance, err := chainClient.BalanceAt(context.TODO(), common.Address{0x1}, big.NewInt(1)) 195 assert.Error(t, err) // EOF, we dont return anything from the server, because of error iterate over all providers 196 assert.Nil(t, balance) 197 wg.Wait() 198 } 199 200 func TestUserAgent(t *testing.T) { 201 require.Equal(t, "procuratee-desktop/", rpcUserAgentName) 202 require.Equal(t, "procuratee-desktop-upstream/", rpcUserAgentUpstreamName) 203 }