Skip to content

Commit

Permalink
Add test that was failing before
Browse files Browse the repository at this point in the history
  • Loading branch information
ayrat555 committed May 22, 2020
1 parent 3d7258a commit f1ce99f
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 221 deletions.
223 changes: 4 additions & 219 deletions lib/abi/type_encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,6 @@ defmodule ABI.TypeEncoder do

@doc """
Encodes the given data based on the function selector.
## Examples
iex> [[17, 1]]
...> |> ABI.TypeEncoder.encode(
...> %ABI.FunctionSelector{
...> function: nil,
...> types: [
...> {:array, {:uint, 32}}
...> ]
...> }
...> )
...> |> Base.encode16(case: :lower)
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000001"
"""

def encode(data, %ABI.FunctionSelector{function: nil, types: types}) do
Expand Down Expand Up @@ -202,16 +180,17 @@ defmodule ABI.TypeEncoder do
end

defp do_encode_type({:array, type, size}, data, static_acc, dynamic_acc) do
types = List.duplicate(type, size)
{static, dynamic} = do_encode_tuple(types, data, static_acc, dynamic_acc)
types = List.duplicate(type, size) |> IO.inspect()
{static, dynamic} = do_encode_tuple(types, data, static_acc, dynamic_acc) |> IO.inspect()

if ABI.FunctionSelector.is_dynamic?(type) do
data_bytes_size =
Enum.reduce(dynamic, 0, fn value, acc ->
byte_size(value) + acc
end)
|> IO.inspect()

{[{:dynamic, data_bytes_size} | static_acc], [dynamic | dynamic_acc]}
{[{:dynamic, data_bytes_size} | [static | static_acc]], [dynamic | dynamic_acc]}
else
{[static | static_acc], dynamic_acc}
end
Expand Down Expand Up @@ -266,33 +245,6 @@ defmodule ABI.TypeEncoder do
pad(bytes, byte_size(bytes), :right)
end

# def encode(data, types) do
# encode_raw(data, types)
# end

# @doc """
# Simiar to `ABI.TypeEncoder.encode/2` except we accept
# an array of types instead of a function selector. We also
# do not pre-pend the method id.

# ## Examples

# iex> [{"awesome", true}]
# ...> |> ABI.TypeEncoder.encode_raw([{:tuple, [:string, :bool]}])
# ...> |> Base.encode16(case: :lower)
# "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000007617765736f6d6500000000000000000000000000000000000000000000000000"
# """
# def encode_raw(data, types) do
# initial_offset =
# if Enum.count(types) > 1 do
# Enum.count(types)
# else
# 0
# end

# do_encode(types, initial_offset, <<>>, data, [])
# end

@spec encode_method_id(%ABI.FunctionSelector{}) :: binary()
defp encode_method_id(%ABI.FunctionSelector{function: nil}), do: ""

Expand All @@ -310,173 +262,6 @@ defmodule ABI.TypeEncoder do
init
end

# @spec do_encode([ABI.FunctionSelector.type()], integer(), binary(), [any()], [binary()]) ::
# binary()
# defp do_encode([], _, dynamic_data, _, acc) do
# :erlang.iolist_to_binary(Enum.reverse(acc)) <> dynamic_data
# end

# defp do_encode([type | remaining_types], offset, dynamic_data, data, acc) do
# {encoded, offset, dynamic_data, remaining_data} =
# encode_type(type, offset, dynamic_data, data)

# do_encode(remaining_types, offset, dynamic_data, remaining_data, [encoded | acc])
# end

# # @spec encode_type(ABI.FunctionSelector.type(), integer(), any(), [any()]) ::
# # {binary(), integer(), any(), [any()]}
# defp encode_type({:uint, size}, offset, dynamic_data, [data | rest]) do
# {encode_uint(data, size), offset, dynamic_data, rest}
# end

# defp encode_type({:int, size}, offset, dynamic_data, [data | rest]) do
# {encode_int(data, size), offset, dynamic_data, rest}
# end

# defp encode_type(:address, offset, dynamic_data, data) do
# encode_type({:uint, 160}, offset, dynamic_data, data)
# end

# defp encode_type(:bool, offset, dynamic_data, [data | rest]) do
# value =
# case data do
# true -> encode_uint(1, 8)
# false -> encode_uint(0, 8)
# _ -> raise "Invalid data for bool: #{data}"
# end

# {value, offset, dynamic_data, rest}
# end

# defp encode_type(:string, input_offset, dynamic_data, [data | rest]) do
# # length + value todo: value can spread to more than 32 bytes
# new_offset = input_offset + 1 + 1

# dynamic_data =
# if dynamic_data == <<>> do
# encode_uint(byte_size(data), 256) <> encode_bytes(data)
# else
# dynamic_data <> encode_uint(byte_size(data), 256) <> encode_bytes(data)
# end

# input_offset = if input_offset == 0, do: 1, else: input_offset
# current_offset = encode_uint(input_offset * 32, 256)

# {current_offset, new_offset, dynamic_data, rest}
# end

# defp encode_type(:bytes, input_offset, dynamic_data, [data | rest]) do
# # length + value todo: value can spread to more than 32 bytes
# new_offset = input_offset + 1 + 1

# dynamic_data =
# if dynamic_data == <<>> do
# encode_uint(byte_size(data), 256) <> encode_bytes(data)
# else
# dynamic_data <> encode_uint(byte_size(data), 256) <> encode_bytes(data)
# end

# input_offset = if input_offset == 0, do: 1, else: input_offset
# current_offset = encode_uint(input_offset * 32, 256)

# {current_offset, new_offset, dynamic_data, rest}
# end

# defp encode_type({:bytes, size}, offset, dynamic_data, [data | rest])
# when is_binary(data) and byte_size(data) <= size do
# {encode_bytes(data), offset, dynamic_data, rest}
# end

# defp encode_type({:bytes, size}, _, _, [data | _]) when is_binary(data) do
# raise "size mismatch for bytes#{size}: #{inspect(data)}"
# end

# defp encode_type({:bytes, size}, _, _, [data | _]) do
# raise "wrong datatype for bytes#{size}: #{inspect(data)}"
# end

# defp encode_type({:tuple, types}, offset, dynamic_data, [data | rest]) do
# # all head items are 32 bytes in length and there will be exactly
# # `count(types)` of them, so the tail starts at `32 * count(types)`.

# IO.inspect({{:tuple, types}, offset, dynamic_data, [data | rest]}, limit: :infinity)
# tail_start = (types |> Enum.count()) * 32

# initial_offset = offset + Enum.count(types)

# {head, tail, [], _, new_offset, new_dynamic_data} =
# Enum.reduce(
# types,
# {<<>>, <<>>, data |> Tuple.to_list(), tail_start, initial_offset, dynamic_data},
# fn type, {head, tail, data, _, offset, dynamic_data} ->
# {el, new_offset, new_dynamic_data, rest} = encode_type(type, offset, dynamic_data, data)

# {head <> el, tail, rest, new_offset * 32, new_offset, new_dynamic_data}
# end
# )

# {head <> tail, new_offset, new_dynamic_data, rest}
# end

# defp encode_type({:tuple, types}, offset, dynamic_data, [data | rest], encoded_prefix) do
# {encoded, new_offset, new_dynamic_data, rest} =
# encode_type({:tuple, types}, offset, dynamic_data, [data | rest])

# {encoded_prefix <> encoded, new_offset, new_dynamic_data, rest}
# end

# defp encode_type({:array, type, element_count}, input_offset, dynamic_data, [data | rest]) do
# repeated_type = List.duplicate(type, element_count)

# if ABI.FunctionSelector.is_dynamic?(type) do
# encode_type(
# {:tuple, repeated_type},
# input_offset,
# dynamic_data,
# [data |> List.to_tuple() | rest],
# encode_uint(32, 256)
# )
# else
# encode_type(
# {:tuple, repeated_type},
# input_offset,
# dynamic_data,
# [data |> List.to_tuple() | rest]
# )
# end
# end

# defp encode_type({:array, type}, input_offset, dynamic_data, [data | _rest] = all_data) do
# element_count = Enum.count(data)

# # we should add the length of array to offset
# offset_with_length = input_offset + 1

# {encoded_array, new_offset, dynamic_data, rest} =
# encode_type({:array, type, element_count}, offset_with_length, dynamic_data, all_data)

# encoded_uint = encode_uint(element_count, 256)

# dynamic_data =
# if dynamic_data == <<>> do
# encoded_uint <> encoded_array
# else
# dynamic_data <> encoded_uint <> encoded_array
# end

# input_offset = if input_offset == 0, do: 1, else: input_offset

# {encode_uint(input_offset * 32, 256), new_offset, dynamic_data, rest}
# end

# defp encode_type(els, a, b, c) do
# raise "Unsupported encoding type: #{inspect(els)} #{inspect(a)} #{inspect(b)} #{inspect(c)}"
# end

# def encode_bytes(bytes) do
# bytes |> pad(byte_size(bytes), :right)
# end

# Note, we'll accept a binary or an integer here, so long as the
# binary is not longer than our allowed data size
defp encode_uint(data, size_in_bits) when rem(size_in_bits, 8) == 0 do
Expand Down
5 changes: 3 additions & 2 deletions test/abi/type_decoder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,9 @@ defmodule ABI.TypeDecoderTest do
62617a0000000000000000000000000000000000000000000000000000000000
"""
|> encode_multiline_string()
|> IO.inspect(limit: :infinity)

encoded_result = TypeEncoder.encode(result, types)
encoded_result = TypeEncoder.encode(result, types) |> IO.inspect(limit: :infinity)
assert encoded_result == encoded_pattern
assert result == encoded_result |> TypeDecoder.decode(types)
end
Expand Down Expand Up @@ -270,7 +271,7 @@ defmodule ABI.TypeDecoderTest do
"""
|> encode_multiline_string()

encoded_result = TypeEncoder.encode(result, types)
encoded_result = TypeEncoder.encode(result, types) |> IO.inspect(limit: :infinity)
assert encoded_result == encoded_pattern
assert result == encoded_result |> TypeDecoder.decode(types)
end
Expand Down
82 changes: 82 additions & 0 deletions test/abi_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,86 @@ defmodule ABITest do
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>
) == [{"Ether Token"}]
end

test "decodes startStandardExit((uint256,bytes,bytes))" do
signature = "startStandardExit((uint256,bytes,bytes))"

params = [
{5_000_000_000_000,
<<248, 116, 1, 225, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 163, 142, 47, 10, 0, 238, 237, 1, 235, 148, 34, 212, 145, 189, 226, 48,
63, 47, 67, 50, 91, 33, 8, 210, 111, 30, 171, 161, 227, 43, 148, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>,
<<243, 154, 134, 159, 98, 231, 92, 245, 240, 191, 145, 70, 136, 166, 178, 137, 202, 242, 4,
148, 53, 216, 230, 140, 92, 94, 109, 5, 228, 73, 19, 243, 78, 213, 192, 45, 109, 72, 200,
147, 36, 134, 201, 157, 58, 217, 153, 229, 216, 148, 157, 195, 190, 59, 48, 88, 204, 41,
121, 105, 12, 62, 58, 98, 28, 121, 43, 20, 191, 102, 248, 42, 243, 111, 0, 245, 251, 167,
1, 79, 160, 193, 226, 255, 60, 124, 39, 59, 254, 82, 60, 26, 207, 103, 220, 63, 95, 160,
128, 166, 134, 165, 160, 208, 92, 61, 72, 34, 253, 84, 214, 50, 220, 156, 192, 75, 22,
22, 4, 110, 186, 44, 228, 153, 235, 154, 247, 159, 94, 185, 73, 105, 10, 4, 4, 171, 244,
206, 186, 252, 124, 255, 250, 56, 33, 145, 183, 221, 158, 125, 247, 120, 88, 30, 111,
183, 142, 250, 179, 95, 211, 100, 201, 213, 218, 218, 212, 86, 155, 109, 212, 127, 127,
234, 186, 250, 53, 113, 248, 66, 67, 68, 37, 84, 131, 53, 172, 110, 105, 13, 208, 113,
104, 216, 188, 91, 119, 151, 156, 26, 103, 2, 51, 79, 82, 159, 87, 131, 247, 158, 148,
47, 210, 205, 3, 246, 229, 90, 194, 207, 73, 110, 132, 159, 222, 156, 68, 111, 171, 70,
168, 210, 125, 177, 227, 16, 15, 39, 90, 119, 125, 56, 91, 68, 227, 203, 192, 69, 202,
186, 201, 218, 54, 202, 224, 64, 173, 81, 96, 130, 50, 76, 150, 18, 124, 242, 159, 69,
53, 235, 91, 126, 186, 207, 226, 161, 214, 211, 170, 184, 236, 4, 131, 211, 32, 121, 168,
89, 255, 112, 249, 33, 89, 112, 168, 190, 235, 177, 193, 100, 196, 116, 232, 36, 56, 23,
76, 142, 235, 111, 188, 140, 180, 89, 75, 136, 201, 68, 143, 29, 64, 176, 155, 234, 236,
172, 91, 69, 219, 110, 65, 67, 74, 18, 43, 105, 92, 90, 133, 134, 45, 142, 174, 64, 179,
38, 143, 111, 55, 228, 20, 51, 123, 227, 142, 186, 122, 181, 187, 243, 3, 208, 31, 75,
122, 224, 127, 215, 62, 220, 47, 59, 224, 94, 67, 148, 138, 52, 65, 138, 50, 114, 80,
156, 67, 194, 129, 26, 130, 30, 92, 152, 43, 165, 24, 116, 172, 125, 201, 221, 121, 168,
12, 194, 240, 95, 111, 102, 76, 157, 187, 46, 69, 68, 53, 19, 125, 160, 108, 228, 77,
228, 85, 50, 165, 106, 58, 112, 7, 162, 208, 198, 180, 53, 247, 38, 249, 81, 4, 191, 166,
231, 7, 4, 111, 193, 84, 186, 233, 24, 152, 208, 58, 26, 10, 198, 249, 180, 94, 71, 22,
70, 226, 85, 90, 199, 158, 63, 232, 126, 177, 120, 30, 38, 242, 5, 0, 36, 12, 55, 146,
116, 254, 145, 9, 110, 96, 209, 84, 90, 128, 69, 87, 31, 218, 185, 181, 48, 208, 214,
231, 232, 116, 110, 120, 191, 159, 32, 244, 232, 111, 6>>}
]

expected_result =
<<112, 224, 20, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 4, 140, 39, 57, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 248, 116, 1, 225, 160, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 163, 142, 47, 10, 0,
238, 237, 1, 235, 148, 34, 212, 145, 189, 226, 48, 63, 47, 67, 50, 91, 33, 8, 210, 111,
30, 171, 161, 227, 43, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
128, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 243, 154, 134, 159, 98, 231, 92, 245,
240, 191, 145, 70, 136, 166, 178, 137, 202, 242, 4, 148, 53, 216, 230, 140, 92, 94, 109,
5, 228, 73, 19, 243, 78, 213, 192, 45, 109, 72, 200, 147, 36, 134, 201, 157, 58, 217, 153,
229, 216, 148, 157, 195, 190, 59, 48, 88, 204, 41, 121, 105, 12, 62, 58, 98, 28, 121, 43,
20, 191, 102, 248, 42, 243, 111, 0, 245, 251, 167, 1, 79, 160, 193, 226, 255, 60, 124, 39,
59, 254, 82, 60, 26, 207, 103, 220, 63, 95, 160, 128, 166, 134, 165, 160, 208, 92, 61, 72,
34, 253, 84, 214, 50, 220, 156, 192, 75, 22, 22, 4, 110, 186, 44, 228, 153, 235, 154, 247,
159, 94, 185, 73, 105, 10, 4, 4, 171, 244, 206, 186, 252, 124, 255, 250, 56, 33, 145, 183,
221, 158, 125, 247, 120, 88, 30, 111, 183, 142, 250, 179, 95, 211, 100, 201, 213, 218,
218, 212, 86, 155, 109, 212, 127, 127, 234, 186, 250, 53, 113, 248, 66, 67, 68, 37, 84,
131, 53, 172, 110, 105, 13, 208, 113, 104, 216, 188, 91, 119, 151, 156, 26, 103, 2, 51,
79, 82, 159, 87, 131, 247, 158, 148, 47, 210, 205, 3, 246, 229, 90, 194, 207, 73, 110,
132, 159, 222, 156, 68, 111, 171, 70, 168, 210, 125, 177, 227, 16, 15, 39, 90, 119, 125,
56, 91, 68, 227, 203, 192, 69, 202, 186, 201, 218, 54, 202, 224, 64, 173, 81, 96, 130, 50,
76, 150, 18, 124, 242, 159, 69, 53, 235, 91, 126, 186, 207, 226, 161, 214, 211, 170, 184,
236, 4, 131, 211, 32, 121, 168, 89, 255, 112, 249, 33, 89, 112, 168, 190, 235, 177, 193,
100, 196, 116, 232, 36, 56, 23, 76, 142, 235, 111, 188, 140, 180, 89, 75, 136, 201, 68,
143, 29, 64, 176, 155, 234, 236, 172, 91, 69, 219, 110, 65, 67, 74, 18, 43, 105, 92, 90,
133, 134, 45, 142, 174, 64, 179, 38, 143, 111, 55, 228, 20, 51, 123, 227, 142, 186, 122,
181, 187, 243, 3, 208, 31, 75, 122, 224, 127, 215, 62, 220, 47, 59, 224, 94, 67, 148, 138,
52, 65, 138, 50, 114, 80, 156, 67, 194, 129, 26, 130, 30, 92, 152, 43, 165, 24, 116, 172,
125, 201, 221, 121, 168, 12, 194, 240, 95, 111, 102, 76, 157, 187, 46, 69, 68, 53, 19,
125, 160, 108, 228, 77, 228, 85, 50, 165, 106, 58, 112, 7, 162, 208, 198, 180, 53, 247,
38, 249, 81, 4, 191, 166, 231, 7, 4, 111, 193, 84, 186, 233, 24, 152, 208, 58, 26, 10,
198, 249, 180, 94, 71, 22, 70, 226, 85, 90, 199, 158, 63, 232, 126, 177, 120, 30, 38, 242,
5, 0, 36, 12, 55, 146, 116, 254, 145, 9, 110, 96, 209, 84, 90, 128, 69, 87, 31, 218, 185,
181, 48, 208, 214, 231, 232, 116, 110, 120, 191, 159, 32, 244, 232, 111, 6>>

assert ABI.encode(signature, params) == expected_result
end
end

0 comments on commit f1ce99f

Please sign in to comment.