github.com/status-im/status-go@v1.1.0/node/status_node_rpc_client_test.go (about)

     1  package node
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/status-im/status-go/appdatabase"
    15  	"github.com/status-im/status-go/multiaccounts"
    16  	"github.com/status-im/status-go/params"
    17  	"github.com/status-im/status-go/t/helpers"
    18  	"github.com/status-im/status-go/walletdatabase"
    19  )
    20  
    21  type TestServiceAPI struct{}
    22  
    23  func (api *TestServiceAPI) SomeMethod(_ context.Context) (string, error) {
    24  	return "some method result", nil
    25  }
    26  
    27  func setupTestDBs() (appDB *sql.DB, walletDB *sql.DB, closeFn func() error, err error) {
    28  	appDB, err = helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{})
    29  	if err != nil {
    30  		return nil, nil, nil, fmt.Errorf("failed to setup app db: %w", err)
    31  	}
    32  
    33  	walletDB, err = helpers.SetupTestMemorySQLDB(walletdatabase.DbInitializer{})
    34  	if err != nil {
    35  		return nil, nil, nil, fmt.Errorf("failed to setup wallet db: %w", err)
    36  	}
    37  	return appDB, walletDB, func() error {
    38  		appErr := appDB.Close()
    39  		walletErr := walletDB.Close()
    40  		if appErr != nil {
    41  			return fmt.Errorf("failed to close app db: %w", appErr)
    42  		}
    43  		if walletErr != nil {
    44  			return fmt.Errorf("failed to close wallet db: %w", walletErr)
    45  		}
    46  		return nil
    47  	}, err
    48  }
    49  
    50  func setupTestMultiDB() (*multiaccounts.Database, func() error, error) {
    51  	tmpfile, err := ioutil.TempFile("", "tests")
    52  	if err != nil {
    53  		return nil, nil, err
    54  	}
    55  	db, err := multiaccounts.InitializeDB(tmpfile.Name())
    56  	if err != nil {
    57  		return nil, nil, err
    58  	}
    59  	return db, func() error {
    60  		err := db.Close()
    61  		if err != nil {
    62  			return err
    63  		}
    64  		return os.Remove(tmpfile.Name())
    65  	}, nil
    66  }
    67  
    68  func createAndStartStatusNode(config *params.NodeConfig) (*StatusNode, error) {
    69  	statusNode := New(nil)
    70  
    71  	appDB, walletDB, stop, err := setupTestDBs()
    72  	defer func() {
    73  		err := stop()
    74  		if err != nil {
    75  			statusNode.log.Error("stopping db", err)
    76  		}
    77  	}()
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	statusNode.appDB = appDB
    82  	statusNode.walletDB = walletDB
    83  
    84  	ma, stop2, err := setupTestMultiDB()
    85  	defer func() {
    86  		err := stop2()
    87  		if err != nil {
    88  			statusNode.log.Error("stopping multiaccount db", err)
    89  		}
    90  	}()
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	statusNode.multiaccountsDB = ma
    95  
    96  	err = statusNode.Start(config, nil)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	return statusNode, nil
   102  }
   103  
   104  func createStatusNode() (*StatusNode, func() error, func() error, error) {
   105  	appDB, walletDB, stop1, err := setupTestDBs()
   106  	if err != nil {
   107  		return nil, nil, nil, err
   108  	}
   109  	statusNode := New(nil)
   110  	statusNode.SetAppDB(appDB)
   111  	statusNode.SetWalletDB(walletDB)
   112  
   113  	ma, stop2, err := setupTestMultiDB()
   114  	statusNode.SetMultiaccountsDB(ma)
   115  
   116  	return statusNode, stop1, stop2, err
   117  }
   118  
   119  func TestNodeRPCClientCallOnlyPublicAPIs(t *testing.T) {
   120  	var err error
   121  
   122  	statusNode, err := createAndStartStatusNode(&params.NodeConfig{
   123  		APIModules: "", // no whitelisted API modules; use only public APIs
   124  		UpstreamConfig: params.UpstreamRPCConfig{
   125  			URL:     "https://infura.io",
   126  			Enabled: true},
   127  		WakuConfig: params.WakuConfig{
   128  			Enabled: true,
   129  		},
   130  	})
   131  	require.NoError(t, err)
   132  	defer func() {
   133  		err := statusNode.Stop()
   134  		require.NoError(t, err)
   135  	}()
   136  
   137  	client := statusNode.RPCClient()
   138  	require.NotNil(t, client)
   139  
   140  	// call public API with public RPC Client
   141  	result, err := statusNode.CallRPC(`{"jsonrpc": "2.0", "id": 1, "method": "eth_uninstallFilter", "params": ["id"]}`)
   142  	require.NoError(t, err)
   143  
   144  	// the call is successful
   145  	require.False(t, strings.Contains(result, "error"))
   146  
   147  	result, err = statusNode.CallRPC(`{"jsonrpc": "2.0", "id": 1, "method": "waku_info"}`)
   148  	require.NoError(t, err)
   149  
   150  	// call private API with public RPC client
   151  	require.Equal(t, ErrRPCMethodUnavailable, result)
   152  
   153  }
   154  
   155  func TestNodeRPCPrivateClientCallPrivateService(t *testing.T) {
   156  	var err error
   157  
   158  	statusNode, err := createAndStartStatusNode(&params.NodeConfig{
   159  		WakuConfig: params.WakuConfig{
   160  			Enabled: true,
   161  		},
   162  	})
   163  	require.NoError(t, err)
   164  	defer func() {
   165  		err := statusNode.Stop()
   166  		require.NoError(t, err)
   167  	}()
   168  
   169  	result, err := statusNode.CallPrivateRPC(`{"jsonrpc": "2.0", "id": 1, "method": "waku_info"}`)
   170  	require.NoError(t, err)
   171  
   172  	// the call is successful
   173  	require.False(t, strings.Contains(result, "error"))
   174  
   175  	_, err = statusNode.CallPrivateRPC(`{"jsonrpc": "2.0", "id": 1, "method": "settings_getSettings"}`)
   176  	require.NoError(t, err)
   177  }