Merge pull request #3171 from poanetwork/vb-import-accounts-from-genesis-geth
Import accounts from Geth genesispull/3173/head
commit
58358bb4f2
@ -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 |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue