-
Notifications
You must be signed in to change notification settings - Fork 66
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
fix ife input spend challenge using wrong index #593
Conversation
This is an effort to add tests to cover challenge IFE input spent on all output indexes. We found a bug that we are using wrong indexes in contract code. But, this test end up does not break the existing contract as although it is attracting wrong output, we are only using the output type with that output. With current system, we only have 1 output type for payment tx. As a result it failed to break with this test.. https://github.com/omisego/security-issues/issues/15
Test in previous commit failed to cover the situation that would fail the contract with wrong index. This one test the index from another side (challenge input index) and it works to break the contract. Without the fix, it would result in "VM Exception while processing transaction: revert Output index out of bounds" error from the EVM.
This commit is the fix on the contract for input spend challenge
@@ -20,6 +21,97 @@ def test_challenge_in_flight_exit_input_spent_should_succeed(testlang, period): | |||
assert not in_flight_exit.input_piggybacked(0) | |||
|
|||
|
|||
|
|||
@pytest.mark.parametrize("num_outputs", [1, 2, 3, 4]) | |||
def test_challenge_in_flight_exit_should_succeed_for_all_output_indexes(testlang, num_outputs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this test (surprisingly) actually would not fail even without the fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think not that surprisingly:
- the problem was with checking just the spending condition
- the index of the double spend in the challenge tx is always 0, where owner[0] signs
- this coincides with the input transaction having owner[0]'s output on position 0.
So even though the double spend would not necessarily be of owner[0] and at position 0, the spending condition would always pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this coincides with the input transaction having owner[0]'s output on position 0.
Yes, but other than 0, the index would mismatch. I was expecting this to break.
However because we are only using outputType
from the output we retrieve, even the index mismatches, it would end up being same output type since we have only one type atm.
|
||
|
||
@pytest.mark.parametrize("challenge_index", [0, 1, 2, 3]) | ||
def test_challenge_in_flight_exit_should_succeed_for_all_challenge_indexes(testlang, challenge_index): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the test that would actually fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pdobacz has also suggested to prepare a parametrizable test that would check all the possibilities - check each input, output index etc.
@pytest.mark.parametrize("period", [1, 2, 4]) | ||
def test_challenge_in_flight_exit_input_spent_should_succeed(testlang, period): | ||
@pytest.mark.parametrize("period", [1, 2, 3, 4]) | ||
def test_challenge_in_flight_exit_input_spent_should_succeed_in_all_periods(testlang, period): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually this test does not check whether we really can challenge in each period - it forwards just to the second and then challenges. Additionally, the comment above the test does not match now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the test name a bit, can you check again?
Actually, the name seems correct to me.
it forwards just to the second and then challenges
No, it actually forward to the period. Or at least, it forward to period * 1/2 MIN_EXIT_PERIOD
for i in range(0, num_outputs): | ||
owners.append(testlang.accounts[i]) | ||
outputs.append((testlang.accounts[i].address, NULL_ADDRESS, tx_output_amount)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we extract it into a separate function? I know that such code is commonly used (which is bad), but this test is quite long and needs simplification so that it is easier to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the way a bit, and also just realize that owners
list is totally useless as the spend_utxo
function would be only using the first owner when signing under the hood.
Please re-review whether your comment still hold with my change?
Suggesting a parametrized test for one of the other cases ( |
On the fix itself: it looks on point, I'd however go for the other similar test cases, like the one I suggested (see #594). Such a test would fit for:
|
1. kudo Piotr's idea to parametize the inputs for indexes at once 1. rename the period test a bit as just realize that it can work with period 0 too Piotr's PR: #594
137a29a
to
2517a88
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! As agreed, #594 will go separately, straight to master
, same as other test expansions suggested!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Note
This is the fix for issue: omisego/security-issues#15
Test
The test in this commit would fail before making the contract change.
VM Exception while processing transaction: revert Output index out of bounds