diff --git a/CHANGELOG.md b/CHANGELOG.md index e450270bee..fe08ece2dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,12 @@ ### Features - [#2366](https://github.com/poanetwork/blockscout/pull/2366) - paginate eth logs +- [#2360](https://github.com/poanetwork/blockscout/pull/2360) - add default evm version to smart contract verification - [#2352](https://github.com/poanetwork/blockscout/pull/2352) - Fetch rewards in parallel with transactions - [#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/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/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/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/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 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"]