diff --git a/CHANGELOG.md b/CHANGELOG.md
index 00cf765d8c..7b8920de99 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,9 @@
## Current
### Features
-
-- [#1895](https://github.com/poanetwork/blockscout/pull/1874) - add changes to poa theme and poa logo
+- [#1907](https://github.com/poanetwork/blockscout/pull/1907) - dropdown color bug fix (lukso theme) and tooltip color bug fix
+- [#1903](https://github.com/poanetwork/blockscout/pull/1903) - added rsk theme and rsk logo
+- [#1895](https://github.com/poanetwork/blockscout/pull/1895) - add changes to poa theme and poa logo
- [#1812](https://github.com/poanetwork/blockscout/pull/1812) - add pagination to addresses page
- [#1874](https://github.com/poanetwork/blockscout/pull/1874) - add changes to ethereum theme and ethereum logo
- [#1815](https://github.com/poanetwork/blockscout/pull/1815) - able to search without prefix "0x"
@@ -24,12 +25,16 @@
- [#1885](https://github.com/poanetwork/blockscout/pull/1885) - highlight reserved words in decompiled code
- [#1896](https://github.com/poanetwork/blockscout/pull/1896) - re-query tokens in top nav automplete
- [#1881](https://github.com/poanetwork/blockscout/pull/1881) - fix: store solc versions locally for performance
+- [#1875](https://github.com/poanetwork/blockscout/pull/1875) - fix: resolve false positive constructor arguments
+- [#1904](https://github.com/poanetwork/blockscout/pull/1904) - fix `BLOCK_COUNT_CACHE_TTL` env var type
+- [#1898](https://github.com/poanetwork/blockscout/pull/1898) - check if the constructor has arguments before verifying constructor arguments
### Chore
- [#1814](https://github.com/poanetwork/blockscout/pull/1814) - Clear build artefacts script
- [#1837](https://github.com/poanetwork/blockscout/pull/1837) - Add -f flag to clear_build.sh script delete static folder
- [#1900](https://github.com/poanetwork/blockscout/pull/1900) - SUPPORTED_CHAINS ENV var
+- [#1892](https://github.com/poanetwork/blockscout/pull/1892) - Remove temporary worker modules
## 1.3.10-beta
diff --git a/README.md b/README.md
index 289a3d35ed..9755475dbe 100644
--- a/README.md
+++ b/README.md
@@ -65,6 +65,7 @@ Currently available block explorers (i.e. Etherscan and Etherchain) are closed s
* [SpringChain](https://explorer.springrole.com/)
* [PIRL](http://pirl.es/)
* [Petrichor](https://explorer.petrichor-dev.com/)
+* [Ether-1](https://blocks.ether1.wattpool.net/)
### Visual Interface
diff --git a/apps/block_scout_web/assets/css/components/_tooltip.scss b/apps/block_scout_web/assets/css/components/_tooltip.scss
index 1cd7797785..4c845a7c1c 100644
--- a/apps/block_scout_web/assets/css/components/_tooltip.scss
+++ b/apps/block_scout_web/assets/css/components/_tooltip.scss
@@ -14,5 +14,6 @@ $tooltip-color: #fff !default;
.arrow::before {
border-top-color: $tooltip-background-color;
+ border-bottom-color: $tooltip-background-color;
}
}
diff --git a/apps/block_scout_web/assets/css/theme/_lukso_variables.scss b/apps/block_scout_web/assets/css/theme/_lukso_variables.scss
index a09049e7c8..c1d8d630f9 100644
--- a/apps/block_scout_web/assets/css/theme/_lukso_variables.scss
+++ b/apps/block_scout_web/assets/css/theme/_lukso_variables.scss
@@ -12,7 +12,7 @@ $dashboard-stats-item-value-color: $primary;
$dashboard-stats-item-border-color: $primary;
$header-links-color-active: #333;
-
+.dropdown-item:hover, .dropdown-item:focus { background-color: $primary !important; }
$tile-type-block-color: $secondary;
$navbar-logo-height: 18px;
diff --git a/apps/block_scout_web/assets/css/theme/_rsk_variables.scss b/apps/block_scout_web/assets/css/theme/_rsk_variables.scss
new file mode 100644
index 0000000000..c357f0f571
--- /dev/null
+++ b/apps/block_scout_web/assets/css/theme/_rsk_variables.scss
@@ -0,0 +1,50 @@
+// general
+$primary: #101f25;
+$secondary: #27ac8d;
+$tertiary: #e39a54;
+$additional-font: #a1ded1;
+
+// footer
+$footer-background-color: $primary;
+$footer-title-color: #fff;
+$footer-text-color: $additional-font;
+$footer-item-disc-color: $secondary;
+.footer-logo { filter: brightness(0) invert(1); }
+
+// dashboard
+$dashboard-line-color-price: $tertiary; // price left border
+
+$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
+
+$dashboard-stats-item-value-color: $additional-font; // stat values
+
+$dashboard-stats-item-border-color: $secondary; // stat border
+
+$dashboard-banner-gradient-start: $primary; // gradient begin
+
+$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end
+
+$dashboard-banner-network-plain-container-background-color: #1a323b; // stats bg
+
+
+// navigation
+.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
+$header-icon-border-color-hover: $secondary; // top border on hover
+$header-icon-color-hover: $secondary; // nav icon on hover
+.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
+
+// buttons
+$btn-line-bg: #fff; // button bg
+$btn-line-color: $secondary; // button border and font color && hover bg color
+$btn-copy-color: $secondary; // btn copy
+$btn-qr-color: $secondary; // btn qr-code
+
+//links & tile
+.tile a { color: $secondary !important; } // links color for badges
+.tile-type-block {
+ border-left: 4px solid $secondary;
+} // tab active bg
+
+// card
+$card-background-1: $secondary;
+$card-tab-active: $secondary;
\ No newline at end of file
diff --git a/apps/block_scout_web/assets/static/images/rsk_logo.svg b/apps/block_scout_web/assets/static/images/rsk_logo.svg
new file mode 100644
index 0000000000..8502c921e5
--- /dev/null
+++ b/apps/block_scout_web/assets/static/images/rsk_logo.svg
@@ -0,0 +1,47 @@
+
diff --git a/apps/explorer/config/config.exs b/apps/explorer/config/config.exs
index ace69884ea..f40e10371b 100644
--- a/apps/explorer/config/config.exs
+++ b/apps/explorer/config/config.exs
@@ -82,7 +82,8 @@ config :spandex_ecto, SpandexEcto.EctoLogger,
tracer: Explorer.Tracer,
otp_app: :explorer
-config :explorer, Explorer.Chain.BlockCountCache, ttl: System.get_env("BLOCK_COUNT_CACHE_TTL")
+config :explorer, Explorer.Chain.BlockCountCache,
+ ttl: System.get_env("BLOCK_COUNT_CACHE_TTL") && String.to_integer(System.get_env("BLOCK_COUNT_CACHE_TTL"))
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
diff --git a/apps/explorer/lib/explorer/chain/block_count_cache.ex b/apps/explorer/lib/explorer/chain/block_count_cache.ex
index 7c900bfedd..84f016dd44 100644
--- a/apps/explorer/lib/explorer/chain/block_count_cache.ex
+++ b/apps/explorer/lib/explorer/chain/block_count_cache.ex
@@ -6,8 +6,8 @@ defmodule Explorer.Chain.BlockCountCache do
alias Explorer.Chain
@tab :block_count_cache
- # 1 minutes
- @cache_period 1_000 * 60
+ # 10 minutes
+ @cache_period 1_000 * 60 * 10
@key "count"
@opts_key "opts"
diff --git a/apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex b/apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex
index 72c5bae186..656f1b9734 100644
--- a/apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex
+++ b/apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex
@@ -5,6 +5,8 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
alias Explorer.SmartContract.SolcDownloader
+ require Logger
+
@new_contract_name "New.sol"
@allowed_evm_versions ["homestead", "tangerineWhistle", "spuriousDragon", "byzantium", "constantinople", "petersburg"]
@@ -63,6 +65,7 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
}
}
"""
+ @spec run(Keyword.t()) :: {:ok, map} | {:error, :compilation | :name}
def run(params) do
name = Keyword.fetch!(params, :name)
compiler_version = Keyword.fetch!(params, :compiler_version)
@@ -100,7 +103,8 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
]
)
- with {:ok, contracts} <- Jason.decode(response),
+ with {:ok, decoded} <- Jason.decode(response),
+ {:ok, contracts} <- get_contracts(decoded),
%{"abi" => abi, "evm" => %{"deployedBytecode" => %{"object" => bytecode}}} <-
get_contract_info(contracts, name) do
{:ok, %{"abi" => abi, "bytecode" => bytecode, "name" => name}}
@@ -108,9 +112,16 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
{:error, %Jason.DecodeError{}} ->
{:error, :compilation}
+ {:error, reason} when reason in [:name, :compilation] ->
+ {:error, reason}
+
error ->
- parse_error(error)
+ error = parse_error(error)
+ Logger.warn(["There was an error compiling a provided contract: ", inspect(error)])
+ {:error, :compilation}
end
+ else
+ {:error, :compilation}
end
end
@@ -133,10 +144,15 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
end
end
- def parse_error(%{"error" => error}), do: {:error, [error]}
- def parse_error(%{"errors" => errors}), do: {:error, errors}
+ def parse_error({:error, %{"error" => error}}), do: {:error, [error]}
+ def parse_error({:error, %{"errors" => errors}}), do: {:error, errors}
def parse_error({:error, _} = error), do: error
+ # Older solc-bin versions don't use filename as contract key
+ defp get_contracts(%{"contracts" => %{"New.sol" => contracts}}), do: {:ok, contracts}
+ defp get_contracts(%{"contracts" => %{"" => contracts}}), do: {:ok, contracts}
+ defp get_contracts(response), do: {:error, response}
+
defp optimize_value(false), do: "0"
defp optimize_value("false"), do: "0"
diff --git a/apps/explorer/lib/explorer/smart_contract/verifier.ex b/apps/explorer/lib/explorer/smart_contract/verifier.ex
index 0fc9f6b21b..e72324f154 100644
--- a/apps/explorer/lib/explorer/smart_contract/verifier.ex
+++ b/apps/explorer/lib/explorer/smart_contract/verifier.ex
@@ -74,7 +74,7 @@ defmodule Explorer.SmartContract.Verifier do
generated_bytecode != blockchain_bytecode_without_whisper ->
{:error, :generated_bytecode}
- !ConstructorArguments.verify(address_hash, arguments_data) ->
+ has_constructor_with_params?(abi) && !ConstructorArguments.verify(address_hash, arguments_data) ->
{:error, :constructor_arguments}
true ->
@@ -86,17 +86,32 @@ defmodule Explorer.SmartContract.Verifier do
In order to discover the bytecode we need to remove the `swarm source` from
the hash.
- `64` characters to the left of `0029` are the `swarm source`. The rest on
- the left is the `bytecode` to be validated.
+ For more information on the swarm hash, check out:
+ https://solidity.readthedocs.io/en/v0.5.3/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode
"""
+ def extract_bytecode("0x" <> code) do
+ "0x" <> extract_bytecode(code)
+ end
+
def extract_bytecode(code) do
- {bytecode, _swarm_source} =
- code
- |> String.split("0029")
- |> List.first()
- |> String.split_at(-64)
+ do_extract_bytecode([], String.downcase(code))
+ end
+
+ defp do_extract_bytecode(extracted, remaining) do
+ case remaining do
+ <<>> ->
+ extracted
+ |> Enum.reverse()
+ |> :binary.list_to_bin()
- bytecode
+ "a165627a7a72305820" <> <<_::binary-size(64)>> <> "0029" <> _constructor_arguments ->
+ extracted
+ |> Enum.reverse()
+ |> :binary.list_to_bin()
+
+ <> <> rest ->
+ do_extract_bytecode([next | extracted], rest)
+ end
end
def next_evm_version(current_evm_version) do
@@ -111,4 +126,8 @@ defmodule Explorer.SmartContract.Verifier do
prev_version
end
end
+
+ defp has_constructor_with_params?(abi) do
+ Enum.any?(abi, fn el -> el["type"] == "constructor" && el["inputs"] != [] end)
+ end
end
diff --git a/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex b/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
index b60bd01927..aa32d85bb6 100644
--- a/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
+++ b/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
@@ -7,20 +7,21 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
def verify(address_hash, arguments_data) do
arguments_data = String.replace(arguments_data, "0x", "")
- creation_input_data = Chain.contract_creation_input_data(address_hash)
- data_with_swarm =
- creation_input_data
- |> String.split("0029")
- |> List.first()
- |> Kernel.<>("0029")
+ address_hash
+ |> Chain.contract_creation_input_data()
+ |> String.replace("0x", "")
+ |> extract_constructor_arguments()
+ |> Kernel.==(arguments_data)
+ end
+
+ defp extract_constructor_arguments(<<>>), do: ""
- expected_arguments_data =
- creation_input_data
- |> String.split(data_with_swarm)
- |> List.last()
- |> String.replace("0x", "")
+ defp extract_constructor_arguments("a165627a7a72305820" <> <<_::binary-size(64)>> <> "0029" <> constructor_arguments) do
+ constructor_arguments
+ end
- expected_arguments_data == arguments_data
+ defp extract_constructor_arguments(<<_::binary-size(2)>> <> rest) do
+ extract_constructor_arguments(rest)
end
end
diff --git a/apps/explorer/priv/compile_solc.js b/apps/explorer/priv/compile_solc.js
index 5aaf3f54d7..eea727802e 100755
--- a/apps/explorer/priv/compile_solc.js
+++ b/apps/explorer/priv/compile_solc.js
@@ -39,6 +39,4 @@ const input = {
const output = JSON.parse(solc.compile(JSON.stringify(input)))
-/** Older solc-bin versions don't use filename as contract key */
-const response = output.contracts[newContractName] || output.contracts['']
-console.log(JSON.stringify(response));
+console.log(JSON.stringify(output));
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 79bbb62f70..57f15577ac 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
@@ -173,6 +173,101 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
assert {:error, :compilation} = response
end
+
+ test "returns constructor in abi" do
+ code = """
+ pragma solidity ^0.4.22;
+
+ contract OwnedToken {
+ // TokenCreator is a contract type that is defined below.
+ // It is fine to reference it as long as it is not used
+ // to create a new contract.
+ TokenCreator creator;
+ address owner;
+ bytes32 name;
+
+ // This is the constructor which registers the
+ // creator and the assigned name.
+ constructor(bytes32 _name) public {
+ // State variables are accessed via their name
+ // and not via e.g. this.owner. This also applies
+ // to functions and especially in the constructors,
+ // you can only call them like that ("internally"),
+ // because the contract itself does not exist yet.
+ owner = msg.sender;
+ // We do an explicit type conversion from `address`
+ // to `TokenCreator` and assume that the type of
+ // the calling contract is TokenCreator, there is
+ // no real way to check that.
+ creator = TokenCreator(msg.sender);
+ name = _name;
+ }
+
+ function changeName(bytes32 newName) public {
+ // Only the creator can alter the name --
+ // the comparison is possible since contracts
+ // are implicitly convertible to addresses.
+ if (msg.sender == address(creator))
+ name = newName;
+ }
+
+ function transfer(address newOwner) public {
+ // Only the current owner can transfer the token.
+ if (msg.sender != owner) return;
+ // We also want to ask the creator if the transfer
+ // is fine. Note that this calls a function of the
+ // contract defined below. If the call fails (e.g.
+ // due to out-of-gas), the execution here stops
+ // immediately.
+ if (creator.isTokenTransferOK(owner, newOwner))
+ owner = newOwner;
+ }
+ }
+
+ contract TokenCreator {
+ function createToken(bytes32 name)
+ public
+ returns (OwnedToken tokenAddress)
+ {
+ // Create a new Token contract and return its address.
+ // From the JavaScript side, the return type is simply
+ // `address`, as this is the closest type available in
+ // the ABI.
+ return new OwnedToken(name);
+ }
+
+ function changeName(OwnedToken tokenAddress, bytes32 name) public {
+ // Again, the external type of `tokenAddress` is
+ // simply `address`.
+ tokenAddress.changeName(name);
+ }
+
+ function isTokenTransferOK(address currentOwner, address newOwner)
+ public
+ view
+ returns (bool ok)
+ {
+ // Check some arbitrary condition.
+ address tokenAddress = msg.sender;
+ return (keccak256(newOwner) & 0xff) == (bytes20(tokenAddress) & 0xff);
+ }
+ }
+ """
+
+ name = "OwnedToken"
+ compiler_version = "v0.4.22+commit.4cb486ee"
+
+ {:ok, %{"abi" => abi}} =
+ CodeCompiler.run(
+ name: name,
+ compiler_version: compiler_version,
+ code: code,
+ evm_version: "byzantium",
+ optimize: true
+ )
+
+ assert Enum.any?(abi, fn el -> el["type"] == "constructor" end)
+ end
end
describe "get_contract_info/1" do
diff --git a/apps/explorer/test/explorer/smart_contract/verifier/constructor_arguments_test.exs b/apps/explorer/test/explorer/smart_contract/verifier/constructor_arguments_test.exs
index 9fe219719d..a5e019c86f 100644
--- a/apps/explorer/test/explorer/smart_contract/verifier/constructor_arguments_test.exs
+++ b/apps/explorer/test/explorer/smart_contract/verifier/constructor_arguments_test.exs
@@ -7,17 +7,19 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArgumentsTest do
alias Explorer.SmartContract.Verifier.ConstructorArguments
test "veriies constructor constructor arguments with whisper data" do
- constructor_arguments = "0x0405"
+ constructor_arguments = Base.encode16(:crypto.strong_rand_bytes(64), case: :lower)
address = insert(:address)
- input = %Data{
- bytes:
- <<1, 2, 3, 93, 148, 60, 87, 91, 232, 162, 174, 226, 187, 119, 55, 167, 101, 253, 210, 198, 228, 155, 116, 205,
- 44, 146, 171, 15, 168, 228, 40, 45, 26, 117, 174, 0, 41, 4, 5>>
+ input =
+ "a165627a7a72305820" <>
+ Base.encode16(:crypto.strong_rand_bytes(32), case: :lower) <> "0029" <> constructor_arguments
+
+ input_data = %Data{
+ bytes: Base.decode16!(input, case: :lower)
}
:transaction
- |> insert(created_contract_address_hash: address.hash, input: input)
+ |> insert(created_contract_address_hash: address.hash, input: input_data)
|> with_block()
assert ConstructorArguments.verify(address.hash, constructor_arguments)
diff --git a/apps/explorer/test/explorer/smart_contract/verifier_test.exs b/apps/explorer/test/explorer/smart_contract/verifier_test.exs
index 631c15695e..ef635c2573 100644
--- a/apps/explorer/test/explorer/smart_contract/verifier_test.exs
+++ b/apps/explorer/test/explorer/smart_contract/verifier_test.exs
@@ -117,31 +117,6 @@ defmodule Explorer.SmartContract.VerifierTest do
assert abi != nil
end
- test "returns error when constructor arguments do not match", %{
- contract_code_info: contract_code_info
- } do
- contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)
-
- constructor_arguments = "0102030405"
-
- params = %{
- "contract_source_code" => contract_code_info.source_code,
- "compiler_version" => contract_code_info.version,
- "name" => contract_code_info.name,
- "optimization" => contract_code_info.optimized,
- "constructor_arguments" => constructor_arguments
- }
-
- :transaction
- |> insert(
- created_contract_address_hash: contract_address.hash,
- input: Verifier.extract_bytecode(contract_code_info.bytecode) <> "010203"
- )
- |> with_block()
-
- assert {:error, :constructor_arguments} = Verifier.evaluate_authenticity(contract_address.hash, params)
- end
-
test "returns error when bytecode doesn't match", %{contract_code_info: contract_code_info} do
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)
@@ -181,7 +156,7 @@ defmodule Explorer.SmartContract.VerifierTest do
swarm_source = "3c381c1b48b38d050c54d7ef296ecd411040e19420dfec94772b9c49ae106a0b"
bytecode =
- "0x608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a72305820"
+ "0x608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600"
assert bytecode == Verifier.extract_bytecode(code)
assert bytecode != code
@@ -189,5 +164,21 @@ defmodule Explorer.SmartContract.VerifierTest do
assert String.contains?(bytecode, "0029") == false
assert String.contains?(bytecode, swarm_source) == false
end
+
+ test "extracts everything to the left of the swarm hash" do
+ code =
+ "0x608060405234801561001057600080fd5b5060df80610010029f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a723058203c381c1b48b38d050c54d7ef296ecd411040e19420dfec94772b9c49ae106a0b0029"
+
+ swarm_source = "3c381c1b48b38d050c54d7ef296ecd411040e19420dfec94772b9c49ae106a0b"
+
+ bytecode =
+ "0x608060405234801561001057600080fd5b5060df80610010029f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600"
+
+ assert bytecode == Verifier.extract_bytecode(code)
+ assert bytecode != code
+ assert String.contains?(code, bytecode) == true
+ assert String.contains?(bytecode, "0029") == true
+ assert String.contains?(bytecode, swarm_source) == false
+ end
end
end
diff --git a/apps/indexer/README.md b/apps/indexer/README.md
index d0844c57d6..34fb6e6ef3 100644
--- a/apps/indexer/README.md
+++ b/apps/indexer/README.md
@@ -91,8 +91,6 @@ These workers are created for fetching information, which previously wasn't fetc
After all deployed instances get all needed data, these fetchers should be deprecated and removed.
- `uncataloged_token_transfers`: extracts token transfers from logs, which previously weren't parsed due to unknown format
-- `addresses_without_codes`: forces complete refetch of blocks, which have created contract addresses without contract code
-- `failed_created_addresses`: forces refetch of contract code for failed transactions, which previously got incorrectly overwritten
- `uncles_without_index`: adds previously unfetched `index` field for unfetched blocks in `block_second_degree_relations`
## Memory Usage
@@ -156,4 +154,3 @@ mix test --exclude no_geth
|:----------|:--------------------------------------------------|
| HTTP | `https://mainnet.infura.io/8lTvJTKmHPCHazkneJsY` |
| WebSocket | `wss://mainnet.infura.io/ws/8lTvJTKmHPCHazkneJsY` |
-
diff --git a/apps/indexer/lib/indexer/supervisor.ex b/apps/indexer/lib/indexer/supervisor.ex
index 375a17e669..21dc3637ec 100644
--- a/apps/indexer/lib/indexer/supervisor.ex
+++ b/apps/indexer/lib/indexer/supervisor.ex
@@ -24,8 +24,6 @@ defmodule Indexer.Supervisor do
}
alias Indexer.Temporary.{
- AddressesWithoutCode,
- FailedCreatedAddresses,
UncatalogedTokenTransfers,
UnclesWithoutIndex
}
@@ -80,12 +78,6 @@ defmodule Indexer.Supervisor do
|> Map.drop(~w(block_interval blocks_concurrency memory_monitor subscribe_named_arguments realtime_overrides)a)
|> Block.Fetcher.new()
- fixing_realtime_fetcher = %Block.Fetcher{
- broadcast: false,
- callback_module: Realtime.Fetcher,
- json_rpc_named_arguments: json_rpc_named_arguments
- }
-
realtime_block_fetcher =
named_arguments
|> Map.drop(~w(block_interval blocks_concurrency memory_monitor subscribe_named_arguments realtime_overrides)a)
@@ -130,8 +122,6 @@ defmodule Indexer.Supervisor do
{TokenUpdater.Supervisor, [%{update_interval: metadata_updater_inverval}]},
# Temporary workers
- {AddressesWithoutCode.Supervisor, [fixing_realtime_fetcher]},
- {FailedCreatedAddresses.Supervisor, [json_rpc_named_arguments]},
{UncatalogedTokenTransfers.Supervisor, [[]]},
{UnclesWithoutIndex.Supervisor,
[[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]}
diff --git a/apps/indexer/lib/indexer/temporary/addresses_without_code.ex b/apps/indexer/lib/indexer/temporary/addresses_without_code.ex
deleted file mode 100644
index 4aa36ce0b6..0000000000
--- a/apps/indexer/lib/indexer/temporary/addresses_without_code.ex
+++ /dev/null
@@ -1,147 +0,0 @@
-defmodule Indexer.Temporary.AddressesWithoutCode do
- @moduledoc """
- Temporary module to fetch contract code for addresses without it.
- """
-
- use GenServer
- use Indexer.Fetcher
-
- require Logger
-
- import Ecto.Query
-
- alias Explorer.Chain.{Address, Block, Transaction}
- alias Explorer.Repo
- alias Indexer.Block.Realtime.Fetcher
- alias Indexer.Temporary.AddressesWithoutCode.TaskSupervisor
-
- @task_options [max_concurrency: 3, timeout: :infinity]
- @batch_size 500
- @query_timeout :infinity
-
- def start_link([fetcher, gen_server_options]) do
- GenServer.start_link(__MODULE__, fetcher, gen_server_options)
- end
-
- @impl GenServer
- def init(fetcher) do
- schedule_work()
-
- {:ok, fetcher}
- end
-
- def schedule_work do
- Process.send_after(self(), :run, 1_000)
- end
-
- @impl GenServer
- def handle_info(:run, fetcher) do
- run(fetcher)
-
- {:noreply, fetcher}
- end
-
- def run(fetcher) do
- fix_transaction_without_to_address_and_created_contract_address(fetcher)
- fix_addresses_with_creation_transaction_but_without_code(fetcher)
- end
-
- def fix_transaction_without_to_address_and_created_contract_address(fetcher) do
- Logger.debug(
- [
- "Started fix_transaction_without_to_address_and_created_contract_address"
- ],
- fetcher: :addresses_without_code
- )
-
- query =
- from(block in Block,
- left_join: transaction in Transaction,
- on: block.hash == transaction.block_hash,
- where:
- is_nil(transaction.to_address_hash) and is_nil(transaction.created_contract_address_hash) and
- block.consensus == true and is_nil(transaction.error) and not is_nil(transaction.hash),
- distinct: block.hash
- )
-
- process_query(query, fetcher)
-
- Logger.debug(
- [
- "Started fix_transaction_without_to_address_and_created_contract_address"
- ],
- fetcher: :addresses_without_code
- )
- end
-
- def fix_addresses_with_creation_transaction_but_without_code(fetcher) do
- Logger.debug(
- [
- "Started fix_addresses_with_creation_transaction_but_without_code"
- ],
- fetcher: :addresses_without_code
- )
-
- second_query =
- from(block in Block,
- left_join: transaction in Transaction,
- on: transaction.block_hash == block.hash,
- left_join: address in Address,
- on: address.hash == transaction.created_contract_address_hash,
- where:
- not is_nil(transaction.block_hash) and not is_nil(transaction.created_contract_address_hash) and
- is_nil(address.contract_code) and
- block.consensus == true and is_nil(transaction.error) and not is_nil(transaction.hash),
- distinct: block.hash
- )
-
- process_query(second_query, fetcher)
-
- Logger.debug(
- [
- "Finished fix_addresses_with_creation_transaction_but_without_code"
- ],
- fetcher: :addresses_without_code
- )
- end
-
- defp process_query(query, fetcher) do
- query_stream = Repo.stream(query, max_rows: @batch_size, timeout: @query_timeout)
-
- stream =
- TaskSupervisor
- |> Task.Supervisor.async_stream_nolink(
- query_stream,
- fn block -> refetch_block(block, fetcher) end,
- @task_options
- )
-
- Repo.transaction(fn -> Stream.run(stream) end, timeout: @query_timeout)
- end
-
- def refetch_block(block, fetcher) do
- Logger.debug(
- [
- "Processing block #{to_string(block.hash)} #{block.number}"
- ],
- fetcher: :addresses_without_code
- )
-
- Fetcher.fetch_and_import_block(block.number, fetcher, false)
-
- Logger.debug(
- [
- "Finished processing block #{to_string(block.hash)} #{block.number}"
- ],
- fetcher: :addresses_without_code
- )
- rescue
- e ->
- Logger.debug(
- [
- "Failed to fetch block #{to_string(block.hash)} #{block.number} because of #{inspect(e)}"
- ],
- fetcher: :addresses_without_code
- )
- end
-end
diff --git a/apps/indexer/lib/indexer/temporary/failed_created_addresses.ex b/apps/indexer/lib/indexer/temporary/failed_created_addresses.ex
deleted file mode 100644
index a80cf657cd..0000000000
--- a/apps/indexer/lib/indexer/temporary/failed_created_addresses.ex
+++ /dev/null
@@ -1,132 +0,0 @@
-defmodule Indexer.Temporary.FailedCreatedAddresses do
- @moduledoc """
- Temporary module to fix internal transactions and their created transactions if a parent transaction has failed.
- """
- use GenServer
- use Indexer.Fetcher
-
- require Logger
-
- import Ecto.Query
-
- alias Explorer.Chain.{Address, Data, InternalTransaction, Transaction}
- alias Explorer.Repo
- alias Indexer.Fetcher.ContractCode
- alias Indexer.Temporary.FailedCreatedAddresses.TaskSupervisor
-
- @task_options [max_concurrency: 3, timeout: :infinity]
- @query_timeout :infinity
-
- def start_link([json_rpc_named_arguments, gen_server_options]) do
- GenServer.start_link(__MODULE__, json_rpc_named_arguments, gen_server_options)
- end
-
- @impl GenServer
- def init(json_rpc_named_arguments) do
- schedule_work()
-
- {:ok, json_rpc_named_arguments}
- end
-
- def schedule_work do
- Process.send_after(self(), :run, 1_000)
- end
-
- @impl GenServer
- def handle_info(:run, json_rpc_named_arguments) do
- run(json_rpc_named_arguments)
-
- {:noreply, json_rpc_named_arguments}
- end
-
- def run(json_rpc_named_arguments) do
- Logger.debug(
- [
- "Started query to fetch internal transactions that need to be fixed"
- ],
- fetcher: :failed_created_addresses
- )
-
- data = %Data{bytes: ""}
-
- query =
- from(t in Transaction,
- left_join: it in InternalTransaction,
- on: it.transaction_hash == t.hash,
- left_join: address in Address,
- on: address.hash == it.created_contract_address_hash,
- where: t.status == ^0 and not is_nil(it.created_contract_address_hash) and address.contract_code != ^data,
- distinct: t.hash
- )
-
- found_transactions = Repo.all(query, timeout: @query_timeout)
-
- Logger.debug(
- [
- "Finished query to fetch internal transactions that need to be fixed. Number of records is #{
- Enum.count(found_transactions)
- }"
- ],
- fetcher: :failed_created_addresses
- )
-
- TaskSupervisor
- |> Task.Supervisor.async_stream_nolink(
- found_transactions,
- fn transaction -> fix_internal_transaction(transaction, json_rpc_named_arguments) end,
- @task_options
- )
- |> Enum.to_list()
- end
-
- def fix_internal_transaction(transaction, json_rpc_named_arguments) do
- # credo:disable-for-next-line
- try do
- Logger.debug(
- [
- "Started fixing transaction #{to_string(transaction.hash)}"
- ],
- fetcher: :failed_created_addresses
- )
-
- transaction_with_internal_transactions = Repo.preload(transaction, [:internal_transactions])
-
- transaction_with_internal_transactions.internal_transactions
- |> Enum.filter(fn internal_transaction ->
- internal_transaction.created_contract_address_hash
- end)
- |> Enum.each(fn internal_transaction ->
- :ok =
- internal_transaction
- |> code_entry()
- |> ContractCode.run(json_rpc_named_arguments)
- end)
-
- Logger.debug(
- [
- "Finished fixing transaction #{to_string(transaction.hash)}"
- ],
- fetcher: :failed_created_addresses
- )
- rescue
- e ->
- Logger.debug(
- [
- "Failed fixing transaction #{to_string(transaction.hash)} because of #{inspect(e)}"
- ],
- fetcher: :failed_created_addresses
- )
- end
- end
-
- def code_entry(%InternalTransaction{
- block_number: block_number,
- created_contract_address_hash: %{bytes: created_contract_bytes}
- }) do
- [{block_number, created_contract_bytes, <<>>}]
- end
-
- def transaction_entry(%Transaction{hash: %{bytes: bytes}, index: index, block_number: block_number}) do
- [{block_number, bytes, index}]
- end
-end
diff --git a/apps/indexer/test/indexer/temporary/addresses_without_code_test.exs b/apps/indexer/test/indexer/temporary/addresses_without_code_test.exs
deleted file mode 100644
index 18efd3b557..0000000000
--- a/apps/indexer/test/indexer/temporary/addresses_without_code_test.exs
+++ /dev/null
@@ -1,389 +0,0 @@
-defmodule Indexer.Temporary.AddressesWithoutCodeTest do
- use Explorer.DataCase, async: false
- use EthereumJSONRPC.Case, async: false
-
- import Mox
-
- import Ecto.Query
-
- alias Explorer.Repo
- alias Explorer.Chain.{Address, Transaction}
- alias Indexer.Block.Fetcher
- alias Indexer.Block.Realtime.Fetcher, as: RealtimeFetcher
- alias Indexer.Fetcher.{CoinBalance, ContractCode, InternalTransaction, ReplacedTransaction, Token, TokenBalance}
- alias Indexer.Temporary.AddressesWithoutCode.Supervisor
-
- @moduletag capture_log: true
-
- setup :set_mox_global
-
- setup :verify_on_exit!
-
- describe "run/1" do
- setup %{json_rpc_named_arguments: json_rpc_named_arguments} do
- CoinBalance.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments)
- ContractCode.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments)
- InternalTransaction.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments)
- Token.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments)
- TokenBalance.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments)
- ReplacedTransaction.Supervisor.Case.start_supervised!()
-
- [name: Indexer.Block.Realtime.TaskSupervisor]
- |> Task.Supervisor.child_spec()
- |> ExUnit.Callbacks.start_supervised!()
-
- fetcher = %Fetcher{
- broadcast: false,
- callback_module: RealtimeFetcher,
- json_rpc_named_arguments: json_rpc_named_arguments
- }
-
- {:ok, %{fetcher: fetcher}}
- end
-
- @tag :no_parity
- @tag :no_geth
- test "refetches blocks setting created address and code", %{
- fetcher: %{json_rpc_named_arguments: json_rpc_named_arguments} = fetcher
- } do
- block = insert(:block, consensus: true)
-
- transaction =
- :transaction
- |> insert(
- status: 0,
- to_address: nil,
- created_contract_address_hash: nil,
- block: block,
- block_number: block.number,
- block_hash: block.hash,
- cumulative_gas_used: 200,
- gas_used: 100,
- index: 0
- )
-
- address = insert(:address, contract_code: nil)
-
- if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do
- EthereumJSONRPC.Mox
- |> expect(:json_rpc, fn [%{id: id, method: "eth_getBlockByNumber", params: [_block_quantity, true]}],
- _options ->
- {:ok,
- [
- %{
- id: id,
- jsonrpc: "2.0",
- result: %{
- "author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "difficulty" => "0xfffffffffffffffffffffffffffffffe",
- "extraData" => "0xd5830108048650617269747986312e32322e31826c69",
- "gasLimit" => "0x69fe20",
- "gasUsed" => "0xc512",
- "hash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "logsBloom" =>
- "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "miner" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "number" => "0x25",
- "parentHash" => "0xc37bbad7057945d1bf128c1ff009fb1ad632110bf6a000aac025a80f7766b66e",
- "receiptsRoot" => "0xd300311aab7dcc98c05ac3f1893629b2c9082c189a0a0c76f4f63e292ac419d5",
- "sealFields" => [
- "0x84120a71de",
- "0xb841fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401"
- ],
- "sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
- "signature" =>
- "fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401",
- "size" => "0x2cf",
- "stateRoot" => "0x2cd84079b0d0c267ed387e3895fd1c1dc21ff82717beb1132adac64276886e19",
- "step" => "302674398",
- "timestamp" => "0x5a343956",
- "totalDifficulty" => "0x24ffffffffffffffffffffffffedf78dfd",
- "transactions" => [
- %{
- "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "blockNumber" => "0x25",
- "chainId" => "0x4d",
- "condition" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "creates" => to_string(address.hash),
- "from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "to" => nil,
- "gas" => "0x47b760",
- "gasPrice" => "0x174876e800",
- "hash" => to_string(transaction.hash),
- "input" => "0x10855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef",
- "nonce" => "0x4",
- "publicKey" =>
- "0xe5d196ad4ceada719d9e592f7166d0c75700f6eab2e3c3de34ba751ea786527cb3f6eb96ad9fdfdb9989ff572df50f1c42ef800af9c5207a38b929aff969b5c9",
- "r" => "0xa7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01",
- "raw" =>
- "0xf88a0485174876e8008347b760948bf38d4764929064f2d4d3a56520a76ab3df415b80a410855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef81bea0a7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01a01f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f",
- "s" => "0x1f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f",
- "standardV" => "0x1",
- "transactionIndex" => "0x0",
- "v" => "0xbe",
- "value" => "0x0"
- }
- ],
- "transactionsRoot" => "0x68e314a05495f390f9cd0c36267159522e5450d2adf254a74567b452e767bf34",
- "uncles" => []
- }
- }
- ]}
- end)
- |> expect(:json_rpc, fn [
- %{
- id: id,
- method: "eth_getTransactionReceipt",
- params: _
- }
- ],
- _options ->
- {:ok,
- [
- %{
- id: id,
- jsonrpc: "2.0",
- result: %{
- "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "blockNumber" => "0x25",
- "contractAddress" => to_string(address.hash),
- "cumulativeGasUsed" => "0xc512",
- "gasUsed" => "0xc512",
- "logs" => [
- %{
- "address" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "blockNumber" => "0x25",
- "data" => "0x000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef",
- "logIndex" => "0x0",
- "topics" => ["0x600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22"],
- "transactionHash" => to_string(transaction.hash),
- "transactionIndex" => "0x0",
- "transactionLogIndex" => "0x0",
- "type" => "mined"
- }
- ],
- "logsBloom" =>
- "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "root" => nil,
- "status" => "0x1",
- "transactionHash" => to_string(transaction.hash),
- "transactionIndex" => "0x0"
- }
- }
- ]}
- end)
- |> expect(:json_rpc, fn [%{id: id, method: "trace_block", params: _}], _options ->
- {:ok, [%{id: id, result: []}]}
- end)
- |> expect(:json_rpc, fn [%{id: id, method: "trace_replayBlockTransactions", params: _}], _options ->
- {:ok, [%{id: id, result: []}]}
- end)
- |> expect(:json_rpc, fn [
- %{
- id: 0,
- jsonrpc: "2.0",
- method: "eth_getBalance",
- params: ["0x0000000000000000000000000000000000000003", "0x25"]
- },
- %{
- id: 1,
- jsonrpc: "2.0",
- method: "eth_getBalance",
- params: ["0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", "0x25"]
- }
- ],
- _options ->
- {:ok, [%{id: 0, jsonrpc: "2.0", result: "0x0"}, %{id: 1, jsonrpc: "2.0", result: "0x0"}]}
- end)
- end
-
- [fetcher, [name: AddressesWithoutCodeTest]]
- |> Supervisor.child_spec()
- |> ExUnit.Callbacks.start_supervised!()
-
- Process.sleep(5_000)
-
- updated_address =
- from(a in Address, where: a.hash == ^address.hash, preload: :contracts_creation_transaction) |> Repo.one()
-
- assert updated_address.contracts_creation_transaction.hash == transaction.hash
-
- updated_transaction =
- from(t in Transaction, where: t.hash == ^transaction.hash, preload: :created_contract_address) |> Repo.one()
-
- assert updated_transaction.created_contract_address.hash == address.hash
-
- assert updated_address.contract_code == updated_transaction.input
- end
-
- @tag :no_parity
- @tag :no_geth
- test "doesn't set contract code if contract wasn't create", %{
- fetcher: %{json_rpc_named_arguments: json_rpc_named_arguments} = fetcher
- } do
- block = insert(:block, consensus: true)
-
- transaction =
- :transaction
- |> insert(
- status: 0,
- to_address: nil,
- created_contract_address_hash: nil,
- block: block,
- block_number: block.number,
- block_hash: block.hash,
- cumulative_gas_used: 200,
- gas_used: 100,
- index: 0
- )
-
- address = insert(:address, contract_code: nil)
-
- if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do
- EthereumJSONRPC.Mox
- |> expect(:json_rpc, fn [%{id: id, method: "eth_getBlockByNumber", params: [_block_quantity, true]}],
- _options ->
- {:ok,
- [
- %{
- id: id,
- jsonrpc: "2.0",
- result: %{
- "author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "difficulty" => "0xfffffffffffffffffffffffffffffffe",
- "extraData" => "0xd5830108048650617269747986312e32322e31826c69",
- "gasLimit" => "0x69fe20",
- "gasUsed" => "0xc512",
- "hash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "logsBloom" =>
- "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "miner" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "number" => "0x25",
- "parentHash" => "0xc37bbad7057945d1bf128c1ff009fb1ad632110bf6a000aac025a80f7766b66e",
- "receiptsRoot" => "0xd300311aab7dcc98c05ac3f1893629b2c9082c189a0a0c76f4f63e292ac419d5",
- "sealFields" => [
- "0x84120a71de",
- "0xb841fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401"
- ],
- "sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
- "signature" =>
- "fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401",
- "size" => "0x2cf",
- "stateRoot" => "0x2cd84079b0d0c267ed387e3895fd1c1dc21ff82717beb1132adac64276886e19",
- "step" => "302674398",
- "timestamp" => "0x5a343956",
- "totalDifficulty" => "0x24ffffffffffffffffffffffffedf78dfd",
- "transactions" => [
- %{
- "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "blockNumber" => "0x25",
- "chainId" => "0x4d",
- "condition" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "to" => nil,
- "gas" => "0x47b760",
- "gasPrice" => "0x174876e800",
- "hash" => to_string(transaction.hash),
- "input" => "0x10855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef",
- "nonce" => "0x4",
- "publicKey" =>
- "0xe5d196ad4ceada719d9e592f7166d0c75700f6eab2e3c3de34ba751ea786527cb3f6eb96ad9fdfdb9989ff572df50f1c42ef800af9c5207a38b929aff969b5c9",
- "r" => "0xa7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01",
- "raw" =>
- "0xf88a0485174876e8008347b760948bf38d4764929064f2d4d3a56520a76ab3df415b80a410855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef81bea0a7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01a01f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f",
- "s" => "0x1f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f",
- "standardV" => "0x1",
- "transactionIndex" => "0x0",
- "v" => "0xbe",
- "value" => "0x0"
- }
- ],
- "transactionsRoot" => "0x68e314a05495f390f9cd0c36267159522e5450d2adf254a74567b452e767bf34",
- "uncles" => []
- }
- }
- ]}
- end)
- |> expect(:json_rpc, fn [
- %{
- id: id,
- method: "eth_getTransactionReceipt",
- params: _
- }
- ],
- _options ->
- {:ok,
- [
- %{
- id: id,
- jsonrpc: "2.0",
- result: %{
- "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "blockNumber" => "0x25",
- "contractAddress" => nil,
- "cumulativeGasUsed" => "0xc512",
- "gasUsed" => "0xc512",
- "logs" => [
- %{
- "address" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
- "blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd",
- "blockNumber" => "0x25",
- "data" => "0x000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef",
- "logIndex" => "0x0",
- "topics" => ["0x600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22"],
- "transactionHash" => to_string(transaction.hash),
- "transactionIndex" => "0x0",
- "transactionLogIndex" => "0x0",
- "type" => "mined"
- }
- ],
- "logsBloom" =>
- "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "root" => nil,
- "status" => "0x1",
- "transactionHash" => to_string(transaction.hash),
- "transactionIndex" => "0x0"
- }
- }
- ]}
- end)
- |> expect(:json_rpc, fn [%{id: id, method: "trace_block", params: _}], _options ->
- {:ok, [%{id: id, result: []}]}
- end)
- |> expect(:json_rpc, fn [%{id: id, method: "trace_replayBlockTransactions", params: _}], _options ->
- {:ok, [%{id: id, result: []}]}
- end)
- |> expect(:json_rpc, fn [
- %{
- id: 1,
- jsonrpc: "2.0",
- method: "eth_getBalance",
- params: ["0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", "0x25"]
- }
- ],
- _options ->
- {:ok, [%{id: 1, jsonrpc: "2.0", result: "0x0"}]}
- end)
- end
-
- [fetcher, [name: AddressesWithoutCodeTest1]]
- |> Supervisor.child_spec()
- |> ExUnit.Callbacks.start_supervised!()
-
- Process.sleep(2_000)
-
- updated_address =
- from(a in Address, where: a.hash == ^address.hash, preload: :contracts_creation_transaction) |> Repo.one()
-
- assert is_nil(updated_address.contracts_creation_transaction)
-
- updated_transaction =
- from(t in Transaction, where: t.hash == ^transaction.hash, preload: :created_contract_address) |> Repo.one()
-
- assert is_nil(updated_transaction.created_contract_address)
-
- assert is_nil(updated_address.contract_code)
- end
- end
-end
diff --git a/apps/indexer/test/indexer/temporary/failed_created_addresses_test.exs b/apps/indexer/test/indexer/temporary/failed_created_addresses_test.exs
deleted file mode 100644
index ef03376161..0000000000
--- a/apps/indexer/test/indexer/temporary/failed_created_addresses_test.exs
+++ /dev/null
@@ -1,78 +0,0 @@
-defmodule Indexer.Temporary.FailedCreatedAddressesTest do
- use Explorer.DataCase, async: false
- use EthereumJSONRPC.Case, async: false
-
- import Mox
-
- import Ecto.Query
-
- alias Explorer.Repo
- alias Explorer.Chain.Address
- alias Indexer.Fetcher.CoinBalance
- alias Indexer.Temporary.FailedCreatedAddresses.Supervisor
-
- @moduletag capture_log: true
-
- setup :set_mox_global
-
- setup :verify_on_exit!
-
- describe "run/1" do
- @tag :no_parity
- @tag :no_geth
- test "updates failed replaced transactions", %{json_rpc_named_arguments: json_rpc_named_arguments} do
- CoinBalance.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments)
-
- block = insert(:block)
-
- transaction =
- :transaction
- |> insert(
- status: 0,
- error: "Reverted",
- internal_transactions_indexed_at: DateTime.utc_now(),
- block: block,
- block_number: block.number,
- cumulative_gas_used: 200,
- gas_used: 100,
- index: 0
- )
-
- address = insert(:address, contract_code: "0x0102030405")
-
- insert(:internal_transaction,
- block_number: transaction.block_number,
- transaction: transaction,
- index: 0,
- created_contract_address_hash: address.hash
- )
-
- if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do
- EthereumJSONRPC.Mox
- |> expect(:json_rpc, fn _json, _options ->
- {:ok, [%{id: 0, jsonrpc: "2.0", result: "0x"}]}
- end)
- |> expect(:json_rpc, fn [%{id: id, method: "eth_getBalance", params: [_address, _block_quantity]}], _options ->
- {:ok, [%{id: id, result: "0x0"}]}
- end)
- end
-
- params = [json_rpc_named_arguments, [name: TestFailedCreatedAddresses]]
-
- params
- |> Supervisor.child_spec()
- |> ExUnit.Callbacks.start_supervised!()
-
- Process.sleep(3_000)
-
- fetched_address =
- Repo.one(
- from(a in Address,
- where: a.hash == ^address.hash
- )
- )
-
- assert fetched_address.contract_code == %Explorer.Chain.Data{bytes: ""}
- end
- end
-end