fix: Don't put error to NFT metadata (#9940)

* fix: Don't put error to NFT metadata

* Remove unused Explorer.Helper.maybe_decode/1
docker-compose-changing-fe-port
nikitosing 7 months ago committed by GitHub
parent 8312379fbf
commit f1392fc6ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 25
      apps/explorer/lib/explorer/helper.ex
  2. 4
      apps/indexer/lib/indexer/fetcher/token_instance/metadata_retriever.ex
  3. 69
      apps/indexer/test/indexer/fetcher/token_instance/helper_test.exs

@ -90,33 +90,24 @@ defmodule Explorer.Helper do
Decode json
"""
@spec decode_json(any()) :: map() | list() | nil
def decode_json(nil), do: nil
def decode_json(data, nft? \\ false)
def decode_json(data) do
def decode_json(nil, _), do: nil
def decode_json(data, nft?) do
if String.valid?(data) do
safe_decode_json(data)
safe_decode_json(data, nft?)
else
data
|> :unicode.characters_to_binary(:latin1)
|> safe_decode_json()
|> safe_decode_json(nft?)
end
end
defp safe_decode_json(data) do
defp safe_decode_json(data, nft?) do
case Jason.decode(data) do
{:ok, decoded} -> decoded
_ -> %{error: data}
end
end
@doc """
Tries to decode binary to json, return either decoded object, or initial binary
"""
@spec maybe_decode(binary) :: any
def maybe_decode(data) do
case safe_decode_json(data) do
%{error: _} -> data
decoded -> decoded
_ -> if nft?, do: {:error, data}, else: %{error: data}
end
end

@ -179,7 +179,7 @@ defmodule Indexer.Fetcher.TokenInstance.MetadataRetriever do
end
defp fetch_json_from_uri({:ok, [json]}, _ipfs?, _token_id, hex_token_id, _from_base_uri?) do
json = ExplorerHelper.decode_json(json)
json = ExplorerHelper.decode_json(json, true)
check_type(json, hex_token_id)
rescue
@ -289,7 +289,7 @@ defmodule Indexer.Fetcher.TokenInstance.MetadataRetriever do
check_type(json, nil)
else
json = ExplorerHelper.decode_json(body)
json = ExplorerHelper.decode_json(body, true)
check_type(json, hex_token_id)
end

@ -3,6 +3,7 @@ defmodule Indexer.Fetcher.TokenInstance.HelperTest do
use Explorer.DataCase
alias Explorer.Chain.Token.Instance
alias Explorer.Repo
alias EthereumJSONRPC.Encoder
alias Indexer.Fetcher.TokenInstance.Helper
alias Plug.Conn
@ -15,6 +16,7 @@ defmodule Indexer.Fetcher.TokenInstance.HelperTest do
setup do
bypass = Bypass.open()
on_exit(fn -> Bypass.down(bypass) end)
{:ok, bypass: bypass}
end
@ -311,5 +313,72 @@ defmodule Indexer.Fetcher.TokenInstance.HelperTest do
}}
] = Helper.batch_fetch_instances([{"0x5caebd3b32e210e85ce3e9d51638b9c445481567", 300_067_000_000_000_000}])
end
test "check that decoding error is stored in error, not in metadata", %{bypass: bypass} do
json = """
invalid json
{
"name": "Sérgio Mendonça {id}"
}
"""
encoded_url =
"0x" <>
(ABI.TypeEncoder.encode(["http://localhost:#{bypass.port}/api/card/{id}"], %ABI.FunctionSelector{
function: nil,
types: [
:string
]
})
|> Base.encode16(case: :lower))
EthereumJSONRPC.Mox
|> expect(:json_rpc, fn [
%{
id: 0,
jsonrpc: "2.0",
method: "eth_call",
params: [
%{
data:
"0x0e89341c0000000000000000000000000000000000000000000000000000000000000309",
to: "0x5caebd3b32e210e85ce3e9d51638b9c445481567"
},
"latest"
]
}
],
_options ->
{:ok,
[
%{
id: 0,
jsonrpc: "2.0",
result: encoded_url
}
]}
end)
Bypass.expect(
bypass,
"GET",
"/api/card/0000000000000000000000000000000000000000000000000000000000000309",
fn conn ->
Conn.resp(conn, 200, json)
end
)
insert(:token,
contract_address: build(:address, hash: "0x5caebd3b32e210e85ce3e9d51638b9c445481567"),
type: "ERC-1155"
)
Helper.batch_fetch_instances([{"0x5caebd3b32e210e85ce3e9d51638b9c445481567", 777}])
%Instance{
metadata: nil,
error: "wrong metadata type"
} = 777 |> Instance.token_instance_query("0x5caebd3b32e210e85ce3e9d51638b9c445481567") |> Repo.one()
end
end
end

Loading…
Cancel
Save