Skip to content

Commit

Permalink
test: test ife deletions
Browse files Browse the repository at this point in the history
  • Loading branch information
pgebal committed Aug 25, 2020
1 parent 987e7e4 commit 3c2fba6
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 13 deletions.
6 changes: 2 additions & 4 deletions apps/omg_watcher/lib/omg_watcher/exit_processor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ defmodule OMG.Watcher.ExitProcessor do
alias OMG.Watcher.ExitProcessor
alias OMG.Watcher.ExitProcessor.Core
alias OMG.Watcher.ExitProcessor.ExitInfo
alias OMG.Watcher.ExitProcessor.InFlightExitInfo
alias OMG.Watcher.ExitProcessor.StandardExit
alias OMG.Watcher.ExitProcessor.Tools

Expand Down Expand Up @@ -382,9 +381,8 @@ defmodule OMG.Watcher.ExitProcessor do
if not Enum.empty?(deletions),
do: Logger.info("Recognized #{Enum.count(deletions)} deletions: #{inspect(deletions)}")

{new_state, deleted_exits, db_updates} = Core.delete_in_flight_exits(state, deletions)
input_utxos = InFlightExitInfo.get_inputs(deleted_exits)
{:ok, db_updates_from_state, _validities} = State.exit_utxos(input_utxos)
{new_state, deleted_utxos, db_updates} = Core.delete_in_flight_exits(state, deletions)
{:ok, db_updates_from_state, _validities} = State.exit_utxos(deleted_utxos)

{:reply, {:ok, db_updates ++ db_updates_from_state}, new_state}
end
Expand Down
21 changes: 14 additions & 7 deletions apps/omg_watcher/lib/omg_watcher/exit_processor/core.ex
Original file line number Diff line number Diff line change
Expand Up @@ -649,17 +649,24 @@ defmodule OMG.Watcher.ExitProcessor.Core do
def delete_in_flight_exits(%__MODULE__{in_flight_exits: ifes} = state, deletions) do
exit_ids =
deletions
|> Enum.map(& &1.exit_id)
|> Enum.map(fn %{exit_id: exit_id} -> InFlightExitInfo.to_contract_id(exit_id) end)
|> MapSet.new()

deleted_ifes_by_key = Enum.filter(ifes, fn {_, ife} -> MapSet.member?(exit_ids, ife.contract_id) end)
deleted_ifes_by_key =
ifes
|> Enum.filter(fn {_, ife} -> MapSet.member?(exit_ids, ife.contract_id) end)
|> Map.new()

keys_to_delete = Map.keys(deleted_ifes_by_key)
updated_ifes = Map.drop(ifes, keys_to_delete)
deleted_keys = Map.keys(deleted_ifes_by_key)
updated_ifes = Map.drop(ifes, deleted_keys)

deleted_utxos =
deleted_ifes_by_key
|> Map.values()
|> InFlightExitInfo.get_inputs()

deleted_ifes = Map.values(deleted_ifes_by_key)
db_updates = Enum.map(keys_to_delete, fn key -> {:delete, :in_flight_exit_info, key} end)
db_updates = Enum.map(deleted_keys, fn key -> {:delete, :in_flight_exit_info, key} end)

{%{state | ifes: updated_ifes}, deleted_ifes, db_updates}
{%{state | in_flight_exits: updated_ifes}, deleted_utxos, db_updates}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ defmodule OMG.Watcher.ExitProcessor.InFlightExitInfo do
@spec get_inputs(list(t())) :: list(Utxo.Position.t())
def get_inputs(ifes) do
ifes
|> Enum.map(fn %{tx: tx} -> Transaction.get_inputs(tx) end)
|> Enum.map(fn %{input_utxos_pos: pos} -> pos end)
|> List.flatten()
end

Expand Down Expand Up @@ -434,6 +434,12 @@ defmodule OMG.Watcher.ExitProcessor.InFlightExitInfo do
}),
do: is_older?(seen_in_pos, oldest_competitor_pos)

@doc """
Converts integer to in-flight exit contract id
"""
@spec to_contract_id(non_neg_integer) :: <<_::192>>
def to_contract_id(id), do: <<id::192>>

@doc """
Checks if the competitor being seen at `competitor_pos` (`nil` if unseen) is viable to challenge with, considering the
current state of the IFE - that is, only if it is older than IFE tx's inclusion and other competitors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,23 @@ defmodule OMG.Watcher.ExitProcessor.Core.StateInteractionTest do
assert [_] = Core.get_active_in_flight_exits(processor)
end

test "deleting in-flight exits works with State",
%{processor_empty: processor, state_empty: state, alice: alice} do
ife_exit_tx = TestHelper.create_recovered([{1, 0, 0, alice}], @eth, [{alice, 9}])
ife_id = 1

state = TestHelper.do_deposit(state, alice, %{amount: 10, currency: @eth, blknum: 1})
{:ok, _, state} = State.Core.form_block(state)

{_processor, deleted_utxos, _db_updates} =
processor
|> start_ife_from(ife_exit_tx, exit_id: ife_id)
|> Core.delete_in_flight_exits([%{exit_id: ife_id}])

assert {:ok, {[{:delete, :utxo, _}], {[{:utxo_position, 1, 0, 0}], []}}, _} =
State.Core.exit_utxos(deleted_utxos, state)
end

defp mock_utxo_exists(%ExitProcessor.Request{utxos_to_check: positions} = request, state) do
%{request | utxo_exists_result: positions |> Enum.map(&State.Core.utxo_exists?(&1, state))}
end
Expand Down
38 changes: 38 additions & 0 deletions apps/omg_watcher/test/omg_watcher/exit_processor/core_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,42 @@ defmodule OMG.Watcher.ExitProcessor.CoreTest do
db_value_map
end
end

describe "delete_in_flight_exits/2" do
test "returns deleted utxos and database updates", %{processor_empty: processor, alice: alice} do
ife_exit_tx1 = TestHelper.create_recovered([{1, 0, 0, alice}], @eth, [{alice, 9}])
ife_id1 = 1
tx_hash1 = Transaction.raw_txhash(ife_exit_tx1)
ife_exit_tx2 = TestHelper.create_recovered([{2, 0, 1, alice}, {2, 0, 2, alice}], @eth, [{alice, 9}])
ife_id2 = 2
ife_exit_tx3 = TestHelper.create_recovered([{3, 0, 1, alice}, {3, 0, 2, alice}], @eth, [{alice, 9}])
ife_id3 = 3
tx_hash3 = Transaction.raw_txhash(ife_exit_tx3)

{_processor, deleted_utxos, db_updates} =
processor
|> start_ife_from(ife_exit_tx1, exit_id: ife_id1)
|> start_ife_from(ife_exit_tx2, exit_id: ife_id2)
|> start_ife_from(ife_exit_tx3, exit_id: ife_id3)
|> Core.delete_in_flight_exits([%{exit_id: ife_id1}, %{exit_id: ife_id3}])

assert Enum.sort(deleted_utxos) ==
Enum.sort([{:utxo_position, 3, 0, 1}, {:utxo_position, 3, 0, 2}, {:utxo_position, 1, 0, 0}])

assert Enum.sort(db_updates) ==
Enum.sort([{:delete, :in_flight_exit_info, tx_hash1}, {:delete, :in_flight_exit_info, tx_hash3}])
end

test "deletes in-flight exits from processor", %{processor_empty: processor, alice: alice} do
ife_exit_tx = TestHelper.create_recovered([{1, 0, 0, alice}], @eth, [{alice, 9}])
ife_id = 1

{processor, _deleted_utxos, _db_updates} =
processor
|> start_ife_from(ife_exit_tx, exit_id: ife_id)
|> Core.delete_in_flight_exits([%{exit_id: ife_id}])

assert Enum.empty?(processor.in_flight_exits)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.Watcher.ExitProcessor.InFlightExitInfoTest do
@moduledoc false

use OMG.Watcher.ExitProcessor.Case, async: true

alias OMG.State.Transaction
alias OMG.Utxo.Position
alias OMG.Watcher.ExitProcessor.InFlightExitInfo

@eth OMG.Eth.zero_address()

describe "get_inputs/1" do
test "returns list of input utxos" do
inputs1 = [
Position.encode({:utxo_position, 1, 0, 0}),
Position.encode({:utxo_position, 1, 0, 1})
]

inputs2 = [Position.encode({:utxo_position, 1, 0, 2})]

ife_infos = [
ife_info_with_inputs(inputs1),
ife_info_with_inputs(inputs2)
]

expected = inputs1 ++ inputs2

assert InFlightExitInfo.get_inputs(ife_infos) == expected
end
end

defp ife_info_with_inputs(inputs) do
tx =
Transaction.Payment.new(
[{1, 0, 0}],
[{"alice", @eth, 1}, {"alice", @eth, 2}],
<<0::256>>
)

%InFlightExitInfo{
tx: %Transaction.Signed{raw_tx: tx, sigs: <<1::520>>},
timestamp: 1,
contract_id: <<1::160>>,
eth_height: 1,
is_active: true,
input_utxos_pos: inputs
}
end
end
2 changes: 1 addition & 1 deletion priv/cabbage
Submodule cabbage updated 1 files
+0 −2 Makefile

0 comments on commit 3c2fba6

Please sign in to comment.