update staking pools import runner

pull/2036/head
saneery 6 years ago
parent f4c25a38de
commit b13019f4e8
  1. 55
      apps/explorer/lib/explorer/chain/import/runner/staking_pools.ex
  2. 19
      apps/explorer/test/explorer/chain/import/runner/staking_pools_test.exs
  3. 2
      apps/explorer/test/explorer/chain/staking_pool_test.exs
  4. 4
      apps/explorer/test/support/factory.ex

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

@ -5,25 +5,30 @@ defmodule Explorer.Chain.Import.Runner.StakingPoolsTest do
alias Ecto.Multi alias Ecto.Multi
alias Explorer.Chain.Import.Runner.StakingPools alias Explorer.Chain.Import.Runner.StakingPools
alias Explorer.Chain.StakingPool
describe "run/1" do describe "run/1" do
test "insert new pools list" do test "insert new pools list" do
pools = [pool1, pool2, pool3, pool4] = build_list(4, :staking_pool) pools =
[pool1, pool2] =
[params_for(:staking_pool), params_for(:staking_pool)]
|> Enum.map(fn param ->
changeset = StakingPool.changeset(%StakingPool{}, param)
changeset.changes
end)
assert {:ok, %{insert_staking_pools: list}} = run_changes(pools) assert {:ok, %{insert_staking_pools: list}} = run_changes(pools)
assert Enum.count(list) == Enum.count(pools) assert Enum.count(list) == Enum.count(pools)
saved_list = saved_list =
Explorer.Chain.Address.Name Explorer.Chain.StakingPool
|> Repo.all() |> Repo.all()
|> Enum.reduce(%{}, fn pool, acc -> |> Enum.reduce(%{}, fn pool, acc ->
Map.put(acc, pool.address_hash, pool) Map.put(acc, pool.staking_address_hash, pool)
end) end)
assert saved_list[pool1.address_hash].metadata["staked_ratio"] == 0.25 assert saved_list[pool1.staking_address_hash].staked_ratio == Decimal.from_float(0.5)
assert saved_list[pool2.address_hash].metadata["staked_ratio"] == 0.25 assert saved_list[pool2.staking_address_hash].staked_ratio == Decimal.from_float(0.5)
assert saved_list[pool3.address_hash].metadata["staked_ratio"] == 0.25
assert saved_list[pool4.address_hash].metadata["staked_ratio"] == 0.25
end end
end end

@ -6,7 +6,7 @@ defmodule Explorer.Chain.StakingPoolTest do
describe "changeset/2" do describe "changeset/2" do
test "with valid attributes" do test "with valid attributes" do
params = params_for(:staking_pool) params = params_for(:staking_pool)
changeset = StakingPool.changeset(%StakingPool{}, params) |> IO.inspect() changeset = StakingPool.changeset(%StakingPool{}, params)
assert changeset.valid? assert changeset.valid?
end end

@ -626,10 +626,10 @@ defmodule Explorer.Factory do
self_staked_amount: wei_per_ether * 300, self_staked_amount: wei_per_ether * 300,
was_banned_count: 0, was_banned_count: 0,
was_validator_count: 1, was_validator_count: 1,
min_delegators_stake: wei_per_ether * 100, min_delegator_stake: wei_per_ether * 100,
min_candidate_stake: wei_per_ether * 200, min_candidate_stake: wei_per_ether * 200,
staked_ratio: 0, staked_ratio: 0,
likelihood: 0, likelihood: 0
} }
end end
end end

Loading…
Cancel
Save