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