|
|
|
@ -227,60 +227,31 @@ defmodule Explorer.Chain do |
|
|
|
|
transaction_hashes_from_token_transfers = |
|
|
|
|
TokenTransfer.where_any_address_fields_match(direction, address_hash, paging_options) |
|
|
|
|
|
|
|
|
|
token_transfers_query = |
|
|
|
|
transaction_hashes_from_token_transfers |
|
|
|
|
|> Transaction.where_transaction_hashes_match() |
|
|
|
|
|> join_associations(necessity_by_association) |
|
|
|
|
|> order_by([transaction], desc: transaction.block_number, desc: transaction.index) |
|
|
|
|
|> Transaction.preload_token_transfers(address_hash) |
|
|
|
|
|
|
|
|
|
base_query = |
|
|
|
|
transactions_list = |
|
|
|
|
paging_options |
|
|
|
|
|> fetch_transactions() |
|
|
|
|
|> Transaction.where_transaction_matches(transaction_hashes_from_token_transfers, direction, address_hash) |
|
|
|
|
|> join_associations(necessity_by_association) |
|
|
|
|
|> Transaction.preload_token_transfers(address_hash) |
|
|
|
|
|> Repo.all() |
|
|
|
|
|
|
|
|
|
from_address_query = |
|
|
|
|
base_query |
|
|
|
|
|> where([t], t.from_address_hash == ^address_hash) |
|
|
|
|
|
|
|
|
|
to_address_query = |
|
|
|
|
base_query |
|
|
|
|
|> where([t], t.to_address_hash == ^address_hash) |
|
|
|
|
|
|
|
|
|
created_contract_query = |
|
|
|
|
base_query |
|
|
|
|
|> where([t], t.created_contract_address_hash == ^address_hash) |
|
|
|
|
|
|
|
|
|
queries = |
|
|
|
|
[token_transfers_query] ++ |
|
|
|
|
case direction do |
|
|
|
|
:from -> [from_address_query] |
|
|
|
|
:to -> [to_address_query, created_contract_query] |
|
|
|
|
_ -> [from_address_query, to_address_query, created_contract_query] |
|
|
|
|
if Application.get_env(:block_scout_web, BlockScoutWeb.Chain)[:has_emission_funds] do |
|
|
|
|
address_hash |
|
|
|
|
|> Reward.fetch_emission_rewards_tuples(paging_options) |
|
|
|
|
|> Enum.concat(transactions_list) |
|
|
|
|
|> Enum.sort_by(fn item -> |
|
|
|
|
case item do |
|
|
|
|
{%Reward{} = emission_reward, _} -> |
|
|
|
|
{-emission_reward.block.number, 1} |
|
|
|
|
|
|
|
|
|
item -> |
|
|
|
|
{-item.block_number, -item.index} |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
rewards_list = |
|
|
|
|
if Application.get_env(:block_scout_web, BlockScoutWeb.Chain)[:has_emission_funds] do |
|
|
|
|
Reward.fetch_emission_rewards_tuples(address_hash, paging_options) |
|
|
|
|
else |
|
|
|
|
[] |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
queries |
|
|
|
|
|> Stream.flat_map(&Repo.all/1) |
|
|
|
|
|> Stream.uniq_by(& &1.hash) |
|
|
|
|
|> Stream.concat(rewards_list) |
|
|
|
|
|> Enum.sort_by(fn item -> |
|
|
|
|
case item do |
|
|
|
|
{%Reward{} = emission_reward, _} -> |
|
|
|
|
{-emission_reward.block.number, 1} |
|
|
|
|
|
|
|
|
|
item -> |
|
|
|
|
{-item.block_number, -item.index} |
|
|
|
|
end |
|
|
|
|
end) |
|
|
|
|
|> Enum.take(paging_options.page_size) |
|
|
|
|
end) |
|
|
|
|
|> Enum.take(paging_options.page_size) |
|
|
|
|
else |
|
|
|
|
transactions_list |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
@spec address_to_logs(Address.t(), Keyword.t()) :: [ |
|
|
|
@ -703,25 +674,32 @@ defmodule Explorer.Chain do |
|
|
|
|
iex> Explorer.Chain.hash_to_address(hash) |
|
|
|
|
{:error, :not_found} |
|
|
|
|
|
|
|
|
|
Optionally accepts: |
|
|
|
|
- a list of bindings to preload, just like `Ecto.Query.preload/3` |
|
|
|
|
- a boolean to also fetch the `has_decompiled_code?` virtual field or not |
|
|
|
|
|
|
|
|
|
""" |
|
|
|
|
@spec hash_to_address(Hash.Address.t()) :: {:ok, Address.t()} | {:error, :not_found} |
|
|
|
|
def hash_to_address(%Hash{byte_count: unquote(Hash.Address.byte_count())} = hash) do |
|
|
|
|
query = |
|
|
|
|
from( |
|
|
|
|
address in Address, |
|
|
|
|
preload: [ |
|
|
|
|
@spec hash_to_address(Hash.Address.t(), [Macro.t()], boolean()) :: {:ok, Address.t()} | {:error, :not_found} |
|
|
|
|
def hash_to_address( |
|
|
|
|
%Hash{byte_count: unquote(Hash.Address.byte_count())} = hash, |
|
|
|
|
preloads \\ [ |
|
|
|
|
:contracts_creation_internal_transaction, |
|
|
|
|
:names, |
|
|
|
|
:smart_contract, |
|
|
|
|
:token, |
|
|
|
|
:contracts_creation_transaction |
|
|
|
|
], |
|
|
|
|
query_decompiled_code_flag \\ true |
|
|
|
|
) do |
|
|
|
|
query = |
|
|
|
|
from( |
|
|
|
|
address in Address, |
|
|
|
|
preload: ^preloads, |
|
|
|
|
where: address.hash == ^hash |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
query_with_decompiled_flag = with_decompiled_code_flag(query, hash) |
|
|
|
|
|
|
|
|
|
query_with_decompiled_flag |
|
|
|
|
query |
|
|
|
|
|> with_decompiled_code_flag(hash, query_decompiled_code_flag) |
|
|
|
|
|> Repo.one() |
|
|
|
|
|> case do |
|
|
|
|
nil -> {:error, :not_found} |
|
|
|
@ -1987,7 +1965,6 @@ defmodule Explorer.Chain do |
|
|
|
|
|> page_pending_transaction(paging_options) |
|
|
|
|
|> limit(^paging_options.page_size) |
|
|
|
|
|> pending_transactions_query() |
|
|
|
|
|> where([transaction], is_nil(transaction.error) or transaction.error != "dropped/replaced") |
|
|
|
|
|> order_by([transaction], desc: transaction.inserted_at, desc: transaction.hash) |
|
|
|
|
|> join_associations(necessity_by_association) |
|
|
|
|
|> preload([{:token_transfers, [:token, :from_address, :to_address]}]) |
|
|
|
@ -1996,7 +1973,7 @@ defmodule Explorer.Chain do |
|
|
|
|
|
|
|
|
|
defp pending_transactions_query(query) do |
|
|
|
|
from(transaction in query, |
|
|
|
|
where: is_nil(transaction.block_hash) |
|
|
|
|
where: is_nil(transaction.block_hash) and (is_nil(transaction.error) or transaction.error != "dropped/replaced") |
|
|
|
|
) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
@ -3161,7 +3138,11 @@ defmodule Explorer.Chain do |
|
|
|
|
|
|
|
|
|
defp staking_pool_filter(query, _), do: query |
|
|
|
|
|
|
|
|
|
defp with_decompiled_code_flag(query, hash) do |
|
|
|
|
defp with_decompiled_code_flag(query, hash, use_option \\ true) |
|
|
|
|
|
|
|
|
|
defp with_decompiled_code_flag(query, _hash, false), do: query |
|
|
|
|
|
|
|
|
|
defp with_decompiled_code_flag(query, hash, true) do |
|
|
|
|
has_decompiled_code_query = |
|
|
|
|
from(decompiled_contract in DecompiledSmartContract, |
|
|
|
|
where: decompiled_contract.address_hash == ^hash, |
|
|
|
|