Merge branch 'master' into ab-fix-try-it-out-section

pull/2688/head
Ayrat Badykov 5 years ago committed by GitHub
commit 03c592695d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      CHANGELOG.md
  2. 12
      apps/block_scout_web/lib/block_scout_web/notifier.ex
  3. 4
      apps/explorer/config/config.exs
  4. 163
      apps/explorer/lib/explorer/chain/import/runner/blocks.ex
  5. 32
      apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex
  6. 7
      apps/explorer/priv/repo/migrations/20190910170703_create_indexes_for_block_number_in_token_transfers_and_transactions.exs
  7. 114
      apps/explorer/test/explorer/chain/import/runner/blocks_test.exs
  8. 101
      apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs
  9. 3
      docs/env-variables.md

@ -9,9 +9,13 @@
### Fixes
- [#2688](https://github.com/poanetwork/blockscout/pull/2688) - fix try it out section
- [#2701](https://github.com/poanetwork/blockscout/pull/2701) - Exclude nonconsensus blocks from avg block time calculation by default
- [#2693](https://github.com/poanetwork/blockscout/pull/2693) - remove non consensus internal transactions
- [#2687](https://github.com/poanetwork/blockscout/pull/2687) - remove non-consensus token transfers, logs when inserting new consensus blocks
- [#2684](https://github.com/poanetwork/blockscout/pull/2684) - do not filter pending logs
- [#2682](https://github.com/poanetwork/blockscout/pull/2682) - Use Task.start instead of Task.async in caches
- [#2671](https://github.com/poanetwork/blockscout/pull/2671) - fixed buttons color at smart contract section
- [#2691](https://github.com/poanetwork/blockscout/pull/2691) - fix exchange rate websocket update for Rootstock
### Chore
@ -51,6 +55,7 @@
- [#2468](https://github.com/poanetwork/blockscout/pull/2468) - fix confirmations for non consensus blocks
### Chore
- [#2662](https://github.com/poanetwork/blockscout/pull/2662) - fetch coin gecko id based on the coin symbol
- [#2646](https://github.com/poanetwork/blockscout/pull/2646) - Added Xerom to list of Additional Chains using BlockScout
- [#2634](https://github.com/poanetwork/blockscout/pull/2634) - add Lukso to networks dropdown
- [#2617](https://github.com/poanetwork/blockscout/pull/2617) - skip cache update if there are no blocks inserted

@ -7,6 +7,7 @@ defmodule BlockScoutWeb.Notifier do
alias BlockScoutWeb.{AddressContractVerificationView, Endpoint}
alias Explorer.{Chain, Market, Repo}
alias Explorer.Chain.{Address, InternalTransaction, Transaction}
alias Explorer.Chain.Supply.RSK
alias Explorer.Counters.AverageBlockTime
alias Explorer.ExchangeRates.Token
alias Explorer.SmartContract.{Solidity.CodeCompiler, Solidity.CompilerVersion}
@ -76,8 +77,17 @@ defmodule BlockScoutWeb.Notifier do
data -> data
end
exchange_rate_with_available_supply =
case Application.get_env(:explorer, :supply) do
RSK ->
%{exchange_rate | available_supply: nil, market_cap_usd: RSK.market_cap(exchange_rate)}
_ ->
exchange_rate
end
Endpoint.broadcast("exchange_rate:new_rate", "new_rate", %{
exchange_rate: exchange_rate,
exchange_rate: exchange_rate_with_available_supply,
market_history_data: Enum.map(market_history_data, fn day -> Map.take(day, [:closing_price, :date]) end)
})
end

@ -14,7 +14,7 @@ config :explorer,
System.get_env("ALLOWED_EVM_VERSIONS") ||
"homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople,petersburg,default",
include_uncles_in_average_block_time:
if(System.get_env("UNCLES_IN_AVERAGE_BLOCK_TIME") == "false", do: false, else: true),
if(System.get_env("UNCLES_IN_AVERAGE_BLOCK_TIME") == "true", do: true, else: false),
healthy_blocks_period: System.get_env("HEALTHY_BLOCKS_PERIOD") || :timer.minutes(5)
average_block_period =
@ -38,8 +38,6 @@ config :explorer, Explorer.Chain.Cache.BlockNumber,
ttl_check_interval: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(1), else: false),
global_ttl: if(System.get_env("DISABLE_INDEXER") == "true", do: :timer.seconds(5))
config :explorer, Explorer.ExchangeRates.Source.CoinGecko, coin_id: System.get_env("COIN_GECKO_ID", "poa-network")
balances_update_interval =
if System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL") do
case Integer.parse(System.get_env("ADDRESS_WITH_BALANCES_UPDATE_INTERVAL")) do

@ -9,7 +9,7 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
alias Ecto.Adapters.SQL
alias Ecto.{Changeset, Multi, Repo}
alias Explorer.Chain.{Address, Block, Hash, Import, InternalTransaction, Transaction}
alias Explorer.Chain.{Address, Block, Hash, Import, InternalTransaction, Log, TokenTransfer, Transaction}
alias Explorer.Chain.Block.Reward
alias Explorer.Chain.Import.Runner
alias Explorer.Chain.Import.Runner.Address.CurrentTokenBalances
@ -58,6 +58,31 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
where_forked: where_forked
})
end)
|> Multi.run(:lose_consensus, fn repo, _ ->
lose_consensus(repo, ordered_consensus_block_numbers, insert_options)
end)
|> Multi.run(:lose_invalid_neighbour_consensus, fn repo, _ ->
lose_invalid_neighbour_consensus(repo, where_invalid_neighbour, insert_options)
end)
|> Multi.run(:remove_nonconsensus_data, fn repo,
%{
lose_consensus: lost_consensus_blocks,
lose_invalid_neighbour_consensus: lost_consensus_neighbours
} ->
nonconsensus_block_numbers =
(lost_consensus_blocks ++ lost_consensus_neighbours)
|> Enum.map(fn %{number: number} ->
number
end)
|> Enum.sort()
|> Enum.dedup()
remove_nonconsensus_data(
repo,
nonconsensus_block_numbers,
insert_options
)
end)
# MUST be after `:derive_transaction_forks`, which depends on values in `transactions` table
|> Multi.run(:fork_transactions, fn repo, _ ->
fork_transactions(%{
@ -67,12 +92,6 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
where_forked: where_forked
})
end)
|> Multi.run(:lose_consensus, fn repo, _ ->
lose_consensus(repo, ordered_consensus_block_numbers, insert_options)
end)
|> Multi.run(:lose_invalid_neighbour_consensus, fn repo, _ ->
lose_invalid_neighbour_consensus(repo, where_invalid_neighbour, insert_options)
end)
|> Multi.run(:delete_address_token_balances, fn repo, _ ->
delete_address_token_balances(repo, ordered_consensus_block_numbers, insert_options)
end)
@ -342,6 +361,136 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
end
end
defp remove_nonconsensus_data(
repo,
nonconsensus_block_numbers,
insert_options
) do
with {:ok, deleted_token_transfers} <-
remove_nonconsensus_token_transfers(repo, nonconsensus_block_numbers, insert_options),
{:ok, deleted_logs} <- remove_nonconsensus_logs(repo, nonconsensus_block_numbers, insert_options),
{:ok, deleted_internal_transactions} <-
remove_nonconsensus_internal_transactions(repo, nonconsensus_block_numbers, insert_options) do
{:ok,
%{
token_transfers: deleted_token_transfers,
logs: deleted_logs,
internal_transactions: deleted_internal_transactions
}}
end
end
defp remove_nonconsensus_token_transfers(repo, nonconsensus_block_numbers, %{timeout: timeout}) do
ordered_token_transfers =
from(token_transfer in TokenTransfer,
where: token_transfer.block_number in ^nonconsensus_block_numbers,
select: map(token_transfer, [:transaction_hash, :log_index]),
# Enforce TokenTransfer ShareLocks order (see docs: sharelocks.md)
order_by: [
token_transfer.transaction_hash,
token_transfer.log_index
],
lock: "FOR UPDATE"
)
query =
from(token_transfer in TokenTransfer,
select: map(token_transfer, [:transaction_hash, :log_index]),
inner_join: ordered_token_transfer in subquery(ordered_token_transfers),
on:
ordered_token_transfer.transaction_hash ==
token_transfer.transaction_hash and
ordered_token_transfer.log_index == token_transfer.log_index
)
try do
{_count, deleted_token_transfers} = repo.delete_all(query, timeout: timeout)
{:ok, deleted_token_transfers}
rescue
postgrex_error in Postgrex.Error ->
{:error, %{exception: postgrex_error, block_numbers: nonconsensus_block_numbers}}
end
end
defp remove_nonconsensus_internal_transactions(repo, nonconsensus_block_numbers, %{timeout: timeout}) do
transaction_query =
from(transaction in Transaction,
where: transaction.block_number in ^nonconsensus_block_numbers,
select: map(transaction, [:hash]),
order_by: transaction.hash
)
ordered_internal_transactions =
from(internal_transaction in InternalTransaction,
inner_join: transaction in subquery(transaction_query),
on: internal_transaction.transaction_hash == transaction.hash,
select: map(internal_transaction, [:transaction_hash, :index]),
# Enforce InternalTransaction ShareLocks order (see docs: sharelocks.md)
order_by: [
internal_transaction.transaction_hash,
internal_transaction.index
],
lock: "FOR UPDATE OF i0"
)
query =
from(internal_transaction in InternalTransaction,
select: map(internal_transaction, [:transaction_hash, :index]),
inner_join: ordered_internal_transaction in subquery(ordered_internal_transactions),
on:
ordered_internal_transaction.transaction_hash == internal_transaction.transaction_hash and
ordered_internal_transaction.index == internal_transaction.index
)
try do
{_count, deleted_internal_transactions} = repo.delete_all(query, timeout: timeout)
{:ok, deleted_internal_transactions}
rescue
postgrex_error in Postgrex.Error ->
{:error, %{exception: postgrex_error, block_numbers: nonconsensus_block_numbers}}
end
end
defp remove_nonconsensus_logs(repo, nonconsensus_block_numbers, %{timeout: timeout}) do
transaction_query =
from(transaction in Transaction,
where: transaction.block_number in ^nonconsensus_block_numbers,
select: map(transaction, [:hash]),
order_by: transaction.hash
)
ordered_logs =
from(log in Log,
inner_join: transaction in subquery(transaction_query),
on: log.transaction_hash == transaction.hash,
select: map(log, [:transaction_hash, :index]),
# Enforce Log ShareLocks order (see docs: sharelocks.md)
order_by: [
log.transaction_hash,
log.index
],
lock: "FOR UPDATE OF l0"
)
query =
from(log in Log,
select: map(log, [:transaction_hash, :index]),
inner_join: ordered_log in subquery(ordered_logs),
on: ordered_log.transaction_hash == log.transaction_hash and ordered_log.index == log.index
)
try do
{_count, deleted_logs} = repo.delete_all(query, timeout: timeout)
{:ok, deleted_logs}
rescue
postgrex_error in Postgrex.Error ->
{:error, %{exception: postgrex_error, block_numbers: nonconsensus_block_numbers}}
end
end
defp delete_address_token_balances(_, [], _), do: {:ok, []}
defp delete_address_token_balances(repo, ordered_consensus_block_numbers, %{timeout: timeout}) do

@ -44,15 +44,41 @@ defmodule Explorer.ExchangeRates.Source.CoinGecko do
@impl Source
def source_url do
"#{base_url()}/coins/#{coin_id()}"
{:ok, id} = coin_id()
"#{base_url()}/coins/#{id}"
end
defp base_url do
config(:base_url) || "https://api.coingecko.com/api/v3"
end
defp coin_id do
Application.get_env(:explorer, __MODULE__)[:coin_id]
def coin_id do
url = "#{base_url()}/coins/list"
symbol = String.downcase(Explorer.coin())
case HTTPoison.get(url, headers()) do
{:ok, %Response{body: body, status_code: 200}} ->
data = decode_json(body)
symbol_data =
Enum.find(data, fn item ->
item["symbol"] == symbol
end)
if symbol_data do
{:ok, symbol_data["id"]}
else
{:error, :not_found}
end
{:ok, %Response{body: body, status_code: status_code}} when status_code in 400..499 ->
{:error, decode_json(body)["error"]}
{:error, %Error{reason: reason}} ->
{:error, reason}
end
end
defp get_btc_price(currency \\ "usd") do

@ -0,0 +1,7 @@
defmodule Explorer.Repo.Migrations.CreateIndexesForBlockNumberInTokenTransfersAndTransactions do
use Ecto.Migration
def change do
create_if_not_exists(index(:token_transfers, [:block_number]))
end
end

@ -7,13 +7,14 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
alias Ecto.Multi
alias Explorer.Chain.Import.Runner.{Blocks, Transactions}
alias Explorer.Chain.{Address, Block, Transaction}
alias Explorer.Chain.{Address, Block, InternalTransaction, Log, Transaction, TokenTransfer}
alias Explorer.Chain
alias Explorer.Repo
describe "run/1" do
setup do
block = insert(:block, consensus: true)
miner = insert(:address)
block = params_for(:block, consensus: true, miner_hash: miner.hash)
timestamp = DateTime.utc_now()
options = %{timestamps: %{inserted_at: timestamp, updated_at: timestamp}}
@ -22,9 +23,11 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
test "derive_transaction_forks replaces hash on conflicting (uncle_hash, index)", %{
consensus_block: %Block{hash: block_hash, miner_hash: miner_hash, number: block_number} = consensus_block,
consensus_block: %{hash: block_hash, miner_hash: miner_hash, number: block_number},
options: options
} do
consensus_block = insert(:block, %{hash: block_hash, number: block_number})
transaction =
:transaction
|> insert()
@ -81,7 +84,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
test "delete_address_current_token_balances deletes rows with matching block number when consensus is true",
%{consensus_block: %Block{number: block_number} = block, options: options} do
%{consensus_block: %{number: block_number} = block, options: options} do
%Address.CurrentTokenBalance{address_hash: address_hash, token_contract_address_hash: token_contract_address_hash} =
insert(:address_current_token_balance, block_number: block_number)
@ -98,7 +101,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
test "delete_address_current_token_balances does not delete rows with matching block number when consensus is false",
%{consensus_block: %Block{number: block_number} = block, options: options} do
%{consensus_block: %{number: block_number} = block, options: options} do
%Address.CurrentTokenBalance{} = insert(:address_current_token_balance, block_number: block_number)
count = 1
@ -113,8 +116,93 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
assert count(Address.CurrentTokenBalance) == count
end
test "remove_nonconsensus_data deletes token transfer rows with matching block number when new consensus block is inserted",
%{consensus_block: %{number: block_number} = block, options: options} do
insert(:block, number: block_number, consensus: true)
%TokenTransfer{transaction_hash: transaction_hash, log_index: log_index} =
insert(:token_transfer, block_number: block_number, transaction: insert(:transaction))
assert count(TokenTransfer) == 1
assert {:ok,
%{
remove_nonconsensus_data: %{
token_transfers: [
%{transaction_hash: ^transaction_hash, log_index: ^log_index}
]
}
}} = run_block_consensus_change(block, true, options)
assert count(TokenTransfer) == 0
end
test "remove_nonconsensus_data does not delete token transfer rows with matching block number when new consensus block wasn't inserted",
%{consensus_block: %{number: block_number} = block, options: options} do
insert(:token_transfer, block_number: block_number, transaction: insert(:transaction))
count = 1
assert count(TokenTransfer) == count
assert {:ok,
%{
remove_nonconsensus_data: %{
token_transfers: []
}
}} = run_block_consensus_change(block, false, options)
assert count(TokenTransfer) == count
end
test "remove_nonconsensus_data deletes nonconsensus logs", %{
consensus_block: %{number: block_number} = block,
options: options
} do
old_block = insert(:block, number: block_number, consensus: true)
forked_transaction = :transaction |> insert() |> with_block(old_block)
%Log{transaction_hash: hash, index: index} = insert(:log, transaction: forked_transaction)
assert count(Log) == 1
assert {:ok,
%{
remove_nonconsensus_data: %{
logs: [
%{transaction_hash: ^hash, index: ^index}
]
}
}} = run_block_consensus_change(block, true, options)
assert count(Log) == 0
end
test "remove_nonconsensus_data deletes nonconsensus internal transactions", %{
consensus_block: %{number: block_number} = block,
options: options
} do
old_block = insert(:block, number: block_number, consensus: true)
forked_transaction = :transaction |> insert() |> with_block(old_block)
%InternalTransaction{index: index, transaction_hash: hash} =
insert(:internal_transaction, index: 0, transaction: forked_transaction)
assert count(InternalTransaction) == 1
assert {:ok,
%{
remove_nonconsensus_data: %{
internal_transactions: [
%{transaction_hash: ^hash, index: ^index}
]
}
}} = run_block_consensus_change(block, true, options)
assert count(InternalTransaction) == 0
end
test "derive_address_current_token_balances inserts rows if there is an address_token_balance left for the rows deleted by delete_address_current_token_balances",
%{consensus_block: %Block{number: block_number} = block, options: options} do
%{consensus_block: %{number: block_number} = block, options: options} do
token = insert(:token)
token_contract_address_hash = token.contract_address_hash
@ -172,7 +260,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
test "a non-holder reverting to a holder increases the holder_count",
%{consensus_block: %Block{hash: block_hash, miner_hash: miner_hash, number: block_number}, options: options} do
%{consensus_block: %{hash: block_hash, miner_hash: miner_hash, number: block_number}, options: options} do
token = insert(:token)
token_contract_address_hash = token.contract_address_hash
@ -204,7 +292,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
test "a holder reverting to a non-holder decreases the holder_count",
%{consensus_block: %Block{hash: block_hash, miner_hash: miner_hash, number: block_number}, options: options} do
%{consensus_block: %{hash: block_hash, miner_hash: miner_hash, number: block_number}, options: options} do
token = insert(:token)
token_contract_address_hash = token.contract_address_hash
@ -236,7 +324,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
test "a non-holder becoming and a holder becoming while a holder becomes a non-holder cancels out and holder_count does not change",
%{consensus_block: %Block{number: block_number} = block, options: options} do
%{consensus_block: %{number: block_number} = block, options: options} do
token = insert(:token)
token_contract_address_hash = token.contract_address_hash
@ -262,7 +350,8 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
# Regression test for https://github.com/poanetwork/blockscout/issues/1644
test "discards neighbouring blocks if they aren't related to the current one because of reorg and/or import timeout",
%{consensus_block: %Block{number: block_number, hash: block_hash, miner_hash: miner_hash}, options: options} do
%{consensus_block: %{number: block_number, hash: block_hash, miner_hash: miner_hash}, options: options} do
insert(:block, %{number: block_number, hash: block_hash})
old_block1 = params_for(:block, miner_hash: miner_hash, parent_hash: block_hash, number: block_number + 1)
new_block1 = params_for(:block, miner_hash: miner_hash, parent_hash: block_hash, number: block_number + 1)
@ -286,7 +375,8 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
# Regression test for https://github.com/poanetwork/blockscout/issues/1911
test "forces block refetch if transaction is re-collated in a different block",
%{consensus_block: %Block{number: block_number, hash: block_hash, miner_hash: miner_hash}, options: options} do
%{consensus_block: %{number: block_number, hash: block_hash, miner_hash: miner_hash}, options: options} do
insert(:block, %{number: block_number, hash: block_hash})
new_block1 = params_for(:block, miner_hash: miner_hash, parent_hash: block_hash, number: block_number + 1)
new_block2 = params_for(:block, miner_hash: miner_hash, parent_hash: new_block1.hash, number: block_number + 2)
@ -365,7 +455,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
defp run_block_consensus_change(
%Block{hash: block_hash, miner_hash: miner_hash, number: block_number},
%{hash: block_hash, miner_hash: miner_hash, number: block_number},
consensus,
options
) do

@ -18,6 +18,46 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do
}
"""
@coins_list """
[
{
"id": "poa-network",
"symbol": "poa",
"name": "POA Network"
},
{
"id": "poc-chain",
"symbol": "pocc",
"name": "POC Chain"
},
{
"id": "pocket-arena",
"symbol": "poc",
"name": "Pocket Arena"
},
{
"id": "ethereum",
"symbol": "eth",
"name": "Ethereum"
},
{
"id": "rootstock",
"symbol": "rbtc",
"name": "Rootstock RSK"
},
{
"id": "dai",
"symbol": "dai",
"name": "Dai"
},
{
"id": "callisto",
"symbol": "clo",
"name": "Callisto Network"
}
]
"""
describe "format_data/1" do
setup do
bypass = Bypass.open()
@ -62,4 +102,65 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do
assert [] = CoinGecko.format_data(bad_data)
end
end
describe "coin_id/0" do
setup do
bypass = Bypass.open()
Application.put_env(:explorer, CoinGecko, base_url: "http://localhost:#{bypass.port}")
on_exit(fn ->
Application.put_env(:explorer, :coin, "POA")
end)
{:ok, bypass: bypass}
end
test "fetches poa coin id by default", %{bypass: bypass} do
Bypass.expect(bypass, "GET", "/coins/list", fn conn ->
Conn.resp(conn, 200, @coins_list)
end)
assert CoinGecko.coin_id() == {:ok, "poa-network"}
end
test "fetches eth coin id", %{bypass: bypass} do
Application.put_env(:explorer, :coin, "ETH")
Bypass.expect(bypass, "GET", "/coins/list", fn conn ->
Conn.resp(conn, 200, @coins_list)
end)
assert CoinGecko.coin_id() == {:ok, "ethereum"}
end
test "fetches rbtc coin id", %{bypass: bypass} do
Application.put_env(:explorer, :coin, "RBTC")
Bypass.expect(bypass, "GET", "/coins/list", fn conn ->
Conn.resp(conn, 200, @coins_list)
end)
assert CoinGecko.coin_id() == {:ok, "rootstock"}
end
test "fetches dai coin id", %{bypass: bypass} do
Application.put_env(:explorer, :coin, "DAI")
Bypass.expect(bypass, "GET", "/coins/list", fn conn ->
Conn.resp(conn, 200, @coins_list)
end)
assert CoinGecko.coin_id() == {:ok, "dai"}
end
test "fetches callisto coin id", %{bypass: bypass} do
Application.put_env(:explorer, :coin, "CLO")
Bypass.expect(bypass, "GET", "/coins/list", fn conn ->
Conn.resp(conn, 200, @coins_list)
end)
assert CoinGecko.coin_id() == {:ok, "callisto"}
end
end
end

@ -56,6 +56,7 @@ $ export NETWORK=POA
| `SUPPORTED_CHAINS` | | Array of supported chains that displays in the footer and in the chains dropdown. This var was introduced in this PR [#1900](https://github.com/poanetwork/blockscout/pull/1900) and looks like an array of JSON objects. | (empty) | v2.0.0+ | | |
| `BLOCK_COUNT_CACHE_PERIOD ` | | time to live of cache in seconds. This var was introduced in [#1876](https://github.com/poanetwork/blockscout/pull/1876) | 600 | v2.0.0+ | | |
| `ALLOWED_EVM_VERSIONS ` | | the comma-separated list of allowed EVM versions for contracts verification. This var was introduced in [#1964](https://github.com/poanetwork/blockscout/pull/1964) | "homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg" | v2.0.0+ | | |
| `UNCLES_IN_AVERAGE_BLOCK_TIME` | Include or exclude nonconsensus blocks in avg block time calculation. Exclude if `false`. | false | v2.0.1+ | | |
| `AVERAGE_BLOCK_CACHE_PERIOD` | | Update of average block cache, in seconds | 30 minutes | v2.0.2+ | |
| `MARKET_HISTORY_CACHE_PERIOD` | | Update of market history cache, in seconds | 6 hours | v2.0.2+ | |
| `DISABLE_WEBAPP` | | If `true`, endpoints to webapp are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: | |
@ -65,6 +66,6 @@ $ export NETWORK=POA
| `WEBAPP_URL` | | Link to web application instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | |
| `API_URL` | | Link to API instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | |
| `CHAIN_SPEC_PATH` | | Chain specification path (absolute file system path or url) to import block emission reward ranges and genesis account balances from | (empty) | v2.0.4+ | | |
| `COIN_GECKO_ID` | | CoinGecko coin id required for fetching an exchange rate | poa-network | v2.0.4+ | | |
| `COIN_GECKO_ID` | | CoinGecko coin id required for fetching an exchange rate | poa-network | v2.0.4+ | | master |
| `EMISSION_FORMAT` | | Should be set to `POA` if you have block emission indentical to POA Network. This env var is used only if `CHAIN_SPEC_PATH` is set | `STANDARD` | v2.0.4+ | | |
| `REWARDS_CONTRACT_ADDRESS` | | Emission rewards contract address. This env var is used only if `EMISSION_FORMAT` is set to `POA` | `0xeca443e8e1ab29971a45a9c57a6a9875701698a5` | v2.0.4+ | | |

Loading…
Cancel
Save