|
|
|
@ -1,12 +1,12 @@ |
|
|
|
|
defmodule Explorer.Chain.Import.Runner.StakingPools do |
|
|
|
|
@moduledoc """ |
|
|
|
|
Bulk imports staking pools to Address.Name tabe. |
|
|
|
|
Bulk imports staking pools to StakingPool tabe. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
require Ecto.Query |
|
|
|
|
|
|
|
|
|
alias Ecto.{Changeset, Multi, Repo} |
|
|
|
|
alias Explorer.Chain.{Address, Import} |
|
|
|
|
alias Explorer.Chain.{Import, StakingPool, Wei} |
|
|
|
|
|
|
|
|
|
import Ecto.Query, only: [from: 2] |
|
|
|
|
|
|
|
|
@ -15,10 +15,10 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do |
|
|
|
|
# milliseconds |
|
|
|
|
@timeout 60_000 |
|
|
|
|
|
|
|
|
|
@type imported :: [Address.Name.t()] |
|
|
|
|
@type imported :: [StakingPool.t()] |
|
|
|
|
|
|
|
|
|
@impl Import.Runner |
|
|
|
|
def ecto_schema_module, do: Address.Name |
|
|
|
|
def ecto_schema_module, do: StakingPool |
|
|
|
|
|
|
|
|
|
@impl Import.Runner |
|
|
|
|
def option_key, do: :staking_pools |
|
|
|
@ -53,17 +53,15 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do |
|
|
|
|
def timeout, do: @timeout |
|
|
|
|
|
|
|
|
|
defp mark_as_deleted(repo, changes_list, %{timeout: timeout}) when is_list(changes_list) do |
|
|
|
|
addresses = Enum.map(changes_list, & &1.address_hash) |
|
|
|
|
addresses = Enum.map(changes_list, & &1.staking_address_hash) |
|
|
|
|
|
|
|
|
|
query = |
|
|
|
|
from( |
|
|
|
|
address_name in Address.Name, |
|
|
|
|
where: |
|
|
|
|
address_name.address_hash not in ^addresses and |
|
|
|
|
fragment("(?->>'is_pool')::boolean = true", address_name.metadata), |
|
|
|
|
pool in StakingPool, |
|
|
|
|
where: pool.staking_address_hash not in ^addresses, |
|
|
|
|
update: [ |
|
|
|
|
set: [ |
|
|
|
|
metadata: fragment("? || '{\"deleted\": true}'::jsonb", address_name.metadata) |
|
|
|
|
is_deleted: true |
|
|
|
|
] |
|
|
|
|
] |
|
|
|
|
) |
|
|
|
@ -83,7 +81,7 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do |
|
|
|
|
required(:timeout) => timeout, |
|
|
|
|
required(:timestamps) => Import.timestamps() |
|
|
|
|
}) :: |
|
|
|
|
{:ok, [Address.Name.t()]} |
|
|
|
|
{:ok, [StakingPool.t()]} |
|
|
|
|
| {:error, [Changeset.t()]} |
|
|
|
|
defp insert(repo, changes_list, %{timeout: timeout, timestamps: timestamps} = options) when is_list(changes_list) do |
|
|
|
|
on_conflict = Map.get_lazy(options, :on_conflict, &default_on_conflict/0) |
|
|
|
@ -92,10 +90,10 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do |
|
|
|
|
Import.insert_changes_list( |
|
|
|
|
repo, |
|
|
|
|
stakes_ratio(changes_list), |
|
|
|
|
conflict_target: {:unsafe_fragment, "(address_hash) where \"primary\" = true"}, |
|
|
|
|
conflict_target: :staking_address_hash, |
|
|
|
|
on_conflict: on_conflict, |
|
|
|
|
for: Address.Name, |
|
|
|
|
returning: [:address_hash], |
|
|
|
|
for: StakingPool, |
|
|
|
|
returning: [:staking_address_hash], |
|
|
|
|
timeout: timeout, |
|
|
|
|
timestamps: timestamps |
|
|
|
|
) |
|
|
|
@ -103,11 +101,23 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do |
|
|
|
|
|
|
|
|
|
defp default_on_conflict do |
|
|
|
|
from( |
|
|
|
|
name in Address.Name, |
|
|
|
|
name in StakingPool, |
|
|
|
|
update: [ |
|
|
|
|
set: [ |
|
|
|
|
name: fragment("EXCLUDED.name"), |
|
|
|
|
metadata: fragment("EXCLUDED.metadata"), |
|
|
|
|
mining_address_hash: fragment("EXCLUDED.mining_address_hash"), |
|
|
|
|
delegators_count: fragment("EXCLUDED.delegators_count"), |
|
|
|
|
is_active: fragment("EXCLUDED.is_active"), |
|
|
|
|
is_banned: fragment("EXCLUDED.is_banned"), |
|
|
|
|
is_validator: fragment("EXCLUDED.is_validator"), |
|
|
|
|
likelihood: fragment("EXCLUDED.likelihood"), |
|
|
|
|
staked_ratio: fragment("EXCLUDED.staked_ratio"), |
|
|
|
|
min_candidate_stake: fragment("EXCLUDED.min_candidate_stake"), |
|
|
|
|
min_delegator_stake: fragment("EXCLUDED.min_delegator_stake"), |
|
|
|
|
self_staked_amount: fragment("EXCLUDED.self_staked_amount"), |
|
|
|
|
staked_amount: fragment("EXCLUDED.staked_amount"), |
|
|
|
|
was_banned_count: fragment("EXCLUDED.was_banned_count"), |
|
|
|
|
was_validator_count: fragment("EXCLUDED.was_validator_count"), |
|
|
|
|
is_deleted: fragment("EXCLUDED.is_deleted"), |
|
|
|
|
inserted_at: fragment("LEAST(?, EXCLUDED.inserted_at)", name.inserted_at), |
|
|
|
|
updated_at: fragment("GREATEST(?, EXCLUDED.updated_at)", name.updated_at) |
|
|
|
|
] |
|
|
|
@ -117,17 +127,18 @@ defmodule Explorer.Chain.Import.Runner.StakingPools do |
|
|
|
|
|
|
|
|
|
# Calculates staked ratio for each pool |
|
|
|
|
defp stakes_ratio(pools) do |
|
|
|
|
active_pools = Enum.filter(pools, & &1.metadata[:is_active]) |
|
|
|
|
active_pools = Enum.filter(pools, & &1.is_active) |
|
|
|
|
|
|
|
|
|
stakes_total = |
|
|
|
|
Enum.reduce(pools, 0, fn pool, acc -> |
|
|
|
|
acc + pool.metadata[:staked_amount] |
|
|
|
|
pools |
|
|
|
|
|> Enum.reduce(0, fn pool, acc -> |
|
|
|
|
acc + Wei.to(pool.staked_amount, :integer) |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
Enum.map(active_pools, fn pool -> |
|
|
|
|
staked_ratio = if stakes_total > 0, do: pool.metadata[:staked_amount] / stakes_total, else: 0 |
|
|
|
|
staked_ratio = if stakes_total > 0, do: Wei.to(pool.staked_amount, :integer) / stakes_total, else: 0 |
|
|
|
|
|
|
|
|
|
put_in(pool, [:metadata, :staked_ratio], staked_ratio) |
|
|
|
|
Map.put(pool, :staked_ratio, staked_ratio) |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|