Merge branch 'master' into fix-compile-time-spandex-config

pull/1272/head
Zach Daniel 6 years ago committed by GitHub
commit 6c8b8a3995
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      apps/block_scout_web/test/block_scout_web/channels/address_channel_test.exs
  2. 4
      apps/block_scout_web/test/block_scout_web/channels/block_channel_test.exs
  3. 4
      apps/block_scout_web/test/block_scout_web/channels/exchange_rate_channel_test.exs
  4. 6
      apps/block_scout_web/test/block_scout_web/channels/transaction_channel_test.exs
  5. 2
      apps/explorer/config/config.exs
  6. 2
      apps/explorer/config/dev.exs
  7. 2
      apps/explorer/config/dev/ganache.exs
  8. 2
      apps/explorer/config/dev/geth.exs
  9. 2
      apps/explorer/config/dev/parity.exs
  10. 2
      apps/explorer/config/prod.exs
  11. 2
      apps/explorer/config/prod/ganache.exs
  12. 2
      apps/explorer/config/prod/geth.exs
  13. 2
      apps/explorer/config/prod/parity.exs
  14. 2
      apps/explorer/config/test.exs
  15. 101
      apps/explorer/lib/explorer/chain.ex
  16. 2
      apps/explorer/lib/explorer/chain/import.ex
  17. 3
      apps/explorer/lib/explorer/chain/import/runner/blocks.ex
  18. 84
      apps/explorer/test/explorer/chain/import/runner/blocks_test.exs
  19. 111
      apps/explorer/test/explorer/chain_test.exs
  20. 4
      apps/indexer/config/dev/ganache.exs
  21. 4
      apps/indexer/config/dev/geth.exs
  22. 4
      apps/indexer/config/dev/parity.exs
  23. 4
      apps/indexer/config/prod/ganache.exs
  24. 4
      apps/indexer/config/prod/geth.exs
  25. 4
      apps/indexer/config/prod/parity.exs
  26. 2
      apps/indexer/test/indexer/block/fetcher_test.exs
  27. 6
      apps/indexer/test/indexer/sequence_test.exs

@ -17,7 +17,7 @@ defmodule BlockScoutWeb.AddressChannelTest do
Notifier.handle_event({:chain_event, :addresses, :realtime, [address]}) Notifier.handle_event({:chain_event, :addresses, :realtime, [address]})
assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "count", payload: %{count: _}}, 5_000 assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "count", payload: %{count: _}}, :timer.seconds(5)
end end
describe "user subscribed to address" do describe "user subscribed to address" do
@ -36,7 +36,9 @@ defmodule BlockScoutWeb.AddressChannelTest do
Notifier.handle_event({:chain_event, :addresses, :realtime, [address_with_balance]}) Notifier.handle_event({:chain_event, :addresses, :realtime, [address_with_balance]})
assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "balance_update", payload: payload}, 5_000 assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "balance_update", payload: payload},
:timer.seconds(5)
assert payload.address.hash == address_with_balance.hash assert payload.address.hash == address_with_balance.hash
end end
@ -54,7 +56,9 @@ defmodule BlockScoutWeb.AddressChannelTest do
Notifier.handle_event({:chain_event, :transactions, :realtime, [pending.hash]}) Notifier.handle_event({:chain_event, :transactions, :realtime, [pending.hash]})
assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "pending_transaction", payload: payload}, 5_000 assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "pending_transaction", payload: payload},
:timer.seconds(5)
assert payload.address.hash == address.hash assert payload.address.hash == address.hash
assert payload.transaction.hash == pending.hash assert payload.transaction.hash == pending.hash
end end
@ -67,7 +71,7 @@ defmodule BlockScoutWeb.AddressChannelTest do
Notifier.handle_event({:chain_event, :transactions, :realtime, [transaction.hash]}) Notifier.handle_event({:chain_event, :transactions, :realtime, [transaction.hash]})
assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload}, 5_000 assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload}, :timer.seconds(5)
assert payload.address.hash == address.hash assert payload.address.hash == address.hash
assert payload.transaction.hash == transaction.hash assert payload.transaction.hash == transaction.hash
end end
@ -80,7 +84,7 @@ defmodule BlockScoutWeb.AddressChannelTest do
Notifier.handle_event({:chain_event, :transactions, :realtime, [transaction.hash]}) Notifier.handle_event({:chain_event, :transactions, :realtime, [transaction.hash]})
assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload}, 5_000 assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload}, :timer.seconds(5)
assert payload.address.hash == address.hash assert payload.address.hash == address.hash
assert payload.transaction.hash == transaction.hash assert payload.transaction.hash == transaction.hash
end end
@ -93,7 +97,7 @@ defmodule BlockScoutWeb.AddressChannelTest do
Notifier.handle_event({:chain_event, :transactions, :realtime, [transaction.hash]}) Notifier.handle_event({:chain_event, :transactions, :realtime, [transaction.hash]})
assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload}, 5_000 assert_receive %Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload}, :timer.seconds(5)
assert payload.address.hash == address.hash assert payload.address.hash == address.hash
assert payload.transaction.hash == transaction.hash assert payload.transaction.hash == transaction.hash
@ -118,7 +122,7 @@ defmodule BlockScoutWeb.AddressChannelTest do
internal_transaction: %{transaction_hash: transaction_hash, index: index} internal_transaction: %{transaction_hash: transaction_hash, index: index}
} }
}, },
5_000 :timer.seconds(5)
assert address_hash == address.hash assert address_hash == address.hash
assert {transaction_hash, index} == {internal_transaction.transaction_hash, internal_transaction.index} assert {transaction_hash, index} == {internal_transaction.transaction_hash, internal_transaction.index}
@ -142,7 +146,7 @@ defmodule BlockScoutWeb.AddressChannelTest do
internal_transaction: %{transaction_hash: transaction_hash, index: index} internal_transaction: %{transaction_hash: transaction_hash, index: index}
} }
}, },
5_000 :timer.seconds(5)
assert address_hash == address.hash assert address_hash == address.hash
assert {transaction_hash, index} == {internal_transaction.transaction_hash, internal_transaction.index} assert {transaction_hash, index} == {internal_transaction.transaction_hash, internal_transaction.index}
@ -170,7 +174,7 @@ defmodule BlockScoutWeb.AddressChannelTest do
internal_transaction: %{transaction_hash: transaction_hash, index: index} internal_transaction: %{transaction_hash: transaction_hash, index: index}
} }
}, },
5_000 :timer.seconds(5)
assert address_hash == address.hash assert address_hash == address.hash
assert {transaction_hash, index} == {internal_transaction.transaction_hash, internal_transaction.index} assert {transaction_hash, index} == {internal_transaction.transaction_hash, internal_transaction.index}

@ -15,7 +15,7 @@ defmodule BlockScoutWeb.BlockChannelTest do
%Phoenix.Socket.Broadcast{topic: ^topic, event: "new_block", payload: %{block: _}} -> %Phoenix.Socket.Broadcast{topic: ^topic, event: "new_block", payload: %{block: _}} ->
assert true assert true
after after
5_000 -> :timer.seconds(5) ->
assert false, "Expected message received nothing." assert false, "Expected message received nothing."
end end
end end
@ -30,7 +30,7 @@ defmodule BlockScoutWeb.BlockChannelTest do
%Phoenix.Socket.Broadcast{topic: ^topic, event: "index_status", payload: %{}} -> %Phoenix.Socket.Broadcast{topic: ^topic, event: "index_status", payload: %{}} ->
assert true assert true
after after
5_000 -> :timer.seconds(5) ->
assert false, "Expected message received nothing." assert false, "Expected message received nothing."
end end
end end

@ -52,7 +52,7 @@ defmodule BlockScoutWeb.ExchangeRateChannelTest do
assert payload.exchange_rate == token assert payload.exchange_rate == token
assert payload.market_history_data == [] assert payload.market_history_data == []
after after
5_000 -> :timer.seconds(5) ->
assert false, "Expected message received nothing." assert false, "Expected message received nothing."
end end
end end
@ -84,7 +84,7 @@ defmodule BlockScoutWeb.ExchangeRateChannelTest do
assert payload.exchange_rate == token assert payload.exchange_rate == token
assert payload.market_history_data == records assert payload.market_history_data == records
after after
5_000 -> :timer.seconds(5) ->
assert false, "Expected message received nothing." assert false, "Expected message received nothing."
end end
end end

@ -19,7 +19,7 @@ defmodule BlockScoutWeb.TransactionChannelTest do
%Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload} -> %Phoenix.Socket.Broadcast{topic: ^topic, event: "transaction", payload: payload} ->
assert payload.transaction.hash == transaction.hash assert payload.transaction.hash == transaction.hash
after after
5_000 -> :timer.seconds(5) ->
assert false, "Expected message received nothing." assert false, "Expected message received nothing."
end end
end end
@ -36,7 +36,7 @@ defmodule BlockScoutWeb.TransactionChannelTest do
%Phoenix.Socket.Broadcast{topic: ^topic, event: "pending_transaction", payload: payload} -> %Phoenix.Socket.Broadcast{topic: ^topic, event: "pending_transaction", payload: payload} ->
assert payload.transaction.hash == pending.hash assert payload.transaction.hash == pending.hash
after after
5_000 -> :timer.seconds(5) ->
assert false, "Expected message received nothing." assert false, "Expected message received nothing."
end end
end end
@ -56,7 +56,7 @@ defmodule BlockScoutWeb.TransactionChannelTest do
%Phoenix.Socket.Broadcast{topic: ^topic, event: "collated", payload: %{}} -> %Phoenix.Socket.Broadcast{topic: ^topic, event: "collated", payload: %{}} ->
assert true assert true
after after
5_000 -> :timer.seconds(5) ->
assert false, "Expected message received nothing." assert false, "Expected message received nothing."
end end
end end

@ -21,7 +21,7 @@ config :explorer, Explorer.Counters.BlockValidationCounter, enabled: true, enabl
config :explorer, Explorer.ExchangeRates, enabled: true, store: :ets config :explorer, Explorer.ExchangeRates, enabled: true, store: :ets
config :explorer, Explorer.Integrations.EctoLogger, query_time_ms_threshold: 2_000 config :explorer, Explorer.Integrations.EctoLogger, query_time_ms_threshold: :timer.seconds(2)
config :explorer, Explorer.Market.History.Cataloger, enabled: true config :explorer, Explorer.Market.History.Cataloger, enabled: true

@ -5,7 +5,7 @@ config :explorer, Explorer.Repo,
database: "explorer_dev", database: "explorer_dev",
hostname: "localhost", hostname: "localhost",
pool_size: 20, pool_size: 20,
timeout: 80_000 timeout: :timer.seconds(80)
config :explorer, Explorer.Tracer, env: "dev", disabled?: true config :explorer, Explorer.Tracer, env: "dev", disabled?: true

@ -6,7 +6,7 @@ config :explorer,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Ganache variant: EthereumJSONRPC.Ganache
], ],

@ -6,7 +6,7 @@ config :explorer,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Geth variant: EthereumJSONRPC.Geth
], ],

@ -11,7 +11,7 @@ config :explorer,
eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545", eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545",
trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545" trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545"
], ],
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Parity variant: EthereumJSONRPC.Parity
], ],

@ -6,7 +6,7 @@ config :explorer, Explorer.Repo,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"), pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
ssl: String.equivalent?(System.get_env("ECTO_USE_SSL") || "true", "true"), ssl: String.equivalent?(System.get_env("ECTO_USE_SSL") || "true", "true"),
prepare: :unnamed, prepare: :unnamed,
timeout: 60_000 timeout: :timer.seconds(60)
config :explorer, Explorer.Tracer, env: "production", disabled?: true config :explorer, Explorer.Tracer, env: "production", disabled?: true

@ -6,7 +6,7 @@ config :explorer,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Ganache variant: EthereumJSONRPC.Ganache
], ],

@ -6,7 +6,7 @@ config :explorer,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Geth variant: EthereumJSONRPC.Geth
], ],

@ -11,7 +11,7 @@ config :explorer,
eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"), eth_getBalance: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"),
trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL")
], ],
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Parity variant: EthereumJSONRPC.Parity
], ],

@ -9,7 +9,7 @@ config :explorer, Explorer.Repo,
hostname: "localhost", hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox, pool: Ecto.Adapters.SQL.Sandbox,
# Default of `5_000` was too low for `BlockFetcher` test # Default of `5_000` was too low for `BlockFetcher` test
ownership_timeout: 60_000 ownership_timeout: :timer.minutes(1)
config :explorer, Explorer.ExchangeRates, enabled: false, store: :ets config :explorer, Explorer.ExchangeRates, enabled: false, store: :ets

@ -1245,76 +1245,69 @@ defmodule Explorer.Chain do
def missing_block_number_ranges(range) def missing_block_number_ranges(range)
def missing_block_number_ranges(range_start..range_end) do def missing_block_number_ranges(range_start..range_end) do
# subquery so we can check for NULL in `range_min_query`, which happens for empty table range_min = min(range_start, range_end)
min_query = from(block in Block, select: %{number: min(block.number)}, where: block.consensus == true) range_max = max(range_start, range_end)
# this acts a fake found block, so it has to before the range of blocks we actually care to check
before_range_min = min(range_start, range_end) - 1
range_min_query = missing_prefix_query =
from(min_block in subquery(min_query), from(block in Block,
select: %{ select: %{min: type(^range_min, block.number), max: min(block.number) - 1},
# `LEAST` ignores `NULL`, so it picks the fake range when there is no `min_block.number` where: block.consensus == true,
# because `blocks` is empty having: ^range_min < min(block.number) and min(block.number) < ^range_max
number: fragment("LEAST(?, ?)", min_block.number, ^before_range_min)
},
# `blocks` is empty
# same number will not be returned by `number_query`
where: is_nil(min_block.number) or min_block.number != ^before_range_min
) )
number_query = from(block in Block, select: %{number: block.number}, where: block.consensus == true) missing_suffix_query =
from(block in Block,
# subquery so we can check for NULL in `range_max_query`, which happens for empty table select: %{min: max(block.number) + 1, max: type(^range_max, block.number)},
max_query = from(block in Block, select: %{number: max(block.number)}, where: block.consensus == true) where: block.consensus == true,
# this acts a fake found block, so it has to after the range of blocks we actually care to check having: ^range_min < max(block.number) and max(block.number) < ^range_max
after_range_max = max(range_start, range_end) + 1
range_max_query =
from(max_block in subquery(max_query),
select: %{
# `GREATEST` ignores `NULL`, so it picks the fake range when there is no `max_block.number`
# because `blocks` is empty
number: fragment("GREATEST(?, ?)", max_block.number, ^after_range_max)
},
# blocks is empty
# same number will not be returned by `number_query`
where: is_nil(max_block.number) or max_block.number != ^after_range_max
) )
# The actual blocks and a boundary of fake found blocks outside of `range_start..range_end` so that there is always missing_infix_query =
# a `lag` block from(block in Block,
search_range_query = select: %{min: type(^range_min, block.number), max: type(^range_max, block.number)},
number_query where: block.consensus == true,
|> union_all(^range_min_query) having:
|> union_all(^range_max_query) (is_nil(min(block.number)) and is_nil(max(block.number))) or
(^range_max < min(block.number) or max(block.number) < ^range_min)
)
# Gaps and Islands is the term-of-art for finding the runs of missing (gaps) and existing (islands) data. If you # Gaps and Islands is the term-of-art for finding the runs of missing (gaps) and existing (islands) data. If you
# Google for `sql missing ranges` you won't find much, but `sql gaps and islands` will get a lot of hits. # Google for `sql missing ranges` you won't find much, but `sql gaps and islands` will get a lot of hits.
island_query = land_query =
from( from(block in Block,
search_block in subquery(search_range_query), where: block.consensus == true and ^range_min <= block.number and block.number <= ^range_max,
windows: [w: [order_by: search_block.number]], windows: [w: [order_by: block.number]],
select: %{last_number: search_block.number |> lag() |> over(:w), next_number: search_block.number} select: %{last_number: block.number |> lag() |> over(:w), next_number: block.number}
) )
gap_query = gap_query =
from( from(
island in subquery(island_query), coastline in subquery(land_query),
where: island.last_number != island.next_number - 1, where: coastline.last_number != coastline.next_number - 1,
select: %Range{first: island.last_number + 1, last: island.next_number - 1}, select: %{min: coastline.last_number + 1, max: coastline.next_number - 1}
order_by: island.last_number
) )
ascending = Repo.all(gap_query, timeout: :infinity) missing_query =
missing_prefix_query
|> union_all(^missing_infix_query)
|> union_all(^gap_query)
|> union_all(^missing_suffix_query)
{first, last, direction} =
if range_start <= range_end do
{:min, :max, :asc}
else
{:max, :min, :desc}
end
if range_start <= range_end do ordered_missing_query =
ascending from(missing_range in subquery(missing_query),
else select: %Range{first: field(missing_range, ^first), last: field(missing_range, ^last)},
ascending order_by: [{^direction, field(missing_range, ^first)}]
|> Enum.reverse() )
|> Enum.map(fn first..last -> last..first end)
end Repo.all(ordered_missing_query, timeout: :infinity)
end end
@doc """ @doc """

@ -60,7 +60,7 @@ defmodule Explorer.Chain.Import do
@type timestamps :: %{inserted_at: DateTime.t(), updated_at: DateTime.t()} @type timestamps :: %{inserted_at: DateTime.t(), updated_at: DateTime.t()}
# milliseconds # milliseconds
@transaction_timeout 120_000 @transaction_timeout :timer.minutes(4)
@imported_table_rows @runners @imported_table_rows @runners
|> Stream.map(&Map.put(&1.imported_table_row(), :key, &1.option_key())) |> Stream.map(&Map.put(&1.imported_table_row(), :key, &1.option_key()))

@ -133,6 +133,9 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
insert_sql = """ insert_sql = """
INSERT INTO transaction_forks (uncle_hash, index, hash, inserted_at, updated_at) INSERT INTO transaction_forks (uncle_hash, index, hash, inserted_at, updated_at)
#{select_sql} #{select_sql}
ON CONFLICT (uncle_hash, index)
DO UPDATE SET hash = EXCLUDED.hash
WHERE EXCLUDED.hash <> transaction_forks.hash
RETURNING uncle_hash, hash RETURNING uncle_hash, hash
""" """

@ -0,0 +1,84 @@
defmodule Explorer.Chain.Import.Runner.BlocksTest do
use Explorer.DataCase
import Ecto.Query, only: [from: 2, select: 2, where: 2]
alias Ecto.Multi
alias Explorer.Chain.Import.Runner.{Blocks, Transaction}
alias Explorer.Chain.{Block, Transaction}
alias Explorer.Repo
describe "run/1" do
setup do
block = insert(:block, consensus: true)
transaction =
:transaction
|> insert()
|> with_block(block)
%{consensus_block: block, transaction: transaction}
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},
transaction: transaction
} do
block_params =
params_for(:block, hash: block_hash, miner_hash: miner_hash, number: block_number, consensus: false)
%Ecto.Changeset{valid?: true, changes: block_changes} = Block.changeset(%Block{}, block_params)
changes_list = [block_changes]
timestamp = DateTime.utc_now()
options = %{timestamps: %{inserted_at: timestamp, updated_at: timestamp}}
assert Repo.aggregate(from(transaction in Transaction, where: is_nil(transaction.block_number)), :count, :hash) ==
0
assert count(Transaction.Fork) == 0
# re-org consensus_block to uncle
assert {:ok, %{derive_transaction_forks: [_]}} =
Multi.new()
|> Blocks.run(changes_list, options)
|> Repo.transaction()
assert Repo.aggregate(where(Block, consensus: false), :count, :number) == 1
assert Repo.aggregate(from(transaction in Transaction, where: is_nil(transaction.block_number)), :count, :hash) ==
1
assert count(Transaction.Fork) == 1
non_consensus_transaction = Repo.get(Transaction, transaction.hash)
non_consensus_block = Repo.get(Block, block_hash)
# Make it consensus again
new_consensus_block =
non_consensus_block
|> Block.changeset(%{consensus: true})
|> Repo.update!()
with_block(non_consensus_transaction, new_consensus_block)
ctid = Repo.one!(from(transaction_fork in Transaction.Fork, select: "ctid"))
assert Repo.aggregate(from(transaction in Transaction, where: is_nil(transaction.block_number)), :count, :hash) ==
0
assert {:ok, %{derive_transaction_forks: []}} =
Multi.new()
|> Blocks.run(changes_list, options)
|> Repo.transaction()
assert Repo.one!(from(transaction_fork in Transaction.Fork, select: "ctid")) == ctid,
"Tuple was written even though it is not distinct"
end
end
defp count(schema) do
Repo.one!(select(schema, fragment("COUNT(*)")))
end
end

@ -2191,6 +2191,117 @@ defmodule Explorer.ChainTest do
end end
end end
describe "missing_block_number_ranges/1" do
# 0000
test "0..0 without blocks" do
assert Chain.missing_block_number_ranges(0..0) == [0..0]
end
# 0001
test "0..0 with block 3" do
insert(:block, number: 3)
assert Chain.missing_block_number_ranges(0..0) == [0..0]
end
# 0010
test "0..0 with block 2" do
insert(:block, number: 2)
assert Chain.missing_block_number_ranges(0..0) == [0..0]
end
# 0011
test "0..0 with blocks 2,3" do
Enum.each([2, 3], &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == [0..0]
end
# 0100
test "0..0 with block 1" do
insert(:block, number: 1)
assert Chain.missing_block_number_ranges(0..0) == [0..0]
end
# 0101
test "0..0 with blocks 1,3" do
Enum.each([1, 3], &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == [0..0]
end
# 0111
test "0..0 with blocks 1..3" do
Enum.each(1..3, &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == [0..0]
end
# 1000
test "0..0 with block 0" do
insert(:block, number: 0)
assert Chain.missing_block_number_ranges(0..0) == []
end
# 1001
test "0..0 with blocks 0,3" do
Enum.each([0, 3], &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == []
end
# 1010
test "0..0 with blocks 0,2" do
Enum.each([0, 2], &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == []
end
# 1011
test "0..0 with blocks 0,2,3" do
Enum.each([0, 2, 3], &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == []
end
# 1100
test "0..0 with blocks 0..1" do
Enum.each(0..1, &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == []
end
# 1101
test "0..0 with blocks 0,1,3" do
Enum.each([0, 1, 3], &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == []
end
# 1110
test "0..0 with blocks 0..2" do
Enum.each(0..2, &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == []
end
# 1111
test "0..0 with blocks 0..3" do
Enum.each(0..2, &insert(:block, number: &1))
assert Chain.missing_block_number_ranges(0..0) == []
end
test "0..2 with block 1" do
insert(:block, number: 1)
assert Chain.missing_block_number_ranges(0..2) == [0..0, 2..2]
end
end
describe "recent_collated_transactions/1" do describe "recent_collated_transactions/1" do
test "with no collated transactions it returns an empty list" do test "with no collated transactions it returns an empty list" do
assert [] == Explorer.Chain.recent_collated_transactions() assert [] == Explorer.Chain.recent_collated_transactions()

@ -1,13 +1,13 @@
use Mix.Config use Mix.Config
config :indexer, config :indexer,
block_interval: 5_000, block_interval: :timer.seconds(5),
json_rpc_named_arguments: [ json_rpc_named_arguments: [
transport: EthereumJSONRPC.HTTP, transport: EthereumJSONRPC.HTTP,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Ganache variant: EthereumJSONRPC.Ganache
], ],

@ -1,13 +1,13 @@
use Mix.Config use Mix.Config
config :indexer, config :indexer,
block_interval: 5_000, block_interval: :timer.seconds(5),
json_rpc_named_arguments: [ json_rpc_named_arguments: [
transport: EthereumJSONRPC.HTTP, transport: EthereumJSONRPC.HTTP,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Geth variant: EthereumJSONRPC.Geth
], ],

@ -1,7 +1,7 @@
use Mix.Config use Mix.Config
config :indexer, config :indexer,
block_interval: 5_000, block_interval: :timer.seconds(5),
json_rpc_named_arguments: [ json_rpc_named_arguments: [
transport: EthereumJSONRPC.HTTP, transport: EthereumJSONRPC.HTTP,
transport_options: [ transport_options: [
@ -12,7 +12,7 @@ config :indexer,
trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545", trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545",
trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545" trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") || "http://localhost:8545"
], ],
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Parity variant: EthereumJSONRPC.Parity
], ],

@ -1,13 +1,13 @@
use Mix.Config use Mix.Config
config :indexer, config :indexer,
block_interval: 5_000, block_interval: :timer.seconds(5),
json_rpc_named_arguments: [ json_rpc_named_arguments: [
transport: EthereumJSONRPC.HTTP, transport: EthereumJSONRPC.HTTP,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "http://localhost:7545",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Ganache variant: EthereumJSONRPC.Ganache
], ],

@ -1,13 +1,13 @@
use Mix.Config use Mix.Config
config :indexer, config :indexer,
block_interval: 5_000, block_interval: :timer.seconds(5),
json_rpc_named_arguments: [ json_rpc_named_arguments: [
transport: EthereumJSONRPC.HTTP, transport: EthereumJSONRPC.HTTP,
transport_options: [ transport_options: [
http: EthereumJSONRPC.HTTP.HTTPoison, http: EthereumJSONRPC.HTTP.HTTPoison,
url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY", url: System.get_env("ETHEREUM_JSONRPC_HTTP_URL") || "https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY",
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Geth variant: EthereumJSONRPC.Geth
], ],

@ -1,7 +1,7 @@
use Mix.Config use Mix.Config
config :indexer, config :indexer,
block_interval: 5_000, block_interval: :timer.seconds(5),
json_rpc_named_arguments: [ json_rpc_named_arguments: [
transport: EthereumJSONRPC.HTTP, transport: EthereumJSONRPC.HTTP,
transport_options: [ transport_options: [
@ -12,7 +12,7 @@ config :indexer,
trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"), trace_block: System.get_env("ETHEREUM_JSONRPC_TRACE_URL"),
trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL") trace_replayTransaction: System.get_env("ETHEREUM_JSONRPC_TRACE_URL")
], ],
http_options: [recv_timeout: 60_000, timeout: 60_000, hackney: [pool: :ethereum_jsonrpc]] http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]]
], ],
variant: EthereumJSONRPC.Parity variant: EthereumJSONRPC.Parity
], ],

@ -611,7 +611,7 @@ defmodule Indexer.Block.FetcherTest do
end end
defp wait_for_tasks(buffered_task) do defp wait_for_tasks(buffered_task) do
wait_until(10_000, fn -> wait_until(:timer.seconds(10), fn ->
counts = BufferedTask.debug_count(buffered_task) counts = BufferedTask.debug_count(buffered_task)
counts.buffer == 0 and counts.tasks == 0 counts.buffer == 0 and counts.tasks == 0
end) end)

@ -16,7 +16,7 @@ defmodule Indexer.SequenceTest do
{child_pid, child_ref} = {child_pid, child_ref} =
spawn_monitor(fn -> spawn_monitor(fn ->
Sequence.start_link(first: 1, step: -1) Sequence.start_link(first: 1, step: -1)
Process.sleep(5_000) Process.sleep(:timer.seconds(5))
end) end)
assert_receive {:DOWN, ^child_ref, :process, ^child_pid, assert_receive {:DOWN, ^child_ref, :process, ^child_pid,
@ -27,7 +27,7 @@ defmodule Indexer.SequenceTest do
{child_pid, child_ref} = {child_pid, child_ref} =
spawn_monitor(fn -> spawn_monitor(fn ->
Sequence.start_link(step: -1) Sequence.start_link(step: -1)
Process.sleep(5_000) Process.sleep(:timer.seconds(5))
end) end)
assert_receive {:DOWN, ^child_ref, :process, ^child_pid, "either :ranges or :first must be set"} assert_receive {:DOWN, ^child_ref, :process, ^child_pid, "either :ranges or :first must be set"}
@ -47,7 +47,7 @@ defmodule Indexer.SequenceTest do
{child_pid, child_ref} = {child_pid, child_ref} =
spawn_monitor(fn -> spawn_monitor(fn ->
Sequence.start_link(ranges: [1..0], first: 1, step: -1) Sequence.start_link(ranges: [1..0], first: 1, step: -1)
Process.sleep(5_000) Process.sleep(:timer.seconds(5))
end) end)
assert_receive {:DOWN, ^child_ref, :process, ^child_pid, assert_receive {:DOWN, ^child_ref, :process, ^child_pid,

Loading…
Cancel
Save