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
@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

@ -5,25 +5,30 @@ defmodule Explorer.Chain.Import.Runner.StakingPoolsTest do
alias Ecto.Multi
alias Explorer.Chain.Import.Runner.StakingPools
alias Explorer.Chain.StakingPool
describe "run/1" 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 Enum.count(list) == Enum.count(pools)
saved_list =
Explorer.Chain.Address.Name
Explorer.Chain.StakingPool
|> Repo.all()
|> Enum.reduce(%{}, fn pool, acc ->
Map.put(acc, pool.address_hash, pool)
Map.put(acc, pool.staking_address_hash, pool)
end)
assert saved_list[pool1.address_hash].metadata["staked_ratio"] == 0.25
assert saved_list[pool2.address_hash].metadata["staked_ratio"] == 0.25
assert saved_list[pool3.address_hash].metadata["staked_ratio"] == 0.25
assert saved_list[pool4.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.staking_address_hash].staked_ratio == Decimal.from_float(0.5)
end
end

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

@ -626,10 +626,10 @@ defmodule Explorer.Factory do
self_staked_amount: wei_per_ether * 300,
was_banned_count: 0,
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,
staked_ratio: 0,
likelihood: 0,
likelihood: 0
}
end
end

Loading…
Cancel
Save