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.
pull/925/head
Luke Imhoff 6 years ago
parent 42d03efcac
commit 3284388120
  1. 5
      apps/explorer/lib/explorer/chain/import/internal_transactions.ex
  2. 106
      apps/explorer/test/explorer/chain/import_test.exs

@ -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(

@ -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

Loading…
Cancel
Save