Use unique pool ID instead of staking address in Staking DApp

to follow the changes 51ae492a2e...7e38982f1a
pull/3712/head
POA 4 years ago
parent 218ad986a9
commit d66e4da176
  1. 2
      .dialyzer-ignore
  2. 10
      apps/block_scout_web/assets/js/pages/stakes/become_candidate.js
  3. 2
      apps/block_scout_web/assets/js/pages/stakes/utils.js
  4. 19
      apps/block_scout_web/lib/block_scout_web/channels/stakes_channel.ex
  5. 18
      apps/block_scout_web/priv/gettext/default.pot
  6. 23
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  7. 92
      apps/explorer/lib/explorer/staking/contract_reader.ex
  8. 104
      apps/explorer/lib/explorer/staking/contract_state.ex
  9. 92
      apps/explorer/lib/explorer/staking/stake_snapshotting.ex
  10. 14
      apps/explorer/priv/contracts_abi/posdao/BlockRewardAuRa.json
  11. 1
      apps/explorer/priv/contracts_abi/posdao/README.md
  12. 109
      apps/explorer/priv/contracts_abi/posdao/StakingAuRa.json
  13. 209
      apps/explorer/priv/contracts_abi/posdao/ValidatorSetAuRa.json
  14. 108
      apps/explorer/test/explorer/staking/contract_state_test.exs

@ -25,4 +25,4 @@ lib/explorer/exchange_rates/source.ex:113
lib/explorer/smart_contract/verifier.ex:89
lib/block_scout_web/templates/address_contract/index.html.eex:118
lib/explorer/staking/stake_snapshotting.ex:15: Function do_snapshotting/6 has no local return
lib/explorer/staking/stake_snapshotting.ex:184
lib/explorer/staking/stake_snapshotting.ex:202

@ -86,10 +86,10 @@ async function becomeCandidate ($modal, store, msg) {
if (!isStakingAllowed(state)) return false
const validatorSetContract = state.validatorSetContract
const stakingAddress = await validatorSetContract.methods.stakingByMiningAddress(miningAddress).call()
const hasEverBeenMiningAddress = await validatorSetContract.methods.hasEverBeenMiningAddress(miningAddress).call()
if (stakingAddress !== '0x0000000000000000000000000000000000000000') {
displayInputError($miningAddressInput, `This mining address is already bound to another staking address (<span title="${stakingAddress}">${shortenAddress(stakingAddress)}</span>). Please use another mining address.`)
if (hasEverBeenMiningAddress) {
displayInputError($miningAddressInput, 'This mining address has already been used for another pool. Please use another mining address.')
$modal.find('form button').blur()
return false
}
@ -102,10 +102,6 @@ async function becomeCandidate ($modal, store, msg) {
}
}
function shortenAddress (address) {
return address.substring(0, 6) + '–' + address.substring(address.length - 6)
}
function isCandidateStakeValid (value, store, msg) {
const decimals = store.getState().tokenDecimals
const minStake = new BigNumber(msg.min_candidate_stake)

@ -24,7 +24,7 @@ export async function makeContractCall (call, store, gasLimit, callbackFunc) {
return callbackFunc('Web3 is undefined. Please, contact support.')
}
const gasPrice = web3.utils.toWei('1', 'gwei')
const gasPrice = web3.utils.toWei('20', 'gwei')
if (!gasLimit) {
try {

@ -480,6 +480,7 @@ defmodule BlockScoutWeb.StakesChannel do
try do
json_rpc_named_arguments = Application.get_env(:explorer, :json_rpc_named_arguments)
staking_contract = ContractState.get(:staking_contract)
validator_set_contract = ContractState.get(:validator_set_contract)
responses =
staker
@ -500,15 +501,23 @@ defmodule BlockScoutWeb.StakesChannel do
|> ContractReader.get_delegator_pools_request(i * chunk_size, chunk_size)
|> ContractReader.perform_requests(%{staking: staking_contract.address}, staking_contract.abi)
acc ++
Enum.map(responses[:pools], fn pool_staking_address ->
address_bytes_to_string(pool_staking_address)
end)
acc ++ responses[:pools]
end)
else
[]
end
# convert pool ids to staking addresses
pools =
pools
|> Enum.map(&ContractReader.staking_by_id_request(&1))
|> ContractReader.perform_grouped_requests(
pools,
%{validator_set: validator_set_contract.address},
validator_set_contract.abi
)
|> Enum.map(fn {_, resp} -> resp.staking_address end)
# if `staker` is a pool, prepend its address to the `pools` array
pools =
if socket.assigns[:mining_address] != nil do
@ -730,8 +739,6 @@ defmodule BlockScoutWeb.StakesChannel do
end
end
defp address_bytes_to_string(hash), do: "0x" <> Base.encode16(hash, case: :lower)
defp array_to_ranges(numbers, prev_ranges \\ []) do
length = Enum.count(numbers)

@ -2183,7 +2183,7 @@ msgid "It's me!"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:762
#: lib/block_scout_web/channels/stakes_channel.ex:769
msgid "JSON RPC error"
msgstr ""
@ -2258,7 +2258,7 @@ msgid "Pool"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:818
#: lib/block_scout_web/channels/stakes_channel.ex:825
msgid "Pools searching is already in progress for this address"
msgstr ""
@ -2284,7 +2284,7 @@ msgid "Remove My Pool"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:859
#: lib/block_scout_web/channels/stakes_channel.ex:866
msgid "Reward calculating is already in progress for this address"
msgstr ""
@ -2358,7 +2358,7 @@ msgid "Stakes Ratio"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:862
#: lib/block_scout_web/channels/stakes_channel.ex:869
msgid "Staking epochs are not specified or not in the allowed range"
msgstr ""
@ -2453,19 +2453,19 @@ msgid "Unable to find any pools you could claim a reward from."
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:825
#: lib/block_scout_web/channels/stakes_channel.ex:872
#: lib/block_scout_web/channels/stakes_channel.ex:832
#: lib/block_scout_web/channels/stakes_channel.ex:879
msgid "Unknown address of Staking contract. Please, contact support"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:865
#: lib/block_scout_web/channels/stakes_channel.ex:872
msgid "Unknown pool staking address. Please, contact support"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:821
#: lib/block_scout_web/channels/stakes_channel.ex:868
#: lib/block_scout_web/channels/stakes_channel.ex:828
#: lib/block_scout_web/channels/stakes_channel.ex:875
msgid "Unknown staker address. Please, choose your account in MetaMask"
msgstr ""

@ -2183,7 +2183,7 @@ msgid "It's me!"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:762
#: lib/block_scout_web/channels/stakes_channel.ex:769
msgid "JSON RPC error"
msgstr ""
@ -2258,7 +2258,7 @@ msgid "Pool"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:818
#: lib/block_scout_web/channels/stakes_channel.ex:825
msgid "Pools searching is already in progress for this address"
msgstr ""
@ -2284,7 +2284,7 @@ msgid "Remove My Pool"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:859
#: lib/block_scout_web/channels/stakes_channel.ex:866
msgid "Reward calculating is already in progress for this address"
msgstr ""
@ -2358,7 +2358,7 @@ msgid "Stakes Ratio"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:862
#: lib/block_scout_web/channels/stakes_channel.ex:869
msgid "Staking epochs are not specified or not in the allowed range"
msgstr ""
@ -2453,19 +2453,19 @@ msgid "Unable to find any pools you could claim a reward from."
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:825
#: lib/block_scout_web/channels/stakes_channel.ex:872
#: lib/block_scout_web/channels/stakes_channel.ex:832
#: lib/block_scout_web/channels/stakes_channel.ex:879
msgid "Unknown address of Staking contract. Please, contact support"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:865
#: lib/block_scout_web/channels/stakes_channel.ex:872
msgid "Unknown pool staking address. Please, contact support"
msgstr ""
#, elixir-format
#: lib/block_scout_web/channels/stakes_channel.ex:821
#: lib/block_scout_web/channels/stakes_channel.ex:868
#: lib/block_scout_web/channels/stakes_channel.ex:828
#: lib/block_scout_web/channels/stakes_channel.ex:875
msgid "Unknown staker address. Please, choose your account in MetaMask"
msgstr ""
@ -2702,6 +2702,11 @@ msgstr ""
msgid "Swap STAKE on Honeyswap"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/stakes/_stakes_top.html.eex:34
msgid "Bridge to Ethereum"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/stakes/_stakes_top.html.eex:52
msgid "Trade STAKE on BitMax"

@ -46,10 +46,10 @@ defmodule Explorer.Staking.ContractReader do
]
end
def active_delegators_request(staking_address, block_number) do
def active_delegators_request(pool_id, block_number) do
[
# 9ea8082b = keccak256(poolDelegators(address))
active_delegators: {:staking, "9ea8082b", [staking_address], block_number}
# 561c4c81 = keccak256(poolDelegators(uint256))
active_delegators: {:staking, "561c4c81", [pool_id], block_number}
]
end
@ -119,7 +119,7 @@ defmodule Explorer.Staking.ContractReader do
# uint256 _stakingEpoch,
# uint256 _totalRewardShareNum,
# uint256 _totalRewardShareDenom,
# address[] memory _validators
# uint256[] memory _validators
# ) public view returns(uint256 rewardToDistribute, uint256 totalReward);
def call_current_token_reward_to_distribute(
block_reward_address,
@ -136,7 +136,7 @@ defmodule Explorer.Staking.ContractReader do
|> Integer.to_string(16)
|> String.pad_leading(64, ["0"])
function_signature = "0x46955281"
function_signature = "0x43544960"
mandatory_params = staking_contract_address <> staking_epoch
optional_params =
@ -356,6 +356,13 @@ defmodule Explorer.Staking.ContractReader do
]
end
def mining_by_id_request(pool_id, block_number) do
[
# e2847895 = keccak256(miningAddressById(uint256))
mining_address: {:validator_set, "e2847895", [pool_id], block_number}
]
end
def mining_by_staking_request(staking_address) do
[
# 00535175 = keccak256(miningByStakingAddress(address))
@ -370,22 +377,21 @@ defmodule Explorer.Staking.ContractReader do
]
end
def pool_staking_requests(staking_address, block_number, net_version) do
staking_address_or_zero = refine_staker_address(staking_address, staking_address, block_number, net_version)
def pool_staking_requests(pool_id, block_number) do
[
active_delegators: active_delegators_request(staking_address, block_number)[:active_delegators],
# 73c21803 = keccak256(poolDelegatorsInactive(address))
inactive_delegators: {:staking, "73c21803", [staking_address], block_number},
# a711e6a1 = keccak256(isPoolActive(address))
is_active: {:staking, "a711e6a1", [staking_address], block_number},
mining_address_hash: mining_by_staking_request(staking_address, block_number)[:mining_address],
# a697ecff = keccak256(stakeAmount(address,address))
self_staked_amount: {:staking, "a697ecff", [staking_address, staking_address_or_zero], block_number},
# 5267e1d6 = keccak256(stakeAmountTotal(address))
total_staked_amount: {:staking, "5267e1d6", [staking_address], block_number},
# 527d8bc4 = keccak256(validatorRewardPercent(address))
validator_reward_percent: {:block_reward, "527d8bc4", [staking_address], block_number}
active_delegators: active_delegators_request(pool_id, block_number)[:active_delegators],
# a1fc2753 = keccak256(poolDelegatorsInactive(uint256))
inactive_delegators: {:staking, "a1fc2753", [pool_id], block_number},
# bbbaf8c8 = keccak256(isPoolActive(uint256))
is_active: {:staking, "bbbaf8c8", [pool_id], block_number},
mining_address_hash: mining_by_id_request(pool_id, block_number)[:mining_address],
staking_address_hash: staking_by_id_request(pool_id, block_number)[:staking_address],
# 3fb1a1e4 = keccak256(stakeAmount(uint256,address))
self_staked_amount: {:staking, "3fb1a1e4", [pool_id, "0x0000000000000000000000000000000000000000"], block_number},
# 2a8f6ecd = keccak256(stakeAmountTotal(uint256))
total_staked_amount: {:staking, "2a8f6ecd", [pool_id], block_number},
# 3bf47e96 = keccak256(validatorRewardPercent(uint256))
validator_reward_percent: {:block_reward, "3bf47e96", [pool_id], block_number}
]
end
@ -408,32 +414,46 @@ defmodule Explorer.Staking.ContractReader do
]
end
def refine_staker_address(pool_staking_address, staker_address, block_number, net_version) do
# this is a block number from which POSDAO on xDai chain started to use a zero address
# instead of staking address for the cases when the staker is a pool staking address
zero_allowed = (net_version == 100 and block_number >= 14_474_689) or net_version != 100
if staker_address == pool_staking_address and zero_allowed do
def staker_requests(pool_id, pool_staking_address, staker_address, block_number) do
delegator_or_zero =
if staker_address == pool_staking_address do
"0x0000000000000000000000000000000000000000"
else
staker_address
end
end
def staker_requests(pool_staking_address, staker_address, block_number, net_version) do
delegator_or_zero = refine_staker_address(pool_staking_address, staker_address, block_number, net_version)
[
# 950a6513 = keccak256(maxWithdrawOrderAllowed(address,address))
max_ordered_withdraw_allowed: {:staking, "950a6513", [pool_staking_address, staker_address], block_number},
# 6bda1577 = keccak256(maxWithdrawAllowed(address,address))
max_withdraw_allowed: {:staking, "6bda1577", [pool_staking_address, staker_address], block_number},
# e9ab0300 = keccak256(orderedWithdrawAmount(address,address))
ordered_withdraw: {:staking, "e9ab0300", [pool_staking_address, delegator_or_zero], block_number},
# a4205967 = keccak256(orderWithdrawEpoch(address,address))
ordered_withdraw_epoch: {:staking, "a4205967", [pool_staking_address, delegator_or_zero], block_number},
# a697ecff = keccak256(stakeAmount(address,address))
stake_amount: {:staking, "a697ecff", [pool_staking_address, delegator_or_zero], block_number}
# e3f0ff66 = keccak256(orderedWithdrawAmount(uint256,address))
ordered_withdraw: {:staking, "e3f0ff66", [pool_id, delegator_or_zero], block_number},
# d2f2a136 = keccak256(orderWithdrawEpoch(uint256,address))
ordered_withdraw_epoch: {:staking, "d2f2a136", [pool_id, delegator_or_zero], block_number},
# 3fb1a1e4 = keccak256(stakeAmount(uint256,address))
stake_amount: {:staking, "3fb1a1e4", [pool_id, delegator_or_zero], block_number}
]
end
def staking_by_id_request(pool_id) do
[
# 16cf66ab = keccak256(stakingAddressById(uint256))
staking_address: {:validator_set, "16cf66ab", [pool_id]}
]
end
def staking_by_id_request(pool_id, block_number) do
[
# 16cf66ab = keccak256(stakingAddressById(uint256))
staking_address: {:validator_set, "16cf66ab", [pool_id], block_number}
]
end
def id_by_mining_request(mining_address, block_number) do
[
# 2bbb7b72 = keccak256(idByMiningAddress(address))
pool_id: {:validator_set, "2bbb7b72", [mining_address], block_number}
]
end

@ -47,7 +47,6 @@ defmodule Explorer.Staking.ContractState do
defstruct [
:eth_blocknumber_pull_interval,
:eth_subscribe_max_delay,
:net_version,
:snapshotting_finished,
:timer,
:contracts,
@ -117,12 +116,9 @@ defmodule Explorer.Staking.ContractState do
"#{block_reward_contract_signature}" => []
})
{:ok, net_version} = EthereumJSONRPC.fetch_net_version(Application.get_env(:explorer, :json_rpc_named_arguments))
state = %__MODULE__{
eth_blocknumber_pull_interval: eth_blocknumber_pull_interval,
eth_subscribe_max_delay: eth_subscribe_max_delay,
net_version: net_version,
snapshotting_finished: false,
timer: nil,
contracts: %{
@ -268,8 +264,7 @@ defmodule Explorer.Staking.ContractState do
global_responses,
state.contracts,
state.abi,
block_number,
state.net_version
block_number
)
end
@ -308,7 +303,9 @@ defmodule Explorer.Staking.ContractState do
def calc_apy_enabled? do
validator_set_apply_block = get(:validator_set_apply_block, 0)
apy_start_block_number = validator_set_apply_block + get(:validators_length, 0) * 10
get(:epoch_number, 0) > 0 and validator_set_apply_block > 0 and get(:seen_block, 0) >= apy_start_block_number
get(:epoch_number, 0) > 0 and validator_set_apply_block > 0 and get(:seen_block, 0) >= apy_start_block_number and
show_snapshotted_data(true, validator_set_apply_block)
end
def staking_epoch_duration do
@ -352,7 +349,7 @@ defmodule Explorer.Staking.ContractState do
defp start_snapshotting?(global_responses) do
global_responses.epoch_number > get(:snapshotted_epoch_number) && global_responses.epoch_number > 0 &&
not get(:is_snapshotting)
not get(:is_snapshotting) && (global_responses.epoch_number >= 49 || global_responses.epoch_number < 47)
end
defp update_database(
@ -361,8 +358,7 @@ defmodule Explorer.Staking.ContractState do
global_responses,
contracts,
abi,
block_number,
net_version
block_number
) do
is_validator = Enum.into(global_responses.validators, %{}, &{address_bytes_to_string(&1), true})
@ -376,13 +372,13 @@ defmodule Explorer.Staking.ContractState do
block_number
)
# miningToStakingAddress mapping
mining_to_staking_address = get_mining_to_staking_address(validators, contracts, abi, block_number)
# miningAddressToId mapping
mining_address_to_id = get_mining_address_to_id(validators.all, contracts, abi, block_number)
# the list of all pools (validators + active pools + inactive pools)
pools =
Enum.uniq(
Map.values(mining_to_staking_address) ++
Map.values(mining_address_to_id) ++
global_responses.active_pools ++
global_responses.inactive_pools
)
@ -391,10 +387,10 @@ defmodule Explorer.Staking.ContractState do
pool_staking_responses: pool_staking_responses,
pool_mining_responses: pool_mining_responses,
staker_responses: staker_responses
} = get_responses(pools, block_number, contracts, abi, net_version)
} = get_responses(pools, block_number, contracts, abi)
# to keep sort order when using `perform_grouped_requests` (see below)
pool_staking_keys = Enum.map(pool_staking_responses, fn {pool_staking_address, _} -> pool_staking_address end)
pool_ids = Enum.map(pool_staking_responses, fn {pool_id, _} -> pool_id end)
# call `BlockReward.validatorShare` function for each pool
# to get validator's reward share of the pool (needed for the `Delegators` list in UI)
@ -402,7 +398,7 @@ defmodule Explorer.Staking.ContractState do
get_candidate_reward_responses(
pool_staking_responses,
global_responses,
pool_staking_keys,
pool_ids,
contracts,
abi,
block_number
@ -424,7 +420,7 @@ defmodule Explorer.Staking.ContractState do
# calculate likelihood of becoming a validator on the next epoch
[likelihood_values, total_likelihood] = global_responses.pools_likelihood
# array of pool addresses (staking addresses)
# array of pool ids
likelihood =
global_responses.pools_to_be_elected
|> Enum.zip(likelihood_values)
@ -467,15 +463,17 @@ defmodule Explorer.Staking.ContractState do
})
if start_snapshotting do
mining_to_staking_address = get_mining_to_staking_address(validators.for_snapshot, contracts, abi, block_number)
do_start_snapshotting(
epoch_very_beginning,
pool_staking_responses,
global_responses,
contracts,
abi,
validators,
validators.for_snapshot,
mining_to_staking_address,
net_version
mining_address_to_id
)
end
end
@ -537,18 +535,25 @@ defmodule Explorer.Staking.ContractState do
:ets.insert(@table_name, settings)
end
defp get_mining_to_staking_address(validators, contracts, abi, block_number) do
validators.all
defp get_mining_address_to_id(mining_addresses, contracts, abi, block_number) do
mining_addresses
|> Enum.map(&ContractReader.id_by_mining_request(&1, block_number))
|> ContractReader.perform_grouped_requests(mining_addresses, contracts, abi)
|> Map.new(fn {mining_address, resp} -> {mining_address, resp.pool_id} end)
end
defp get_mining_to_staking_address(mining_addresses, contracts, abi, block_number) do
mining_addresses
|> Enum.map(&ContractReader.staking_by_mining_request(&1, block_number))
|> ContractReader.perform_grouped_requests(validators.all, contracts, abi)
|> ContractReader.perform_grouped_requests(mining_addresses, contracts, abi)
|> 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, net_version) do
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, net_version))
|> 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
@ -557,19 +562,19 @@ defmodule Explorer.Staking.ContractState do
|> 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_staking_address, staker_address, is_active}
# 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_staking_address, resp} ->
[{pool_staking_address, pool_staking_address, true}] ++
Enum.map(resp.active_delegators, &{pool_staking_address, &1, true}) ++
Enum.map(resp.inactive_delegators, &{pool_staking_address, &1, false})
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_staking_address, staker_address, _is_active} ->
ContractReader.staker_requests(pool_staking_address, staker_address, block_number, net_version)
|> 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)
@ -583,13 +588,13 @@ defmodule Explorer.Staking.ContractState do
defp get_candidate_reward_responses(
pool_staking_responses,
global_responses,
pool_staking_keys,
pool_ids,
contracts,
abi,
block_number
) do
pool_staking_responses
|> Enum.map(fn {_pool_staking_address, resp} ->
|> Enum.map(fn {_pool_id, resp} ->
ContractReader.validator_reward_request(
[
global_responses.epoch_number,
@ -600,11 +605,12 @@ defmodule Explorer.Staking.ContractState do
block_number
)
end)
|> ContractReader.perform_grouped_requests(pool_staking_keys, contracts, abi)
|> ContractReader.perform_grouped_requests(pool_ids, contracts, abi)
end
defp get_delegator_responses(staker_responses) do
Enum.reduce(staker_responses, %{}, fn {{pool_staking_address, staker_address, _is_active} = key, value}, acc ->
Enum.reduce(staker_responses, %{}, fn {{_pool_id, pool_staking_address, staker_address, _is_active} = key, value},
acc ->
if pool_staking_address != staker_address do
Map.put(acc, key, value)
else
@ -625,8 +631,8 @@ defmodule Explorer.Staking.ContractState do
delegator_keys = Enum.map(delegator_responses, fn {key, _} -> key end)
delegator_responses
|> Enum.map(fn {{pool_staking_address, _staker_address, _is_active}, resp} ->
staking_resp = pool_staking_responses[pool_staking_address]
|> Enum.map(fn {{pool_id, _pool_staking_address, _staker_address, _is_active}, resp} ->
staking_resp = pool_staking_responses[pool_id]
ContractReader.delegator_reward_request(
[
@ -643,7 +649,7 @@ defmodule Explorer.Staking.ContractState do
end
defp get_delegator_entries(staker_responses, delegator_reward_responses) do
Enum.map(staker_responses, fn {{pool_address, delegator_address, is_active} = key, response} ->
Enum.map(staker_responses, fn {{_pool_id, pool_address, delegator_address, is_active} = key, response} ->
delegator_share =
if Map.has_key?(delegator_reward_responses, key) do
delegator_reward_responses[key].delegator_share
@ -771,11 +777,12 @@ defmodule Explorer.Staking.ContractState do
# total amount staked into all active pools
staked_total = Enum.sum(for {_, pool} <- pool_staking_responses, pool.is_active, do: pool.total_staked_amount)
Enum.map(pools, fn pool_staking_address ->
staking_resp = pool_staking_responses[pool_staking_address]
mining_resp = pool_mining_responses[pool_staking_address]
candidate_reward_resp = candidate_reward_responses[pool_staking_address]
Enum.map(pools, fn pool_id ->
staking_resp = pool_staking_responses[pool_id]
mining_resp = pool_mining_responses[pool_id]
candidate_reward_resp = candidate_reward_responses[pool_id]
is_validator = is_validator[staking_resp.mining_address_hash] || false
pool_staking_address = staking_resp.staking_address_hash
delegators_count =
length(staking_resp.active_delegators) +
@ -790,11 +797,11 @@ defmodule Explorer.Staking.ContractState do
0
end
is_unremovable = address_bytes_to_string(pool_staking_address) == global_responses.unremovable_validator
is_unremovable = pool_id == global_responses.unremovable_validator
likelihood_value =
if get(:active_pools_length) > global_responses.max_validators and not is_unremovable do
ratio(likelihood[pool_staking_address] || 0, total_likelihood)
ratio(likelihood[pool_id] || 0, total_likelihood)
else
100
end
@ -901,9 +908,9 @@ defmodule Explorer.Staking.ContractState do
global_responses,
contracts,
abi,
validators,
mining_addresses,
mining_to_staking_address,
net_version
mining_address_to_id
) do
# start snapshotting at the beginning of the staking epoch
:ets.insert(@table_name, is_snapshotting: true)
@ -916,12 +923,13 @@ defmodule Explorer.Staking.ContractState do
end
spawn(StakeSnapshotting, :do_snapshotting, [
%{contracts: contracts, abi: abi, ets_table_name: @table_name, net_version: net_version},
%{contracts: contracts, abi: abi, ets_table_name: @table_name},
global_responses.epoch_number,
cached_pool_staking_responses,
# mining addresses of pending/current validators
validators.for_snapshot,
mining_addresses,
mining_to_staking_address,
mining_address_to_id,
# the last block of the previous staking epoch
global_responses.epoch_start_block - 1
])

@ -13,66 +13,83 @@ defmodule Explorer.Staking.StakeSnapshotting do
alias Explorer.Staking.ContractReader
def do_snapshotting(
%{contracts: contracts, abi: abi, ets_table_name: ets_table_name, net_version: net_version},
%{contracts: contracts, abi: abi, ets_table_name: ets_table_name},
epoch_number,
cached_pool_staking_responses,
pools_mining_addresses,
mining_to_staking_address,
mining_address_to_id,
block_number
) do
# get staking addresses for the pending validators
# get pool ids and staking addresses for the pending validators
pool_ids =
pools_mining_addresses
|> Enum.map(&mining_address_to_id[&1])
pool_staking_addresses =
pools_mining_addresses
|> Enum.map(&mining_to_staking_address[&1])
staking_to_mining_address =
pool_staking_addresses
id_to_mining_address =
pool_ids
|> Enum.zip(pools_mining_addresses)
|> Map.new()
id_to_staking_address =
pool_ids
|> Enum.zip(pool_staking_addresses)
|> Map.new()
# get snapshotted amounts and active delegator list for the pool for each
# pending validator by their staking address.
# pending validator by their pool id.
# use `cached_pool_staking_responses` when possible
pool_staking_responses =
pool_staking_addresses
|> Enum.map(fn staking_address_hash ->
case Map.fetch(cached_pool_staking_responses, staking_address_hash) do
pool_ids
|> Enum.map(fn pool_id ->
case Map.fetch(cached_pool_staking_responses, pool_id) do
{:ok, resp} ->
Map.merge(
resp,
ContractReader.perform_requests(
snapshotted_pool_amounts_requests(staking_address_hash, block_number, net_version),
snapshotted_pool_amounts_requests(pool_id, resp.staking_address_hash, block_number),
contracts,
abi
)
)
:error ->
pool_staking_address = id_to_staking_address[pool_id]
Map.merge(
%{
staking_address_hash: pool_staking_address
},
ContractReader.perform_requests(
ContractReader.active_delegators_request(staking_address_hash, block_number) ++
snapshotted_pool_amounts_requests(staking_address_hash, block_number, net_version),
ContractReader.active_delegators_request(pool_id, block_number) ++
snapshotted_pool_amounts_requests(pool_id, pool_staking_address, block_number),
contracts,
abi
)
)
end
end)
|> Enum.zip(pool_staking_addresses)
|> Enum.zip(pool_ids)
|> Map.new(fn {key, val} -> {val, key} end)
# get a flat list of all stakers of each validator
# in the form of {pool_staking_address, staker_address}
# in the form of {pool_id, pool_staking_address, staker_address}
stakers =
Enum.flat_map(pool_staking_responses, fn {pool_staking_address, resp} ->
[{pool_staking_address, pool_staking_address}] ++
Enum.map(resp.active_delegators, &{pool_staking_address, &1})
Enum.flat_map(pool_staking_responses, fn {pool_id, resp} ->
[{pool_id, resp.staking_address_hash, resp.staking_address_hash}] ++
Enum.map(resp.active_delegators, &{pool_id, resp.staking_address_hash, &1})
end)
# read info about each staker from the contracts
staker_responses =
stakers
|> Enum.map(fn {pool_staking_address, staker_address} ->
|> Enum.map(fn {pool_id, pool_staking_address, staker_address} ->
ContractReader.perform_requests(
snapshotted_staker_amount_request(pool_staking_address, staker_address, block_number, net_version),
snapshotted_staker_amount_request(pool_id, pool_staking_address, staker_address, block_number),
contracts,
abi
)
@ -87,7 +104,7 @@ defmodule Explorer.Staking.StakeSnapshotting do
# to get validator's reward share of the pool (needed for the `Delegators` list in UI)
validator_reward_responses =
pool_staking_responses
|> Enum.map(fn {_pool_staking_address, resp} ->
|> Enum.map(fn {_pool_id, resp} ->
ContractReader.validator_reward_request(
[
epoch_number,
@ -103,7 +120,7 @@ defmodule Explorer.Staking.StakeSnapshotting 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 =
Enum.reduce(staker_responses, %{}, fn {{pool_staking_address, staker_address} = key, value}, acc ->
Enum.reduce(staker_responses, %{}, fn {{_pool_id, pool_staking_address, staker_address} = key, value}, acc ->
if pool_staking_address != staker_address do
Map.put(acc, key, value)
else
@ -115,8 +132,8 @@ defmodule Explorer.Staking.StakeSnapshotting do
delegator_reward_responses =
delegator_responses
|> Enum.map(fn {{pool_staking_address, _staker_address}, resp} ->
staking_resp = pool_staking_responses[pool_staking_address]
|> Enum.map(fn {{pool_id, _pool_staking_address, _staker_address}, resp} ->
staking_resp = pool_staking_responses[pool_id]
ContractReader.delegator_reward_request(
[
@ -133,9 +150,10 @@ defmodule Explorer.Staking.StakeSnapshotting do
# form entries for updating the `staking_pools` table in DB
pool_entries =
Enum.map(pool_staking_addresses, fn pool_staking_address ->
staking_resp = pool_staking_responses[pool_staking_address]
validator_reward_resp = validator_reward_responses[pool_staking_address]
Enum.map(pool_ids, fn pool_id ->
staking_resp = pool_staking_responses[pool_id]
validator_reward_resp = validator_reward_responses[pool_id]
pool_staking_address = id_to_staking_address[pool_id]
%{
banned_until: 0,
@ -145,7 +163,7 @@ defmodule Explorer.Staking.StakeSnapshotting do
is_validator: false,
staking_address_hash: pool_staking_address,
delegators_count: 0,
mining_address_hash: address_bytes_to_string(staking_to_mining_address[pool_staking_address]),
mining_address_hash: address_bytes_to_string(id_to_mining_address[pool_id]),
self_staked_amount: 0,
snapshotted_self_staked_amount: staking_resp.snapshotted_self_staked_amount,
snapshotted_total_staked_amount: staking_resp.snapshotted_total_staked_amount,
@ -158,7 +176,7 @@ defmodule Explorer.Staking.StakeSnapshotting do
# form entries for updating the `staking_pools_delegators` table in DB
delegator_entries =
Enum.map(staker_responses, fn {{pool_staking_address, staker_address} = key, resp} ->
Enum.map(staker_responses, fn {{_pool_id, pool_staking_address, staker_address} = key, resp} ->
delegator_share =
if Map.has_key?(delegator_reward_responses, key) do
delegator_reward_responses[key].delegator_share
@ -201,24 +219,28 @@ defmodule Explorer.Staking.StakeSnapshotting do
defp address_bytes_to_string(hash), do: "0x" <> Base.encode16(hash, case: :lower)
defp snapshotted_pool_amounts_requests(pool_staking_address, block_number, net_version) do
defp snapshotted_pool_amounts_requests(pool_id, pool_staking_address, block_number) do
[
# 5267e1d6 = keccak256(stakeAmountTotal(address))
snapshotted_total_staked_amount: {:staking, "5267e1d6", [pool_staking_address], block_number},
# 2a8f6ecd = keccak256(stakeAmountTotal(uint256))
snapshotted_total_staked_amount: {:staking, "2a8f6ecd", [pool_id], block_number},
snapshotted_self_staked_amount:
snapshotted_staker_amount_request(pool_staking_address, pool_staking_address, block_number, net_version)[
snapshotted_staker_amount_request(pool_id, pool_staking_address, pool_staking_address, block_number)[
:snapshotted_stake_amount
]
]
end
defp snapshotted_staker_amount_request(pool_staking_address, staker_address, block_number, net_version) do
defp snapshotted_staker_amount_request(pool_id, pool_staking_address, staker_address, block_number) do
delegator_or_zero =
ContractReader.refine_staker_address(pool_staking_address, staker_address, block_number, net_version)
if staker_address == pool_staking_address do
"0x0000000000000000000000000000000000000000"
else
staker_address
end
[
# a697ecff = keccak256(stakeAmount(address,address))
snapshotted_stake_amount: {:staking, "a697ecff", [pool_staking_address, delegator_or_zero], block_number}
# 3fb1a1e4 = keccak256(stakeAmount(uint256,address))
snapshotted_stake_amount: {:staking, "3fb1a1e4", [pool_id, delegator_or_zero], block_number}
]
end

@ -68,7 +68,7 @@
},
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "epochPoolNativeReward",
@ -190,7 +190,7 @@
},
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "epochPoolTokenReward",
@ -260,7 +260,7 @@
},
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "blocksCreated",
@ -365,6 +365,10 @@
{
"name": "_validatorSet",
"type": "address"
},
{
"name": "_prevBlockReward",
"type": "address"
}
],
"name": "initialize",
@ -548,8 +552,8 @@
"constant": true,
"inputs": [
{
"name": "_stakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
}
],
"name": "validatorRewardPercent",

@ -1,2 +1 @@
ABIs are taken from compiled contract JSONs in the `build/` directory of https://github.com/poanetwork/posdao-contracts.
Docs: https://poanetwork.github.io/posdao-contracts/docs/

@ -4,7 +4,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
},
{
"name": "",
@ -56,7 +56,7 @@
"outputs": [
{
"name": "result",
"type": "address[]"
"type": "uint256[]"
}
],
"payable": false,
@ -87,7 +87,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "poolInactiveIndex",
@ -148,7 +148,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
},
{
"name": "",
@ -185,7 +185,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
},
{
"name": "",
@ -208,7 +208,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "poolIndex",
@ -255,7 +255,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "orderedWithdrawAmountTotal",
@ -288,7 +288,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
},
{
"name": "",
@ -311,7 +311,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "poolToBeRemovedIndex",
@ -344,7 +344,7 @@
"inputs": [
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"name": "poolToBeElectedIndex",
@ -380,6 +380,11 @@
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "fromPoolId",
"type": "uint256"
}
],
"name": "ClaimedOrderedWithdrawal",
@ -407,6 +412,11 @@
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "toPoolId",
"type": "uint256"
}
],
"name": "PlacedStake",
@ -439,6 +449,16 @@
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "fromPoolId",
"type": "uint256"
},
{
"indexed": false,
"name": "toPoolId",
"type": "uint256"
}
],
"name": "MovedStake",
@ -466,6 +486,11 @@
"indexed": false,
"name": "amount",
"type": "int256"
},
{
"indexed": false,
"name": "fromPoolId",
"type": "uint256"
}
],
"name": "OrderedWithdrawal",
@ -493,6 +518,11 @@
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "fromPoolId",
"type": "uint256"
}
],
"name": "WithdrewStake",
@ -511,7 +541,12 @@
}
],
"name": "addPool",
"outputs": [],
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
@ -538,8 +573,8 @@
"constant": false,
"inputs": [
{
"name": "_unremovableStakingAddress",
"type": "address"
"name": "_unremovablePoolId",
"type": "uint256"
}
],
"name": "clearUnremovableValidator",
@ -565,8 +600,8 @@
"type": "address"
},
{
"name": "_initialStakingAddresses",
"type": "address[]"
"name": "_initialIds",
"type": "uint256[]"
},
{
"name": "_delegatorMinStake",
@ -599,8 +634,8 @@
"constant": false,
"inputs": [
{
"name": "_stakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
}
],
"name": "removePool",
@ -771,7 +806,7 @@
"outputs": [
{
"name": "",
"type": "address[]"
"type": "uint256[]"
}
],
"payable": false,
@ -785,7 +820,7 @@
"outputs": [
{
"name": "",
"type": "address[]"
"type": "uint256[]"
}
],
"payable": false,
@ -817,7 +852,7 @@
"outputs": [
{
"name": "",
"type": "address[]"
"type": "uint256[]"
}
],
"payable": false,
@ -831,7 +866,7 @@
"outputs": [
{
"name": "",
"type": "address[]"
"type": "uint256[]"
}
],
"payable": false,
@ -870,8 +905,8 @@
"constant": true,
"inputs": [
{
"name": "_stakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
}
],
"name": "isPoolActive",
@ -932,7 +967,7 @@
"type": "function"
},
{
"constant": true,
"constant": false,
"inputs": [
{
"name": "",
@ -955,15 +990,15 @@
}
],
"payable": false,
"stateMutability": "pure",
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_poolStakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
}
],
"name": "poolDelegators",
@ -981,8 +1016,8 @@
"constant": true,
"inputs": [
{
"name": "_poolStakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
}
],
"name": "poolDelegatorsInactive",
@ -1000,11 +1035,11 @@
"constant": true,
"inputs": [
{
"name": "_poolStakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
},
{
"name": "_staker",
"name": "_delegatorOrZero",
"type": "address"
}
],
@ -1023,11 +1058,11 @@
"constant": true,
"inputs": [
{
"name": "_poolStakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
},
{
"name": "_staker",
"name": "_delegatorOrZero",
"type": "address"
}
],
@ -1046,8 +1081,8 @@
"constant": true,
"inputs": [
{
"name": "_poolStakingAddress",
"type": "address"
"name": "_poolId",
"type": "uint256"
}
],
"name": "stakeAmountTotal",

@ -70,48 +70,6 @@
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "isValidatorPrevious",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "uint256"
}
],
"name": "reportingCounter",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
@ -190,7 +148,7 @@
"outputs": [
{
"name": "",
"type": "address"
"type": "uint256"
}
],
"payable": false,
@ -272,52 +230,6 @@
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "reportingCounterTotal",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "uint256"
}
],
"name": "maliceReportedForBlock",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
@ -455,16 +367,7 @@
"constant": false,
"inputs": [],
"name": "newValidatorSet",
"outputs": [
{
"name": "called",
"type": "bool"
},
{
"name": "poolsToBeElectedLength",
"type": "uint256"
}
],
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
@ -505,24 +408,6 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_miningAddress",
"type": "address"
},
{
"name": "_stakingAddress",
"type": "address"
}
],
"name": "setStakingAddress",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
@ -537,20 +422,6 @@
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getPreviousValidators",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
@ -708,5 +579,81 @@
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "hasEverBeenMiningAddress",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "idByMiningAddress",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "miningAddressById",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "stakingAddressById",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]

@ -73,15 +73,6 @@ defmodule Explorer.Staking.ContractStateTest do
end
)
expect(
EthereumJSONRPC.Mox,
:json_rpc,
fn _request, _opts ->
# net_version
{:ok, "101"}
end
)
# get_token, fetch_token, MetadataRetriever.get_functions_of
expect(
EthereumJSONRPC.Mox,
@ -244,7 +235,7 @@ defmodule Explorer.Staking.ContractStateTest do
end
)
# get_mining_to_staking_address
# get_mining_address_to_id
expect(
EthereumJSONRPC.Mox,
:json_rpc,
@ -253,17 +244,17 @@ defmodule Explorer.Staking.ContractStateTest do
{:ok,
format_responses([
# 1 ValidatorSetAuRa.stakingByMiningAddress
# 1 ValidatorSetAuRa.idByMiningAddress
"0x0000000000000000000000000b2f5e2f3cbd864eaa2c642e3769c1582361caf6",
# 2 ValidatorSetAuRa.stakingByMiningAddress
# 2 ValidatorSetAuRa.idByMiningAddress
"0x000000000000000000000000aa94b687d3f9552a453b81b2834ca53778980dc0",
# 3 ValidatorSetAuRa.stakingByMiningAddress
# 3 ValidatorSetAuRa.idByMiningAddress
"0x000000000000000000000000312c230e7d6db05224f60208a656e3541c5c42ba",
# 4 ValidatorSetAuRa.stakingByMiningAddress
# 4 ValidatorSetAuRa.idByMiningAddress
"0x000000000000000000000000b916e7e1f4bcb13549602ed042d36746fd0d96c9",
# 5 ValidatorSetAuRa.stakingByMiningAddress
# 5 ValidatorSetAuRa.idByMiningAddress
"0x000000000000000000000000db9cb2478d917719c53862008672166808258577",
# 6 ValidatorSetAuRa.stakingByMiningAddress
# 6 ValidatorSetAuRa.idByMiningAddress
"0x000000000000000000000000b6695f5c2e3f5eff8036b5f5f3a9d83a5310e51e"
])}
end
@ -274,7 +265,7 @@ defmodule Explorer.Staking.ContractStateTest do
EthereumJSONRPC.Mox,
:json_rpc,
fn requests, _opts ->
assert length(requests) == 6 * 7
assert length(requests) == 6 * 8
{:ok,
format_responses([
@ -284,13 +275,15 @@ defmodule Explorer.Staking.ContractStateTest do
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
# 1.3 StakingAuRa.isPoolActive
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 1.4 ValidatorSetAuRa.miningByStakingAddress
# 1.4 ValidatorSetAuRa.miningAddressById
"0x000000000000000000000000522df396ae70a058bd69778408630fdb023389b2",
# 1.5 StakingAuRa.stakeAmount
# 1.5 ValidatorSetAuRa.stakingAddressById
"0x0000000000000000000000000b2f5e2f3cbd864eaa2c642e3769c1582361caf6",
# 1.6 StakingAuRa.stakeAmount
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 1.6 StakingAuRa.stakeAmountTotal
# 1.7 StakingAuRa.stakeAmountTotal
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 1.7 BlockRewardAuRa.validatorRewardPercent
# 1.8 BlockRewardAuRa.validatorRewardPercent
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 2.1 StakingAuRa.poolDelegators
@ -299,13 +292,15 @@ defmodule Explorer.Staking.ContractStateTest do
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
# 2.3 StakingAuRa.isPoolActive
"0x0000000000000000000000000000000000000000000000000000000000000001",
# 2.4 ValidatorSetAuRa.miningByStakingAddress
# 2.4 ValidatorSetAuRa.miningAddressById
"0x000000000000000000000000720e118ab1006cc97ed2ef6b4b49ac04bb3aa6d9",
# 2.5 StakingAuRa.stakeAmount
# 2.5 ValidatorSetAuRa.stakingAddressById
"0x000000000000000000000000aa94b687d3f9552a453b81b2834ca53778980dc0",
# 2.6 StakingAuRa.stakeAmount
"0x0000000000000000000000000000000000000000000000001bc16d674ec80000",
# 2.6 StakingAuRa.stakeAmountTotal
# 2.7 StakingAuRa.stakeAmountTotal
"0x00000000000000000000000000000000000000000000000029a2241af62c0000",
# 2.7 BlockRewardAuRa.validatorRewardPercent
# 2.8 BlockRewardAuRa.validatorRewardPercent
"0x00000000000000000000000000000000000000000000000000000000000a2c2a",
# 3.1 StakingAuRa.poolDelegators
@ -314,13 +309,15 @@ defmodule Explorer.Staking.ContractStateTest do
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
# 3.3 StakingAuRa.isPoolActive
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 3.4 ValidatorSetAuRa.miningByStakingAddress
# 3.4 ValidatorSetAuRa.miningAddressById
"0x00000000000000000000000075df42383afe6bf5194aa8fa0e9b3d5f9e869441",
# 3.5 StakingAuRa.stakeAmount
# 3.5 ValidatorSetAuRa.stakingAddressById
"0x000000000000000000000000312c230e7d6db05224f60208a656e3541c5c42ba",
# 3.6 StakingAuRa.stakeAmount
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 3.6 StakingAuRa.stakeAmountTotal
# 3.7 StakingAuRa.stakeAmountTotal
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 3.7 BlockRewardAuRa.validatorRewardPercent
# 3.8 BlockRewardAuRa.validatorRewardPercent
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 4.1 StakingAuRa.poolDelegators
@ -329,13 +326,15 @@ defmodule Explorer.Staking.ContractStateTest do
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
# 4.3 StakingAuRa.isPoolActive
"0x0000000000000000000000000000000000000000000000000000000000000001",
# 4.4 ValidatorSetAuRa.miningByStakingAddress
# 4.4 ValidatorSetAuRa.miningAddressById
"0x000000000000000000000000bbcaa8d48289bb1ffcf9808d9aa4b1d215054c78",
# 4.5 StakingAuRa.stakeAmount
# 4.5 ValidatorSetAuRa.stakingAddressById
"0x000000000000000000000000b916e7e1f4bcb13549602ed042d36746fd0d96c9",
# 4.6 StakingAuRa.stakeAmount
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 4.6 StakingAuRa.stakeAmountTotal
# 4.7 StakingAuRa.stakeAmountTotal
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 4.7 BlockRewardAuRa.validatorRewardPercent
# 4.8 BlockRewardAuRa.validatorRewardPercent
"0x0000000000000000000000000000000000000000000000000000000000000000",
# 5.1 StakingAuRa.poolDelegators
@ -344,13 +343,15 @@ defmodule Explorer.Staking.ContractStateTest do
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
# 5.3 StakingAuRa.isPoolActive
"0x0000000000000000000000000000000000000000000000000000000000000001",
# 5.4 ValidatorSetAuRa.miningByStakingAddress
# 5.4 ValidatorSetAuRa.miningAddressById
"0x000000000000000000000000be69eb0968226a1808975e1a1f2127667f2bffb3",
# 5.5 StakingAuRa.stakeAmount
# 5.5 ValidatorSetAuRa.stakingAddressById
"0x000000000000000000000000db9cb2478d917719c53862008672166808258577",
# 5.6 StakingAuRa.stakeAmount
"0x0000000000000000000000000000000000000000000000001bc16d674ec80000",
# 5.6 StakingAuRa.stakeAmountTotal
# 5.7 StakingAuRa.stakeAmountTotal
"0x00000000000000000000000000000000000000000000000098a7d9b8314c0000",
# 5.7 BlockRewardAuRa.validatorRewardPercent
# 5.8 BlockRewardAuRa.validatorRewardPercent
"0x00000000000000000000000000000000000000000000000000000000000493e0",
# 6.1 StakingAuRa.poolDelegators
@ -359,13 +360,15 @@ defmodule Explorer.Staking.ContractStateTest do
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
# 6.3 StakingAuRa.isPoolActive
"0x0000000000000000000000000000000000000000000000000000000000000001",
# 6.4 ValidatorSetAuRa.miningByStakingAddress
# 6.4 ValidatorSetAuRa.miningAddressById
"0x000000000000000000000000f67cc5231c5858ad6cc87b105217426e17b824bb",
# 6.5 StakingAuRa.stakeAmount
# 6.5 ValidatorSetAuRa.stakingAddressById
"0x000000000000000000000000b6695f5c2e3f5eff8036b5f5f3a9d83a5310e51e",
# 6.6 StakingAuRa.stakeAmount
"0x0000000000000000000000000000000000000000000000001bc16d674ec80000",
# 6.6 StakingAuRa.stakeAmountTotal
# 6.7 StakingAuRa.stakeAmountTotal
"0x0000000000000000000000000000000000000000000000001bc16d674ec80000",
# 6.7 BlockRewardAuRa.validatorRewardPercent
# 6.8 BlockRewardAuRa.validatorRewardPercent
"0x00000000000000000000000000000000000000000000000000000000000f4240"
])}
end
@ -719,7 +722,28 @@ defmodule Explorer.Staking.ContractStateTest do
end
)
# invoke do_snapshotting()
# invoke do_start_snapshotting()
## get_mining_to_staking_address
expect(
EthereumJSONRPC.Mox,
:json_rpc,
fn requests, _opts ->
assert length(requests) == 4
{:ok,
format_responses([
# 1 ValidatorSetAuRa.stakingByMiningAddress
"0x000000000000000000000000b916e7e1f4bcb13549602ed042d36746fd0d96c9",
# 2 ValidatorSetAuRa.stakingByMiningAddress
"0x000000000000000000000000b6695f5c2e3f5eff8036b5f5f3a9d83a5310e51e",
# 3 ValidatorSetAuRa.stakingByMiningAddress
"0x000000000000000000000000db9cb2478d917719c53862008672166808258577",
# 4 ValidatorSetAuRa.stakingByMiningAddress
"0x000000000000000000000000aa94b687d3f9552a453b81b2834ca53778980dc0"
])}
end
)
## 1 snapshotted_pool_amounts_requests
expect(

Loading…
Cancel
Save