From 32843881209d9a71ce1dc10009d286edb8dc7575 Mon Sep 17 00:00:00 2001 From: Luke Imhoff Date: Mon, 15 Oct 2018 12:24:27 -0500 Subject: [PATCH] Get transaction created_contract_address_hash from first internal Fixes #593 Fixes #621 Fixes #920 `created_contract_address_hash` should be treated like `error` and `status`, where only the first internal transaction matters. --- .../chain/import/internal_transactions.ex | 5 +- .../test/explorer/chain/import_test.exs | 106 ++---------------- 2 files changed, 9 insertions(+), 102 deletions(-) diff --git a/apps/explorer/lib/explorer/chain/import/internal_transactions.ex b/apps/explorer/lib/explorer/chain/import/internal_transactions.ex index 02c3dce0cb..fae31ac669 100644 --- a/apps/explorer/lib/explorer/chain/import/internal_transactions.ex +++ b/apps/explorer/lib/explorer/chain/import/internal_transactions.ex @@ -100,9 +100,8 @@ defmodule Explorer.Chain.Import.InternalTransactions do internal_transactions_indexed_at: ^timestamps.updated_at, created_contract_address_hash: fragment( - "(SELECT it.created_contract_address_hash FROM internal_transactions AS it WHERE it.transaction_hash = ? and it.type = 'create' and ? IS NULL)", - t.hash, - t.to_address_hash + "(SELECT it.created_contract_address_hash FROM internal_transactions AS it WHERE it.transaction_hash = ? ORDER BY it.index ASC LIMIT 1)", + t.hash ), error: fragment( diff --git a/apps/explorer/test/explorer/chain/import_test.exs b/apps/explorer/test/explorer/chain/import_test.exs index 91d5485b3a..49198560a0 100644 --- a/apps/explorer/test/explorer/chain/import_test.exs +++ b/apps/explorer/test/explorer/chain/import_test.exs @@ -686,101 +686,6 @@ defmodule Explorer.Chain.ImportTest do Chain.string_to_address_hash(created_contract_address_hash) end - test "when the transaction has a to_address and an internal transaction with type create it does not populates the denormalized created_contract_address_hash" do - smart_contract_bytecode = - "0x608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a7230582040d82a7379b1ee1632ad4d8a239954fd940277b25628ead95259a85c5eddb2120029" - - block_hash = "0xe52d77084cab13a4e724162bcd8c6028e5ecfaa04d091ee476e96b9958ed6b47" - block_number = 34 - miner_hash = from_address_hash = "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" - to_address_hash = "0xf7ddc5c7a2d2f0d7a9798459c0104fdf5e9a7bbb" - created_contract_address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" - transaction_hash = "0x3a3eb134e6792ce9403ea4188e5e79693de9e4c94e499db132be086400da79e6" - - options = %{ - addresses: %{ - params: [ - %{hash: from_address_hash}, - %{ - contract_code: smart_contract_bytecode, - hash: created_contract_address_hash - }, - %{hash: to_address_hash} - ] - }, - blocks: %{ - params: [ - %{ - consensus: true, - difficulty: 340_282_366_920_938_463_463_374_607_431_768_211_454, - gas_limit: 6_926_030, - gas_used: 269_607, - hash: block_hash, - miner_hash: miner_hash, - nonce: 0, - number: block_number, - parent_hash: "0x106d528393159b93218dd410e2a778f083538098e46f1a44902aa67a164aed0b", - size: 1493, - timestamp: Timex.parse!("2017-12-15T21:06:15Z", "{ISO:Extended:Z}"), - total_difficulty: 11_569_600_475_311_907_757_754_736_652_679_816_646_147 - } - ] - }, - transactions: %{ - params: [ - %{ - block_hash: block_hash, - block_number: block_number, - cumulative_gas_used: 269_607, - from_address_hash: from_address_hash, - gas: 269_607, - gas_price: 1, - gas_used: 269_607, - hash: transaction_hash, - index: 0, - input: "0x", - nonce: 0, - r: 0, - s: 0, - status: :ok, - to_address_hash: to_address_hash, - v: 0, - value: 0 - } - ], - on_conflict: :replace_all - }, - internal_transactions: %{ - params: [ - %{ - block_number: 35, - call_type: "call", - created_contract_code: smart_contract_bytecode, - created_contract_address_hash: created_contract_address_hash, - from_address_hash: from_address_hash, - gas: 4_677_320, - gas_used: 27770, - index: 0, - init: - "0x6060604052341561000c57fe5b5b6101a68061001c6000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631d3b9edf811461005b57806366098d4f1461007b578063a12f69e01461009b578063f4f3bdc1146100bb575bfe5b6100696004356024356100db565b60408051918252519081900360200190f35b61006960043560243561010a565b60408051918252519081900360200190f35b610069600435602435610124565b60408051918252519081900360200190f35b610069600435602435610163565b60408051918252519081900360200190f35b60008282028315806100f757508284828115156100f457fe5b04145b15156100ff57fe5b8091505b5092915050565b6000828201838110156100ff57fe5b8091505b5092915050565b60008080831161013057fe5b828481151561013b57fe5b049050828481151561014957fe5b0681840201841415156100ff57fe5b8091505b5092915050565b60008282111561016f57fe5b508082035b929150505600a165627a7a7230582020c944d8375ca14e2c92b14df53c2d044cb99dc30c3ba9f55e2bcde87bd4709b0029", - output: "0x", - to_address_hash: to_address_hash, - trace_address: [], - transaction_hash: transaction_hash, - type: "create", - value: 0 - } - ] - } - } - - assert {:ok, _} = Import.all(options) - - transaction = Explorer.Repo.get(Transaction, transaction_hash) - - assert transaction.created_contract_address_hash == nil - end - test "import balances" do assert {:ok, _} = Import.all(%{ @@ -794,10 +699,8 @@ defmodule Explorer.Chain.ImportTest do }) end - test "transactions with multiple create internal transactions return error" do - assert {:error, :internal_transactions_indexed_at_transactions, - %{exception: %Postgrex.Error{postgres: %{code: :cardinality_violation}}, transaction_hashes: [_]}, - _} = + test "transactions with multiple create uses first internal transaction's created contract address hash" do + assert {:ok, _} = Import.all(%{ blocks: %{ params: [ @@ -890,6 +793,11 @@ defmodule Explorer.Chain.ImportTest do timeout: 5 } }) + + assert %Transaction{created_contract_address_hash: created_contract_address_hash} = + Repo.get(Transaction, "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5") + + assert to_string(created_contract_address_hash) == "0xffc87239eb0267bc3ca2cd51d12fbf278e02ccb4" end test "updates transaction error and status from internal transactions when status is not set from (pre-Byzantium/Ethereum Classic) receipts" do