|
|
|
@ -443,14 +443,14 @@ defmodule Explorer.Staking.ContractState do |
|
|
|
|
global_responses.inactive_pools |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
%{ |
|
|
|
|
pool_staking_responses: pool_staking_responses, |
|
|
|
|
pool_mining_responses: pool_mining_responses, |
|
|
|
|
staker_responses: staker_responses |
|
|
|
|
} = get_responses(pools, block_number, contracts, abi) |
|
|
|
|
# read pool info from the contracts by its staking address |
|
|
|
|
pool_staking_responses = get_pool_staking_responses(pools, block_number, contracts, abi) |
|
|
|
|
|
|
|
|
|
# to keep sort order when using `perform_grouped_requests` (see below) |
|
|
|
|
pool_ids = Enum.map(pool_staking_responses, fn {pool_id, _} -> pool_id end) |
|
|
|
|
# read pool info from the contracts by its mining address |
|
|
|
|
pool_mining_responses = get_pool_mining_responses(pools, pool_staking_responses, block_number, contracts, abi) |
|
|
|
|
|
|
|
|
|
# read info of each staker from the contracts |
|
|
|
|
staker_responses = get_staker_responses(pool_staking_responses, block_number, contracts, abi) |
|
|
|
|
|
|
|
|
|
# call `BlockReward.validatorShare` function for each pool |
|
|
|
|
# to get validator's reward share of the pool (needed for the `Delegators` list in UI) |
|
|
|
@ -458,7 +458,6 @@ defmodule Explorer.Staking.ContractState do |
|
|
|
|
get_candidate_reward_responses( |
|
|
|
|
pool_staking_responses, |
|
|
|
|
global_responses, |
|
|
|
|
pool_ids, |
|
|
|
|
contracts, |
|
|
|
|
abi, |
|
|
|
|
block_number |
|
|
|
@ -466,11 +465,10 @@ defmodule Explorer.Staking.ContractState do |
|
|
|
|
|
|
|
|
|
# call `BlockReward.delegatorShare` function for each delegator |
|
|
|
|
# to get their reward share of the pool (needed for the `Delegators` list in UI) |
|
|
|
|
delegator_responses = get_delegator_responses(staker_responses) |
|
|
|
|
|
|
|
|
|
delegator_reward_responses = |
|
|
|
|
get_delegator_reward_responses( |
|
|
|
|
delegator_responses, |
|
|
|
|
staker_responses |
|
|
|
|
|> get_delegator_responses() |
|
|
|
|
|> get_delegator_reward_responses( |
|
|
|
|
pool_staking_responses, |
|
|
|
|
global_responses, |
|
|
|
|
contracts, |
|
|
|
@ -609,63 +607,43 @@ defmodule Explorer.Staking.ContractState do |
|
|
|
|
|> Map.new(fn {mining_address, resp} -> {mining_address, address_string_to_bytes(resp.staking_address).bytes} end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_responses(pools, block_number, contracts, abi) do |
|
|
|
|
# read pool info from the contracts by its staking address |
|
|
|
|
pool_staking_responses = |
|
|
|
|
pools |
|
|
|
|
|> Enum.map(&ContractReader.pool_staking_requests(&1, block_number)) |
|
|
|
|
|> ContractReader.perform_grouped_requests(pools, contracts, abi) |
|
|
|
|
|
|
|
|
|
# read pool info from the contracts by its mining address |
|
|
|
|
pool_mining_responses = |
|
|
|
|
pools |
|
|
|
|
|> Enum.map(&ContractReader.pool_mining_requests(pool_staking_responses[&1].mining_address_hash, block_number)) |
|
|
|
|
|> ContractReader.perform_grouped_requests(pools, contracts, abi) |
|
|
|
|
|
|
|
|
|
# get a flat list of all stakers in the form of {pool_id, pool_staking_address, staker_address, is_active} |
|
|
|
|
stakers = |
|
|
|
|
Enum.flat_map(pool_staking_responses, fn {pool_id, resp} -> |
|
|
|
|
[{pool_id, resp.staking_address_hash, resp.staking_address_hash, true}] ++ |
|
|
|
|
Enum.map(resp.active_delegators, &{pool_id, resp.staking_address_hash, &1, true}) ++ |
|
|
|
|
Enum.map(resp.inactive_delegators, &{pool_id, resp.staking_address_hash, &1, false}) |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
# read info of each staker from the contracts |
|
|
|
|
staker_responses = |
|
|
|
|
stakers |
|
|
|
|
|> Enum.map(fn {pool_id, pool_staking_address, staker_address, _is_active} -> |
|
|
|
|
ContractReader.staker_requests(pool_id, pool_staking_address, staker_address, block_number) |
|
|
|
|
end) |
|
|
|
|
|> ContractReader.perform_grouped_requests(stakers, contracts, abi) |
|
|
|
|
|
|
|
|
|
%{ |
|
|
|
|
pool_staking_responses: pool_staking_responses, |
|
|
|
|
pool_mining_responses: pool_mining_responses, |
|
|
|
|
staker_responses: staker_responses |
|
|
|
|
} |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_candidate_reward_responses( |
|
|
|
|
pool_staking_responses, |
|
|
|
|
global_responses, |
|
|
|
|
pool_ids, |
|
|
|
|
contracts, |
|
|
|
|
abi, |
|
|
|
|
block_number |
|
|
|
|
) do |
|
|
|
|
pool_staking_responses |
|
|
|
|
|> Enum.map(fn {_pool_id, resp} -> |
|
|
|
|
ContractReader.validator_reward_request( |
|
|
|
|
[ |
|
|
|
|
global_responses.epoch_number, |
|
|
|
|
resp.self_staked_amount, |
|
|
|
|
resp.total_staked_amount, |
|
|
|
|
1000_000 |
|
|
|
|
], |
|
|
|
|
block_number |
|
|
|
|
) |
|
|
|
|
# to keep sort order when using `perform_grouped_requests` (see below) |
|
|
|
|
pool_ids = Enum.map(pool_staking_responses, fn {pool_id, _} -> pool_id end) |
|
|
|
|
|
|
|
|
|
requests = |
|
|
|
|
pool_staking_responses |
|
|
|
|
|> Enum.map(fn {_pool_id, resp} -> |
|
|
|
|
ContractReader.validator_reward_request( |
|
|
|
|
[ |
|
|
|
|
global_responses.epoch_number, |
|
|
|
|
resp.self_staked_amount, |
|
|
|
|
resp.total_staked_amount, |
|
|
|
|
1000_000 |
|
|
|
|
], |
|
|
|
|
block_number |
|
|
|
|
) |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
chunk_size = 100 |
|
|
|
|
chunks = 0..trunc(ceil(Enum.count(pool_ids) / chunk_size) - 1) |
|
|
|
|
|
|
|
|
|
Enum.reduce(chunks, %{}, fn i, acc -> |
|
|
|
|
pool_ids_slice = Enum.slice(pool_ids, i * chunk_size, chunk_size) |
|
|
|
|
|
|
|
|
|
responses = |
|
|
|
|
requests |
|
|
|
|
|> Enum.slice(i * chunk_size, chunk_size) |
|
|
|
|
|> ContractReader.perform_grouped_requests(pool_ids_slice, contracts, abi) |
|
|
|
|
|
|
|
|
|
Map.merge(acc, responses) |
|
|
|
|
end) |
|
|
|
|
|> ContractReader.perform_grouped_requests(pool_ids, contracts, abi) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_delegator_responses(staker_responses) do |
|
|
|
@ -690,22 +668,36 @@ defmodule Explorer.Staking.ContractState do |
|
|
|
|
# to keep sort order when using `perform_grouped_requests` (see below) |
|
|
|
|
delegator_keys = Enum.map(delegator_responses, fn {key, _} -> key end) |
|
|
|
|
|
|
|
|
|
delegator_responses |
|
|
|
|
|> Enum.map(fn {{pool_id, _pool_staking_address, _staker_address, _is_active}, resp} -> |
|
|
|
|
staking_resp = pool_staking_responses[pool_id] |
|
|
|
|
requests = |
|
|
|
|
delegator_responses |
|
|
|
|
|> Enum.map(fn {{pool_id, _pool_staking_address, _staker_address, _is_active}, resp} -> |
|
|
|
|
staking_resp = pool_staking_responses[pool_id] |
|
|
|
|
|
|
|
|
|
ContractReader.delegator_reward_request( |
|
|
|
|
[ |
|
|
|
|
global_responses.epoch_number, |
|
|
|
|
resp.stake_amount, |
|
|
|
|
staking_resp.self_staked_amount, |
|
|
|
|
staking_resp.total_staked_amount, |
|
|
|
|
1000_000 |
|
|
|
|
], |
|
|
|
|
block_number |
|
|
|
|
) |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
ContractReader.delegator_reward_request( |
|
|
|
|
[ |
|
|
|
|
global_responses.epoch_number, |
|
|
|
|
resp.stake_amount, |
|
|
|
|
staking_resp.self_staked_amount, |
|
|
|
|
staking_resp.total_staked_amount, |
|
|
|
|
1000_000 |
|
|
|
|
], |
|
|
|
|
block_number |
|
|
|
|
) |
|
|
|
|
chunk_size = 100 |
|
|
|
|
chunks = 0..trunc(ceil(Enum.count(delegator_keys) / chunk_size) - 1) |
|
|
|
|
|
|
|
|
|
Enum.reduce(chunks, %{}, fn i, acc -> |
|
|
|
|
delegator_keys_slice = Enum.slice(delegator_keys, i * chunk_size, chunk_size) |
|
|
|
|
|
|
|
|
|
responses = |
|
|
|
|
requests |
|
|
|
|
|> Enum.slice(i * chunk_size, chunk_size) |
|
|
|
|
|> ContractReader.perform_grouped_requests(delegator_keys_slice, contracts, abi) |
|
|
|
|
|
|
|
|
|
Map.merge(acc, responses) |
|
|
|
|
end) |
|
|
|
|
|> ContractReader.perform_grouped_requests(delegator_keys, contracts, abi) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_delegator_entries(staker_responses, delegator_reward_responses) do |
|
|
|
@ -726,6 +718,68 @@ defmodule Explorer.Staking.ContractState do |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_pool_mining_responses(pools, pool_staking_responses, block_number, contracts, abi) do |
|
|
|
|
# we split batch requests by chunks |
|
|
|
|
chunk_size = 80 |
|
|
|
|
chunks = 0..trunc(ceil(Enum.count(pools) / chunk_size) - 1) |
|
|
|
|
|
|
|
|
|
Enum.reduce(chunks, %{}, fn i, acc -> |
|
|
|
|
pools_slice = Enum.slice(pools, i * chunk_size, chunk_size) |
|
|
|
|
|
|
|
|
|
responses = |
|
|
|
|
pools_slice |
|
|
|
|
|> Enum.map(&ContractReader.pool_mining_requests(pool_staking_responses[&1].mining_address_hash, block_number)) |
|
|
|
|
|> ContractReader.perform_grouped_requests(pools_slice, contracts, abi) |
|
|
|
|
|
|
|
|
|
Map.merge(acc, responses) |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_pool_staking_responses(pools, block_number, contracts, abi) do |
|
|
|
|
# we split batch requests by chunks |
|
|
|
|
chunk_size = 20 |
|
|
|
|
chunks = 0..trunc(ceil(Enum.count(pools) / chunk_size) - 1) |
|
|
|
|
|
|
|
|
|
Enum.reduce(chunks, %{}, fn i, acc -> |
|
|
|
|
pools_slice = Enum.slice(pools, i * chunk_size, chunk_size) |
|
|
|
|
|
|
|
|
|
responses = |
|
|
|
|
pools_slice |
|
|
|
|
|> Enum.map(&ContractReader.pool_staking_requests(&1, block_number)) |
|
|
|
|
|> ContractReader.perform_grouped_requests(pools_slice, contracts, abi) |
|
|
|
|
|
|
|
|
|
Map.merge(acc, responses) |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_staker_responses(pool_staking_responses, block_number, contracts, abi) do |
|
|
|
|
# get a flat list of all stakers in the form of {pool_id, pool_staking_address, staker_address, is_active} |
|
|
|
|
stakers = |
|
|
|
|
pool_staking_responses |
|
|
|
|
|> Enum.flat_map(fn {pool_id, resp} -> |
|
|
|
|
[{pool_id, resp.staking_address_hash, resp.staking_address_hash, true}] ++ |
|
|
|
|
Enum.map(resp.active_delegators, &{pool_id, resp.staking_address_hash, &1, true}) ++ |
|
|
|
|
Enum.map(resp.inactive_delegators, &{pool_id, resp.staking_address_hash, &1, false}) |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
# we split batch requests by chunks |
|
|
|
|
chunk_size = 100 |
|
|
|
|
chunks = 0..trunc(ceil(Enum.count(stakers) / chunk_size) - 1) |
|
|
|
|
|
|
|
|
|
Enum.reduce(chunks, %{}, fn i, acc -> |
|
|
|
|
stakers_slice = Enum.slice(stakers, i * chunk_size, chunk_size) |
|
|
|
|
|
|
|
|
|
responses = |
|
|
|
|
stakers_slice |
|
|
|
|
|> Enum.map(fn {pool_id, pool_staking_address, staker_address, _is_active} -> |
|
|
|
|
ContractReader.staker_requests(pool_id, pool_staking_address, staker_address, block_number) |
|
|
|
|
end) |
|
|
|
|
|> ContractReader.perform_grouped_requests(stakers_slice, contracts, abi) |
|
|
|
|
|
|
|
|
|
Map.merge(acc, responses) |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp get_validator_min_reward_percent(epoch_number, block_number, contracts, abi) do |
|
|
|
|
ContractReader.perform_requests( |
|
|
|
|
ContractReader.validator_min_reward_percent_request(epoch_number, block_number), |
|
|
|
|