Merge pull request #2770 from poanetwork/ab-do-not-refetch-token-instances-without-uris

do not re-fetch token instances without uris
pull/2777/head
Ayrat Badykov 5 years ago committed by GitHub
commit 93e8757b6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 7
      apps/explorer/lib/explorer/chain/token/instance.ex
  3. 12
      apps/explorer/lib/explorer/token/instance_metadata_retriever.ex
  4. 11
      apps/explorer/priv/repo/migrations/20191010075740_add_error_to_token_instances.exs
  5. 36
      apps/explorer/test/explorer/chain_test.exs
  6. 3
      apps/explorer/test/support/factory.ex
  7. 14
      apps/indexer/lib/indexer/fetcher/token_instance.ex

@ -16,6 +16,7 @@
- [#2762](https://github.com/poanetwork/blockscout/pull/2762) - on-fly fetching of token instances
### Fixes
- [#2770](https://github.com/poanetwork/blockscout/pull/2770) - do not re-fetch token instances without uris
- [#2767](https://github.com/poanetwork/blockscout/pull/2767) - fix websocket subscriptions with token instances
- [#2765](https://github.com/poanetwork/blockscout/pull/2765) - fixed width issue for cards in mobile view for Transaction Details page
- [#2753](https://github.com/poanetwork/blockscout/pull/2753) - fix nft token instance images

@ -12,18 +12,21 @@ defmodule Explorer.Chain.Token.Instance do
* `token_id` - ID of the token
* `token_contract_address_hash` - Address hash foreign key
* `metadata` - Token instance metadata
* `error` - error fetching token instance
"""
@type t :: %Instance{
token_id: non_neg_integer(),
token_contract_address_hash: Hash.Address.t(),
metadata: Map.t()
metadata: Map.t(),
error: String.t()
}
@primary_key false
schema "token_instances" do
field(:token_id, :decimal, primary_key: true)
field(:metadata, :map)
field(:error, :string)
belongs_to(
:token,
@ -39,7 +42,7 @@ defmodule Explorer.Chain.Token.Instance do
def changeset(%Instance{} = instance, params \\ %{}) do
instance
|> cast(params, [:token_id, :metadata, :token_contract_address_hash])
|> cast(params, [:token_id, :metadata, :token_contract_address_hash, :error])
|> validate_required([:token_id, :token_contract_address_hash])
|> foreign_key_constraint(:token_contract_address_hash)
end

@ -29,6 +29,8 @@ defmodule Explorer.Token.InstanceMetadataRetriever do
@cryptokitties_address_hash "0x06012c8cf97bead5deae237070f9587f8e7a266d"
@no_uri_error "no uri"
def fetch_metadata(unquote(@cryptokitties_address_hash), token_id) do
%{"tokenURI" => {:ok, ["https://api.cryptokitties.co/kitties/#{token_id}"]}}
|> fetch_json()
@ -47,13 +49,19 @@ defmodule Explorer.Token.InstanceMetadataRetriever do
end
defp fetch_json(%{"tokenURI" => {:ok, [""]}}) do
{:error, :no_uri}
{:ok, %{error: @no_uri_error}}
end
defp fetch_json(%{"tokenURI" => {:error, "(-32015) VM execution error."}}) do
{:ok, %{error: @no_uri_error}}
end
defp fetch_json(%{"tokenURI" => {:ok, [token_uri]}}) do
case HTTPoison.get(token_uri) do
{:ok, %Response{body: body, status_code: 200}} ->
Jason.decode(body)
{:ok, json} = Jason.decode(body)
{:ok, %{metadata: json}}
{:ok, %Response{body: body}} ->
{:error, body}

@ -0,0 +1,11 @@
defmodule Explorer.Repo.Migrations.AddErrorToTokenInstances do
use Ecto.Migration
def change do
alter table(:token_instances) do
add(:error, :string)
end
create(index(:token_instances, [:error]))
end
end

@ -173,6 +173,42 @@ defmodule Explorer.ChainTest do
valid?: false
}} = Chain.upsert_token_instance(params)
end
test "inserts just an error without metadata" do
token = insert(:token)
error = "no uri"
params = %{
token_id: 1,
token_contract_address_hash: token.contract_address_hash,
error: error
}
{:ok, result} = Chain.upsert_token_instance(params)
assert result.error == error
end
test "nillifies error" do
token = insert(:token)
insert(:token_instance,
token_id: 1,
token_contract_address_hash: token.contract_address_hash,
error: "no uri"
)
params = %{
token_id: 1,
token_contract_address_hash: token.contract_address_hash,
metadata: %{uri: "http://example1.com"}
}
{:ok, result} = Chain.upsert_token_instance(params)
assert is_nil(result.error)
assert result.metadata == params.metadata
end
end
describe "address_to_logs/2" do

@ -547,7 +547,8 @@ defmodule Explorer.Factory do
%Instance{
token_contract_address_hash: build(:address),
token_id: 5,
metadata: %{key: "value"}
metadata: %{key: "value"},
error: nil
}
end

@ -50,11 +50,21 @@ defmodule Indexer.Fetcher.TokenInstance do
@impl BufferedTask
def run([%{contract_address_hash: token_contract_address_hash, token_id: token_id}], _json_rpc_named_arguments) do
case InstanceMetadataRetriever.fetch_metadata(to_string(token_contract_address_hash), Decimal.to_integer(token_id)) do
{:ok, metadata} ->
{:ok, %{metadata: metadata}} ->
params = %{
token_id: token_id,
token_contract_address_hash: token_contract_address_hash,
metadata: metadata
metadata: metadata,
error: nil
}
{:ok, _result} = Chain.upsert_token_instance(params)
{:ok, %{error: error}} ->
params = %{
token_id: token_id,
token_contract_address_hash: token_contract_address_hash,
error: error
}
{:ok, _result} = Chain.upsert_token_instance(params)

Loading…
Cancel
Save