From 43d0dde83f946bec8ab137e297707106104a114a Mon Sep 17 00:00:00 2001 From: obasilakis <33531476+obasilakis@users.noreply.github.com> Date: Thu, 9 Dec 2021 12:03:19 +0100 Subject: [PATCH 1/3] Obasilakis/make sure pending celo is indexed (#503) * Rename pending celo to celo unlocked * Make sure celo unlocked is inserted into table * Add method to insert unlocked celo to db * Remove IO.inspect * Insert unlocked CELO to db when receiving GoldLocked event * Credo * Fix tests * Format --- .../controllers/api/rpc/stats_controller.ex | 6 +- .../views/api/rpc/stats_view.ex | 4 +- .../lib/explorer/celo/account_reader.ex | 8 +- .../explorer/lib/explorer/celo/event_types.ex | 10 + apps/explorer/lib/explorer/chain.ex | 36 +- apps/explorer/lib/explorer/chain/address.ex | 4 +- .../{pending_celo.ex => celo_unlocked.ex} | 30 +- .../{pending_celo.ex => celo_unlocked.ex} | 36 +- .../chain/import/stage/address_referencing.ex | 2 +- apps/explorer/lib/mix/tasks/core_contracts.ex | 1 - ...0_rename_pending_celo_to_celo_unlocked.exs | 7 + .../20211206152854_update_celo_unlocked.exs | 12 + apps/explorer/test/explorer/chain_test.exs | 41 +- apps/explorer/test/support/factory.ex | 9 +- apps/indexer/lib/indexer/block/fetcher.ex | 22 +- .../{pending_celo.ex => celo_unlocked.ex} | 12 +- apps/indexer/lib/indexer/supervisor.ex | 4 +- .../lib/indexer/transform/celo_accounts.ex | 20 +- .../test/indexer/block/fetcher_test.exs | 350 ++++++++++++------ .../indexer/fetcher/celo_unlocked_test.exs | 73 ++++ .../indexer/fetcher/pending_celo_test.exs | 85 ----- .../indexer/fetcher/pending_celo_case.ex | 6 +- 22 files changed, 477 insertions(+), 301 deletions(-) rename apps/explorer/lib/explorer/chain/{pending_celo.ex => celo_unlocked.ex} (52%) rename apps/explorer/lib/explorer/chain/import/runner/{pending_celo.ex => celo_unlocked.ex} (59%) create mode 100644 apps/explorer/priv/repo/migrations/20211206151850_rename_pending_celo_to_celo_unlocked.exs create mode 100644 apps/explorer/priv/repo/migrations/20211206152854_update_celo_unlocked.exs rename apps/indexer/lib/indexer/fetcher/{pending_celo.ex => celo_unlocked.ex} (89%) create mode 100644 apps/indexer/test/indexer/fetcher/celo_unlocked_test.exs delete mode 100644 apps/indexer/test/indexer/fetcher/pending_celo_test.exs diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/stats_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/stats_controller.ex index 79920a008492..64849e1f280e 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/stats_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/stats_controller.ex @@ -71,10 +71,10 @@ defmodule BlockScoutWeb.API.RPC.StatsController do render(conn, "totaltransactions.json", count: transaction_estimated_count) end - def pendingcelo(conn, _params) do - sum_pending_celo = Chain.fetch_sum_pending_celo() + def celounlocked(conn, _params) do + sum_celo_unlocked = Chain.fetch_sum_celo_unlocked() - render(conn, "pendingcelo.json", count: sum_pending_celo) + render(conn, "celounlocked.json", count: sum_celo_unlocked) end defp fetch_contractaddress(params) do diff --git a/apps/block_scout_web/lib/block_scout_web/views/api/rpc/stats_view.ex b/apps/block_scout_web/lib/block_scout_web/views/api/rpc/stats_view.ex index 07abc7c1f23e..9c11a530b208 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/api/rpc/stats_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/api/rpc/stats_view.ex @@ -27,8 +27,8 @@ defmodule BlockScoutWeb.API.RPC.StatsView do RPCView.render("show.json", data: count) end - def render("pendingcelo.json", %{count: sum_pending_celo}) do - RPCView.render("show.json", data: sum_pending_celo) + def render("celounlocked.json", %{count: sum_celo_unlocked}) do + RPCView.render("show.json", data: sum_celo_unlocked) end def render("totalfees.json", %{total_fees: total_fees}) do diff --git a/apps/explorer/lib/explorer/celo/account_reader.ex b/apps/explorer/lib/explorer/celo/account_reader.ex index 099bba1199f9..d853cfdb519c 100644 --- a/apps/explorer/lib/explorer/celo/account_reader.ex +++ b/apps/explorer/lib/explorer/celo/account_reader.ex @@ -261,13 +261,17 @@ defmodule Explorer.Celo.AccountReader do def withdrawal_data(address) do data = fetch_withdrawal_data(address) + {:ok, cast_address} = Explorer.Chain.Hash.Address.cast(address) + case data["getPendingWithdrawals"] do {:ok, [values, timestamps]} -> {:ok, %{ - address: address, + address: cast_address, pending: - Enum.map(Enum.zip(values, timestamps), fn {v, t} -> %{address: address, amount: v, timestamp: t} end) + Enum.map(Enum.zip(values, timestamps), fn {v, t} -> + %{address: cast_address, amount: v, timestamp: DateTime.from_unix!(t)} + end) }} _ -> diff --git a/apps/explorer/lib/explorer/celo/event_types.ex b/apps/explorer/lib/explorer/celo/event_types.ex index 5e3a3eac8703..5b7b9439d47b 100644 --- a/apps/explorer/lib/explorer/celo/event_types.ex +++ b/apps/explorer/lib/explorer/celo/event_types.ex @@ -124,6 +124,16 @@ defmodule Explorer.Celo.Events do @gold_locked ] + def gold_unlocked, + do: [ + @gold_unlocked + ] + + def gold_withdrawn, + do: [ + @gold_withdrawn + ] + def signer_events, do: [ @validator_signer_authorized, diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 306119312b13..9787ebaec445 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -49,6 +49,7 @@ defmodule Explorer.Chain do CeloParams, CeloPendingEpochOperation, CeloSigners, + CeloUnlocked, CeloValidator, CeloValidatorGroup, CeloValidatorHistory, @@ -62,7 +63,6 @@ defmodule Explorer.Chain do InternalTransaction, Log, PendingBlockOperation, - PendingCelo, ProxyContract, SmartContract, SmartContractAdditionalSource, @@ -7708,14 +7708,13 @@ defmodule Explorer.Chain do end @doc """ - Returns the total amount of CELO that is in the unlocking period (pending). + Returns the total amount of CELO that is unlocked and can't or hasn't yet been withdrawn. Details at: https://docs.celo.org/celo-codebase/protocol/proof-of-stake/locked-gold#unlocking-period """ - @spec fetch_sum_pending_celo() :: non_neg_integer() - def fetch_sum_pending_celo do + @spec fetch_sum_celo_unlocked() :: non_neg_integer() + def fetch_sum_celo_unlocked do query = - from(w in PendingCelo, - where: w.timestamp >= fragment("NOW()"), + from(w in CeloUnlocked, select: sum(w.amount) ) @@ -7728,18 +7727,33 @@ defmodule Explorer.Chain do end @doc """ - Deletes pending CELO when passed the address and the amount + Deletes unlocked CELO when passed the address and the amount """ - @spec delete_pending_celo(Hash.t(), non_neg_integer()) :: {integer(), nil | [term()]} - def delete_pending_celo(address, amount) do + @spec delete_celo_unlocked(Hash.t(), non_neg_integer()) :: {integer(), nil | [term()]} + def delete_celo_unlocked(address, amount) do query = - from(pending_celo in PendingCelo, - where: pending_celo.account_address == ^address and pending_celo.amount == ^amount + from(celo_unlocked in CeloUnlocked, + where: celo_unlocked.account_address == ^address and celo_unlocked.amount == ^amount ) Repo.delete_all(query) end + @doc """ + Insert unlocked CELO when passed the address, the amount and when the amount will be available as a unix timestamp + """ + @spec insert_celo_unlocked(Hash.t(), non_neg_integer(), non_neg_integer()) :: {integer(), nil | [term()]} + def insert_celo_unlocked(address, amount, available) do + changeset = + CeloUnlocked.changeset(%CeloUnlocked{}, %{ + account_address: address, + amount: amount, + available: DateTime.from_unix!(available, :second) + }) + + Repo.insert(changeset) + end + @spec get_token_icon_url_by(String.t(), String.t()) :: String.t() | nil def get_token_icon_url_by(chain_id, address_hash) do chain_name = diff --git a/apps/explorer/lib/explorer/chain/address.ex b/apps/explorer/lib/explorer/chain/address.ex index 42bb441f8d00..49d8ac419a2f 100644 --- a/apps/explorer/lib/explorer/chain/address.ex +++ b/apps/explorer/lib/explorer/chain/address.ex @@ -13,6 +13,7 @@ defmodule Explorer.Chain.Address do CeloAccount, CeloClaims, CeloSigners, + CeloUnlocked, CeloValidator, CeloValidatorGroup, CeloVoters, @@ -20,7 +21,6 @@ defmodule Explorer.Chain.Address do DecompiledSmartContract, Hash, InternalTransaction, - PendingCelo, ProxyContract, SmartContract, SmartContractAdditionalSource, @@ -128,7 +128,7 @@ defmodule Explorer.Chain.Address do has_many(:celo_voters, CeloVoters, foreign_key: :group_address_hash) has_many(:celo_voted, CeloVoters, foreign_key: :voter_address_hash) has_many(:celo_claims, CeloClaims, foreign_key: :address) - has_many(:pending_celo, PendingCelo, foreign_key: :account_address) + has_many(:celo_unlocked, CeloUnlocked, foreign_key: :account_address) has_one(:implementation_contract, ProxyContract, foreign_key: :proxy_address) diff --git a/apps/explorer/lib/explorer/chain/pending_celo.ex b/apps/explorer/lib/explorer/chain/celo_unlocked.ex similarity index 52% rename from apps/explorer/lib/explorer/chain/pending_celo.ex rename to apps/explorer/lib/explorer/chain/celo_unlocked.ex index 598938928b9b..4fb8833c7fbc 100644 --- a/apps/explorer/lib/explorer/chain/pending_celo.ex +++ b/apps/explorer/lib/explorer/chain/celo_unlocked.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.PendingCelo do +defmodule Explorer.Chain.CeloUnlocked do @moduledoc """ Table for storing unlocked CELO that has not been withdrawn yet. """ @@ -15,24 +15,22 @@ defmodule Explorer.Chain.PendingCelo do """ @type t :: %__MODULE__{ - address: Hash.Address.t(), - timestamp: DateTime.t(), - amount: Wei.t(), - index: non_neg_integer() + account_address: Hash.Address.t(), + available: DateTime.t(), + amount: Wei.t() } @attrs ~w( - account_address timestamp amount index + available amount )a @required_attrs ~w( - address + account_address )a @primary_key false - schema "pending_celo" do - field(:timestamp, :utc_datetime_usec) - field(:index, :integer, primary_key: true) + schema "celo_unlocked" do + field(:available, :utc_datetime_usec) field(:amount, Wei) belongs_to( @@ -46,10 +44,14 @@ defmodule Explorer.Chain.PendingCelo do timestamps(null: false, type: :utc_datetime_usec) end - def changeset(%__MODULE__{} = pending_celo, attrs) do - pending_celo - |> cast(attrs, @attrs) + def changeset(%__MODULE__{} = celo_unlocked, %{address: a} = attrs) do + attrs = attrs |> Map.delete(:address) |> Map.put(:account_address, a) + changeset(celo_unlocked, attrs) + end + + def changeset(%__MODULE__{} = celo_unlocked, attrs) do + celo_unlocked + |> cast(attrs, @attrs ++ @required_attrs) |> validate_required(@required_attrs) - |> unique_constraint(:pending_celo_key, name: :pending_celo_account_address_index_index) end end diff --git a/apps/explorer/lib/explorer/chain/import/runner/pending_celo.ex b/apps/explorer/lib/explorer/chain/import/runner/celo_unlocked.ex similarity index 59% rename from apps/explorer/lib/explorer/chain/import/runner/pending_celo.ex rename to apps/explorer/lib/explorer/chain/import/runner/celo_unlocked.ex index 51c68076bdfd..9b8e1d531e77 100644 --- a/apps/explorer/lib/explorer/chain/import/runner/pending_celo.ex +++ b/apps/explorer/lib/explorer/chain/import/runner/celo_unlocked.ex @@ -1,4 +1,4 @@ -defmodule Explorer.Chain.Import.Runner.PendingCelo do +defmodule Explorer.Chain.Import.Runner.CeloUnlocked do @moduledoc """ Bulk imports pending Celo to the DB table. """ @@ -6,7 +6,7 @@ defmodule Explorer.Chain.Import.Runner.PendingCelo do require Ecto.Query alias Ecto.{Changeset, Multi, Repo} - alias Explorer.Chain.{Import, PendingCelo} + alias Explorer.Chain.{CeloUnlocked, Import} alias Explorer.Chain.Import.Runner.Util import Ecto.Query, only: [from: 2] @@ -16,13 +16,13 @@ defmodule Explorer.Chain.Import.Runner.PendingCelo do # milliseconds @timeout 60_000 - @type imported :: [PendingCelo.t()] + @type imported :: [CeloUnlocked.t()] @impl Import.Runner - def ecto_schema_module, do: PendingCelo + def ecto_schema_module, do: CeloUnlocked @impl Import.Runner - def option_key, do: :pending_celo + def option_key, do: :celo_unlocked @impl Import.Runner def imported_table_row do @@ -45,40 +45,22 @@ defmodule Explorer.Chain.Import.Runner.PendingCelo do @impl Import.Runner def timeout, do: @timeout - @spec insert(Repo.t(), [map()], Util.insert_options()) :: {:ok, [PendingCelo.t()]} | {:error, [Changeset.t()]} + @spec insert(Repo.t(), [map()], Util.insert_options()) :: {:ok, [CeloUnlocked.t()]} | {:error, [Changeset.t()]} defp insert(repo, changes_list, %{timeout: timeout, timestamps: timestamps} = options) when is_list(changes_list) do - on_conflict = Map.get_lazy(options, :on_conflict, &default_on_conflict/0) - # Enforce ShareLocks order (see docs: sharelocks.md) uniq_changes_list = changes_list - |> Enum.sort_by(&{&1.address, &1.index}) - |> Enum.uniq_by(&{&1.address, &1.index}) + |> Enum.sort_by(&{&1.account_address}) + |> Enum.uniq_by(&{&1.account_address}) {:ok, _} = Import.insert_changes_list( repo, uniq_changes_list, - conflict_target: [:address, :index], - on_conflict: on_conflict, - for: PendingCelo, + for: CeloUnlocked, returning: true, timeout: timeout, timestamps: timestamps ) end - - defp default_on_conflict do - from( - account in PendingCelo, - update: [ - set: [ - timestamp: fragment("EXCLUDED.timestamp"), - amount: fragment("EXCLUDED.amount"), - inserted_at: fragment("LEAST(?, EXCLUDED.inserted_at)", account.inserted_at), - updated_at: fragment("GREATEST(?, EXCLUDED.updated_at)", account.updated_at) - ] - ] - ) - end end diff --git a/apps/explorer/lib/explorer/chain/import/stage/address_referencing.ex b/apps/explorer/lib/explorer/chain/import/stage/address_referencing.ex index 0447c959a1b2..5c6f826f915c 100644 --- a/apps/explorer/lib/explorer/chain/import/stage/address_referencing.ex +++ b/apps/explorer/lib/explorer/chain/import/stage/address_referencing.ex @@ -23,7 +23,7 @@ defmodule Explorer.Chain.Import.Stage.AddressReferencing do Runner.CeloValidatorStatus, Runner.CeloEpochRewards, Runner.CeloVoters, - Runner.PendingCelo, + Runner.CeloUnlocked, Runner.CeloWallets, Runner.ExchangeRate, Runner.StakingPools, diff --git a/apps/explorer/lib/mix/tasks/core_contracts.ex b/apps/explorer/lib/mix/tasks/core_contracts.ex index e4948c655709..44b0bc770e62 100644 --- a/apps/explorer/lib/mix/tasks/core_contracts.ex +++ b/apps/explorer/lib/mix/tasks/core_contracts.ex @@ -12,7 +12,6 @@ defmodule Mix.Tasks.CoreContracts do url |> full_cache_build() - |> IO.inspect() end def full_cache_build(url) do diff --git a/apps/explorer/priv/repo/migrations/20211206151850_rename_pending_celo_to_celo_unlocked.exs b/apps/explorer/priv/repo/migrations/20211206151850_rename_pending_celo_to_celo_unlocked.exs new file mode 100644 index 000000000000..2479765ec08c --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20211206151850_rename_pending_celo_to_celo_unlocked.exs @@ -0,0 +1,7 @@ +defmodule Explorer.Repo.Migrations.RenamePendingCeloToCeloUnlocked do + use Ecto.Migration + + def change do + rename(table(:pending_celo), to: table(:celo_unlocked)) + end +end diff --git a/apps/explorer/priv/repo/migrations/20211206152854_update_celo_unlocked.exs b/apps/explorer/priv/repo/migrations/20211206152854_update_celo_unlocked.exs new file mode 100644 index 000000000000..92b12cc8dab6 --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20211206152854_update_celo_unlocked.exs @@ -0,0 +1,12 @@ +defmodule Explorer.Repo.Migrations.UpdateCeloUnlocked do + use Ecto.Migration + + def change do + drop(index(:celo_withdrawal, [:account_address, :index], unique: true)) + rename(table("celo_unlocked"), :timestamp, to: :available) + + alter table(:celo_unlocked) do + remove(:index) + end + end +end diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 2f980f9976bd..65e2e2cad402 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -15,7 +15,7 @@ defmodule Explorer.ChainTest do Address, Block, CeloPendingEpochOperation, - PendingCelo, + CeloUnlocked, Data, DecompiledSmartContract, Hash, @@ -5914,32 +5914,41 @@ defmodule Explorer.ChainTest do end end - describe "fetch_sum_pending_celo/0" do - test "fetches all CELO that is in the unlocking period" do - insert(:pending_celo, %{timestamp: Timex.shift(DateTime.utc_now(), days: -1), amount: 1}) - insert(:pending_celo, %{timestamp: Timex.shift(DateTime.utc_now(), days: 0), amount: 2}) - insert(:pending_celo, %{timestamp: Timex.shift(DateTime.utc_now(), days: 1), amount: 3}) + describe "fetch_sum_celo_unlocked/0" do + test "fetches all unlocked CELO" do + insert(:celo_unlocked, %{available: Timex.shift(DateTime.utc_now(), days: -1), amount: 1}) + insert(:celo_unlocked, %{available: Timex.shift(DateTime.utc_now(), days: 0), amount: 2}) + insert(:celo_unlocked, %{available: Timex.shift(DateTime.utc_now(), days: 1), amount: 3}) - assert %Wei{value: Decimal.new(5)} == Chain.fetch_sum_pending_celo() + assert %Wei{value: Decimal.new(6)} == Chain.fetch_sum_celo_unlocked() end test "fetches all pending CELO when there are no blocks" do - assert %Wei{value: Decimal.new(0)} == Chain.fetch_sum_pending_celo() + assert %Wei{value: Decimal.new(0)} == Chain.fetch_sum_celo_unlocked() end end - describe "delete_pending_celo/2" do - test "delete pending celo entries when passed amount and address" do - insert(:pending_celo, %{timestamp: Timex.shift(DateTime.utc_now(), days: -1), amount: 1}) + describe "delete_celo_unlocked/2" do + test "delete unlocked celo entries when passed amount and address" do + insert(:celo_unlocked, %{available: Timex.shift(DateTime.utc_now(), days: -1), amount: 1}) - %PendingCelo{account_address: account_address} = - insert(:pending_celo, %{timestamp: Timex.shift(DateTime.utc_now(), days: 0), amount: 2}) + %CeloUnlocked{account_address: account_address} = + insert(:celo_unlocked, %{available: Timex.shift(DateTime.utc_now(), days: 0), amount: 2}) - insert(:pending_celo, %{timestamp: Timex.shift(DateTime.utc_now(), days: 1), amount: 3}) + insert(:celo_unlocked, %{available: Timex.shift(DateTime.utc_now(), days: 1), amount: 3}) - Chain.delete_pending_celo(account_address, 2) + Chain.delete_celo_unlocked(account_address, 2) - assert Repo.aggregate(PendingCelo, :count, :index) == 2 + assert Repo.aggregate(CeloUnlocked, :count) == 2 + end + end + + describe "insert_celo_unlocked/2" do + test "inserts unlocked celo entries when passed amount, address and available" do + account_address = insert(:address) + Chain.insert_celo_unlocked(account_address.hash, 2, 1_639_103_736) + + assert Repo.aggregate(CeloUnlocked, :count) == 1 end end diff --git a/apps/explorer/test/support/factory.ex b/apps/explorer/test/support/factory.ex index b37173779b93..2a54b2338bd3 100644 --- a/apps/explorer/test/support/factory.ex +++ b/apps/explorer/test/support/factory.ex @@ -27,7 +27,7 @@ defmodule Explorer.Factory do InternalTransaction, Log, PendingBlockOperation, - PendingCelo, + CeloUnlocked, SmartContract, Token, TokenTransfer, @@ -715,12 +715,11 @@ defmodule Explorer.Factory do } end - def pending_celo_factory do - %PendingCelo{ + def celo_unlocked_factory do + %CeloUnlocked{ account_address: address_hash(), amount: Decimal.new(1), - index: sequence("pending_index", & &1), - timestamp: Timex.shift(Timex.now(), days: Enum.random(0..100) * -1) + available: Timex.shift(Timex.now(), days: Enum.random(0..100) * -1) } end end diff --git a/apps/indexer/lib/indexer/block/fetcher.ex b/apps/indexer/lib/indexer/block/fetcher.ex index 2e85b492fd7f..3126aee06c53 100644 --- a/apps/indexer/lib/indexer/block/fetcher.ex +++ b/apps/indexer/lib/indexer/block/fetcher.ex @@ -224,7 +224,8 @@ defmodule Indexer.Block.Fetcher do exchange_rates: exchange_rates, account_names: account_names, wallets: celo_wallets, - withdrawals: celo_withdrawals + withdrawals: celo_withdrawals, + unlocked: celo_unlocked } = CeloAccounts.parse(logs, oracle_address), market_history = exchange_rates @@ -336,7 +337,8 @@ defmodule Indexer.Block.Fetcher do async_import_celo_voters(%{celo_voters: %{params: celo_voters}}) async_import_celo_validator_history(range) - delete_pending_celo(celo_withdrawals) + insert_celo_unlocked(celo_unlocked) + delete_celo_unlocked(celo_withdrawals) update_block_cache(inserted[:blocks]) update_transactions_cache(inserted[:transactions]) update_addresses_cache(inserted[:addresses]) @@ -376,13 +378,25 @@ defmodule Indexer.Block.Fetcher do Uncles.update_from_second_degree_relations(updated_relations) end - defp delete_pending_celo(withdrawals) do + defp delete_celo_unlocked(withdrawals) do case withdrawals do [[]] -> 0 withdrawals -> - Enum.each(withdrawals, fn %{address: address, amount: amount} -> Chain.delete_pending_celo(address, amount) end) + Enum.each(withdrawals, fn %{address: address, amount: amount} -> Chain.delete_celo_unlocked(address, amount) end) + end + end + + defp insert_celo_unlocked(unlocked) do + case unlocked do + [[]] -> + 0 + + unlocked -> + Enum.each(unlocked, fn %{address: address, amount: amount, available: available} -> + Chain.insert_celo_unlocked(address, amount, available) + end) end end diff --git a/apps/indexer/lib/indexer/fetcher/pending_celo.ex b/apps/indexer/lib/indexer/fetcher/celo_unlocked.ex similarity index 89% rename from apps/indexer/lib/indexer/fetcher/pending_celo.ex rename to apps/indexer/lib/indexer/fetcher/celo_unlocked.ex index 829027293a55..db754534401f 100644 --- a/apps/indexer/lib/indexer/fetcher/pending_celo.ex +++ b/apps/indexer/lib/indexer/fetcher/celo_unlocked.ex @@ -1,4 +1,4 @@ -defmodule Indexer.Fetcher.PendingCelo do +defmodule Indexer.Fetcher.CeloUnlocked do @moduledoc """ Fetches pending Celo. """ @@ -7,11 +7,11 @@ defmodule Indexer.Fetcher.PendingCelo do require Logger - alias Indexer.Fetcher.PendingCelo.Supervisor, as: PendingCeloSupervisor + alias Indexer.Fetcher.CeloUnlocked.Supervisor, as: CeloUnlockedSupervisor alias Explorer.Celo.AccountReader alias Explorer.Chain - alias Explorer.Chain.PendingCelo + alias Explorer.Chain.CeloUnlocked alias Indexer.BufferedTask alias Indexer.Fetcher.Util @@ -21,7 +21,7 @@ defmodule Indexer.Fetcher.PendingCelo do @max_retries 3 def async_fetch(accounts) do - if PendingCeloSupervisor.disabled?() do + if CeloUnlockedSupervisor.disabled?() do :ok else params = @@ -84,7 +84,7 @@ defmodule Indexer.Fetcher.PendingCelo do {[account | failed], success} item, {failed, success} -> - changeset = PendingCelo.changeset(%PendingCelo{}, item) + changeset = CeloUnlocked.changeset(%CeloUnlocked{}, item) if changeset.valid? do {failed, [changeset.changes | success]} @@ -106,7 +106,7 @@ defmodule Indexer.Fetcher.PendingCelo do end) import_params = %{ - pending_celo: %{params: success}, + celo_unlocked: %{params: success}, timeout: :infinity } diff --git a/apps/indexer/lib/indexer/supervisor.ex b/apps/indexer/lib/indexer/supervisor.ex index 9636451d6b16..a8c71e80d4e9 100644 --- a/apps/indexer/lib/indexer/supervisor.ex +++ b/apps/indexer/lib/indexer/supervisor.ex @@ -23,6 +23,7 @@ defmodule Indexer.Supervisor do CeloAccount, CeloEpochRewards, CeloMaterializedViewRefresh, + CeloUnlocked, CeloValidator, CeloValidatorGroup, CeloValidatorHistory, @@ -31,7 +32,6 @@ defmodule Indexer.Supervisor do CoinBalanceOnDemand, ContractCode, InternalTransaction, - PendingCelo, PendingTransaction, ReplacedTransaction, Token, @@ -157,7 +157,7 @@ defmodule Indexer.Supervisor do [[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]}, {CeloEpochRewards.Supervisor, [[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]}, - {PendingCelo.Supervisor, [[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]}, + {CeloUnlocked.Supervisor, [[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]}, {CeloVoters.Supervisor, [[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]}, {CeloMaterializedViewRefresh, [[], []]} ] diff --git a/apps/indexer/lib/indexer/transform/celo_accounts.ex b/apps/indexer/lib/indexer/transform/celo_accounts.ex index 17aee646626b..998a615d2e64 100644 --- a/apps/indexer/lib/indexer/transform/celo_accounts.ex +++ b/apps/indexer/lib/indexer/transform/celo_accounts.ex @@ -24,7 +24,8 @@ defmodule Indexer.Transform.CeloAccounts do validator_groups: get_addresses(logs, Events.validator_group_events()) ++ get_addresses(logs, Events.vote_events(), fn a -> a.third_topic end), - withdrawals: [get_withdrawals(logs, Events.withdrawal_events())], + withdrawals: [get_withdrawal_events(logs, Events.gold_withdrawn())], + unlocked: [get_withdrawal_events(logs, Events.gold_unlocked())], signers: get_signers(logs, Events.signer_events()), voters: get_voters(logs, Events.voter_events()), attestations_fulfilled: get_addresses(logs, [Events.attestation_completed_event()], fn a -> a.fourth_topic end), @@ -56,10 +57,10 @@ defmodule Indexer.Transform.CeloAccounts do |> Enum.map(fn address -> %{address: address} end) end - defp get_withdrawals(logs, topics) do + defp get_withdrawal_events(logs, topics) do logs |> Enum.filter(fn log -> Enum.member?(topics, log.first_topic) end) - |> Enum.reduce([], fn log, accounts -> do_parse_withdrawals(log, accounts, fn a -> a.second_topic end) end) + |> Enum.reduce([], fn log, accounts -> do_parse_withdrawal_events(log, accounts, fn a -> a.second_topic end) end) end defp get_signers(logs, topics) do @@ -148,11 +149,18 @@ defmodule Indexer.Transform.CeloAccounts do names end - defp do_parse_withdrawals(log, accounts, get_topic) do + defp do_parse_withdrawal_events(log, accounts, get_topic) do account_address = parse_params(log, get_topic) - [amount] = decode_data(log.data, [{:uint, 256}]) - %{address: account_address, amount: amount} + # GoldUnlocked has 2 unindexed parameters which end up in the data field, while the rest of the withdrawal events + # only 1. Each of these parameters are of length 64 plus 2 for the 0x. + if String.length(log.data) > 66 do + [amount, available] = decode_data(log.data, [{:uint, 256}, {:uint, 256}]) + %{address: account_address, amount: amount, available: available} + else + [amount] = decode_data(log.data, [{:uint, 256}]) + %{address: account_address, amount: amount} + end rescue _ in [FunctionClauseError, MatchError] -> Logger.error(fn -> "Unknown account event format: #{inspect(log)}" end) diff --git a/apps/indexer/test/indexer/block/fetcher_test.exs b/apps/indexer/test/indexer/block/fetcher_test.exs index 9e0b09f62c75..1fca5a061f2c 100644 --- a/apps/indexer/test/indexer/block/fetcher_test.exs +++ b/apps/indexer/test/indexer/block/fetcher_test.exs @@ -7,8 +7,9 @@ defmodule Indexer.Block.FetcherTest do import EthereumJSONRPC, only: [integer_to_quantity: 1] import Explorer.Celo.CacheHelper + alias Explorer.Celo.Events alias Explorer.Chain - alias Explorer.Chain.{Address, CeloPendingEpochOperation, PendingCelo, Log, Transaction, Wei} + alias Explorer.Chain.{Address, CeloPendingEpochOperation, CeloUnlocked, Log, Transaction, Wei} alias Indexer.Block.Fetcher alias Indexer.BufferedTask @@ -297,6 +298,8 @@ defmodule Indexer.Block.FetcherTest do from_address_hash = "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" to_address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" transaction_hash = "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5" + [event_first_topic] = Events.gold_withdrawn() + event_data = "0x0000000000000000000000000000000000000000000000000000000000000f00" setup_mox( block_quantity, @@ -304,6 +307,8 @@ defmodule Indexer.Block.FetcherTest do to_address_hash, transaction_hash, unprefixed_celo_token_address_hash, + event_first_topic, + event_data, 22 ) @@ -507,114 +512,235 @@ defmodule Indexer.Block.FetcherTest do end end - # @tag :no_geth - # test "deletes the entry in pending celo in case of a gold_withdrawn event", %{ - # block_fetcher: %Fetcher{json_rpc_named_arguments: json_rpc_named_arguments} = block_fetcher - # } do - # celo_token_address = insert(:contract_address) - # insert(:token, contract_address: celo_token_address) - # "0x" <> unprefixed_celo_token_address_hash = to_string(celo_token_address.hash) - # - # block_number = @first_full_block_number - # insert(:pending_celo, %{account_address: "0xC257274276a4E539741Ca11b590B9447B26A8051", amount: 3840}) - # - # if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do - # case Keyword.fetch!(json_rpc_named_arguments, :variant) do - # EthereumJSONRPC.Parity -> - # block_quantity = integer_to_quantity(block_number) - # from_address_hash = "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" - # to_address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" - # transaction_hash = "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5" - # - # setup_mox( - # block_quantity, - # from_address_hash, - # to_address_hash, - # transaction_hash, - # unprefixed_celo_token_address_hash, - # 31 - # ) - # - # variant -> - # raise ArgumentError, "Unsupported variant (#{variant})" - # end - # end - # - # case Keyword.fetch!(json_rpc_named_arguments, :variant) do - # EthereumJSONRPC.Parity -> - # assert {:ok, - # %{ - # inserted: %{ - # addresses: [ - # %Address{ - # hash: %Explorer.Chain.Hash{ - # byte_count: 20, - # bytes: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>> - # } - # }, - # %Address{ - # hash: %Explorer.Chain.Hash{ - # byte_count: 20, - # bytes: - # <<139, 243, 141, 71, 100, 146, 144, 100, 242, 212, 211, 165, 101, 32, 167, 106, 179, 223, - # 65, 91>> - # } - # }, - # %Address{ - # hash: %Explorer.Chain.Hash{ - # byte_count: 20, - # bytes: - # <<232, 221, 197, 199, 162, 210, 240, 215, 169, 121, 132, 89, 192, 16, 79, 223, 94, 152, - # 122, 202>> - # } - # } - # ], - # blocks: [ - # %Chain.Block{ - # hash: %Explorer.Chain.Hash{ - # byte_count: 32, - # bytes: - # <<246, 180, 184, 200, 141, 243, 235, 210, 82, 236, 71, 99, 40, 51, 77, 192, 38, 207, 102, - # 96, 106, 132, 251, 118, 155, 61, 60, 188, 204, 132, 113, 189>> - # } - # } - # ], - # logs: [ - # %Log{ - # index: 0, - # transaction_hash: %Explorer.Chain.Hash{ - # byte_count: 32, - # bytes: - # <<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, - # 77, 57, 101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>> - # } - # } - # ], - # transactions: [ - # %Transaction{ - # block_number: _, - # index: 0, - # hash: %Explorer.Chain.Hash{ - # byte_count: 32, - # bytes: - # <<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, - # 77, 57, 101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>> - # } - # } - # ] - # }, - # errors: [] - # }} = Fetcher.fetch_and_import_range(block_fetcher, block_number..block_number) - # - # wait_for_tasks(InternalTransaction) - # wait_for_tasks(CoinBalance) - # - # assert Repo.aggregate(PendingCelo, :count, :index) == 0 - # - # variant -> - # raise ArgumentError, "Unsupported variant (#{variant})" - # end - # end + @tag :no_geth + test "inserts an entry to unlocked celo in case of a gold_unlocked event", %{ + block_fetcher: %Fetcher{json_rpc_named_arguments: json_rpc_named_arguments} = block_fetcher + } do + celo_token_address = insert(:contract_address) + insert(:token, contract_address: celo_token_address) + "0x" <> unprefixed_celo_token_address_hash = to_string(celo_token_address.hash) + set_test_address(to_string(celo_token_address.hash)) + + block_number = @first_full_block_number + # insert(:celo_unlocked, %{account_address: "0xC257274276a4E539741Ca11b590B9447B26A8051", amount: 3840}) + + if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do + case Keyword.fetch!(json_rpc_named_arguments, :variant) do + EthereumJSONRPC.Parity -> + block_quantity = integer_to_quantity(block_number) + from_address_hash = "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" + to_address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" + transaction_hash = "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5" + [event_first_topic] = Events.gold_unlocked() + + event_data = + "0x00000000000000000000000000000000000000000000001aabdf2145b43000000000000000000000000000000000000000000000000000000000000061b2bcf8" + + setup_mox( + block_quantity, + from_address_hash, + to_address_hash, + transaction_hash, + unprefixed_celo_token_address_hash, + event_first_topic, + event_data, + 22 + ) + + variant -> + raise ArgumentError, "Unsupported variant (#{variant})" + end + end + + case Keyword.fetch!(json_rpc_named_arguments, :variant) do + EthereumJSONRPC.Parity -> + assert {:ok, + %{ + inserted: %{ + addresses: [ + %Address{ + hash: %Explorer.Chain.Hash{ + byte_count: 20, + bytes: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>> + } + }, + %Address{ + hash: %Explorer.Chain.Hash{ + byte_count: 20, + bytes: + <<139, 243, 141, 71, 100, 146, 144, 100, 242, 212, 211, 165, 101, 32, 167, 106, 179, 223, + 65, 91>> + } + }, + %Address{ + hash: %Explorer.Chain.Hash{ + byte_count: 20, + bytes: + <<232, 221, 197, 199, 162, 210, 240, 215, 169, 121, 132, 89, 192, 16, 79, 223, 94, 152, + 122, 202>> + } + } + ], + blocks: [ + %Chain.Block{ + hash: %Explorer.Chain.Hash{ + byte_count: 32, + bytes: + <<246, 180, 184, 200, 141, 243, 235, 210, 82, 236, 71, 99, 40, 51, 77, 192, 38, 207, 102, + 96, 106, 132, 251, 118, 155, 61, 60, 188, 204, 132, 113, 189>> + } + } + ], + logs: [ + %Log{ + index: 0, + transaction_hash: %Explorer.Chain.Hash{ + byte_count: 32, + bytes: + <<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, + 77, 57, 101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>> + } + } + ], + transactions: [ + %Transaction{ + block_number: _, + index: 0, + hash: %Explorer.Chain.Hash{ + byte_count: 32, + bytes: + <<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, + 77, 57, 101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>> + } + } + ] + }, + errors: [] + }} = Fetcher.fetch_and_import_range(block_fetcher, block_number..block_number) + + wait_for_tasks(InternalTransaction) + wait_for_tasks(CoinBalance) + + assert Repo.aggregate(CeloUnlocked, :count, :account_address) == 1 + + variant -> + raise ArgumentError, "Unsupported variant (#{variant})" + end + end + + @tag :no_geth + test "deletes the entry in unlocked celo in case of a gold_withdrawn event", %{ + block_fetcher: %Fetcher{json_rpc_named_arguments: json_rpc_named_arguments} = block_fetcher + } do + celo_token_address = insert(:contract_address) + insert(:token, contract_address: celo_token_address) + "0x" <> unprefixed_celo_token_address_hash = to_string(celo_token_address.hash) + set_test_address(to_string(celo_token_address.hash)) + + block_number = @first_full_block_number + insert(:celo_unlocked, %{account_address: "0xC257274276a4E539741Ca11b590B9447B26A8051", amount: 3840}) + + if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do + case Keyword.fetch!(json_rpc_named_arguments, :variant) do + EthereumJSONRPC.Parity -> + block_quantity = integer_to_quantity(block_number) + from_address_hash = "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" + to_address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" + transaction_hash = "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5" + [event_first_topic] = Events.gold_withdrawn() + event_data = "0x0000000000000000000000000000000000000000000000000000000000000f00" + + setup_mox( + block_quantity, + from_address_hash, + to_address_hash, + transaction_hash, + unprefixed_celo_token_address_hash, + event_first_topic, + event_data, + 22 + ) + + variant -> + raise ArgumentError, "Unsupported variant (#{variant})" + end + end + + case Keyword.fetch!(json_rpc_named_arguments, :variant) do + EthereumJSONRPC.Parity -> + assert {:ok, + %{ + inserted: %{ + addresses: [ + %Address{ + hash: %Explorer.Chain.Hash{ + byte_count: 20, + bytes: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>> + } + }, + %Address{ + hash: %Explorer.Chain.Hash{ + byte_count: 20, + bytes: + <<139, 243, 141, 71, 100, 146, 144, 100, 242, 212, 211, 165, 101, 32, 167, 106, 179, 223, + 65, 91>> + } + }, + %Address{ + hash: %Explorer.Chain.Hash{ + byte_count: 20, + bytes: + <<232, 221, 197, 199, 162, 210, 240, 215, 169, 121, 132, 89, 192, 16, 79, 223, 94, 152, + 122, 202>> + } + } + ], + blocks: [ + %Chain.Block{ + hash: %Explorer.Chain.Hash{ + byte_count: 32, + bytes: + <<246, 180, 184, 200, 141, 243, 235, 210, 82, 236, 71, 99, 40, 51, 77, 192, 38, 207, 102, + 96, 106, 132, 251, 118, 155, 61, 60, 188, 204, 132, 113, 189>> + } + } + ], + logs: [ + %Log{ + index: 0, + transaction_hash: %Explorer.Chain.Hash{ + byte_count: 32, + bytes: + <<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, + 77, 57, 101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>> + } + } + ], + transactions: [ + %Transaction{ + block_number: _, + index: 0, + hash: %Explorer.Chain.Hash{ + byte_count: 32, + bytes: + <<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, + 77, 57, 101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>> + } + } + ] + }, + errors: [] + }} = Fetcher.fetch_and_import_range(block_fetcher, block_number..block_number) + + wait_for_tasks(InternalTransaction) + wait_for_tasks(CoinBalance) + + assert Repo.aggregate(CeloUnlocked, :count, :account_address) == 0 + + variant -> + raise ArgumentError, "Unsupported variant (#{variant})" + end + end @tag :no_geth test "correctly imports blocks with multiple uncle rewards for the same address", %{ @@ -795,6 +921,8 @@ defmodule Indexer.Block.FetcherTest do to_address_hash, transaction_hash, unprefixed_celo_token_address_hash, + event_first_topic, + event_data, call_json_rpc_times ) do EthereumJSONRPC.Mox @@ -1014,10 +1142,10 @@ defmodule Indexer.Block.FetcherTest do "address" => "0x8bf38d4764929064f2d4d3a56520a76ab3df415b", "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", "blockNumber" => "0x25", - "data" => "0x0000000000000000000000000000000000000000000000000000000000000f00", + "data" => event_data, "logIndex" => "0x0", "topics" => [ - "0x292d39ba701489b7f640c83806d3eeabe0a32c9f0a61b49e95612ebad42211cd", + event_first_topic, "0x000000000000000000000000C257274276a4E539741Ca11b590B9447B26A8051" ], "transactionHash" => "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5", diff --git a/apps/indexer/test/indexer/fetcher/celo_unlocked_test.exs b/apps/indexer/test/indexer/fetcher/celo_unlocked_test.exs new file mode 100644 index 000000000000..a827cc7d8a35 --- /dev/null +++ b/apps/indexer/test/indexer/fetcher/celo_unlocked_test.exs @@ -0,0 +1,73 @@ +defmodule Indexer.Fetcher.CeloUnlockedTest do + use EthereumJSONRPC.Case + use Explorer.DataCase + + import Mox + import Explorer.Celo.CacheHelper + + alias Explorer.Chain.{Address, Hash} + alias Explorer.Chain.CeloUnlocked, as: ChainCeloUnlocked + alias Indexer.Fetcher.CeloUnlocked + + @moduletag :capture_log + + setup :verify_on_exit! + setup :set_mox_global + + @tag :skip + describe "run/3" do + setup %{json_rpc_named_arguments: json_rpc_named_arguments} do + CeloUnlocked.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) + + :ok + end + + test "imports the pending celo for the given address" do + %Address{ + hash: %Hash{ + bytes: address + } + } = insert(:address, hash: "0xe26b6a5655601a9db347be8bd23dd7d4eabcf818") + + set_test_address("0x6cc083aed9e3ebe302a6336dbc7c921c9f03349e") + + stub( + EthereumJSONRPC.Mox, + :json_rpc, + fn [ + %{ + id: id, + method: "eth_call", + params: [ + %{ + data: "0xf340c0d0000000000000000000000000e26b6a5655601a9db347be8bd23dd7d4eabcf818", + to: "0x6cc083aed9e3ebe302a6336dbc7c921c9f03349e" + }, + "latest" + ] + } + ], + _options -> + { + :ok, + [ + %{ + id: id, + jsonrpc: "2.0", + result: + "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000a2bd4de46c65dc02c300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000061582bf1" + } + ] + } + end + ) + + CeloUnlocked.run( + [%{address: address, retries_count: 0}], + nil + ) + + assert Repo.one!(select(ChainCeloUnlocked, fragment("COUNT(*)"))) == 1 + end + end +end diff --git a/apps/indexer/test/indexer/fetcher/pending_celo_test.exs b/apps/indexer/test/indexer/fetcher/pending_celo_test.exs deleted file mode 100644 index d7e2f31e2b55..000000000000 --- a/apps/indexer/test/indexer/fetcher/pending_celo_test.exs +++ /dev/null @@ -1,85 +0,0 @@ -defmodule Indexer.Fetcher.PendingCeloTest do - use EthereumJSONRPC.Case - use Explorer.DataCase - - import Mox - import Explorer.Celo.CacheHelper - - alias Explorer.Chain.{Address, Hash} - alias Explorer.Chain.PendingCelo, as: ChainPendingCelo - alias Indexer.Fetcher.PendingCelo - - @moduletag :capture_log - - setup :verify_on_exit! - setup :set_mox_global - - describe "run/3" do - setup %{json_rpc_named_arguments: json_rpc_named_arguments} do - PendingCelo.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) - - :ok - end - - test "imports the pending celo for the given address" do - %Address{ - hash: %Hash{bytes: address} - } = insert(:address, hash: "0xe26b6a5655601a9db347be8bd23dd7d4eabcf818") - - set_test_address("0x6cc083aed9e3ebe302a6336dbc7c921c9f03349e") - - stub( - EthereumJSONRPC.Mox, - :json_rpc, - fn [ - %{ - id: id, - method: "eth_call", - params: [ - %{ - data: "0xf340c0d0000000000000000000000000e26b6a5655601a9db347be8bd23dd7d4eabcf818", - to: "0x6cc083aed9e3ebe302a6336dbc7c921c9f03349e" - }, - "latest" - ] - } - ], - _options -> - {:ok, - [ - %{ - id: id, - jsonrpc: "2.0", - result: - "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000a2bd4de46c65dc02c300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000061582bf1" - } - ]} - end - ) - - assert PendingCelo.run( - [%{address: address, retries_count: 0}], - nil - ) == - {:retry, - [ - %{ - address: - <<226, 107, 106, 86, 85, 96, 26, 157, 179, 71, 190, 139, 210, 61, 215, 212, 234, 188, 248, 24>>, - retries_count: 1, - pending: [ - %{ - address: - <<226, 107, 106, 86, 85, 96, 26, 157, 179, 71, 190, 139, 210, 61, 215, 212, 234, 188, 248, - 24>>, - amount: 3_002_013_349_941_538_980_547, - timestamp: 1_633_168_369 - } - ] - } - ]} - - Explorer.Repo.get_by(ChainPendingCelo, account_address: address) - end - end -end diff --git a/apps/indexer/test/support/indexer/fetcher/pending_celo_case.ex b/apps/indexer/test/support/indexer/fetcher/pending_celo_case.ex index 8553519217c5..ff08f1eedad6 100644 --- a/apps/indexer/test/support/indexer/fetcher/pending_celo_case.ex +++ b/apps/indexer/test/support/indexer/fetcher/pending_celo_case.ex @@ -1,5 +1,5 @@ -defmodule Indexer.Fetcher.PendingCelo.Supervisor.Case do - alias Indexer.Fetcher.PendingCelo +defmodule Indexer.Fetcher.CeloUnlocked.Supervisor.Case do + alias Indexer.Fetcher.CeloUnlocked def start_supervised!(fetcher_arguments \\ []) when is_list(fetcher_arguments) do merged_fetcher_arguments = @@ -11,7 +11,7 @@ defmodule Indexer.Fetcher.PendingCelo.Supervisor.Case do ) [merged_fetcher_arguments] - |> PendingCelo.Supervisor.child_spec() + |> CeloUnlocked.Supervisor.child_spec() |> ExUnit.Callbacks.start_supervised!() end end From fbbe83a960aa8de1675e6ea12a10eef1d49fb13c Mon Sep 17 00:00:00 2001 From: Enrique Ruiz Date: Thu, 9 Dec 2021 16:48:01 +0100 Subject: [PATCH 2/3] Fix typo in the label (#504) --- .../templates/address/overview.html.eex | 2 +- apps/block_scout_web/priv/gettext/default.pot | 12 ++++++------ .../priv/gettext/en/LC_MESSAGES/default.po | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex index 711e8c309e29..6fb0fad89512 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex @@ -163,7 +163,7 @@
<%= render BlockScoutWeb.CommonComponentsView, "_i_tooltip_2.html", - text: gettext("Address balance in xDAI (doesn't include ERC20, ERC721, ERC1155 tokens).") %> + text: gettext("Address balance in CELO (doesn't include ERC20, ERC721, ERC1155 tokens).") %> <%= gettext("Balance") %>
diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index a6f877943e23..b3bed9cf5b1d 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -219,7 +219,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:166 -msgid "Address balance in xDAI (doesn't include ERC20, ERC721, ERC1155 tokens)." +msgid "Address balance in CELO (doesn't include ERC20, ERC721, ERC1155 tokens)." msgstr "" #, elixir-format @@ -511,6 +511,11 @@ msgstr "" msgid "CSV" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/csv_export/index.html.eex:28 +msgid "CSV is being prepared, please wait..." +msgstr "" + #, elixir-format #: lib/block_scout_web/views/internal_transaction_view.ex:21 msgid "Call" @@ -3306,8 +3311,3 @@ msgstr "CELO" # From templates/tokens/overview/details.html.eex# msgid "Celo Gold" msgstr "CELO" - -#, elixir-format -#: lib/block_scout_web/templates/csv_export/index.html.eex:28 -msgid "CSV is being prepared, please wait..." -msgstr "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index c110af18d71d..fbc307c004cb 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -220,7 +220,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:166 -msgid "Address balance in xDAI (doesn't include ERC20, ERC721, ERC1155 tokens)." +msgid "Address balance in CELO (doesn't include ERC20, ERC721, ERC1155 tokens)." msgstr "" #, elixir-format @@ -512,6 +512,11 @@ msgstr "" msgid "CSV" msgstr "" +#, elixir-format +#: lib/block_scout_web/templates/csv_export/index.html.eex:28 +msgid "CSV is being prepared, please wait..." +msgstr "" + #, elixir-format #: lib/block_scout_web/views/internal_transaction_view.ex:21 msgid "Call" @@ -3307,8 +3312,3 @@ msgstr "CELO" # From templates/tokens/overview/details.html.eex# msgid "Celo Gold" msgstr "CELO" - -#, elixir-format -#: lib/block_scout_web/templates/csv_export/index.html.eex:28 -msgid "CSV is being prepared, please wait..." -msgstr "" From a4b80bd6f35f97b90d924adb33473bbeadae86ca Mon Sep 17 00:00:00 2001 From: Enrique Ruiz Date: Fri, 10 Dec 2021 15:06:35 +0100 Subject: [PATCH 3/3] Fix issue with wrong updated token balances (#506) * Fix issue with wrong updated token balances * Update mistake * Only update balances --- .../lib/indexer/fetcher/internal_transaction.ex | 11 ++++++++--- apps/indexer/test/indexer/block/fetcher_test.exs | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/indexer/lib/indexer/fetcher/internal_transaction.ex b/apps/indexer/lib/indexer/fetcher/internal_transaction.ex index f94460441bd3..6ed940d06c56 100644 --- a/apps/indexer/lib/indexer/fetcher/internal_transaction.ex +++ b/apps/indexer/lib/indexer/fetcher/internal_transaction.ex @@ -269,8 +269,13 @@ defmodule Indexer.Fetcher.InternalTransaction do _ -> [] end + token_transfers_addresses_params = + Addresses.extract_addresses(%{ + token_transfers: token_transfers + }) + address_hash_to_block_number = - Enum.into(addresses_params, %{}, fn %{fetched_coin_balance_block_number: block_number, hash: hash} -> + Enum.into(token_transfers_addresses_params, %{}, fn %{fetched_coin_balance_block_number: block_number, hash: hash} -> {hash, block_number} end) @@ -293,10 +298,10 @@ defmodule Indexer.Fetcher.InternalTransaction do case imports do {:ok, imported} -> - Accounts.drop(imported[:addreses]) + Accounts.drop(imported[:addresses]) Blocks.drop_nonconsensus(imported[:remove_consensus_of_missing_transactions_blocks]) - async_import_coin_balances(imported, %{ + async_import_coin_balances(token_transfers_addresses_params, %{ address_hash_to_fetched_balance_block_number: address_hash_to_block_number }) diff --git a/apps/indexer/test/indexer/block/fetcher_test.exs b/apps/indexer/test/indexer/block/fetcher_test.exs index 1fca5a061f2c..0d34f4129f8e 100644 --- a/apps/indexer/test/indexer/block/fetcher_test.exs +++ b/apps/indexer/test/indexer/block/fetcher_test.exs @@ -309,7 +309,7 @@ defmodule Indexer.Block.FetcherTest do unprefixed_celo_token_address_hash, event_first_topic, event_data, - 22 + 18 ) variant -> @@ -544,7 +544,7 @@ defmodule Indexer.Block.FetcherTest do unprefixed_celo_token_address_hash, event_first_topic, event_data, - 22 + 18 ) variant -> @@ -658,7 +658,7 @@ defmodule Indexer.Block.FetcherTest do unprefixed_celo_token_address_hash, event_first_topic, event_data, - 22 + 18 ) variant ->