fix POSDAO snapshotting and remove temporary code

pull/3732/head
POA 4 years ago
parent 595f2f1c35
commit bbb60106ef
  1. 2
      .dialyzer-ignore
  2. 44
      apps/explorer/lib/explorer/staking/contract_reader.ex
  3. 63
      apps/explorer/lib/explorer/staking/contract_state.ex
  4. 58
      apps/explorer/lib/explorer/staking/stake_snapshotting.ex

@ -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/7 has no local return
lib/explorer/staking/stake_snapshotting.ex:216
lib/explorer/staking/stake_snapshotting.ex:207

@ -46,18 +46,10 @@ defmodule Explorer.Staking.ContractReader do
]
end
def active_delegators_request(pool_id, block_number, new_signatures) do
pool_delegators_signature =
if new_signatures do
# 561c4c81 = keccak256(poolDelegators(uint256))
"561c4c81"
else
# 9ea8082b = keccak256(poolDelegators(address))
"9ea8082b"
end
def active_delegators_request(pool_id, block_number) do
[
active_delegators: {:staking, pool_delegators_signature, [pool_id], block_number}
# 561c4c81 = keccak256(poolDelegators(uint256))
active_delegators: {:staking, "561c4c81", [pool_id], block_number}
]
end
@ -387,7 +379,7 @@ defmodule Explorer.Staking.ContractReader do
def pool_staking_requests(pool_id, block_number) do
[
active_delegators: active_delegators_request(pool_id, block_number, true)[:active_delegators],
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))
@ -509,6 +501,34 @@ defmodule Explorer.Staking.ContractReader do
|> parse_grouped_responses(keys, requests)
end
def get_contract_events(contract_address, from_block, to_block, event_hash) do
json_rpc_named_arguments = Application.get_env(:explorer, :json_rpc_named_arguments)
result =
%{
id: 0,
method: "eth_getLogs",
params: [
%{
fromBlock: "0x" <> Integer.to_string(from_block, 16),
toBlock: "0x" <> Integer.to_string(to_block, 16),
address: contract_address,
topics: [event_hash]
}
]
}
|> EthereumJSONRPC.request()
|> EthereumJSONRPC.json_rpc(json_rpc_named_arguments)
case result do
{:ok, events} ->
events
{:error, _reason} ->
[]
end
end
defp address_pad_to_64(address) do
address
|> String.replace_leading("0x", "")

@ -31,6 +31,7 @@ defmodule Explorer.Staking.ContractState do
:pool_rewards,
:seen_block,
:snapshotted_epoch_number,
:snapshotting_scheduled,
:staking_allowed,
:staking_contract,
:token_contract,
@ -136,6 +137,7 @@ defmodule Explorer.Staking.ContractState do
pool_rewards: %{},
seen_block: 0,
snapshotted_epoch_number: -1,
snapshotting_scheduled: false,
staking_contract: %{abi: staking_abi, address: staking_contract_address},
token_contract: %{abi: token_abi, address: token_contract_address},
token: get_token(token_contract_address),
@ -231,7 +233,7 @@ defmodule Explorer.Staking.ContractState do
epoch_very_beginning = global_responses.epoch_start_block == block_number + 1
start_snapshotting = start_snapshotting?(global_responses)
start_snapshotting = start_snapshotting?(global_responses, state, block_number)
# determine if something changed in contracts state since the previous seen block.
# if something changed or the `fetch_state` function is called for the first time
@ -348,9 +350,62 @@ defmodule Explorer.Staking.ContractState do
end
end
defp start_snapshotting?(global_responses) do
global_responses.epoch_number > get(:snapshotted_epoch_number) && global_responses.epoch_number > 0 &&
not get(:is_snapshotting)
defp start_snapshotting?(global_responses, state, block_number) do
if global_responses.epoch_number == 0 do
# we never snapshot at initial staking epoch
false
else
already_snapshotting = get(:is_snapshotting)
start =
(global_responses.epoch_number > get(:snapshotted_epoch_number) or get(:snapshotting_scheduled)) and
not already_snapshotting
if start do
:ets.insert(@table_name, snapshotting_scheduled: false)
true
else
# check for ChangedMiningAddress and ChangedStakingAddress events
# from the ValidatorSetAuRa contract: if one of these events
# emitted, we need to do snapshotting
seen_block = get(:seen_block, 0)
from_block =
if seen_block > 0 do
seen_block + 1
else
block_number
end
change_pool_address_events =
ContractReader.get_contract_events(
state.contracts.validator_set,
from_block,
block_number,
[
# keccak-256 of `ChangedMiningAddress(uint256,address,address)`
"0xad4c947995a3daa512a7371d31325a21227249f8dc1c52c1a4c6fe8475a3ebb1",
# keccak-256 of `ChangedStakingAddress(uint256,address,address)`
"0x5c44164828293bba0353472e907f7ee26a8659f916e6311fe826a7c70510e352"
]
)
if Enum.count(change_pool_address_events) > 0 do
# we see at least one of the events, so start snapshotting
if already_snapshotting do
# since the snapshotting procedure is already in progress,
# we schedule snapshotting restart after the current
# procedure is finished
:ets.insert(@table_name, snapshotting_scheduled: true)
false
else
true
end
else
false
end
end
end
end
defp update_database(

@ -21,12 +21,6 @@ defmodule Explorer.Staking.StakeSnapshotting do
mining_address_to_id,
block_number
) do
# temporary code (should be removed after staking epoch #48 on xDai is finished).
# this is a block number from which POSDAO on xDai chain started to use other signatures
# in the StakingAuRa contract
{:ok, net_version} = EthereumJSONRPC.fetch_net_version(Application.get_env(:explorer, :json_rpc_named_arguments))
new_signatures = (net_version == 100 and block_number > 14_994_040) or net_version != 100
# get pool ids and staking addresses for the pending validators
pool_ids =
pools_mining_addresses
@ -46,8 +40,6 @@ defmodule Explorer.Staking.StakeSnapshotting do
|> Enum.zip(pool_staking_addresses)
|> Map.new()
abi = abi_clarify_signatures(abi, new_signatures)
# get snapshotted amounts and active delegator list for the pool for each
# pending validator by their pool id.
# use `cached_pool_staking_responses` when possible
@ -59,7 +51,7 @@ defmodule Explorer.Staking.StakeSnapshotting do
Map.merge(
resp,
ContractReader.perform_requests(
snapshotted_pool_amounts_requests(pool_id, resp.staking_address_hash, block_number, new_signatures),
snapshotted_pool_amounts_requests(pool_id, resp.staking_address_hash, block_number),
contracts,
abi
)
@ -73,8 +65,8 @@ defmodule Explorer.Staking.StakeSnapshotting do
staking_address_hash: pool_staking_address
},
ContractReader.perform_requests(
ContractReader.active_delegators_request(pool_id, block_number, new_signatures) ++
snapshotted_pool_amounts_requests(pool_id, pool_staking_address, block_number, new_signatures),
ContractReader.active_delegators_request(pool_id, block_number) ++
snapshotted_pool_amounts_requests(pool_id, pool_staking_address, block_number),
contracts,
abi
)
@ -101,8 +93,7 @@ defmodule Explorer.Staking.StakeSnapshotting do
pool_id,
pool_staking_address,
staker_address,
block_number,
new_signatures
block_number
),
contracts,
abi
@ -231,42 +222,23 @@ defmodule Explorer.Staking.StakeSnapshotting do
Publisher.broadcast(:stake_snapshotting_finished)
end
defp abi_clarify_signatures(abi, new_signatures) do
if new_signatures do
abi
else
Jason.decode!(
~s([{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"stakeAmountTotal","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"stakeAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"poolDelegators","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"validatorShare","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"delegatorShare","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}])
)
end
end
defp address_bytes_to_string(hash), do: "0x" <> Base.encode16(hash, case: :lower)
defp snapshotted_pool_amounts_requests(pool_id, pool_staking_address, block_number, new_signatures) do
stake_amount_total_signature =
if new_signatures do
# keccak256(stakeAmountTotal(uint256))
"2a8f6ecd"
else
# keccak256(stakeAmountTotal(address))
"5267e1d6"
end
defp snapshotted_pool_amounts_requests(pool_id, pool_staking_address, block_number) do
[
snapshotted_total_staked_amount: {:staking, stake_amount_total_signature, [pool_id], 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_id,
pool_staking_address,
pool_staking_address,
block_number,
new_signatures
block_number
)[:snapshotted_stake_amount]
]
end
defp snapshotted_staker_amount_request(pool_id, pool_staking_address, staker_address, block_number, new_signatures) do
defp snapshotted_staker_amount_request(pool_id, pool_staking_address, staker_address, block_number) do
delegator_or_zero =
if staker_address == pool_staking_address do
"0x0000000000000000000000000000000000000000"
@ -274,17 +246,9 @@ defmodule Explorer.Staking.StakeSnapshotting do
staker_address
end
stake_amount_signature =
if new_signatures do
# keccak256(stakeAmount(uint256,address))
"3fb1a1e4"
else
# keccak256(stakeAmount(address,address))
"a697ecff"
end
[
snapshotted_stake_amount: {:staking, stake_amount_signature, [pool_id, delegator_or_zero], block_number}
# 3fb1a1e4 = keccak256(stakeAmount(uint256,address))
snapshotted_stake_amount: {:staking, "3fb1a1e4", [pool_id, delegator_or_zero], block_number}
]
end

Loading…
Cancel
Save