fix: `GAS_PRICE_ORACLE_NUM_OF_BLOCKS` calculation (#9943)

pull/9953/head
Maxim Filonov 7 months ago committed by GitHub
parent 4b272cf61d
commit 14435dad2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 23
      apps/explorer/lib/explorer/chain/cache/gas_price_oracle.ex
  2. 71
      apps/explorer/test/explorer/chain/cache/gas_price_oracle_test.exs

@ -12,6 +12,7 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
alias Explorer.Chain.{Block, Wei}
alias Explorer.Chain.Cache.BlockNumber
alias Explorer.Counters.AverageBlockTime
alias Explorer.{Market, Repo}
alias Timex.Duration
@ -81,12 +82,16 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
acc = get_gas_prices_acc()
from_block =
from_block_actual = BlockNumber.get_max() - num_of_blocks
from_block_acc =
case acc do
[%{block_number: from_block} | _] -> from_block
_ -> -1
end
from_block_query = max(from_block_acc, from_block_actual)
average_block_time =
case AverageBlockTime.average_block_time() do
{:error, _} -> nil
@ -99,7 +104,7 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
left_join: transaction in assoc(block, :transactions),
where: block.consensus == true,
where: is_nil(transaction.gas_price) or transaction.gas_price > ^0,
where: transaction.block_number > ^from_block,
where: transaction.block_number > ^from_block_query,
group_by: transaction.block_number,
order_by: [desc: transaction.block_number],
select: %{
@ -164,11 +169,10 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
block.timestamp - transaction.earliest_processing_start,
^(average_block_time && average_block_time * fast_time_coefficient())
)
},
limit: ^num_of_blocks
}
)
new_acc = fee_query |> Repo.all(timeout: :infinity) |> merge_gas_prices(acc, num_of_blocks)
new_acc = fee_query |> Repo.all(timeout: :infinity) |> merge_gas_prices(acc, from_block_actual)
gas_prices = new_acc |> process_fee_data_from_db()
@ -179,7 +183,7 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
{{:error, error}, get_gas_prices_acc()}
end
defp merge_gas_prices(new, acc, acc_size), do: Enum.take(new ++ acc, acc_size)
defp merge_gas_prices(new, acc, from_block), do: Enum.take_while(new ++ acc, &(&1.block_number > from_block))
defp process_fee_data_from_db([]) do
%{
@ -259,12 +263,13 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
base_fee: base_fee |> format_wei(),
priority_fee: base_fee && priority_fee && priority_fee |> Decimal.new() |> Wei.from(:wei) |> format_wei(),
priority_fee_wei: base_fee && priority_fee && priority_fee |> Decimal.new() |> Decimal.round(),
wei: fee |> Wei.to(:wei) |> Decimal.round()
wei: fee && fee |> Wei.to(:wei) |> Decimal.round()
}
end
defp fiat_fee(fee, exchange_rate) do
exchange_rate.usd_value &&
fee &&
exchange_rate.usd_value &&
fee
|> Wei.to(:ether)
|> Decimal.mult(exchange_rate.usd_value)
@ -276,6 +281,8 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
priority |> Wei.from(:wei) |> Wei.sum(base_fee)
end
defp gas_price(nil), do: nil
defp gas_price(value) do
value |> Wei.from(:wei)
end

@ -460,5 +460,76 @@ defmodule Explorer.Chain.Cache.GasPriceOracleTest do
}
}, _} = GasPriceOracle.get_average_gas_price(3, 35, 60, 90)
end
test "does not take into account old transaction even if there is no new ones" do
gas_price_oracle_old_env = Application.get_env(:explorer, GasPriceOracle)
Application.put_env(:explorer, GasPriceOracle, num_of_blocks: 3)
on_exit(fn ->
Application.put_env(:explorer, GasPriceOracle, gas_price_oracle_old_env)
end)
block1 = insert(:block, number: 1)
block2 = insert(:block, number: 2)
block3 = insert(:block, number: 3)
block4 = insert(:block, number: 4)
block5 = insert(:block, number: 5)
:transaction
|> insert(
status: :ok,
block_hash: block1.hash,
block_number: block1.number,
cumulative_gas_used: 884_322,
gas_used: 106_025,
index: 0,
gas_price: 1_000_000_000,
max_priority_fee_per_gas: 1_000_000_000,
max_fee_per_gas: 1_000_000_000
)
:transaction
|> insert(
status: :ok,
block_hash: block2.hash,
block_number: block2.number,
cumulative_gas_used: 884_322,
gas_used: 106_025,
index: 0,
gas_price: 1_000_000_000,
max_priority_fee_per_gas: 1_000_000_000,
max_fee_per_gas: 1_000_000_000
)
:transaction
|> build(
status: :ok,
block_hash: block3.hash,
block_number: block3.number,
gas_price: 0,
cumulative_gas_used: 884_322
)
:transaction
|> build(
status: :ok,
block_hash: block4.hash,
block_number: block4.number,
gas_price: 0,
cumulative_gas_used: 884_322
)
:transaction
|> build(
status: :ok,
block_hash: block5.hash,
block_number: block5.number,
gas_price: 0,
cumulative_gas_used: 884_322
)
assert {{:ok, %{average: nil, fast: nil, slow: nil}}, _} = GasPriceOracle.get_average_gas_price(3, 35, 60, 90)
end
end
end

Loading…
Cancel
Save