Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add in-flight exit deletion test #8

Merged
merged 1 commit into from
Sep 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
pgebal marked this conversation as resolved.
Show resolved Hide resolved
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why some lines use quoted Alice, some lines don't?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first I've come up with more complex test that involved Bob. I wanted to reuse code for Bob so I "quoted" Alice. Later I simplified the test but left Alice "quoted".

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