Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic url feature #37

Merged
merged 3 commits into from
Jul 31, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ config :ethereumex,
iex> Ethereumex.HttpClient.web3_client_version
{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"}

# Using the url option will overwrite the configuration
iex> Ethereumex.HttpClient.web3_client_version(url: "http://localhost:8545")
{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"}

iex> Ethereumex.HttpClient.web3_sha3("wrong_param")
{:error, %{"code" => -32602, "message" => "Invalid params: invalid format."}}

Expand Down
2 changes: 1 addition & 1 deletion lib/ethereumex/client/behaviour.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ defmodule Ethereumex.Client.Behaviour do
# actual request methods

@callback request(binary(), list(binary()), keyword()) :: {:ok, any() | [any()]} | error
@callback single_request(map()) :: {:ok, any() | [any()]} | error
@callback single_request(map(), keyword()) :: {:ok, any() | [any()]} | error
@callback batch_request([{atom(), list(binary())}]) :: {:ok, [any()]} | error
end
15 changes: 9 additions & 6 deletions lib/ethereumex/client/macro.ex
Original file line number Diff line number Diff line change
Expand Up @@ -419,14 +419,17 @@ defmodule Ethereumex.Client.Macro do

@spec request(binary(), list(binary() | boolean | map), keyword()) ::
{:ok, any() | [any()]} | error
def request(_name, _params, batch: true, url: _url),
do: raise("Cannot use batch and url options at the same time")

def request(name, params, batch: true) do
name |> add_request_info(params)
end

def request(name, params, _) do
def request(name, params, opts) do
name
|> add_request_info(params)
|> server_request
|> server_request(opts)
end

@spec batch_request([{atom(), list(binary())}]) :: {:ok, [any()]} | error
Expand All @@ -441,8 +444,8 @@ defmodule Ethereumex.Client.Macro do
|> server_request
end

defp server_request(params) do
GenServer.call(__MODULE__, {:request, params})
defp server_request(params, opts \\ []) do
GenServer.call(__MODULE__, {:request, params, opts})
end

def start_link do
Expand All @@ -453,11 +456,11 @@ defmodule Ethereumex.Client.Macro do
GenServer.cast(__MODULE__, :reset_id)
end

def single_request(params) do
def single_request(params, opts) do
{:error, :not_implemented}
end

defoverridable single_request: 1
defoverridable single_request: 2
end
end
end
12 changes: 8 additions & 4 deletions lib/ethereumex/client/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,31 @@ defmodule Ethereumex.Client.Server do

@moduledoc false

def init(args) do
{:ok, args}
end

def start_link(module) when is_atom(module) do
GenServer.start_link(__MODULE__, {module, 0}, name: module)
end

def handle_call({:request, params}, _from, {module, id}) when is_list(params) do
def handle_call({:request, params, opts}, _from, {module, id}) when is_list(params) do
params =
params
|> Enum.with_index()
|> Enum.map(fn {req_data, index} ->
Map.put(req_data, "id", index + id)
end)

response = apply(module, :single_request, [params])
response = apply(module, :single_request, [params, opts])

{:reply, response, {module, id + Enum.count(params)}}
end

def handle_call({:request, params}, _from, {module, id}) do
def handle_call({:request, params, opts}, _from, {module, id}) do
params = Map.put(params, "id", id)

response = apply(module, :single_request, [params])
response = apply(module, :single_request, [params, opts])

{:reply, response, {module, id + 1}}
end
Expand Down
13 changes: 7 additions & 6 deletions lib/ethereumex/http_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@ defmodule Ethereumex.HttpClient do
import Ethereumex.Config
@moduledoc false

@spec single_request(map()) :: {:ok, any() | [any()]} | error
def single_request(payload) do
@spec single_request(map(), []) :: {:ok, any() | [any()]} | error
def single_request(payload, opts \\ []) do
payload
|> encode_payload
|> post_request
|> post_request(opts)
end

@spec encode_payload(map()) :: binary()
defp encode_payload(payload) do
payload |> Poison.encode!()
end

@spec post_request(binary()) :: {:ok | :error, any()}
defp post_request(payload) do
@spec post_request(binary(), []) :: {:ok | :error, any()}
defp post_request(payload, opts) do
headers = [{"Content-Type", "application/json"}]
options = Ethereumex.Config.http_options()
url = Keyword.get(opts, :url) || rpc_url()

with {:ok, response} <- HTTPoison.post(rpc_url(), payload, headers, options),
with {:ok, response} <- HTTPoison.post(url, payload, headers, options),
%HTTPoison.Response{body: body, status_code: code} = response do
decode_body(body, code)
else
Expand Down
23 changes: 19 additions & 4 deletions test/ethereumex/client/macro_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ defmodule Ethereumex.Client.MacroTest do
defmodule ClientMock do
use Ethereumex.Client.Macro

def single_request(payload) do
def single_request(payload, opts) do
%{"method" => method, "jsonrpc" => "2.0", "params" => params} = payload

{method, params}
{method, params, opts}
end
end

Expand All @@ -19,7 +19,11 @@ defmodule Ethereumex.Client.MacroTest do
end

def assert_method({ex_method, eth_method}, params, payload) do
{^eth_method, ^payload} = apply(ClientMock, String.to_atom(ex_method), params)
{^eth_method, ^payload, _opts} = apply(ClientMock, String.to_atom(ex_method), params)
end

def assert_opts({ex_method, _eth_method}, params, opts) do
{_eth_method, _payload, ^opts} = apply(ClientMock, String.to_atom(ex_method), params)
end

def make_tuple(ex_method) do
Expand Down Expand Up @@ -69,7 +73,18 @@ defmodule Ethereumex.Client.MacroTest do
topics: ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]
}

test ".web3_client_version/0", do: Helpers.check("web3_client_version")
describe ".web3_client_version/0" do
test "with configuration url", do: Helpers.check("web3_client_version")

test "with dynamic url",
do:
Helpers.assert_opts(
{"web3_client_version", "web3_client_version"},
[[url: "http://localhost:4000"]],
url: "http://localhost:4000"
)
end

test ".net_version/0", do: Helpers.check("net_version")
test ".net_peer_count/0", do: Helpers.check("net_peer_count")
test ".net_listening/0", do: Helpers.check("net_listening")
Expand Down