parent
3e19a8afab
commit
e40e4dca27
@ -0,0 +1,50 @@ |
||||
defmodule EthereumJSONRPC.FetchedCode do |
||||
@moduledoc """ |
||||
A single code fetched from `eth_getCode`. |
||||
""" |
||||
|
||||
import EthereumJSONRPC, only: [quantity_to_integer: 1] |
||||
|
||||
@type params :: %{address: EthereumJSONRPC.address(), block_number: non_neg_integer(), code: non_neg_integer()} |
||||
@type error :: %{code: integer(), message: String.t(), data: %{block_quantity: String.t(), address: String.t()}} |
||||
|
||||
@doc """ |
||||
Converts `response` to code params or annotated error. |
||||
""" |
||||
|
||||
def from_response(%{id: id, result: fetched_code}, id_to_params) when is_map(id_to_params) do |
||||
%{block_quantity: block_quantity, address: address} = Map.fetch!(id_to_params, id) |
||||
|
||||
{:ok, |
||||
%{ |
||||
address: address, |
||||
block_number: quantity_to_integer(block_quantity), |
||||
code: fetched_code |
||||
}} |
||||
end |
||||
|
||||
@spec from_response(%{id: id, result: String.t()}, %{id => %{block_quantity: block_quantity, address: address}}) :: |
||||
{:ok, params()} |
||||
when id: non_neg_integer(), block_quantity: String.t(), address: String.t() |
||||
def from_response(%{id: id, error: %{code: code, message: message} = error}, id_to_params) |
||||
when is_integer(code) and is_binary(message) and is_map(id_to_params) do |
||||
%{block_quantity: block_quantity, address: address} = Map.fetch!(id_to_params, id) |
||||
|
||||
annotated_error = Map.put(error, :data, %{block_quantity: block_quantity, address: address}) |
||||
|
||||
{:error, annotated_error} |
||||
end |
||||
|
||||
@spec request(%{id: id, block_quantity: block_quantity, address: address}) :: %{ |
||||
jsonrpc: String.t(), |
||||
id: id, |
||||
method: String.t(), |
||||
params: [address | block_quantity] |
||||
} |
||||
when id: EthereumJSONRPC.request_id(), |
||||
block_quantity: EthereumJSONRPC.quantity(), |
||||
address: EthereumJSONRPC.address() |
||||
def request(%{id: id, block_quantity: block_quantity, address: address}) do |
||||
EthereumJSONRPC.request(%{id: id, method: "eth_getCode", params: [address, block_quantity]}) |
||||
end |
||||
end |
@ -0,0 +1,49 @@ |
||||
defmodule EthereumJSONRPC.FetchedCodes do |
||||
@moduledoc """ |
||||
Code params and errors from a batch request from `eth_getCode`. |
||||
""" |
||||
|
||||
alias EthereumJSONRPC.FetchedCode |
||||
|
||||
defstruct params_list: [], |
||||
errors: [] |
||||
|
||||
@typedoc """ |
||||
* `params_list` - all the code params from requests that succeeded in the batch. |
||||
* `errors` - all the errors from requests that failed in the batch. |
||||
""" |
||||
@type t :: %__MODULE__{params_list: [FetchedCode.params()], errors: [FetchedCode.error()]} |
||||
|
||||
@doc """ |
||||
`eth_getCode` requests for `id_to_params`. |
||||
""" |
||||
@spec requests(%{id => %{block_quantity: block_quantity, address: address}}) :: [ |
||||
%{jsonrpc: String.t(), id: id, method: String.t(), params: [address | block_quantity]} |
||||
] |
||||
when id: EthereumJSONRPC.request_id(), |
||||
block_quantity: EthereumJSONRPC.quantity(), |
||||
address: EthereumJSONRPC.address() |
||||
def requests(id_to_params) when is_map(id_to_params) do |
||||
Enum.map(id_to_params, fn {id, %{block_quantity: block_quantity, address: address}} -> |
||||
FetchedCode.request(%{id: id, block_quantity: block_quantity, address: address}) |
||||
end) |
||||
end |
||||
|
||||
@doc """ |
||||
Converts `responses` to `t/0`. |
||||
""" |
||||
def from_responses(responses, id_to_params) do |
||||
responses |
||||
|> Enum.map(&FetchedCode.from_response(&1, id_to_params)) |
||||
|> Enum.reduce( |
||||
%__MODULE__{}, |
||||
fn |
||||
{:ok, params}, %__MODULE__{params_list: params_list} = acc -> |
||||
%__MODULE__{acc | params_list: [params | params_list]} |
||||
|
||||
{:error, reason}, %__MODULE__{errors: errors} = acc -> |
||||
%__MODULE__{acc | errors: [reason | errors]} |
||||
end |
||||
) |
||||
end |
||||
end |
Loading…
Reference in new issue