diff --git a/.dialyzer-ignore b/.dialyzer-ignore index 5223bbf632..a75410c17d 100644 --- a/.dialyzer-ignore +++ b/.dialyzer-ignore @@ -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 diff --git a/apps/block_scout_web/assets/js/pages/stakes/become_candidate.js b/apps/block_scout_web/assets/js/pages/stakes/become_candidate.js index ac59b42c73..ec5ec1fbb3 100644 --- a/apps/block_scout_web/assets/js/pages/stakes/become_candidate.js +++ b/apps/block_scout_web/assets/js/pages/stakes/become_candidate.js @@ -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 (${shortenAddress(stakingAddress)}). 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) diff --git a/apps/block_scout_web/assets/js/pages/stakes/utils.js b/apps/block_scout_web/assets/js/pages/stakes/utils.js index 71c6c1080b..375330eba5 100644 --- a/apps/block_scout_web/assets/js/pages/stakes/utils.js +++ b/apps/block_scout_web/assets/js/pages/stakes/utils.js @@ -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 { diff --git a/apps/block_scout_web/lib/block_scout_web/channels/stakes_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/stakes_channel.ex index 1a25cc43c8..cb13770b72 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/stakes_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/stakes_channel.ex @@ -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) diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 110cae2f5c..14fd7d16a7 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -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 "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index 110cae2f5c..ad8a22f21b 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -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" diff --git a/apps/explorer/lib/explorer/staking/contract_reader.ex b/apps/explorer/lib/explorer/staking/contract_reader.ex index 30a3e5570f..41dd0637f1 100644 --- a/apps/explorer/lib/explorer/staking/contract_reader.ex +++ b/apps/explorer/lib/explorer/staking/contract_reader.ex @@ -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 - "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) + 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 [ # 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 diff --git a/apps/explorer/lib/explorer/staking/contract_state.ex b/apps/explorer/lib/explorer/staking/contract_state.ex index c6f5b85070..a0e5b92588 100644 --- a/apps/explorer/lib/explorer/staking/contract_state.ex +++ b/apps/explorer/lib/explorer/staking/contract_state.ex @@ -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 ]) diff --git a/apps/explorer/lib/explorer/staking/stake_snapshotting.ex b/apps/explorer/lib/explorer/staking/stake_snapshotting.ex index 4fff1f23d2..d6db33d150 100644 --- a/apps/explorer/lib/explorer/staking/stake_snapshotting.ex +++ b/apps/explorer/lib/explorer/staking/stake_snapshotting.ex @@ -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 -> - ContractReader.perform_requests( - ContractReader.active_delegators_request(staking_address_hash, block_number) ++ - snapshotted_pool_amounts_requests(staking_address_hash, block_number, net_version), - contracts, - abi + pool_staking_address = id_to_staking_address[pool_id] + + Map.merge( + %{ + staking_address_hash: pool_staking_address + }, + ContractReader.perform_requests( + 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 diff --git a/apps/explorer/priv/contracts_abi/posdao/BlockRewardAuRa.json b/apps/explorer/priv/contracts_abi/posdao/BlockRewardAuRa.json index 87b535f05f..49737b7a32 100644 --- a/apps/explorer/priv/contracts_abi/posdao/BlockRewardAuRa.json +++ b/apps/explorer/priv/contracts_abi/posdao/BlockRewardAuRa.json @@ -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", diff --git a/apps/explorer/priv/contracts_abi/posdao/README.md b/apps/explorer/priv/contracts_abi/posdao/README.md index 5920a12993..98a1dd2109 100644 --- a/apps/explorer/priv/contracts_abi/posdao/README.md +++ b/apps/explorer/priv/contracts_abi/posdao/README.md @@ -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/ diff --git a/apps/explorer/priv/contracts_abi/posdao/StakingAuRa.json b/apps/explorer/priv/contracts_abi/posdao/StakingAuRa.json index bc64d53d01..aebd900c42 100644 --- a/apps/explorer/priv/contracts_abi/posdao/StakingAuRa.json +++ b/apps/explorer/priv/contracts_abi/posdao/StakingAuRa.json @@ -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", diff --git a/apps/explorer/priv/contracts_abi/posdao/ValidatorSetAuRa.json b/apps/explorer/priv/contracts_abi/posdao/ValidatorSetAuRa.json index 0a3d2fc4a4..e86aec8b6d 100644 --- a/apps/explorer/priv/contracts_abi/posdao/ValidatorSetAuRa.json +++ b/apps/explorer/priv/contracts_abi/posdao/ValidatorSetAuRa.json @@ -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" } ] diff --git a/apps/explorer/test/explorer/staking/contract_state_test.exs b/apps/explorer/test/explorer/staking/contract_state_test.exs index af2a31a995..2032747ae5 100644 --- a/apps/explorer/test/explorer/staking/contract_state_test.exs +++ b/apps/explorer/test/explorer/staking/contract_state_test.exs @@ -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(