# Node Balancer application

## Installation and configuration

-   Prepare environment variables, according with `sample.env`.
-   Build application

```bash
go build -o nodebalancer .
```

-   Generate configuration

```bash
nodebalancer generate-config
```

-   Modify configuration. Tags should NOT repeat blockchain, as it is specified in `blockchain` key. Example of configuration:

```bash
[
  {
    "blockchain": "ethereum",
    "endpoint": "http://127.0.0.1:8545",
	"tags": ["local"]
  },
  {
    "blockchain": "ethereum",
    "endpoint": "http://127.0.0.1:9585",
	"tags": ["local"]
  },
  {
	"blockchain": "ethereum",
    "endpoint": "https://cool-name.quiknode.pro/y0urn0de1den1f1cat0r/",
	"tags": ["external"]
  }
]
```

So if with request will be specified tag `local` will be returned node with corresponding tag.

## Work with nodebalancer

**IMPORTANT** Do not use flag `-debug` in production.

### add-access

Add new access for user:

```bash
nodebalancer add-access \
	--user-id "<user_uuid>" \
	--access-id "<access_uuid>" \
	--name "Access name" \
	--description "Description of access" \
	--extended-methods false \
	--blockchain--access true
```

### delete-access

Delete user access:

```bash
nodebalancer delete-access \
	--user-id "<user_uuid>" \
	--access-id "<access_uuid>"
```

If `access-id` not specified, all user accesses will be deleted.

### users

```bash
nodebalancer users | jq .
```

This command will return a list of bugout resources of registered users to access node balancer with their `crawlers/app/project` (in our project we will call it `crawlers`).

```json
[
	{
		"user_id": "<user_id_from_any_bugout_application>",
		"access_id": "<access_uuid_which_provided_with_query>",
		"name": "<short_description_of_purpose_of_this_crawler>",
		"description": "<long_description>",
		"blockchain_access": true,
		"extended_methods": false
	}
]
```

`access_id` - token which allow access to nodebalancer, could be specified in both ways:

-   as a header `x-moonstream-access-id` with value `access_id`
-   as query parameter `access_id=access_id`

`blockchain_access` - boolean which allow you or not to have access to blockchain node, otherwise you will be redirected to database

`extended_methods` - boolean which allow you to call not whitelisted method to blockchain node, by default for new user this is equal to `false`

### server

```bash
nodebalancer server -host 0.0.0.0 -port 8544 -healthcheck
```

Flag `--healthcheck` will execute background process to ping-pong available nodes to keep their status and current block number.
Flag `--debug` will extend output of each request to server and healthchecks summary.

## Work with node

Common request to fetch block number

```bash
curl --request POST 'http://127.0.0.1:8544/nb/ethereum/jsonrpc?access_id=<access_id>&data_source=<blockchain/database>' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "jsonrpc":"2.0",
        "method":"eth_getBlockByNumber",
        "params":["latest", false],
        "id":1
    }'
```

For Web3 providers `access_id` and `data_source` could be specified in headers

```bash
--header 'x-node-balancer-data-source: <blockchain/database>'
--header 'x-node-balancer-access-id: <access_id>'
```

Same request to fetch specific nodes using tags

```bash
curl --request POST 'http://127.0.0.1:8544/nb/ethereum/jsonrpc?access_id=<access_id>&data_source=<blockchain/database>&tag=<specific_tag_1>&tag=<specific_tag_2>' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "jsonrpc":"2.0",
        "method":"eth_getBlockByNumber",
        "params":["latest", false],
        "id":1
    }'
```

# Tests

## Running tests with fake node

```bash
go build -o fakenode tests/fake_node/main.go
./fakenode
```

```bash
TEST_API_URL="http://127.0.0.1:8545/nb" /usr/local/go/bin/go test -run ^TestHealthCheck$ github.com/bugout-dev/moonstream/nodes/node_balancer/cmd/nodebalancer -v -count=1
```
