Merge pull request #27 from poanetwork/ferigis.17.sending_history

[#17] Send history to the Dashboard
This commit is contained in:
Joseph Yiasemides 2018-05-16 15:18:42 +02:00 committed by GitHub
commit ff3465b1af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 13 deletions

View File

@ -1,5 +1,11 @@
defmodule POAAgent.Entity.Ethereum.History do defmodule POAAgent.Entity.Ethereum.History do
@moduledoc false @moduledoc false
@type t :: [POAAgent.Entity.Ethereum.Block.t()] @type t :: %__MODULE__{
history: [POAAgent.Entity.Ethereum.Block.t()]
}
defstruct [
:history
]
end end

View File

@ -9,4 +9,9 @@ defmodule POAAgent.Entity.Ethereum.Pending do
pending: nil pending: nil
] ]
defimpl POAAgent.Entity.NameConvention do
def from_elixir_to_node(x) do
Map.from_struct(x)
end
end
end end

View File

@ -5,6 +5,8 @@ defmodule POAAgent.Plugins.Collectors.Eth.LatestBlock do
This is a Collector's Plugin which makes requests to a Ethereum node in order to know if This is a Collector's Plugin which makes requests to a Ethereum node in order to know if
a new block has been added. a new block has been added.
It also sends the history when the plugin starts.
This Collector needs the url of the node to iteract. That url must be placed in the args field This Collector needs the url of the node to iteract. That url must be placed in the args field
in the config file. For example: in the config file. For example:
@ -23,7 +25,17 @@ defmodule POAAgent.Plugins.Collectors.Eth.LatestBlock do
def init_collector(args) do def init_collector(args) do
:ok = config(args) :ok = config(args)
{:ok, %{last_block: get_latest_block()}} with block_number <- get_latest_block(),
{:ok, block} <- Ethereumex.HttpClient.eth_get_block_by_number(block_number, :false)
do
block = format_block(block)
range = history_range(block, 0)
history = history(range)
{:transfer, [block, history], %{last_block: get_latest_block()}}
else
_error -> {:ok, %{last_block: get_latest_block()}}
end
end end
@doc false @doc false
@ -34,9 +46,9 @@ defmodule POAAgent.Plugins.Collectors.Eth.LatestBlock do
{:notransfer, state} {:notransfer, state}
^latest_block -> ^latest_block ->
{:notransfer, state} {:notransfer, state}
latest_block -> block_number ->
{:ok, block} = Ethereumex.HttpClient.eth_get_block_by_number(latest_block, :false) {:ok, block} = Ethereumex.HttpClient.eth_get_block_by_number(block_number, :false)
{:transfer, format_block(block), %{state | last_block: latest_block}} {:transfer, format_block(block), %{state | last_block: block_number}}
end end
end end
@ -46,6 +58,19 @@ defmodule POAAgent.Plugins.Collectors.Eth.LatestBlock do
:ok :ok
end end
@doc false
def history(range) do
history = for i <- range do
block_number = "0x" <> Integer.to_string(i, 16)
{:ok, block} = Ethereumex.HttpClient.eth_get_block_by_number(block_number, :false)
format_block(block)
end
%POAAgent.Entity.Ethereum.History{
history: Enum.reverse(history)
}
end
@doc false @doc false
defp config([url: url]) do defp config([url: url]) do
Application.put_env(:ethereumex, :url, url) Application.put_env(:ethereumex, :url, url)
@ -61,7 +86,7 @@ defmodule POAAgent.Plugins.Collectors.Eth.LatestBlock do
end end
@doc false @doc false
defp format_block(block) do defp format_block(block) when is_map(block) do
difficulty = POAAgent.Format.Literal.Hex.decimalize(block["difficulty"]) difficulty = POAAgent.Format.Literal.Hex.decimalize(block["difficulty"])
gas_limit = String.to_integer(POAAgent.Format.Literal.Hex.decimalize(block["gasLimit"])) gas_limit = String.to_integer(POAAgent.Format.Literal.Hex.decimalize(block["gasLimit"]))
gas_used = String.to_integer(POAAgent.Format.Literal.Hex.decimalize(block["gasUsed"])) gas_used = String.to_integer(POAAgent.Format.Literal.Hex.decimalize(block["gasUsed"]))
@ -94,5 +119,17 @@ defmodule POAAgent.Plugins.Collectors.Eth.LatestBlock do
uncles: block["uncles"] uncles: block["uncles"]
} }
end end
defp format_block(_) do
nil
end
defp history_range(block, last_block) do
max_blocks_history = 40
from = Enum.max([block.number - max_blocks_history, last_block + 1])
to = Enum.max([block.number, 0])
from..to
end
end end

View File

@ -40,17 +40,23 @@ defmodule POAAgent.Plugins.Transfers.WebSocket.Primus do
{:ok, %{client: client, context: context}} {:ok, %{client: client, context: context}}
end end
def data_received(label, data, %{client: client, context: context} = state) do def data_received(label, data, %{client: client, context: context} = state) when is_list(data) do
require Logger require Logger
Logger.info("Received data from the collector referenced by label: #{label}.") Logger.info("Received data from the collector referenced by label: #{label}.")
event = data :ok = Enum.each(data, fn(message) ->
event =
message
|> Primus.encode(context) |> Primus.encode(context)
|> Jason.encode!() |> Jason.encode!()
:ok = Primus.Client.send(client, event) :ok = Primus.Client.send(client, event)
end)
{:ok, state} {:ok, state}
end end
def data_received(label, data, state) do
data_received(label, [data], state)
end
def handle_message(:ping, %{client: client, context: context} = state) do def handle_message(:ping, %{client: client, context: context} = state) do
@ -99,13 +105,26 @@ defmodule POAAgent.Plugins.Transfers.WebSocket.Primus do
|> POAAgent.Format.PrimusEmitter.wrap(event: "stats") |> POAAgent.Format.PrimusEmitter.wrap(event: "stats")
end end
def encode(x, %Primus.State{identifier: i}) do def encode(%POAAgent.Entity.Ethereum.History{} = x, %Primus.State{identifier: i}) do
history = for i <- x.history do
Entity.NameConvention.from_elixir_to_node(i)
end
%{} %{}
|> Map.put(:id, i) |> Map.put(:id, i)
|> Map.put(:history, x) |> Map.put(:history, history)
|> POAAgent.Format.PrimusEmitter.wrap(event: "history") |> POAAgent.Format.PrimusEmitter.wrap(event: "history")
end end
def encode(%POAAgent.Entity.Ethereum.Pending{} = x, %Primus.State{identifier: i}) do
x = Entity.NameConvention.from_elixir_to_node(x)
%{}
|> Map.put(:id, i)
|> Map.put(:stats, x)
|> POAAgent.Format.PrimusEmitter.wrap(event: "pending")
end
def information() do def information() do
config = Application.get_env(:poa_agent, __MODULE__) config = Application.get_env(:poa_agent, __MODULE__)
@ -171,6 +190,23 @@ defmodule POAAgent.Plugins.Transfers.WebSocket.Primus do
{:reply, {:text, event}, state} {:reply, {:text, event}, state}
end end
defp handle_primus_event(["history", %{"max" => max, "min" => min}], state) do
context = struct!(Primus.State, Application.get_env(:poa_agent, Primus))
h = POAAgent.Plugins.Collectors.Eth.LatestBlock.history(min..max)
history = for i <- h.history do
Entity.NameConvention.from_elixir_to_node(i)
end
event = %{}
|> Map.put(:id, context.identifier)
|> Map.put(:history, history)
|> POAAgent.Format.PrimusEmitter.wrap(event: "history")
|> Jason.encode!()
{:reply, {:text, event}, state}
end
defp handle_primus_event(data, state) do defp handle_primus_event(data, state) do
require Logger require Logger