From d95f60f225c687f2eac52cd3160da447c06f66b6 Mon Sep 17 00:00:00 2001 From: hswick Date: Tue, 25 Sep 2018 15:20:21 -0500 Subject: [PATCH] Filter is properly returning data even with indexed and non indexed fields --- lib/exw3.ex | 66 ++++++++++++++++++++++++++++++++++------------ test/exw3_test.exs | 14 ++++------ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/lib/exw3.ex b/lib/exw3.ex index 019e8dc..fe7b262 100644 --- a/lib/exw3.ex +++ b/lib/exw3.ex @@ -427,9 +427,9 @@ defmodule ExW3 do :ok end - def filter(filter_id, event_signature, event_fields, pid) do + def filter(filter_id, event_fields, pid) do Poller.filter(filter_id) - send Listener, {:filter, filter_id, event_signature, event_fields, pid} + send Listener, {:filter, filter_id, event_fields, pid} end def listen(callback) do @@ -438,19 +438,50 @@ defmodule ExW3 do end listen(callback) end + + defp extract_non_indexed_fields(data, names, signature) do + Enum.zip(names, ExW3.decode_event(data, signature)) |> Enum.into(%{}) + end + + defp format_log(log, event_attributes) do + non_indexed_fields = + extract_non_indexed_fields( + Map.get(log, "data"), + event_attributes[:non_indexed_names], + event_attributes[:signature] + ) + + indexed_fields = + if length(log["topics"]) > 1 do + [ _head | tail ] = log["topics"] + decoded_topics = Enum.map(0..length(tail) - 1, fn i -> + topic_type = Enum.at(event_attributes[:topic_types], i) + topic_data = Enum.at(tail, i) + + {decoded} = ExW3.decode_data(topic_type, topic_data) + + decoded + end) + + Enum.zip(event_attributes[:topic_names], decoded_topics) |> Enum.into(%{}) + else + %{} + end + + Map.merge(indexed_fields, non_indexed_fields) + end defp loop(state) do receive do - {:filter, filter_id, event_signature, event_fields, pid} -> - loop(Map.put(state, filter_id, %{pid: pid, signature: event_signature, names: event_fields})) + {:filter, filter_id, event_attributes, pid} -> + loop(Map.put(state, filter_id, %{pid: pid, event_attributes: event_attributes})) {:event, filter_id, logs} -> filter_attributes = Map.get(state, filter_id) + event_attributes = filter_attributes[:event_attributes] + unless logs == [] do Enum.each(logs, fn log -> - data = Map.get(log, "data") - new_data = Enum.zip(filter_attributes[:names], ExW3.decode_event(data, filter_attributes[:signature])) |> Enum.into(%{}) - new_log = Map.put(log, "data", new_data) - send filter_attributes[:pid], {:event, {filter_id, new_log}} + send filter_attributes[:pid], {:event, {filter_id, format_log(log, event_attributes)}} end) end loop(state) @@ -685,7 +716,7 @@ defmodule ExW3 do {:noreply, Map.put(state, name, contract_info ++ [address: address])} end - def handle_cast({:register, {name, contract_info}}, state) do + def handle_cast({:register, {name, contract_info}}, state) do {:noreply, Map.put(state, name, add_helper(contract_info))} end @@ -701,9 +732,10 @@ defmodule ExW3 do payload = Map.merge(%{address: contract_info[:address], topics: [contract_info[:event_names][event_name]]}, event_data) filter_id = ExW3.new_filter(payload) - event_signature = contract_info[:events][contract_info[:event_names][event_name]][:signature] - event_fields = contract_info[:events][contract_info[:event_names][event_name]][:non_indexed_names] - EventListener.filter(filter_id, event_signature, event_fields, other_pid) + event_attributes = contract_info[:events][contract_info[:event_names][event_name]] + + EventListener.filter(filter_id, event_attributes, other_pid) + {:reply, filter_id, Map.put(state, contract_name, contract_info ++ [event_name, filter_id])} end @@ -763,17 +795,17 @@ defmodule ExW3 do formatted_logs = Enum.map(logs, fn log -> topic = Enum.at(log["topics"], 0) - event = Map.get(events, topic) + event_attributes = Map.get(events, topic) - if event do - non_indexed_fields = Enum.zip(event[:non_indexed_names], ExW3.decode_event(log["data"], event[:signature])) |> Enum.into(%{}) + if event_attributes do + non_indexed_fields = Enum.zip(event_attributes[:non_indexed_names], ExW3.decode_event(log["data"], event_attributes[:signature])) |> Enum.into(%{}) if length(log["topics"]) > 1 do [ _head | tail ] = log["topics"] decoded_topics = Enum.map(0..length(tail) - 1, fn i -> - topic_type = Enum.at(event[:topic_types], i) + topic_type = Enum.at(event_attributes[:topic_types], i) topic_data = Enum.at(tail, i) {decoded} = ExW3.decode_data(topic_type, topic_data) @@ -781,7 +813,7 @@ defmodule ExW3 do decoded end) - indexed_fields = Enum.zip(event[:topic_names], decoded_topics) |> Enum.into(%{}) + indexed_fields = Enum.zip(event_attributes[:topic_names], decoded_topics) |> Enum.into(%{}) Map.merge(indexed_fields, non_indexed_fields) else non_indexed_fields diff --git a/test/exw3_test.exs b/test/exw3_test.exs index 07e76ce..5d93cc7 100644 --- a/test/exw3_test.exs +++ b/test/exw3_test.exs @@ -226,10 +226,8 @@ defmodule EXW3Test do event_log = Enum.at(state, 0) assert event_log |> is_map - log_data = Map.get(event_log, "data") - assert log_data |> is_map - assert Map.get(log_data, "num") == 42 - assert ExW3.bytes_to_string(Map.get(log_data, "data")) == "Hello, World!" + assert Map.get(event_log, "num") == 42 + assert ExW3.bytes_to_string(Map.get(event_log, "data")) == "Hello, World!" ExW3.uninstall_filter(filter_id) @@ -258,11 +256,9 @@ defmodule EXW3Test do event_log = Enum.at(state, 0) assert event_log |> is_map - log_data = Map.get(event_log, "data") - assert log_data |> is_map - assert Map.get(log_data, "num") == 46 - assert ExW3.bytes_to_string(Map.get(log_data, "data")) == "Hello, World!" - assert Map.get(log_data, "otherNum") == 42 + assert Map.get(event_log, "num") == 46 + assert ExW3.bytes_to_string(Map.get(event_log, "data")) == "Hello, World!" + assert Map.get(event_log, "otherNum") == 42 ExW3.uninstall_filter(indexed_filter_id) end