Merge branch 'master' into 943-read-contract-query-styling

pull/1020/head
Andrew Cravenho 6 years ago committed by GitHub
commit 9c6cb25971
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      .dockerignore
  2. 18
      apps/block_scout_web/assets/css/_typography.scss
  3. 2
      apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex
  4. 2
      apps/block_scout_web/lib/block_scout_web/templates/internal_transaction/_tile.html.eex
  5. 18
      apps/block_scout_web/lib/block_scout_web/views/currency_helpers.ex
  6. 2
      apps/block_scout_web/lib/block_scout_web/views/tokens/helpers.ex
  7. 2
      apps/block_scout_web/lib/block_scout_web/views/tokens/holder_view.ex
  8. 12
      apps/block_scout_web/test/block_scout_web/views/currency_helpers_test.exs
  9. 2
      apps/block_scout_web/test/block_scout_web/views/tokens/helpers_test.exs
  10. 2
      apps/block_scout_web/test/block_scout_web/views/tokens/holder_view_test.exs
  11. 2
      apps/explorer/lib/explorer/chain/token.ex
  12. 17
      apps/explorer/priv/repo/migrations/20181029174420_update_tokens_table_decimals_from_bigint_to_numeric.exs
  13. 2
      apps/explorer/test/explorer/chain/address/token_test.exs
  14. 2
      apps/explorer/test/explorer/chain_test.exs
  15. 4
      apps/indexer/test/indexer/token/fetcher_test.exs
  16. 39
      docker/Dockerfile
  17. 101
      docker/Makefile
  18. 77
      docker/README.md

@ -0,0 +1,9 @@
_build
deps
apps/block_scout_web/assets/node_modules
apps/explorer/node_modules
test
.git
.circleci
logs
apps/*/test

@ -99,10 +99,24 @@ label, textarea.form-control {
}
}
[data-transaction-status="Success"] {
[data-transaction-status="Success"],
[data-internal-transaction-type="Reward"] {
color: $success;
}
[data-transaction-status^="Error"] {
[data-internal-transaction-type="Call"] {
color: $info;
}
[data-internal-transaction-type="Delegate Call"] {
color: $purple;
}
[data-internal-transaction-type="Create"] {
color: $pink;
}
[data-transaction-status^="Error"],
[data-internal-transaction-type="Suicide"] {
color: $danger;
}

@ -44,7 +44,7 @@
<%= gettext("Code") %>
<%= if smart_contract_verified?(@address) do %>
<i class="far fa-check-circle"></i>
<i class="far fa-check-circle text-success"></i>
<% end %>
<% end %>
</li>

@ -2,7 +2,7 @@
<div class="row">
<div class="col-md-2 d-flex flex-row flex-md-column align-items-left justify-content-start justify-content-lg-center mb-1 mb-md-0 pl-md-4">
<%= gettext("Internal Transaction") %>
<span>(<%= type(@internal_transaction) %>)</span>
<span data-internal-transaction-type="<%= type(@internal_transaction) %>"><%= type(@internal_transaction) %></span>
</div>
<div class="col-md-7 col-lg-8 d-flex flex-column text-nowrap pr-2 pr-sm-2 pr-md-0">
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @internal_transaction.transaction_hash %>

@ -25,24 +25,24 @@ defmodule BlockScoutWeb.CurrencyHelpers do
## Examples
iex> format_according_to_decimals(Decimal.new(20500000), 5)
iex> format_according_to_decimals(Decimal.new(20500000), Decimal.new(5))
"205"
iex> format_according_to_decimals(Decimal.new(20500000), 7)
iex> format_according_to_decimals(Decimal.new(20500000), Decimal.new(7))
"2.05"
iex> format_according_to_decimals(Decimal.new(205000), 12)
iex> format_according_to_decimals(Decimal.new(205000), Decimal.new(12))
"0.000000205"
iex> format_according_to_decimals(Decimal.new(205000), 2)
iex> format_according_to_decimals(Decimal.new(205000), Decimal.new(2))
"2,050"
iex> format_according_to_decimals(205000, 2)
iex> format_according_to_decimals(205000, Decimal.new(2))
"2,050"
"""
@spec format_according_to_decimals(non_neg_integer(), non_neg_integer()) :: String.t()
@spec format_according_to_decimals(non_neg_integer(), nil) :: String.t()
def format_according_to_decimals(value, nil) do
format_according_to_decimals(value, 0)
format_according_to_decimals(value, Decimal.new(0))
end
def format_according_to_decimals(value, decimals) when is_integer(value) do
@ -51,10 +51,10 @@ defmodule BlockScoutWeb.CurrencyHelpers do
|> format_according_to_decimals(decimals)
end
@spec format_according_to_decimals(Decimal.t(), non_neg_integer()) :: String.t()
@spec format_according_to_decimals(Decimal.t(), Decimal.t()) :: String.t()
def format_according_to_decimals(%Decimal{sign: sign, coef: coef, exp: exp}, decimals) do
sign
|> Decimal.new(coef, exp - decimals)
|> Decimal.new(coef, exp - Decimal.to_integer(decimals))
|> Decimal.reduce()
|> thousands_separator()
end

@ -25,7 +25,7 @@ defmodule BlockScoutWeb.Tokens.Helpers do
end
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: nil}, amount, _token_id) do
CurrencyHelpers.format_according_to_decimals(amount, 0)
CurrencyHelpers.format_according_to_decimals(amount, Decimal.new(0))
end
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: decimals}, amount, _token_id) do

@ -49,7 +49,7 @@ defmodule BlockScoutWeb.Tokens.HolderView do
## Examples
iex> token = build(:token, type: "ERC-20", decimals: 2)
iex> token = build(:token, type: "ERC-20", decimals: Decimal.new(2))
iex> BlockScoutWeb.Tokens.HolderView.format_token_balance_value(100000, token)
"1,000"

@ -8,42 +8,42 @@ defmodule BlockScoutWeb.CurrencyHelpersTest do
describe "format_according_to_decimals/1" do
test "formats the amount as value considering the given decimals" do
amount = Decimal.new(205_000_000_000_000)
decimals = 12
decimals = Decimal.new(12)
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "205"
end
test "considers the decimal places according to the given decimals" do
amount = Decimal.new(205_000)
decimals = 12
decimals = Decimal.new(12)
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "0.000000205"
end
test "does not consider right zeros in decimal places" do
amount = Decimal.new(90_000_000)
decimals = 6
decimals = Decimal.new(6)
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "90"
end
test "returns the full number when there is no right zeros in decimal places" do
amount = Decimal.new(9_324_876)
decimals = 6
decimals = Decimal.new(6)
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "9.324876"
end
test "formats the value considering thousands separators" do
amount = Decimal.new(1_000_450)
decimals = 2
decimals = Decimal.new(2)
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "10,004.5"
end
test "supports value as integer" do
amount = 1_000_450
decimals = 2
decimals = Decimal.new(2)
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "10,004.5"
end

@ -12,7 +12,7 @@ defmodule BlockScoutWeb.Tokens.HelpersTest do
end
test "returns the formatted amount according to token decimals with ERC-20 token" do
token = build(:token, type: "ERC-20", decimals: 6)
token = build(:token, type: "ERC-20", decimals: Decimal.new(6))
token_transfer = build(:token_transfer, token: token, amount: Decimal.new(1_000_000))
assert Helpers.token_transfer_amount(token_transfer) == "1"

@ -44,7 +44,7 @@ defmodule BlockScoutWeb.Tokens.HolderViewTest do
describe "format_token_balance_value/1" do
test "formats according to token decimals when it's a ERC-20" do
token = build(:token, type: "ERC-20", decimals: 2)
token = build(:token, type: "ERC-20", decimals: Decimal.new(2))
token_balance = build(:token_balance, value: 2_000_000)
assert HolderView.format_token_balance_value(token_balance.value, token) == "20,000"

@ -50,7 +50,7 @@ defmodule Explorer.Chain.Token do
field(:name, :string)
field(:symbol, :string)
field(:total_supply, :decimal)
field(:decimals, :integer)
field(:decimals, :decimal)
field(:type, :string)
field(:cataloged, :boolean)

@ -0,0 +1,17 @@
defmodule Explorer.Repo.Migrations.UpdateTokensTableDecimalsFromBigintToNumeric do
use Ecto.Migration
def up do
alter table("tokens") do
modify(:decimals, :decimal)
end
end
def down do
execute("""
ALTER TABLE tokens
ALTER COLUMN decimals TYPE bigint
USING CASE WHEN decimals > 9223372036854775807 THEN NULL ELSE decimals END;
""")
end
end

@ -48,7 +48,7 @@ defmodule Explorer.Chain.Address.TokenTest do
name: "token-c",
symbol: "TC",
balance: Decimal.new(1000),
decimals: 0,
decimals: Decimal.new(0),
type: "ERC-721",
transfers_count: 2
}

@ -2795,7 +2795,7 @@ defmodule Explorer.ChainTest do
name: "Hodl Token",
symbol: "HT",
total_supply: 10,
decimals: 1,
decimals: Decimal.new(1),
cataloged: true
}

@ -64,12 +64,14 @@ defmodule Indexer.Token.FetcherTest do
expected_supply = Decimal.new(1_000_000_000_000_000_000)
decimals_expected = Decimal.new(18)
assert {:ok,
%Token{
name: "Bancor",
symbol: "BNT",
total_supply: ^expected_supply,
decimals: 18,
decimals: ^decimals_expected,
cataloged: true
}} = Chain.token_from_address_hash(contract_address_hash)
end

@ -0,0 +1,39 @@
FROM bitwalker/alpine-elixir-phoenix:latest
RUN apk --no-cache --update add automake libtool inotify-tools autoconf
EXPOSE 4000
ENV PORT=4000 \
MIX_ENV="prod" \
SECRET_KEY_BASE="RMgI4C1HSkxsEjdhtGMfwAHfyT6CKWXOgzCboJflfSm4jeAlic52io05KB6mqzc5"
# Cache elixir deps
ADD mix.exs mix.lock ./
ADD apps/block_scout_web/mix.exs ./apps/block_scout_web/
ADD apps/explorer/mix.exs ./apps/explorer/
ADD apps/ethereum_jsonrpc/mix.exs ./apps/ethereum_jsonrpc/
ADD apps/indexer/mix.exs ./apps/indexer/
RUN mix do deps.get, deps.compile
ADD . .
# Run forderground build and phoenix digest
RUN mix compile
# Add blockscout npm deps
RUN cd apps/block_scout_web/assets/ && \
npm install && \
npm run deploy && \
cd -
RUN cd apps/explorer/ && \
npm install && \
cd -
# RUN mix do ecto.drop --force, ecto.create, ecto.migrate
# USER default
# CMD ["mix", "phx.server"]

@ -0,0 +1,101 @@
SYSTEM = $(shell uname -s)
HOST = host.docker.internal
DOCKER_IMAGE = blockscout_prod
PG_CONTAINER_NAME = postgres
PG_CONTAINER_IMAGE = postgres:10.4
THIS_FILE = $(lastword $(MAKEFILE_LIST))
ifeq ($(SYSTEM), Linux)
HOST=localhost
endif
DB_URL = postgresql://postgres:@$(HOST):5432/explorer?ssl=false
BLOCKSCOUT_CONTAINNER_PARAMS = -e 'MIX_ENV=prod' \
-e 'DATABASE_URL=$(DB_URL)'
ifeq ($(SYSTEM), Linux)
BLOCKSCOUT_CONTAINNER_PARAMS += --network=host
endif
ifdef ETHEREUM_JSONRPC_VARIANT
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_VARIANT=$(ETHEREUM_JSONRPC_VARIANT)'
endif
ifdef ETHEREUM_JSONRPC_HTTP_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_HTTP_URL=$(ETHEREUM_JSONRPC_HTTP_URL)'
endif
ifdef ETHEREUM_JSONRPC_WS_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_WS_URL=$(ETHEREUM_JSONRPC_WS_URL)'
endif
ifdef ETHEREUM_JSONRPC_TRACE_URL
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'ETHEREUM_JSONRPC_TRACE_URL=$(ETHEREUM_JSONRPC_TRACE_URL)'
endif
ifdef COIN
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'COIN=$(COIN)'
endif
ifdef LOGO
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'LOGO=$(LOGO)'
endif
ifdef NETWORK
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK=$(NETWORK)'
endif
ifdef SUBNETWORK
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'SUBNETWORK=$(SUBNETWORK)'
endif
ifdef NETWORK_ICON
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK_ICON=$(NETWORK_ICON)'
endif
ifdef NETWORK_PATH
BLOCKSCOUT_CONTAINNER_PARAMS += -e 'NETWORK_PATH=$(NETWORK_PATH)'
endif
HAS_BLOCKSCOUT_IMAGE := $(shell docker images | grep ${DOCKER_IMAGE})
build:
@echo "==> Checking for blockscout image $(DOCKER_IMAGE)"
ifdef HAS_BLOCKSCOUT_IMAGE
@echo "==> Image exist. Using $(DOCKER_IMAGE)"
else
@echo "==> No image found trying to build one..."
@docker build -f ./Dockerfile -t $(DOCKER_IMAGE) ../
endif
migrate: build postgres
@echo "==> Running migrations"
@docker run --rm \
$(BLOCKSCOUT_CONTAINNER_PARAMS) \
$(DOCKER_IMAGE) /bin/sh -c "echo $$MIX_ENV && mix do ecto.drop --force, ecto.create, ecto.migrate"
PG_EXIST := $(shell docker ps -a | grep ${PG_CONTAINER_NAME})
PG_STARTED := $(shell docker ps | grep ${PG_CONTAINER_NAME})
postgres:
ifdef PG_EXIST
@echo "==> Checking PostrgeSQL container"
ifdef PG_STARTED
@echo "==> PostgreSQL Already started"
else
@echo "==> Starting PostgreSQL container"
@docker start $(PG_CONTAINER_NAME)
endif
else
@echo "==> Creating new PostgreSQL container"
@docker run -d --name $(PG_CONTAINER_NAME) \
-e POSTGRES_PASSWORD="" \
-e POSTGRES_USER="postgres" \
-p 5432:5432 \
$(PG_CONTAINER_IMAGE)
@sleep 1
@$(MAKE) -f $(THIS_FILE) migrate
endif
start: build postgres
@echo "==> Starting blockscout"
@docker run --rm \
$(BLOCKSCOUT_CONTAINNER_PARAMS) \
-p 4000:4000 \
$(DOCKER_IMAGE) /bin/sh -c "mix phx.server"
run: start
.PHONY: build \
migrate \
start \
postgres \
run

@ -0,0 +1,77 @@
# BlockScout Docker integration
For now this integration is not production ready. It made only for local usage only !
## How to use ?
First of all blockscout requires `PostgreSQL` server for working.
It will be provided by starting script (new docker image will be created named `postgres`)
**Starting command**
`make start` - will set everything up and start blockscout in container.
To connect it to your local environment you will have to configure it using [env variables](#env-variables)
Exmaple connecting to local `ganache` instance running on port `2000` on Mac/Windows:
```bash
COIN=DAI \
ETHEREUM_JSONRPC_VARIANT=ganache \
ETHEREUM_JSONRPC_HTTP_URL=http://host.docker.internal:2000 \
ETHEREUM_JSONRPC_WEB_SOCKET_URL=ws://host.docker.internal:2000 \
make start
```
Blockscout will be available on `localhost:4000`
**Note**
On mac/Windows Docker provides with a special URL `host.docker.internal` that will be available into container and routed to your local machine.
On Linux docker is starting using `--network=host` and all services should be available on `localhost`
### Migrations
By default `Makefile` will do migrations for you on `PostgreSQL` creation.
But you could run migrations manualy using `make migrate` command.
**WARNING** Migrations will clean up your local database !
## Env variables
BlockScout support 3 different JSON RPC Variants.
Vriant could be configured using `ETHEREUM_JSONRPC_VARIANT` environment variable.
Example:
```bash
ETHEREUM_JSONRPC_VARIANT=ganache make start
```
Available options are:
* `parity` - Parity JSON RPC (**Default one**)
* `geth` - Geth JSON RPC
* `ganache` - Ganache JSON RPC
| Variable | Description | Default value |
| -------- | ----------- | ------------- |
| `ETHEREUM_JSONRPC_VARIANT` | Variant of your JSON RPC service: `parity`, `geth` or `ganache` | `parity` |
| `ETHEREUM_JSONRPC_HTTP_URL` | HTTP JSON RPC URL Only for `geth` or `ganache` variant | Different per JSONRPC variant |
| `ETHEREUM_JSONRPC_WS_URL` | WS JSON RPC url | Different per JSONRPC variant |
| `ETHEREUM_JSONRPC_TRACE_URL` | Trace URL **Only for `parity` variant** | `https://sokol-trace.poa.network` |
| `COIN` | Default Coin | `POA` |
| `LOGO` | Coin logo | Empty |
| `NETWORK` | Network | Empty |
| `SUBNETWORK` | Subnetwork | Empty |
| `NETWORK_ICON` | Network icon | Empty |
| `NETWORK_PATH` | Network path | `/` |
`ETHEREUM_JSONRPC_HTTP_URL` default values:
* For `parity` - `https://sokol.poa.network`
* For `geth` - `https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY`
* For `ganache` - `http://localhost:7545`
`ETHEREUM_JSONRPC_WS_URL` default values:
* For `parity` - `wss://sokol-ws.poa.network/ws`
* For `geth` - `wss://mainnet.infura.io/8lTvJTKmHPCHazkneJsY/ws`
* For `ganache` - `ws://localhost:7545`
Loading…
Cancel
Save