From 03fd6f954080be1fa4abaaeb0a3073d29936fb7f Mon Sep 17 00:00:00 2001 From: saneery Date: Tue, 21 May 2019 15:21:00 +0300 Subject: [PATCH] create staking_pool schema --- .../lib/explorer/chain/staking_pool.ex | 73 +++++++++++++++++++ .../20190521104412_create_staking_pools.exs | 28 +++++++ .../test/explorer/chain/staking_pool_test.exs | 18 +++++ apps/explorer/test/support/factory.ex | 37 +++++----- 4 files changed, 139 insertions(+), 17 deletions(-) create mode 100644 apps/explorer/lib/explorer/chain/staking_pool.ex create mode 100644 apps/explorer/priv/repo/migrations/20190521104412_create_staking_pools.exs create mode 100644 apps/explorer/test/explorer/chain/staking_pool_test.exs diff --git a/apps/explorer/lib/explorer/chain/staking_pool.ex b/apps/explorer/lib/explorer/chain/staking_pool.ex new file mode 100644 index 0000000000..59bffdd43e --- /dev/null +++ b/apps/explorer/lib/explorer/chain/staking_pool.ex @@ -0,0 +1,73 @@ +defmodule Explorer.Chain.StakingPool do + @moduledoc """ + The representation of staking pool from POSDAO network. + Staking pools might be candidate or validator. + """ + use Ecto.Schema + import Ecto.Changeset + + alias Explorer.Chain.{ + Wei, + Address, + Hash + } + + @attrs ~w( + is_active delegators_count staked_amount self_staked_amount is_validator + was_validator_count is_banned was_banned_count banned_until likelihood + staked_ratio min_delegators_stake min_candidate_stake + staking_address_hash mining_address_hash + )a + + schema "staking_pools" do + field(:banned_until, :integer) + field(:delegators_count, :integer) + field(:is_active, :boolean, default: false) + field(:is_banned, :boolean, default: false) + field(:is_validator, :boolean, default: false) + field(:likelihood, :decimal) + field(:staked_ratio, :decimal) + field(:min_candidate_stake, Wei) + field(:min_delegators_stake, Wei) + field(:self_staked_amount, Wei) + field(:staked_amount, Wei) + field(:was_banned_count, :integer) + field(:was_validator_count, :integer) + + belongs_to( + :staking_address, + Address, + foreign_key: :staking_address_hash, + references: :hash, + type: Hash.Address + ) + + belongs_to( + :mining_address, + Address, + foreign_key: :mining_address_hash, + references: :hash, + type: Hash.Address + ) + + timestamps() + end + + @doc false + def changeset(staking_pool, attrs) do + staking_pool + |> cast(attrs, @attrs) + |> validate_required(@attrs) + |> validate_staked_amount() + end + + defp validate_staked_amount(%{valid?: false} = c), do: c + + defp validate_staked_amount(changeset) do + if get_field(changeset, :staked_amount) < get_field(changeset, :self_staked_amount) do + add_error(changeset, :staked_amount, "must be greater than self_staked_amount") + else + changeset + end + end +end diff --git a/apps/explorer/priv/repo/migrations/20190521104412_create_staking_pools.exs b/apps/explorer/priv/repo/migrations/20190521104412_create_staking_pools.exs new file mode 100644 index 0000000000..2499641eda --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20190521104412_create_staking_pools.exs @@ -0,0 +1,28 @@ +defmodule Explorer.Repo.Migrations.CreateStakingPools do + use Ecto.Migration + + def change do + create table(:staking_pools) do + add(:is_active, :boolean, default: false, null: false) + add(:delegators_count, :integer) + add(:staked_amount, :numeric, precision: 100) + add(:self_staked_amount, :numeric, precision: 100) + add(:is_validator, :boolean, default: false, null: false) + add(:was_validator_count, :integer) + add(:is_banned, :boolean, default: false, null: false) + add(:was_banned_count, :integer) + add(:banned_until, :bigint) + add(:likelihood, :decimal) + add(:staked_ratio, :decimal) + add(:min_delegators_stake, :numeric, precision: 100) + add(:min_candidate_stake, :numeric, precision: 100) + add(:staking_address_hash, references(:addresses, on_delete: :nothing, column: :hash, type: :bytea)) + add(:mining_address_hash, references(:addresses, on_delete: :nothing, column: :hash, type: :bytea)) + + timestamps() + end + + create(index(:staking_pools, [:staking_address_hash])) + create(index(:staking_pools, [:mining_address_hash])) + end +end diff --git a/apps/explorer/test/explorer/chain/staking_pool_test.exs b/apps/explorer/test/explorer/chain/staking_pool_test.exs new file mode 100644 index 0000000000..78d01a0f19 --- /dev/null +++ b/apps/explorer/test/explorer/chain/staking_pool_test.exs @@ -0,0 +1,18 @@ +defmodule Explorer.Chain.StakingPoolTest do + use Explorer.DataCase + + alias Explorer.Chain.StakingPool + + describe "changeset/2" do + test "with valid attributes" do + params = params_for(:staking_pool) + changeset = StakingPool.changeset(%StakingPool{}, params) |> IO.inspect() + assert changeset.valid? + end + + test "with invalid attributes" do + changeset = StakingPool.changeset(%StakingPool{}, %{staking_address_hash: 0}) + refute changeset.valid? + end + end +end diff --git a/apps/explorer/test/support/factory.ex b/apps/explorer/test/support/factory.ex index 115b07e066..6a08c2df8b 100644 --- a/apps/explorer/test/support/factory.ex +++ b/apps/explorer/test/support/factory.ex @@ -26,7 +26,8 @@ defmodule Explorer.Factory do SmartContract, Token, TokenTransfer, - Transaction + Transaction, + StakingPool } alias Explorer.Market.MarketHistory @@ -611,22 +612,24 @@ defmodule Explorer.Factory do end def staking_pool_factory do - %{ - address_hash: address_hash(), - metadata: %{ - banned_unitil: 0, - delegators_count: 0, - is_active: true, - is_banned: false, - is_validator: true, - mining_address: address_hash(), - retries_count: 1, - staked_amount: 25, - was_banned_count: 0, - was_validator_count: 1 - }, - name: "anonymous", - primary: true + wei_per_ether = 1_000_000_000_000_000_000 + + %StakingPool{ + staking_address_hash: address_hash(), + mining_address_hash: address_hash(), + banned_until: 0, + delegators_count: 0, + is_active: true, + is_banned: false, + is_validator: true, + staked_amount: wei_per_ether * 500, + self_staked_amount: wei_per_ether * 300, + was_banned_count: 0, + was_validator_count: 1, + min_delegators_stake: wei_per_ether * 100, + min_candidate_stake: wei_per_ether * 200, + staked_ratio: 0, + likelihood: 0, } end end