@ -22,6 +22,133 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
assert :error == Repo . get ( Transaction , transaction . hash ) . status
end
test " simple coin transfer's status becomes :error when its internal_transaction has an error " do
transaction = insert ( :transaction ) |> with_block ( status : :ok )
insert ( :pending_block_operation , block_hash : transaction . block_hash , fetch_internal_transactions : true )
assert :ok == transaction . status
index = 0
error = " Out of gas "
internal_transaction_changes =
make_internal_transaction_changes_for_simple_coin_transfers ( transaction , index , error )
assert { :ok , _ } = run_internal_transactions ( [ internal_transaction_changes ] )
assert :error == Repo . get ( Transaction , transaction . hash ) . status
end
test " for block with 2 simple coin transfer's statuses become :error when its both internal_transactions has an error " do
a_block = insert ( :block , number : 1000 )
transaction1 = insert ( :transaction ) |> with_block ( a_block , status : :ok )
transaction2 = insert ( :transaction ) |> with_block ( a_block , status : :ok )
insert ( :pending_block_operation , block_hash : a_block . hash , fetch_internal_transactions : true )
assert :ok == transaction1 . status
assert :ok == transaction2 . status
index = 0
error = " Out of gas "
internal_transaction_changes_1 =
make_internal_transaction_changes_for_simple_coin_transfers ( transaction1 , index , error )
internal_transaction_changes_2 =
make_internal_transaction_changes_for_simple_coin_transfers ( transaction2 , index , error )
assert { :ok , _ } = run_internal_transactions ( [ internal_transaction_changes_1 , internal_transaction_changes_2 ] )
assert :error == Repo . get ( Transaction , transaction1 . hash ) . status
assert :error == Repo . get ( Transaction , transaction2 . hash ) . status
end
test " for block with 2 simple coin transfer's only status become :error for tx where internal_transactions has an error " do
a_block = insert ( :block , number : 1000 )
transaction1 = insert ( :transaction ) |> with_block ( a_block , status : :ok )
transaction2 = insert ( :transaction ) |> with_block ( a_block , status : :ok )
insert ( :pending_block_operation , block_hash : a_block . hash , fetch_internal_transactions : true )
assert :ok == transaction1 . status
assert :ok == transaction2 . status
index = 0
error = " Out of gas "
internal_transaction_changes_1 =
make_internal_transaction_changes_for_simple_coin_transfers ( transaction1 , index , error )
internal_transaction_changes_2 =
make_internal_transaction_changes_for_simple_coin_transfers ( transaction2 , index , nil )
assert { :ok , _ } = run_internal_transactions ( [ internal_transaction_changes_1 , internal_transaction_changes_2 ] )
assert :error == Repo . get ( Transaction , transaction1 . hash ) . status
assert :ok == Repo . get ( Transaction , transaction2 . hash ) . status
end
test " for block with simple coin transfer and method calls, method calls internal txs have correct block_index " do
a_block = insert ( :block , number : 1000 )
transaction0 = insert ( :transaction ) |> with_block ( a_block , status : :ok )
transaction1 = insert ( :transaction ) |> with_block ( a_block , status : :ok )
transaction2 = insert ( :transaction ) |> with_block ( a_block , status : :ok )
insert ( :pending_block_operation , block_hash : a_block . hash , fetch_internal_transactions : true )
assert :ok == transaction0 . status
assert :ok == transaction1 . status
assert :ok == transaction2 . status
index = 0
internal_transaction_changes_0 = make_internal_transaction_changes ( transaction0 , index , nil )
internal_transaction_changes_0_1 = make_internal_transaction_changes ( transaction0 , 1 , nil )
internal_transaction_changes_1 =
make_internal_transaction_changes_for_simple_coin_transfers ( transaction1 , index , nil )
internal_transaction_changes_2 = make_internal_transaction_changes ( transaction2 , index , nil )
internal_transaction_changes_2_1 = make_internal_transaction_changes ( transaction2 , 1 , nil )
assert { :ok , _ } =
run_internal_transactions ( [
internal_transaction_changes_0 ,
internal_transaction_changes_0_1 ,
internal_transaction_changes_1 ,
internal_transaction_changes_2 ,
internal_transaction_changes_2_1
] )
assert from ( i in InternalTransaction , where : i . transaction_hash == ^ transaction0 . hash , where : i . index == 0 )
|> Repo . one ( )
|> is_nil ( )
assert 1 == Repo . get_by! ( InternalTransaction , transaction_hash : transaction0 . hash , index : 1 ) . block_index
assert from ( i in InternalTransaction , where : i . transaction_hash == ^ transaction1 . hash ) |> Repo . one ( ) |> is_nil ( )
assert from ( i in InternalTransaction , where : i . transaction_hash == ^ transaction2 . hash , where : i . index == 0 )
|> Repo . one ( )
|> is_nil ( )
assert 4 == Repo . get_by! ( InternalTransaction , transaction_hash : transaction2 . hash , index : 1 ) . block_index
end
test " simple coin transfer has no internal transaction inserted " do
transaction = insert ( :transaction ) |> with_block ( status : :ok )
insert ( :pending_block_operation , block_hash : transaction . block_hash , fetch_internal_transactions : true )
assert :ok == transaction . status
index = 0
internal_transaction_changes =
make_internal_transaction_changes_for_simple_coin_transfers ( transaction , index , nil )
assert { :ok , _ } = run_internal_transactions ( [ internal_transaction_changes ] )
assert ! Repo . exists? ( from ( i in InternalTransaction , where : i . transaction_hash == ^ transaction . hash ) )
end
test " pending transactions don't get updated not its internal_transactions inserted " do
transaction = insert ( :transaction ) |> with_block ( status : :ok )
pending = insert ( :transaction )
@ -31,7 +158,7 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
assert :ok == transaction . status
assert is_nil ( pending . block_hash )
index = 0
index = 1
transaction_changes = make_internal_transaction_changes ( transaction , index , nil )
pending_changes = make_internal_transaction_changes ( pending , index , nil )
@ -62,7 +189,7 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
assert full_block . hash == inserted . block_hash
index = 0
index = 1
pending_transaction_changes =
pending
@ -142,17 +269,23 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
assert full_block . hash == inserted . block_hash
index = 0
transaction_changes = make_internal_transaction_changes ( inserted , index , nil )
transaction_changes = make_internal_transaction_changes ( inserted , 0 , nil )
transaction_changes_2 = make_internal_transaction_changes ( inserted , 1 , nil )
empty_changes = make_empty_block_changes ( empty_block . number )
assert { :ok , _ } = run_internal_transactions ( [ empty_changes , transaction_changes ] )
assert { :ok , _ } = run_internal_transactions ( [ empty_changes , transaction_changes , transaction_changes_2 ] )
assert %{ consensus : true } = Repo . get ( Block , empty_block . hash )
assert PendingBlockOperation |> Repo . get ( empty_block . hash ) |> is_nil ( )
assert from ( i in InternalTransaction , where : i . transaction_hash == ^ inserted . hash ) |> Repo . one ( ) |> is_nil ( ) ==
assert from ( i in InternalTransaction , where : i . transaction_hash == ^ inserted . hash , where : i . index == 0 )
|> Repo . one ( )
|> is_nil ( ) ==
true
assert from ( i in InternalTransaction , where : i . transaction_hash == ^ inserted . hash , where : i . index == 1 )
|> Repo . one ( )
|> is_nil ( ) ==
false
assert %{ consensus : true } = Repo . get ( Block , full_block . hash )
@ -199,4 +332,28 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
block_number : transaction . block_number
}
end
defp make_internal_transaction_changes_for_simple_coin_transfers ( transaction , index , error ) do
%{
from_address_hash : insert ( :address ) . hash ,
to_address_hash : insert ( :address ) . hash ,
call_type : :call ,
gas : 0 ,
gas_used : nil ,
input : % Data { bytes : << >> } ,
output :
if is_nil ( error ) do
% Data { bytes : << 0 >> }
else
nil
end ,
index : index ,
trace_address : [ ] ,
transaction_hash : transaction . hash ,
type : :call ,
value : Wei . from ( Decimal . new ( 1 ) , :wei ) ,
error : error ,
block_number : transaction . block_number
}
end
end