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

Papa/sec 27 watcher info ife support #1496

Merged
merged 14 commits into from
May 19, 2020

Conversation

pnowosie
Copy link
Contributor

@pnowosie pnowosie commented Apr 30, 2020

Fixes https://github.com/omisego/security-issues/issues/27

Overview

Watcher-Info subscribes to Watcher's event bus to catch up on network changes. As the issue describes IFE events wasn't handled at all. Raw contract events just report changes they are not sufficient for Watcher-Info to be able to work on them without storing its own context and Watcher already has this context any way.

Changes

This :pr: introduces 3 new watcher events (new category as we have contract's marked with :root_chain and plasma's :child_chain events)

  • {:watcher, "InFlightExitStarted"} - this events extends data from ExitProcessor's new_in_flight_exits that can be used to spend (all) in-flight transaction's inputs (with Eth_Event)
  • {:watcher, "InFlightTxOutputPiggybacked"} - guides Info API to spend output when in-flight transaction's output is piggybacked, is broadcasted from [piggyback_exits].
  • {:watcher, "InFlightExitIOputProcessed"} - propagated after IFE is processed in [finalize_in_flight_exits] - which contains UTXO that security Watcher spends. It is a bit late for Info API but still can be useful is edge cases or just as sanity check.

For the Child-chain the first 2 events are sufficient to eagerly spend IFE's I/Oputs, it should suffice in most cases for Info API as well. However here there is some latency involved in when events about new blocks and exits are processed so I think having 3rd event as a last-resort is a good idea.

Only the first event is persisted as a spending eth event in Postgres. Action on these event is idempotent.

Testing

  • [Cabbage's in_fligth_exits_test] demonstrates that issue is fixed.
  • More unit tests

@pnowosie pnowosie force-pushed the papa/sec-27-Watcher-info-IFE-support branch from a60ab71 to fb26a03 Compare April 30, 2020 13:29
@coveralls
Copy link

coveralls commented Apr 30, 2020

Coverage Status

Coverage increased (+0.2%) to 78.324% when pulling a72aa51 on papa/sec-27-Watcher-info-IFE-support into e8d486d on master.

@pnowosie pnowosie force-pushed the papa/sec-27-Watcher-info-IFE-support branch 3 times, most recently from 29cb3d3 to c866970 Compare May 4, 2020 07:51
@pnowosie pnowosie marked this pull request as ready for review May 4, 2020 07:51
@pnowosie pnowosie force-pushed the papa/sec-27-Watcher-info-IFE-support branch from c866970 to 3723b31 Compare May 4, 2020 07:59
:ok =
events_with_utxos
|> Tools.to_bus_events_data()
|> publish_internal_bus_events("InFlightExitIOputProcessed")
Copy link
Contributor

Choose a reason for hiding this comment

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

What is IOput?

Copy link
Contributor Author

@pnowosie pnowosie May 4, 2020

Choose a reason for hiding this comment

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

Input or Output (credits to @JBunCE) alternative is Xput 👐

More context: we already publish InFlightExitInputWithdrawn & InFlightExitOutputWithdrawn event from rootchain. The above event from Watcher is focused to let consumer know that particular *put can be marked as spent (if not done yet) than on the ife processing... I'm open to better names

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, why not just call it InFlightExitProcessed if it can be either? Introducing yet another term for this isn't helpful since, both inputs and outputs are viable means to do an IFE. Also, let's consider that an input and output are references to an output.

Copy link
Contributor

Choose a reason for hiding this comment

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

I can't come up with any scenario where we need this. Watcher info can do without it as all the utxos involved here are either:

  • inputs of ife tx and we have an eth_event spending entry for that, as we put it into the db when exit starts
  • outputs, which had to be piggybacked and we put eth events for piggybacks into the db

Copy link
Contributor Author

@pnowosie pnowosie May 8, 2020

Choose a reason for hiding this comment

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

@achiurizo: I'd go with InFlightExitOutputWithdrawn then - exit processed is fine however in my opinion it could be confusing as Info-Watcher (consumer) process no exits

@pgebal: #1496 (comment)

Copy link
Contributor

@pgebal pgebal left a comment

Choose a reason for hiding this comment

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

I didn't get into implementation details yet. I've just glanced through it but I think we should have a test that checks what happens when

  1. ife is started
  2. transaction is included in a block
  3. output is piggybacked and successfully challenged

edit: to clarify, output can be challenged by other tx spending this output, signed by output owner, it does not need to be included in a plasma block

I think the output should be available to spend in that case. I have a feeling it has not been addressed in this PR.

edit: that scenario is wrong

:ok =
events_with_utxos
|> Tools.to_bus_events_data()
|> publish_internal_bus_events("InFlightExitIOputProcessed")
Copy link
Contributor

Choose a reason for hiding this comment

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

I can't come up with any scenario where we need this. Watcher info can do without it as all the utxos involved here are either:

  • inputs of ife tx and we have an eth_event spending entry for that, as we put it into the db when exit starts
  • outputs, which had to be piggybacked and we put eth events for piggybacks into the db

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
Then Alice can processes her own most recent in flight exit
Copy link
Contributor

@pgebal pgebal May 5, 2020

Choose a reason for hiding this comment

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

It would be nice to have a test where:

  1. ife and piggyback come first
  2. then comes the ch-ch block with a transaction that created the piggybacked output
  3. piggybacked output is not available to spend

it might be hard to implement that in cabbage, but maybe a test involving just the db would do?

Copy link
Contributor Author

@pnowosie pnowosie May 7, 2020

Choose a reason for hiding this comment

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

Yes - that's exactly the egde case I included handling the on-finalization event and also the aswer to you comment:

I can't come up with any scenario where we need this.

We don't have such control of the events in cabbage test - I'll include it elsewhere and point here. Thanks 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added ExitConsumer tests, however testing on DB level above scenario with all 3 steps above will be unnecessary bloat because in pt 1. we know we are trying to spent non-existing output then in pt 2. we're adding it and finally spending in 3.

I've check these points in the separate tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think test we have in OMG.WatcherInfo.ExitConsumerTest do not add up to the scenario I posted.
We do not have a test where event comes before the utxo.
If this is implied from the tests we have, please put a comment explaining how that works.

Copy link
Contributor

@pgebal pgebal May 12, 2020

Choose a reason for hiding this comment

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

Reasoning from what I can find in the code it looks like it will work well but tests confirming that are welcomed.

I still do not get why we need spending on finalization. I think all would work well without it. Could you please explain why we need that?

Copy link
Contributor Author

@pnowosie pnowosie May 12, 2020

Choose a reason for hiding this comment

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

In the scenario you posted:

  1. Watcher-Info receives an event IFE-started and spends inputs,
  2. Watcher-Info receives an event Output piggybacked, but block including in-flight tx has not been received yet (👇 next point), so there are no utxos to spend in the DB,
  3. Watcher-Info receives an event New block - which creates an in-flight tx outputs (it does not matter for Watcher-Info that inputs are already spend).

Without additinal „sanity” spending on finalizations the outputs will persist.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Regarding the explicit test for the scenario I think we have it splitted into separated (smaller) tests:
Pt 1 is covered,
Pt 2 - test showing that spending non-existing output does not break,
Pt 3 - test spending output by „finalization”-like event

I’ll add a comment in the test module to describe the scenario and it’s coverage by the tests already present

@pnowosie pnowosie force-pushed the papa/sec-27-Watcher-info-IFE-support branch 2 times, most recently from af45cbb to 6558cda Compare May 8, 2020 09:10
@pnowosie pnowosie force-pushed the papa/sec-27-Watcher-info-IFE-support branch from d106109 to 1807930 Compare May 8, 2020 14:42
@pnowosie pnowosie force-pushed the papa/sec-27-Watcher-info-IFE-support branch from 1807930 to 9292d94 Compare May 12, 2020 10:31
Copy link
Contributor

@pgebal pgebal left a comment

Choose a reason for hiding this comment

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

Maybe I just can't find it, but I think that we still do not have any test that would somehow check a scenario where event comes before the utxo.

Other than that it looks good, just a couple of minors.

@pnowosie
Copy link
Contributor Author

pnowosie commented May 13, 2020

Edit: I rethink the case raised by @pgebal and create #1515.
There is still the risk (under high load) that current solution won't work.

@pnowosie pnowosie force-pushed the papa/sec-27-Watcher-info-IFE-support branch from b009a8c to a72aa51 Compare May 19, 2020 08:42
@pnowosie pnowosie merged commit 4ab2549 into master May 19, 2020
@pnowosie pnowosie deleted the papa/sec-27-Watcher-info-IFE-support branch May 19, 2020 10:18
@unnawut unnawut added the enhancement New feature or request label Aug 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants