Merge pull request #3171 from poanetwork/vb-import-accounts-from-genesis-geth

Import accounts from Geth genesis
pull/3173/head
Victor Baranov 4 years ago committed by GitHub
commit 58358bb4f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 14
      apps/explorer/lib/explorer/chain_spec/genesis_data.ex
  3. 93
      apps/explorer/lib/explorer/chain_spec/geth/importer.ex
  4. 3
      apps/explorer/lib/explorer/chain_spec/parity/importer.ex
  5. 145
      apps/explorer/test/explorer/chain_spec/geth/importer_test.exs
  6. 53
      apps/explorer/test/support/fixture/chain_spec/qdai_genesis.json

@ -1,6 +1,7 @@
## Current
### Features
- [#3171](https://github.com/poanetwork/blockscout/pull/3171) - Import accounts/contracts/balances from Geth genesis.json
- [#3157](https://github.com/poanetwork/blockscout/pull/3157) - Read methods of implementation on proxy contract
### Fixes

@ -7,6 +7,7 @@ defmodule Explorer.ChainSpec.GenesisData do
require Logger
alias Explorer.ChainSpec.Geth.Importer, as: GethImporter
alias Explorer.ChainSpec.Parity.Importer
alias HTTPoison.Response
@ -58,11 +59,24 @@ defmodule Explorer.ChainSpec.GenesisData do
path = Application.get_env(:explorer, __MODULE__)[:chain_spec_path]
if path do
json_rpc_named_arguments = Application.fetch_env!(:indexer, :json_rpc_named_arguments)
variant = Keyword.fetch!(json_rpc_named_arguments, :variant)
Task.Supervisor.async_nolink(Explorer.GenesisDataTaskSupervisor, fn ->
case fetch_spec(path) do
{:ok, chain_spec} ->
case variant do
EthereumJSONRPC.Parity ->
Importer.import_emission_rewards(chain_spec)
{:ok, _} = Importer.import_genesis_accounts(chain_spec)
EthereumJSONRPC.Geth ->
{:ok, _} = GethImporter.import_genesis_accounts(chain_spec)
_ ->
Importer.import_emission_rewards(chain_spec)
{:ok, _} = Importer.import_genesis_accounts(chain_spec)
end
{:error, reason} ->
Logger.warn(fn -> "Failed to fetch genesis data. #{inspect(reason)}" end)

@ -0,0 +1,93 @@
# credo:disable-for-this-file
defmodule Explorer.ChainSpec.Geth.Importer do
@moduledoc """
Imports data from Geth genesis.json.
"""
require Logger
alias EthereumJSONRPC.Blocks
alias Explorer.Chain
alias Explorer.Chain.Hash.Address, as: AddressHash
def import_genesis_accounts(chain_spec) do
balance_params =
chain_spec
|> genesis_accounts()
|> Stream.map(fn balance_map ->
Map.put(balance_map, :block_number, 0)
end)
|> Enum.to_list()
json_rpc_named_arguments = Application.get_env(:explorer, :json_rpc_named_arguments)
{:ok, %Blocks{blocks_params: [%{timestamp: timestamp}]}} =
EthereumJSONRPC.fetch_blocks_by_range(1..1, json_rpc_named_arguments)
day = DateTime.to_date(timestamp)
balance_daily_params =
chain_spec
|> genesis_accounts()
|> Stream.map(fn balance_map ->
Map.put(balance_map, :day, day)
end)
|> Enum.to_list()
address_params =
balance_params
|> Stream.map(fn %{address_hash: hash} = map ->
Map.put(map, :hash, hash)
end)
|> Enum.to_list()
params = %{
address_coin_balances: %{params: balance_params},
address_coin_balances_daily: %{params: balance_daily_params},
addresses: %{params: address_params}
}
Chain.import(params)
end
def genesis_accounts(chain_spec) do
accounts = chain_spec["alloc"]
if accounts do
parse_accounts(accounts)
else
Logger.warn(fn -> "No accounts are defined in genesis" end)
[]
end
end
defp parse_accounts(accounts) do
accounts
|> Stream.filter(fn {_address, map} ->
!is_nil(map["balance"])
end)
|> Stream.map(fn {address, %{"balance" => value} = params} ->
formatted_address = if String.starts_with?(address, "0x"), do: address, else: "0x" <> address
{:ok, address_hash} = AddressHash.cast(formatted_address)
balance = parse_number(value)
code = params["code"]
%{address_hash: address_hash, value: balance, contract_code: code}
end)
|> Enum.to_list()
end
defp parse_number("0x" <> hex_number) do
{number, ""} = Integer.parse(hex_number, 16)
number
end
defp parse_number(string_number) do
{number, ""} = Integer.parse(string_number, 10)
number
end
end

@ -1,6 +1,7 @@
# credo:disable-for-this-file
defmodule Explorer.ChainSpec.Parity.Importer do
@moduledoc """
Imports data from parity chain spec.
Imports data from Parity/Open Ethereum chain spec.
"""
require Logger

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save