parent
7549b8f8c8
commit
be397fbd7b
@ -0,0 +1,76 @@ |
||||
defmodule Explorer.Validator.MetadataRetriever do |
||||
@moduledoc """ |
||||
Consults the configured smart contracts to fetch the valivators' metadata |
||||
""" |
||||
|
||||
alias Explorer.SmartContract.Reader |
||||
|
||||
def fetch_data do |
||||
fetch_validators_list() |
||||
|> Enum.map(fn validator -> |
||||
validator |
||||
|> fetch_validator_metadata |
||||
|> translate_metadata |
||||
|> Map.merge(%{address_hash: validator, primary: true}) |
||||
end) |
||||
end |
||||
|
||||
defp fetch_validators_list do |
||||
%{"getValidators" => {:ok, [validators]}} = |
||||
Reader.query_contract(config(:validators_contract_address), contract_abi("validators.json"), %{ |
||||
"getValidators" => [] |
||||
}) |
||||
|
||||
validators |
||||
end |
||||
|
||||
defp fetch_validator_metadata(validator_address) do |
||||
%{"validators" => {:ok, fields}} = |
||||
Reader.query_contract(config(:metadata_contract_address), contract_abi("metadata.json"), %{ |
||||
"validators" => [validator_address] |
||||
}) |
||||
|
||||
fields |
||||
end |
||||
|
||||
defp translate_metadata([ |
||||
first_name, |
||||
last_name, |
||||
license_id, |
||||
full_address, |
||||
state, |
||||
zipcode, |
||||
expiration_date, |
||||
created_date, |
||||
_updated_date, |
||||
_min_treshold |
||||
]) do |
||||
%{ |
||||
name: trim_null_bytes(first_name) <> " " <> trim_null_bytes(last_name), |
||||
metadata: %{ |
||||
license_id: trim_null_bytes(license_id), |
||||
address: full_address, |
||||
state: trim_null_bytes(state), |
||||
zipcode: trim_null_bytes(zipcode), |
||||
expiration_date: expiration_date, |
||||
created_date: created_date |
||||
} |
||||
} |
||||
end |
||||
|
||||
defp trim_null_bytes(bytes) do |
||||
String.trim_trailing(bytes, <<0>>) |
||||
end |
||||
|
||||
defp config(key) do |
||||
Application.get_env(:explorer, __MODULE__, [])[key] |
||||
end |
||||
|
||||
# sobelow_skip ["Traversal"] |
||||
defp contract_abi(file_name) do |
||||
:explorer |
||||
|> Application.app_dir("priv/validator_contracts_abi/#{file_name}") |
||||
|> File.read!() |
||||
|> Jason.decode!() |
||||
end |
||||
end |
@ -0,0 +1,100 @@ |
||||
defmodule Explorer.Validator.MetadataRetrieverTest do |
||||
use EthereumJSONRPC.Case |
||||
|
||||
alias Explorer.Validator.MetadataRetriever |
||||
import Mox |
||||
|
||||
setup :verify_on_exit! |
||||
setup :set_mox_global |
||||
|
||||
describe "fetch_data/0" do |
||||
test "returns maps with the info on each validator" do |
||||
validators_list_mox_ok() |
||||
validator_metadata_mox_ok() |
||||
|
||||
expected = [ |
||||
%{ |
||||
address_hash: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1>>, |
||||
name: "Testname Unitarion", |
||||
primary: true, |
||||
metadata: %{ |
||||
address: "", |
||||
created_date: 0, |
||||
expiration_date: 253_370_764_800, |
||||
license_id: "00000000", |
||||
state: "XX", |
||||
zipcode: "00000" |
||||
} |
||||
} |
||||
] |
||||
|
||||
assert MetadataRetriever.fetch_data() == expected |
||||
end |
||||
|
||||
test "raise error when the first contract call fails" do |
||||
contract_request_with_error("getValidators") |
||||
assert_raise(MatchError, fn -> MetadataRetriever.fetch_data() end) |
||||
end |
||||
|
||||
test "raise error when a call to the metadatc contract fails" do |
||||
validators_list_mox_ok() |
||||
contract_request_with_error("validators") |
||||
assert_raise(MatchError, fn -> MetadataRetriever.fetch_data() end) |
||||
end |
||||
end |
||||
|
||||
defp contract_request_with_error(id) do |
||||
expect( |
||||
EthereumJSONRPC.Mox, |
||||
:json_rpc, |
||||
fn [%{id: id, method: _, params: _}], _options -> |
||||
{:ok, |
||||
[ |
||||
%{ |
||||
error: %{code: -32015, data: "Reverted 0x", message: "VM execution error."}, |
||||
id: id, |
||||
jsonrpc: "2.0" |
||||
} |
||||
]} |
||||
end |
||||
) |
||||
end |
||||
|
||||
defp validators_list_mox_ok() do |
||||
expect( |
||||
EthereumJSONRPC.Mox, |
||||
:json_rpc, |
||||
1, |
||||
fn [%{id: "getValidators"}], _opts -> |
||||
{:ok, |
||||
[ |
||||
%{ |
||||
id: "getValidators", |
||||
jsonrpc: "2.0", |
||||
result: |
||||
"0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001" |
||||
} |
||||
]} |
||||
end |
||||
) |
||||
end |
||||
|
||||
defp validator_metadata_mox_ok() do |
||||
expect( |
||||
EthereumJSONRPC.Mox, |
||||
:json_rpc, |
||||
1, |
||||
fn [%{id: "validators"}], _opts -> |
||||
{:ok, |
||||
[ |
||||
%{ |
||||
id: "validators", |
||||
jsonrpc: "2.0", |
||||
result: |
||||
"0x546573746e616d65000000000000000000000000000000000000000000000000556e69746172696f6e000000000000000000000000000000000000000000000030303030303030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140585800000000000000000000000000000000000000000000000000000000000030303030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003afe130e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058585858585858207374726565742058585858585800000000000000000000000000000000000000000000000000000000000000000000000000000000000000" |
||||
} |
||||
]} |
||||
end |
||||
) |
||||
end |
||||
end |
Loading…
Reference in new issue