commit
9106c8e887
@ -0,0 +1,94 @@ |
||||
defmodule EthereumJSONRPC.IPC do |
||||
use GenServer |
||||
@moduledoc false |
||||
|
||||
import EthereumJSONRPC.HTTP, only: [standardize_response: 1] |
||||
|
||||
# Server |
||||
|
||||
def start_link(opts) do |
||||
GenServer.start_link(__MODULE__, Keyword.merge(opts, socket: nil)) |
||||
end |
||||
|
||||
def init(state) do |
||||
opts = [:binary, active: false, reuseaddr: true] |
||||
|
||||
response = :gen_tcp.connect({:local, state[:path]}, 0, opts) |
||||
|
||||
case response do |
||||
{:ok, socket} -> {:ok, Keyword.put(state, :socket, socket)} |
||||
{:error, reason} -> {:error, reason} |
||||
end |
||||
end |
||||
|
||||
def post(pid, request) do |
||||
GenServer.call(pid, {:request, request}) |
||||
end |
||||
|
||||
def receive_response(data, socket, timeout, result \\ <<>>) |
||||
|
||||
def receive_response({:error, reason}, _socket, _timeout, _result) do |
||||
{:error, reason} |
||||
end |
||||
|
||||
def receive_response(:ok, socket, timeout, result) do |
||||
with {:ok, response} <- :gen_tcp.recv(socket, 0, timeout) do |
||||
new_result = result <> response |
||||
|
||||
if String.ends_with?(response, "\n") do |
||||
{:ok, new_result} |
||||
else |
||||
receive_response(:ok, socket, timeout, new_result) |
||||
end |
||||
end |
||||
end |
||||
|
||||
def receive_response(data, _socket, _timeout, _result) do |
||||
{:error, data} |
||||
end |
||||
|
||||
def handle_call( |
||||
{:request, request}, |
||||
_from, |
||||
[socket: socket, path: _] = state |
||||
) do |
||||
response = |
||||
socket |
||||
|> :gen_tcp.send(request) |
||||
|> receive_response(socket, 500_000) |
||||
|
||||
{:reply, response, state} |
||||
end |
||||
|
||||
# Client |
||||
|
||||
def request(pid, payload) do |
||||
with {:ok, response} <- post(pid, Jason.encode!(payload)), |
||||
{:ok, decoded_body} <- Jason.decode(response) do |
||||
case decoded_body do |
||||
%{"error" => error} -> |
||||
{:error, error} |
||||
|
||||
result = [%{} | _] -> |
||||
list = |
||||
result |
||||
|> Enum.reverse() |
||||
|> List.flatten() |
||||
|> Enum.map(&standardize_response/1) |
||||
|
||||
{:ok, list} |
||||
|
||||
result -> |
||||
{:ok, Map.get(result, "result")} |
||||
end |
||||
else |
||||
{:error, %Jason.DecodeError{data: ""}} -> {:error, :empty_response} |
||||
{:error, error} -> {:error, {:invalid_json, error}} |
||||
{:error, error} -> {:error, error} |
||||
end |
||||
end |
||||
|
||||
def json_rpc(payload, _opts) do |
||||
:poolboy.transaction(:ipc_worker, fn pid -> request(pid, payload) end, 600_000) |
||||
end |
||||
end |
@ -1,77 +1,5 @@ |
||||
# BlockScout Docker integration |
||||
# BlockScout Docker Integration |
||||
|
||||
For now this integration is not production ready. It made only for local usage only ! |
||||
|
||||
## How to use ? |
||||
First of all, blockscout requires `PostgreSQL` server for working. |
||||
It will be provided by starting script (new docker image will be created named `postgres`) |
||||
|
||||
**Starting command** |
||||
`make start` - will set everything up and start blockscout in container. |
||||
To connect it to your local environment you will have to configure it using [env variables](#env-variables) |
||||
|
||||
Example connecting to local `ganache` instance running on port `2000` on Mac/Windows: |
||||
```bash |
||||
COIN=DAI \ |
||||
ETHEREUM_JSONRPC_VARIANT=ganache \ |
||||
ETHEREUM_JSONRPC_HTTP_URL=http://host.docker.internal:2000 \ |
||||
ETHEREUM_JSONRPC_WS_URL=ws://host.docker.internal:2000 \ |
||||
make start |
||||
``` |
||||
|
||||
Blockscout will be available on `localhost:4000` |
||||
|
||||
**Note** |
||||
On mac/Windows Docker provides with a special URL `host.docker.internal` that will be available into container and routed to your local machine. |
||||
On Linux docker is starting using `--network=host` and all services should be available on `localhost` |
||||
|
||||
### Migrations |
||||
|
||||
By default, `Makefile` will do migrations for you on `PostgreSQL` creation. |
||||
But you could run migrations manually using `make migrate` command. |
||||
|
||||
**WARNING** Migrations will clean up your local database ! |
||||
|
||||
## Env variables |
||||
|
||||
BlockScout supports 3 different JSON RPC Variants. |
||||
Variant could be configured using `ETHEREUM_JSONRPC_VARIANT` environment variable. |
||||
|
||||
Example: |
||||
```bash |
||||
ETHEREUM_JSONRPC_VARIANT=ganache make start |
||||
``` |
||||
|
||||
Available options are: |
||||
|
||||
* `parity` - Parity JSON RPC (**Default one**) |
||||
* `geth` - Geth JSON RPC |
||||
* `ganache` - Ganache JSON RPC |
||||
|
||||
|
||||
| Variable | Description | Default value | |
||||
| -------- | ----------- | ------------- | |
||||
| `ETHEREUM_JSONRPC_VARIANT` | Variant of your JSON RPC service: `parity`, `geth` or `ganache` | `parity` | |
||||
| `ETHEREUM_JSONRPC_HTTP_URL` | HTTP JSON RPC URL Only for `geth` or `ganache` variant | Different per JSONRPC variant | |
||||
| `ETHEREUM_JSONRPC_WS_URL` | WS JSON RPC url | Different per JSONRPC variant | |
||||
| `ETHEREUM_JSONRPC_TRACE_URL` | Trace URL **Only for `parity` variant** | `http://localhost:8545` | |
||||
| `COIN` | Default Coin | `POA` | |
||||
| `LOGO` | Coin logo | Empty | |
||||
| `NETWORK` | Network | Empty | |
||||
| `SUBNETWORK` | Subnetwork | Empty | |
||||
| `NETWORK_ICON` | Network icon | Empty | |
||||
| `NETWORK_PATH` | Network path | `/` | |
||||
|
||||
|
||||
`ETHEREUM_JSONRPC_HTTP_URL` default values: |
||||
|
||||
* For `parity` - `http://localhost:8545` |
||||
* For `geth` - `https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY` |
||||
* For `ganache` - `http://localhost:7545` |
||||
|
||||
`ETHEREUM_JSONRPC_WS_URL` default values: |
||||
|
||||
* For `parity` - `ws://localhost:8546` |
||||
* For `geth` - `wss://mainnet.infura.io/8lTvJTKmHPCHazkneJsY/ws` |
||||
* For `ganache` - `ws://localhost:7545` |
||||
This integration is not production ready, and should be used for local BlockScout deployment only. |
||||
|
||||
For usage instructions and ENV variables, see the [docker integration documentation](https://docs.blockscout.com/for-developers/information-and-settings/docker-integration-local-use-only). |
Loading…
Reference in new issue