zcash-explorer/lib/zcash_explorer_web/controllers/search_controller.ex

115 lines
2.7 KiB
Elixir

defmodule ZcashExplorerWeb.SearchController do
use ZcashExplorerWeb, :controller
def search(conn, %{"qs" => qs}) do
qs = String.trim(qs)
# query zcashd to find out if the user has entered a valid resource
# Valid resources:
# Block - height, hash
# Transaction - hash
# Address - Transparent , Shielded
# If zcashd responds that a resource is valid, we redirect the user
# to the appropriate resource view or redirect them to an error view.
tasks = [
Task.async(fn -> Zcashex.getblock(qs, 0) end),
Task.async(fn -> Zcashex.getrawtransaction(qs, 0) end),
Task.async(fn -> Zcashex.validateaddress(qs) end),
Task.async(fn -> Zcashex.z_validateaddress(qs) end)
]
run = Task.yield_many(tasks, 5000)
results =
Enum.map(run, fn {task, res} ->
# Shut down the tasks that did not reply nor exit
res || Task.shutdown(task, :brutal_kill)
end)
# order in which the tasks are above defined matters
{:ok, block_resp} = Enum.at(results, 0)
{:ok, tx_resp} = Enum.at(results, 1)
{:ok, tadd_resp} = Enum.at(results, 2)
{:ok, zadd_resp} = Enum.at(results, 3)
IO.inspect(block_resp)
IO.inspect(tx_resp)
IO.inspect(tadd_resp)
IO.inspect(zadd_resp)
cond do
is_valid_block?(block_resp) ->
redirect(conn, to: "/blocks/#{qs}")
is_valid_tx?(tx_resp) ->
redirect(conn, to: "/transactions/#{qs}")
is_valid_taddr?(tadd_resp) ->
redirect(conn, to: "/address/#{qs}")
is_valid_zaddr?(zadd_resp) ->
redirect(conn, to: "/address/#{qs}")
is_valid_unified_address?(zadd_resp) ->
redirect(conn, to: "/ua/#{qs}")
true ->
conn
|> put_status(:not_found)
|> put_view(ZcashExplorerWeb.ErrorView)
|> render(:invalid_input)
end
end
def is_valid_block?({:ok, {:error, "Block not found"}}) do
false
end
def is_valid_block?({:ok, _hex}) do
true
end
def is_valid_block?({:error, _reason}) do
false
end
def is_valid_tx?({:ok, _hex}) do
true
end
def is_valid_tx?({:error, _reason}) do
false
end
def is_valid_taddr?({:ok, %{"isvalid" => true}}) do
true
end
def is_valid_taddr?({:ok, %{"isvalid" => false}}) do
false
end
def is_valid_zaddr?({:ok, %{"isvalid" => true, "type" => "sprout"}}) do
true
end
def is_valid_zaddr?({:ok, %{"isvalid" => true, "type" => "sapling"}}) do
true
end
def is_valid_zaddr?({:ok, %{"isvalid" => true, "type" => "unified"}}) do
false
end
def is_valid_zaddr?({:ok, %{"isvalid" => false}}) do
false
end
def is_valid_unified_address?({:ok, %{"isvalid" => true, "type" => "unified"}}) do
true
end
def is_valid_unified_address?(resp) do
false
end
end