parent
fa320dc3ec
commit
8780fdfdac
@ -0,0 +1,46 @@ |
|||||||
|
defmodule Explorer.Application.Constants do |
||||||
|
@moduledoc """ |
||||||
|
Tracks some kv info |
||||||
|
""" |
||||||
|
|
||||||
|
use Explorer.Schema |
||||||
|
alias Explorer.Repo |
||||||
|
|
||||||
|
@keys_manager_contract_address_key "keys_manager_contract_address" |
||||||
|
|
||||||
|
@primary_key false |
||||||
|
schema "constants" do |
||||||
|
field(:key, :string, primary_key: true) |
||||||
|
field(:value, :string) |
||||||
|
|
||||||
|
timestamps() |
||||||
|
end |
||||||
|
|
||||||
|
def changeset(attrs) do |
||||||
|
%__MODULE__{} |
||||||
|
|> changeset(attrs) |
||||||
|
end |
||||||
|
|
||||||
|
@required_attrs ~w(key value)a |
||||||
|
def changeset(%__MODULE__{} = constant, attrs) do |
||||||
|
constant |
||||||
|
|> cast(attrs, @required_attrs) |
||||||
|
|> validate_required(@required_attrs) |
||||||
|
end |
||||||
|
|
||||||
|
def get_constant_by_key(key) do |
||||||
|
__MODULE__ |
||||||
|
|> where([constant], constant.key == ^key) |
||||||
|
|> Repo.one() |
||||||
|
end |
||||||
|
|
||||||
|
def insert_keys_manager_contract_address(value) do |
||||||
|
%{key: @keys_manager_contract_address_key, value: value} |
||||||
|
|> changeset() |
||||||
|
|> Repo.insert!() |
||||||
|
end |
||||||
|
|
||||||
|
def get_keys_manager_contract_address do |
||||||
|
get_constant_by_key(@keys_manager_contract_address_key) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,69 @@ |
|||||||
|
defmodule Explorer.Chain.Fetcher.FetchValidatorInfoOnDemand do |
||||||
|
@moduledoc """ |
||||||
|
On demand fetcher info about validator |
||||||
|
""" |
||||||
|
|
||||||
|
use GenServer |
||||||
|
|
||||||
|
alias Explorer.Application.Constants |
||||||
|
alias Explorer.Chain.Block.Reward |
||||||
|
alias Explorer.Chain.Cache.BlockNumber |
||||||
|
alias Explorer.Chain.Validator |
||||||
|
|
||||||
|
def trigger_fetch(address_hash) do |
||||||
|
GenServer.cast(__MODULE__, {:fetch_or_update, address_hash}) |
||||||
|
end |
||||||
|
|
||||||
|
defp actualize_validator_info(address_hash) do |
||||||
|
contract_address_from_db = Constants.get_keys_manager_contract_address() |
||||||
|
|
||||||
|
contract_address_from_env = |
||||||
|
Application.get_env(:explorer, Explorer.Chain.Block.Reward, %{})[:keys_manager_contract_address] |
||||||
|
|
||||||
|
cond do |
||||||
|
is_nil(contract_address_from_env) -> |
||||||
|
:ignore |
||||||
|
|
||||||
|
is_nil(contract_address_from_db) -> |
||||||
|
Validator.drop_all_validators() |
||||||
|
Constants.insert_keys_manager_contract_address(contract_address_from_env) |
||||||
|
fetch_and_store_validator_info(address_hash) |
||||||
|
|
||||||
|
String.downcase(contract_address_from_db.value) == contract_address_from_env |> String.downcase() -> |
||||||
|
fetch_and_store_validator_info(address_hash) |
||||||
|
|
||||||
|
true -> |
||||||
|
Validator.drop_all_validators() |
||||||
|
Constants.insert_keys_manager_contract_address(contract_address_from_env) |
||||||
|
fetch_and_store_validator_info(address_hash) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
defp fetch_and_store_validator_info(validator_address) do |
||||||
|
validator = Validator.get_validator_by_address_hash(validator_address) |
||||||
|
%{is_validator: is_validator, payout_key: payout_key} = Reward.get_validator_payout_key_by_mining(validator_address) |
||||||
|
|
||||||
|
Validator.insert_or_update(validator, %{ |
||||||
|
address_hash: validator_address, |
||||||
|
is_validator: is_validator, |
||||||
|
payout_key_hash: payout_key, |
||||||
|
last_block_updated_at: BlockNumber.get_max() |
||||||
|
}) |
||||||
|
end |
||||||
|
|
||||||
|
def start_link(_) do |
||||||
|
GenServer.start_link(__MODULE__, :ok, name: __MODULE__) |
||||||
|
end |
||||||
|
|
||||||
|
@impl true |
||||||
|
def init(opts) do |
||||||
|
{:ok, opts} |
||||||
|
end |
||||||
|
|
||||||
|
@impl true |
||||||
|
def handle_cast({:fetch_or_update, address_hash}, state) do |
||||||
|
actualize_validator_info(address_hash) |
||||||
|
|
||||||
|
{:noreply, state} |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,56 @@ |
|||||||
|
defmodule Explorer.Chain.Validator do |
||||||
|
@moduledoc """ |
||||||
|
Tracks info about POA validator |
||||||
|
""" |
||||||
|
|
||||||
|
use Explorer.Schema |
||||||
|
alias Explorer.Chain.Hash.Address |
||||||
|
alias Explorer.Repo |
||||||
|
|
||||||
|
@primary_key false |
||||||
|
schema "validators" do |
||||||
|
field(:address_hash, Address, primary_key: true) |
||||||
|
field(:is_validator, :boolean) |
||||||
|
field(:payout_key_hash, Address) |
||||||
|
field(:last_block_updated_at, :integer) |
||||||
|
|
||||||
|
timestamps() |
||||||
|
end |
||||||
|
|
||||||
|
def insert_or_update(nil, attrs) do |
||||||
|
attrs |
||||||
|
|> changeset() |
||||||
|
|> Repo.insert() |
||||||
|
end |
||||||
|
|
||||||
|
def insert_or_update(validator, attrs) do |
||||||
|
validator |
||||||
|
|> changeset(attrs) |
||||||
|
|> Repo.update() |
||||||
|
end |
||||||
|
|
||||||
|
def changeset(attrs) do |
||||||
|
%__MODULE__{} |
||||||
|
|> changeset(attrs) |
||||||
|
end |
||||||
|
|
||||||
|
@required_attrs ~w(address_hash)a |
||||||
|
@optional_attrs ~w(is_validator payout_key_hash last_block_updated_at)a |
||||||
|
def changeset(%__MODULE__{} = constant, attrs) do |
||||||
|
constant |
||||||
|
|> cast(attrs, @required_attrs ++ @optional_attrs) |
||||||
|
|> validate_required(@required_attrs) |
||||||
|
|> unique_constraint(:address_hash) |
||||||
|
end |
||||||
|
|
||||||
|
def get_validator_by_address_hash(address_hash) do |
||||||
|
__MODULE__ |
||||||
|
|> where([validator], validator.address_hash == ^address_hash) |
||||||
|
|> Repo.one() |
||||||
|
end |
||||||
|
|
||||||
|
def drop_all_validators() do |
||||||
|
__MODULE__ |
||||||
|
|> Repo.delete_all() |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,21 @@ |
|||||||
|
defmodule Explorer.Repo.Migrations.AddValidatorsAndConstantsTables do |
||||||
|
use Ecto.Migration |
||||||
|
|
||||||
|
def change do |
||||||
|
create table(:constants, primary_key: false) do |
||||||
|
add(:key, :string, primary_key: true, null: false) |
||||||
|
add(:value, :string) |
||||||
|
|
||||||
|
timestamps() |
||||||
|
end |
||||||
|
|
||||||
|
create table(:validators, primary_key: false) do |
||||||
|
add(:address_hash, :bytea, primary_key: true, null: false) |
||||||
|
add(:is_validator, :boolean) |
||||||
|
add(:payout_key_hash, :bytea) |
||||||
|
add(:last_block_updated_at, :bigint) |
||||||
|
|
||||||
|
timestamps() |
||||||
|
end |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue