Periodically refresh the table with staking pools (#2557)

The table is refreshed when new staking epoch starts and after an interval
configured in apps/block_scout_web/config/config.exs.
If no interval is configured, the table is only updated on new epoch.
staking
Paul Tsupikoff 5 years ago committed by Victor Baranov
parent 190e86f908
commit d020fc9baa
  1. 34
      apps/block_scout_web/assets/js/pages/stakes.js
  2. 3
      apps/block_scout_web/config/config.exs
  3. 14
      apps/block_scout_web/lib/block_scout_web/channels/stakes_channel.ex
  4. 3
      apps/block_scout_web/lib/block_scout_web/controllers/stakes_controller.ex
  5. 5
      apps/block_scout_web/lib/block_scout_web/notifier.ex
  6. 2
      apps/block_scout_web/lib/block_scout_web/templates/stakes/index.html.eex

@ -21,7 +21,10 @@ export const initialState = {
stakingContract: null,
blockRewardContract: null,
tokenDecimals: 0,
tokenSymbol: ''
tokenSymbol: '',
refreshInterval: null,
lastEpochNumber: 0,
lastBlockNumber: 0
}
export function reducer (state = initialState, action) {
@ -42,6 +45,12 @@ export function reducer (state = initialState, action) {
additionalParams: { account: action.account }
})
}
case 'RECEIVED_UPDATE': {
return Object.assign({}, state, {
lastEpochNumber: action.lastEpochNumber,
lastBlockNumber: action.lastBlockNumber
})
}
case 'RECEIVED_CONTRACTS': {
return Object.assign({}, state, {
stakingContract: action.stakingContract,
@ -56,6 +65,11 @@ export function reducer (state = initialState, action) {
}
const elements = {
'[data-page="stakes"]': {
load ($el) {
return { refreshInterval: $el.data('refresh-interval') || null }
}
}
}
const $stakesPage = $('[data-page="stakes"]')
@ -67,7 +81,23 @@ if ($stakesPage.length) {
const channel = subscribeChannel('stakes:staking_update')
store.dispatch({ type: 'CHANNEL_CONNECTED', channel })
channel.on('staking_update', msg => $stakesTop.html(msg.top_html))
channel.on('staking_update', msg => {
$stakesTop.html(msg.top_html)
const state = store.getState()
if (
msg.epoch_number > state.lastEpochNumber ||
(state.refreshInterval && msg.block_number >= state.lastBlockNumber + state.refreshInterval)
) {
store.dispatch({
type: 'RECEIVED_UPDATE',
lastEpochNumber: msg.epoch_number,
lastBlockNumber: msg.block_number
})
refreshPage(store)
}
})
channel.on('contracts', msg => {
const web3 = store.getState().web3
const stakingContract =

@ -23,7 +23,8 @@ config :block_scout_web, BlockScoutWeb.Chain,
logo_footer: System.get_env("LOGO_FOOTER"),
logo_text: System.get_env("LOGO_TEXT"),
has_emission_funds: false,
staking_enabled: not is_nil(System.get_env("POS_STAKING_CONTRACT"))
staking_enabled: not is_nil(System.get_env("POS_STAKING_CONTRACT")),
staking_table_refresh_interval: 10
config :block_scout_web,
link_to_other_explorers: System.get_env("LINK_TO_OTHER_EXPLORERS") == "true",

@ -6,6 +6,7 @@ defmodule BlockScoutWeb.StakesChannel do
alias BlockScoutWeb.{StakesController, StakesView}
alias Explorer.Chain
alias Explorer.Chain.Cache.BlockNumber
alias Explorer.Counters.AverageBlockTime
alias Explorer.Staking.ContractState
alias Phoenix.View
@ -22,7 +23,14 @@ defmodule BlockScoutWeb.StakesChannel do
|> assign(:account, account)
|> push_staking_contract()
handle_out("staking_update", nil, socket)
handle_out(
"staking_update",
%{
block_number: BlockNumber.get_max(),
epoch_number: ContractState.get(:epoch_number, 0)
},
socket
)
end
def handle_in("render_validator_info", %{"address" => staking_address}, socket) do
@ -167,8 +175,10 @@ defmodule BlockScoutWeb.StakesChannel do
{:reply, {:ok, result}, socket}
end
def handle_out("staking_update", _data, socket) do
def handle_out("staking_update", data, socket) do
push(socket, "staking_update", %{
epoch_number: data.epoch_number,
block_number: data.block_number,
top_html: StakesController.render_top(socket)
})

@ -104,7 +104,8 @@ defmodule BlockScoutWeb.StakesController do
top: render_top(conn),
pools_type: filter,
current_path: current_path(conn),
average_block_time: AverageBlockTime.average_block_time()
average_block_time: AverageBlockTime.average_block_time(),
refresh_interval: Application.get_env(:block_scout_web, BlockScoutWeb.Chain)[:staking_table_refresh_interval]
)
end

@ -7,6 +7,7 @@ defmodule BlockScoutWeb.Notifier do
alias BlockScoutWeb.{AddressContractVerificationView, Endpoint}
alias Explorer.{Chain, Market, Repo}
alias Explorer.Chain.{Address, InternalTransaction, TokenTransfer, Transaction}
alias Explorer.Chain.Cache.BlockNumber
alias Explorer.Chain.Supply.RSK
alias Explorer.Chain.Transaction.History.TransactionStats
alias Explorer.Counters.AverageBlockTime
@ -104,10 +105,12 @@ defmodule BlockScoutWeb.Notifier do
def handle_event({:chain_event, :staking_update}) do
epoch_number = ContractState.get(:epoch_number, 0)
epoch_end_block = ContractState.get(:epoch_end_block, 0)
block_number = BlockNumber.get_max()
Endpoint.broadcast("stakes:staking_update", "staking_update", %{
epoch_number: epoch_number,
epoch_end_block: epoch_end_block
epoch_end_block: epoch_end_block,
block_number: block_number
})
end

@ -1,7 +1,7 @@
<div data-selector="stakes-top">
<%= raw(@top) %>
</div>
<section data-page="stakes" class="container">
<section data-page="stakes" class="container" data-refresh-interval="<%= @refresh_interval %>">
<div class="card" data-async-load data-async-listing="<%= @current_path %>">
<%= render BlockScoutWeb.StakesView, "_stakes_tabs.html", conn: @conn %>

Loading…
Cancel
Save