do not allow update code

pull/1596/head
Ayrat Badykov 6 years ago
parent 26fb7ca944
commit e76ab75d5b
No known key found for this signature in database
GPG Key ID: B44668E265E9396F
  1. 24
      apps/block_scout_web/lib/block_scout_web/controllers/api/v1/decompiled_smart_contract_controller.ex
  2. 24
      apps/block_scout_web/test/block_scout_web/controllers/api/v1/decompiled_smart_contract_controller_test.exs
  3. 14
      apps/explorer/lib/explorer/chain.ex

@ -7,7 +7,8 @@ defmodule BlockScoutWeb.API.V1.DecompiledSmartContractController do
def create(conn, params) do def create(conn, params) do
if auth_token(conn) == actual_token() do if auth_token(conn) == actual_token() do
with {:ok, hash} <- validate_address_hash(params["address_hash"]), with {:ok, hash} <- validate_address_hash(params["address_hash"]),
:ok <- smart_contract_exists?(hash) do :ok <- smart_contract_exists?(hash),
:ok <- decompiled_contract_exists?(params["address_hash"], params["decompiler_version"]) do
case Chain.create_decompiled_smart_contract(params) do case Chain.create_decompiled_smart_contract(params) do
{:ok, decompiled_smart_contract} -> {:ok, decompiled_smart_contract} ->
send_resp(conn, :created, Jason.encode!(decompiled_smart_contract)) send_resp(conn, :created, Jason.encode!(decompiled_smart_contract))
@ -22,8 +23,18 @@ defmodule BlockScoutWeb.API.V1.DecompiledSmartContractController do
send_resp(conn, :unprocessable_entity, encode(errors)) send_resp(conn, :unprocessable_entity, encode(errors))
end end
else else
:invalid_address -> send_resp(conn, :unprocessable_entity, encode(%{error: "address_hash is invalid"})) :invalid_address ->
:not_found -> send_resp(conn, :unprocessable_entity, encode(%{error: "address is not found"})) send_resp(conn, :unprocessable_entity, encode(%{error: "address_hash is invalid"}))
:not_found ->
send_resp(conn, :unprocessable_entity, encode(%{error: "address is not found"}))
:contract_exists ->
send_resp(
conn,
:unprocessable_entity,
encode(%{error: "decompiled code already exists for the decompiler version"})
)
end end
else else
send_resp(conn, :forbidden, "") send_resp(conn, :forbidden, "")
@ -44,6 +55,13 @@ defmodule BlockScoutWeb.API.V1.DecompiledSmartContractController do
end end
end end
defp decompiled_contract_exists?(address_hash, decompiler_version) do
case Chain.decompiled_code(address_hash, decompiler_version) do
{:ok, _} -> :contract_exists
_ -> :ok
end
end
defp auth_token(conn) do defp auth_token(conn) do
case get_req_header(conn, "auth_token") do case get_req_header(conn, "auth_token") do
[token] -> token [token] -> token

@ -40,6 +40,30 @@ defmodule BlockScoutWeb.API.V1.DecompiledControllerTest do
assert request.resp_body == "{\"decompiled_source_code\":\"can't be blank\"}" assert request.resp_body == "{\"decompiled_source_code\":\"can't be blank\"}"
end end
test "can not update code for the same decompiler version", %{conn: conn} do
address_hash = to_string(insert(:address, hash: "0x0000000000000000000000000000000000000001").hash)
decompiler_version = "test_decompiler"
decompiled_source_code = "hello world"
insert(:decompiled_smart_contract,
address_hash: address_hash,
decompiler_version: decompiler_version,
decompiled_source_code: decompiled_source_code
)
params = %{
"address_hash" => address_hash,
"decompiler_version" => decompiler_version,
"decompiled_source_code" => decompiled_source_code
}
request = post(conn, api_v1_decompiled_smart_contract_path(conn, :create), params)
assert request.status == 422
assert request.resp_body == "{\"error\":\"decompiled code already exists for the decompiler version\"}"
end
test "creates decompiled smart contract", %{conn: conn} do test "creates decompiled smart contract", %{conn: conn} do
address_hash = to_string(insert(:address, hash: "0x0000000000000000000000000000000000000001").hash) address_hash = to_string(insert(:address, hash: "0x0000000000000000000000000000000000000001").hash)
decompiler_version = "test_decompiler" decompiler_version = "test_decompiler"

@ -668,6 +668,20 @@ defmodule Explorer.Chain do
end end
end end
def decompiled_code(address_hash, version) do
query =
from(contract in DecompiledSmartContract,
where: contract.address_hash == ^address_hash and contract.decompiler_version == ^version
)
query
|> Repo.one()
|> case do
nil -> {:error, :not_found}
contract -> {:ok, contract.decompiled_source_code}
end
end
@spec token_contract_address_from_token_name(String.t()) :: {:ok, Hash.Address.t()} | {:error, :not_found} @spec token_contract_address_from_token_name(String.t()) :: {:ok, Hash.Address.t()} | {:error, :not_found}
def token_contract_address_from_token_name(name) when is_binary(name) do def token_contract_address_from_token_name(name) when is_binary(name) do
query = query =

Loading…
Cancel
Save