From eff839f1c4f215cd9aa3c87d607bb1c8ca676dde Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 15 Jul 2019 15:53:55 +0300 Subject: [PATCH 1/3] add default evm version to smart contract verification --- .../new.html.eex | 2 +- apps/explorer/config/config.exs | 2 +- apps/explorer/priv/compile_solc.js | 25 +++++++++++-------- .../solidity/code_compiler_test.exs | 20 +++++++++++++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex index fd93b0af2b..e73e1434f0 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex @@ -50,7 +50,7 @@
<%= label :evm_version, :evm_version, gettext("EVM Version") %>
- <%= select f, :evm_version, @evm_versions, class: "form-control border-rounded", selected: "petersburg", "aria-describedby": "evm-version-help-block" %> + <%= select f, :evm_version, @evm_versions, class: "form-control border-rounded", selected: "default", "aria-describedby": "evm-version-help-block" %>
The EVM version the contract is written for. If the bytecode does not match the version, we try to verify using the latest EVM version. EVM version details.
diff --git a/apps/explorer/config/config.exs b/apps/explorer/config/config.exs index 65528753eb..defd5ae9e5 100644 --- a/apps/explorer/config/config.exs +++ b/apps/explorer/config/config.exs @@ -12,7 +12,7 @@ config :explorer, token_functions_reader_max_retries: 3, allowed_evm_versions: System.get_env("ALLOWED_EVM_VERSIONS") || - "homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople,petersburg", + "homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople,petersburg,default", include_uncles_in_average_block_time: if(System.get_env("UNCLES_IN_AVERAGE_BLOCK_TIME") == "false", do: false, else: true), healthy_blocks_period: System.get_env("HEALTHY_BLOCKS_PERIOD") || :timer.minutes(5) diff --git a/apps/explorer/priv/compile_solc.js b/apps/explorer/priv/compile_solc.js index 99048d9ffd..e6ba69c300 100755 --- a/apps/explorer/priv/compile_solc.js +++ b/apps/explorer/priv/compile_solc.js @@ -16,15 +16,7 @@ var solc = solc.setupMethods(compilerSnapshot); var fs = require('fs'); var sourceCode = fs.readFileSync(sourceCodePath, 'utf8'); -const input = { - language: 'Solidity', - sources: { - [newContractName]: { - content: sourceCode - } - }, - settings: { - evmVersion: evmVersion, +var settings = { optimizer: { enabled: optimize == '1', runs: optimizationRuns @@ -37,7 +29,20 @@ const input = { '*': ['*'] } } - } +} + +if (evmVersion !== 'default') { + settings = Object.assign(settings, {evmVersion: evmVersion}) +} + +const input = { + language: 'Solidity', + sources: { + [newContractName]: { + content: sourceCode + } + }, + settings: settings } diff --git a/apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs b/apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs index d1c1d04b45..29674274ca 100644 --- a/apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs +++ b/apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs @@ -53,6 +53,26 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do }} = response end + test "compiles smart contract with default evm version", %{contract_code_info: contract_code_info} do + optimize = true + + response = + CodeCompiler.run( + name: contract_code_info.name, + compiler_version: contract_code_info.version, + code: contract_code_info.source_code, + optimize: optimize, + evm_version: "default" + ) + + assert {:ok, + %{ + "abi" => _, + "bytecode" => _, + "name" => _ + }} = response + end + test "compiles code with external libraries" do Enum.each(@compiler_tests, fn compiler_test -> compiler_version = compiler_test["compiler_version"] From aec8b8fccde5982f212e1e477ad224690b5de7d8 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 15 Jul 2019 15:58:32 +0300 Subject: [PATCH 2/3] add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a8a58beef..1399ca1fc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#2360](https://github.com/poanetwork/blockscout/pull/2360) - add default evm version to smart contract verification - [#2294](https://github.com/poanetwork/blockscout/pull/2294) - add healthy block period checking endpoint ### Fixes From 6615e8593c36d789b0b73e0f76b1dde7b0d19b9e Mon Sep 17 00:00:00 2001 From: pasqu4le Date: Wed, 17 Jul 2019 15:20:14 +0200 Subject: [PATCH 3/3] Update created_contract_code_indexed_at on transaction import conflict Problem: a transaction created_contract_code_indexed_at gets ignored during a conflicting update, so it is not updated. In particular it is not reset to NULL and this has been source of errors. Solution: add it as a field to check and update during an import with conflict. --- CHANGELOG.md | 1 + .../chain/import/runner/transactions.ex | 4 +- .../chain/import/runner/transactions_test.exs | 50 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 apps/explorer/test/explorer/chain/import/runner/transactions_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cd9165b22..484ebcdcb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [#2294](https://github.com/poanetwork/blockscout/pull/2294) - add healthy block period checking endpoint ### Fixes +- [#2375](https://github.com/poanetwork/blockscout/pull/2375) - Update created_contract_code_indexed_at on transaction import conflict - [#2346](https://github.com/poanetwork/blockscout/pull/2346) - Avoid fetching internal transactions of blocks that still need refetching - [#2350](https://github.com/poanetwork/blockscout/pull/2350) - fix invalid User agent headers - [#2345](https://github.com/poanetwork/blockscout/pull/2345) - do not override existing market records diff --git a/apps/explorer/lib/explorer/chain/import/runner/transactions.ex b/apps/explorer/lib/explorer/chain/import/runner/transactions.ex index 2c36d7c7e5..570d934218 100644 --- a/apps/explorer/lib/explorer/chain/import/runner/transactions.ex +++ b/apps/explorer/lib/explorer/chain/import/runner/transactions.ex @@ -105,6 +105,7 @@ defmodule Explorer.Chain.Import.Runner.Transactions do old_block_hash: transaction.block_hash, block_number: fragment("EXCLUDED.block_number"), created_contract_address_hash: fragment("EXCLUDED.created_contract_address_hash"), + created_contract_code_indexed_at: fragment("EXCLUDED.created_contract_code_indexed_at"), cumulative_gas_used: fragment("EXCLUDED.cumulative_gas_used"), error: fragment("EXCLUDED.error"), from_address_hash: fragment("EXCLUDED.from_address_hash"), @@ -128,10 +129,11 @@ defmodule Explorer.Chain.Import.Runner.Transactions do ], where: fragment( - "(EXCLUDED.block_hash, EXCLUDED.block_number, EXCLUDED.created_contract_address_hash, EXCLUDED.cumulative_gas_used, EXCLUDED.cumulative_gas_used, EXCLUDED.from_address_hash, EXCLUDED.gas, EXCLUDED.gas_price, EXCLUDED.gas_used, EXCLUDED.index, EXCLUDED.internal_transactions_indexed_at, EXCLUDED.input, EXCLUDED.nonce, EXCLUDED.r, EXCLUDED.s, EXCLUDED.status, EXCLUDED.to_address_hash, EXCLUDED.v, EXCLUDED.value) IS DISTINCT FROM (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + "(EXCLUDED.block_hash, EXCLUDED.block_number, EXCLUDED.created_contract_address_hash, EXCLUDED.created_contract_code_indexed_at, EXCLUDED.cumulative_gas_used, EXCLUDED.cumulative_gas_used, EXCLUDED.from_address_hash, EXCLUDED.gas, EXCLUDED.gas_price, EXCLUDED.gas_used, EXCLUDED.index, EXCLUDED.internal_transactions_indexed_at, EXCLUDED.input, EXCLUDED.nonce, EXCLUDED.r, EXCLUDED.s, EXCLUDED.status, EXCLUDED.to_address_hash, EXCLUDED.v, EXCLUDED.value) IS DISTINCT FROM (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", transaction.block_hash, transaction.block_number, transaction.created_contract_address_hash, + transaction.created_contract_code_indexed_at, transaction.cumulative_gas_used, transaction.cumulative_gas_used, transaction.from_address_hash, diff --git a/apps/explorer/test/explorer/chain/import/runner/transactions_test.exs b/apps/explorer/test/explorer/chain/import/runner/transactions_test.exs new file mode 100644 index 0000000000..2bfea8750b --- /dev/null +++ b/apps/explorer/test/explorer/chain/import/runner/transactions_test.exs @@ -0,0 +1,50 @@ +defmodule Explorer.Chain.Import.Runner.TransactionsTest do + use Explorer.DataCase + + alias Ecto.Multi + alias Explorer.Chain.{Address, Transaction} + alias Explorer.Chain.Import.Runner.Transactions + + describe "run/1" do + test "transaction's created_contract_code_indexed_at is modified on update" do + %Address{hash: address_hash} = insert(:address) + + transaction = + insert(:transaction, + created_contract_address_hash: address_hash, + created_contract_code_indexed_at: DateTime.utc_now() + ) + + assert not is_nil(transaction.created_contract_code_indexed_at) + + non_indexed_transaction_params = %{ + from_address_hash: transaction.from_address.hash, + gas: transaction.gas, + gas_price: transaction.gas_price, + hash: transaction.hash, + input: transaction.input, + nonce: transaction.nonce, + r: transaction.r, + s: transaction.s, + to_address_hash: transaction.to_address.hash, + v: transaction.v, + value: transaction.value, + created_contract_address_hash: address_hash, + created_contract_code_indexed_at: nil + } + + assert {:ok, _} = run_transactions([non_indexed_transaction_params]) + + assert is_nil(Repo.get(Transaction, transaction.hash).created_contract_code_indexed_at) + end + end + + defp run_transactions(changes_list) when is_list(changes_list) do + Multi.new() + |> Transactions.run(changes_list, %{ + timeout: :infinity, + timestamps: %{inserted_at: DateTime.utc_now(), updated_at: DateTime.utc_now()} + }) + |> Repo.transaction() + end +end