Skip to content

Commit

Permalink
test: add in-flight exit deletion test
Browse files Browse the repository at this point in the history
  • Loading branch information
pgebal committed Sep 2, 2020
1 parent 0952386 commit 36eedb3
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 7 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ make test
# To run a specific test, see the <test_file_name> in apps/itest/test/
mix test test/itest/<test_file_name>.exs
```

## CI flow

If you made a change in repo that requires e2e test (`elixir-omg` is used as an example here):
1. Code the test and open PR in `specs` repo.
3. Edit `.gitmodules` to change the `specs` repo in `elixir-omg` to point to your `specs` PR branch.
4. Before you merge `elixir-omg` PR, change the `specs` repo back to master.
5. Merge the PR in `specs` repo.
43 changes: 43 additions & 0 deletions apps/itest/lib/in_flight_exit_client.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 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 Itest.InFlightExitClient do
@moduledoc """
Implements in-flight exit related actions.
"""
alias Itest.Transactions.Encoding

import Itest.Poller, only: [wait_on_receipt_confirmed: 1]

require Logger

@gas 540_000

def delete_in_flight_exit(owner, exit_game_contract_address, exit_id) do
_ = Logger.info("Deleting in-flight exit.")

data = ABI.encode("deleteNonPiggybackedInFlightExit(uint160)", [exit_id])

tx = %{
from: owner,
to: exit_game_contract_address,
data: Encoding.to_hex(data),
gas: Encoding.to_hex(@gas)
}

{:ok, receipt_hash} = Ethereumex.HttpClient.eth_send_transaction(tx)
wait_on_receipt_confirmed(receipt_hash)
:ok
end
end
18 changes: 14 additions & 4 deletions apps/itest/test/features/in_flight_exits.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Feature: In Flight Exits
And Bob gets in flight exit data for "5" ETH from his most recent deposit
And Alice sends the most recently created transaction
And Bob spends an output from the most recently sent transaction
And Alice starts an in flight exit from the most recently created transaction
And "Alice" starts an in flight exit from the most recently created transaction
Then "Alice" verifies its in flight exit from the most recently created transaction
Given Bob piggybacks inputs and outputs from Alices most recent in flight exit
And Bob starts a piggybacked in flight exit using his most recently prepared in flight exit data
Expand All @@ -35,7 +35,7 @@ Feature: In Flight Exits
Given "Alice" deposits "10" ETH to the root chain
Then "Alice" should have "10" ETH on the child chain after finality margin
Given Alice creates a transaction for "5" ETH
And Alice starts an in flight exit from the most recently created transaction
And "Alice" starts an in flight exit from the most recently created transaction
Then "Alice" verifies its in flight exit from the most recently created transaction
Given Alice piggybacks output from her most recent in flight exit
And "Alice" in flight transaction inputs are not spendable any more
Expand All @@ -46,7 +46,7 @@ Feature: In Flight Exits
Then "Alice" should have "10" ETH on the child chain after finality margin
Given Alice creates a transaction for "5" ETH
And Alice sends the most recently created transaction
And Alice starts an in flight exit from the most recently created transaction
And "Alice" starts an in flight exit from the most recently created transaction
Then "Alice" verifies its in flight exit from the most recently created transaction
Given Alice piggybacks output from her most recent in flight exit
And "Alice" in flight transaction most recently piggybacked output is not spendable any more
Expand All @@ -56,9 +56,19 @@ Feature: In Flight Exits
Given "Alice" deposits "10" ETH to the root chain
Then "Alice" should have "10" ETH on the child chain after finality margin
Given Alice creates a transaction for "5" ETH
And Alice starts an in flight exit from the most recently created transaction
And "Alice" starts an in flight exit from the most recently created transaction
Then "Alice" verifies its in flight exit from the most recently created transaction
Given "Alice" is aware of available piggyback
Then "Alice" in flight transaction inputs are not exitable any more
Given Alice piggybacks output from her most recent in flight exit
Then "Alice" can processes its own most recent in flight exit

Scenario: In-flight exit can be deleted
Given "Alice" deposits "10" ETH to the root chain
Then "Alice" should have "10" ETH on the child chain after finality margin
Given Alice creates a transaction for "5" ETH
And "Alice" starts an in flight exit from the most recently created transaction
Then "Alice" verifies its in flight exit from the most recently created transaction
Given "Alice" is aware of available piggyback
When "Alice" deletes its most recent in flight exit
Then watcher does not report any byzantine events
27 changes: 24 additions & 3 deletions apps/itest/test/itest/in_flight_exits_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ defmodule InFlightExitsTests do
alias Itest.ApiModel.WatcherSecurityCriticalConfiguration
alias Itest.Client
alias Itest.Fee
alias Itest.InFlightExitClient
alias Itest.StandardExitChallengeClient
alias Itest.StandardExitClient
alias Itest.Transactions.Currency
Expand Down Expand Up @@ -450,10 +451,12 @@ defmodule InFlightExitsTests do
{:ok, Map.put(state, entity, bob_state)}
end

defand ~r/^Alice starts an in flight exit from the most recently created transaction$/, _, state do
defand ~r/^"(?<entity>[^"]+)" starts an in flight exit from the most recently created transaction$/,
%{entity: entity},
state do
exit_game_contract_address = state["exit_game_contract_address"]
in_flight_exit_bond_size = state["in_flight_exit_bond_size"]
%{address: address, txbytes: txbytes} = alice_state = state["Alice"]
%{address: address, txbytes: txbytes} = alice_state = state[entity]
payload = %InFlightExitTxBytesBodySchema{txbytes: Encoding.to_hex(txbytes)}
response = pull_api_until_successful(InFlightExit, :in_flight_exit_get_data, Watcher.new(), payload)
exit_data = IfeExitData.to_struct(response)
Expand All @@ -464,7 +467,6 @@ defmodule InFlightExitsTests do
|> Map.put(:exit_data, exit_data)
|> Map.put(:receipt_hashes, [receipt_hash | alice_state.receipt_hashes])

entity = "Alice"
{:ok, Map.put(state, entity, alice_state)}
end

Expand Down Expand Up @@ -958,6 +960,25 @@ defmodule InFlightExitsTests do
assert Itest.Poller.exitable_utxo_absent?(address, input_pos)
end

defwhen ~r/^"(?<entity>[^"]+)" deletes its most recent in flight exit$/,
%{entity: entity},
state do
exit_game_contract_address = state["exit_game_contract_address"]
%{address: address, exit_data: exit_data} = state[entity]

in_flight_exit_id = get_in_flight_exit_id(exit_game_contract_address, exit_data)

_ = wait_for_min_exit_period()
InFlightExitClient.delete_in_flight_exit(address, exit_game_contract_address, in_flight_exit_id)

{:ok, state}
end

defthen ~r/^watcher does not report any byzantine events/, _, state do
assert all_events_in_status?([])
{:ok, state}
end

###############################################################################################
####
#### PRIVATE
Expand Down

0 comments on commit 36eedb3

Please sign in to comment.