Skip to content

Withdraw expiry#4289

Merged
rakanalh merged 54 commits into
raiden-network:developfrom
rakanalh:withdraw-expiry
Jul 8, 2019
Merged

Withdraw expiry#4289
rakanalh merged 54 commits into
raiden-network:developfrom
rakanalh:withdraw-expiry

Conversation

@rakanalh
Copy link
Copy Markdown
Contributor

@rakanalh rakanalh commented Jun 26, 2019

Resolves #4195 .

TODO

  • Change total_withdraw to hold the value on-chain
  • The list of withdraws should only contain the list of pending withdraw states

@rakanalh rakanalh marked this pull request as ready for review June 26, 2019 12:59
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 26, 2019

Codecov Report

Merging #4289 into develop will decrease coverage by 0.04%.
The diff coverage is 82.63%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #4289      +/-   ##
===========================================
- Coverage    80.21%   80.16%   -0.05%     
===========================================
  Files          102      102              
  Lines        13618    13807     +189     
  Branches      2111     2148      +37     
===========================================
+ Hits         10923    11069     +146     
- Misses        2089     2126      +37     
- Partials       606      612       +6
Impacted Files Coverage Δ
raiden/utils/packing.py 100% <ø> (ø) ⬆️
raiden/transfer/mediated_transfer/target.py 98.56% <ø> (ø) ⬆️
raiden/network/proxies/payment_channel.py 80% <ø> (ø) ⬆️
raiden/transfer/mediated_transfer/state_change.py 100% <ø> (+4.44%) ⬆️
raiden/transfer/token_network.py 99.23% <100%> (+0.03%) ⬆️
raiden/settings.py 100% <100%> (ø) ⬆️
raiden/transfer/node.py 94.1% <100%> (+0.03%) ⬆️
raiden/api/python.py 67.43% <100%> (ø) ⬆️
raiden/raiden_event_handler.py 85.71% <100%> (-0.3%) ⬇️
raiden/transfer/mediated_transfer/initiator.py 98.62% <100%> (-0.02%) ⬇️
... and 15 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update be50c14...530d821. Read the comment docs.

Copy link
Copy Markdown
Contributor

@hackaugusto hackaugusto left a comment

Choose a reason for hiding this comment

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

I have to do a second pass on this ones. This first review was more on a structural level, thinking about the protocol and edge cases is pending.

Comment thread raiden/messages.py Outdated
Comment thread raiden/messages.py Outdated
Comment thread raiden/tests/unit/test_channelstate.py Outdated
Comment thread raiden/tests/unit/test_channelstate.py Outdated
Comment thread raiden/tests/unit/test_channelstate.py
Comment thread raiden/transfer/channel.py Outdated
Comment thread raiden/transfer/channel.py Outdated
Comment thread raiden/transfer/channel.py Outdated
Comment thread raiden/transfer/channel.py Outdated
Comment thread raiden/transfer/channel.py Outdated
@rakanalh rakanalh requested a review from hackaugusto June 28, 2019 09:10
Copy link
Copy Markdown
Contributor

@hackaugusto hackaugusto left a comment

Choose a reason for hiding this comment

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

The signature does not contain the expiration and the tests are passing, this tells me the raiden-contracts are not supporting this expiration functionality. This must not be merged until that is fixed

Comment thread raiden/tests/unit/test_channelstate.py Outdated
Comment thread raiden/messages.py
Comment thread raiden/tests/integration/long_running/test_settlement.py Outdated
Comment thread raiden/tests/integration/long_running/test_settlement.py Outdated
Comment thread raiden/tests/integration/long_running/test_settlement.py Outdated
Comment thread raiden/tests/integration/long_running/test_settlement.py
Comment thread raiden/transfer/channel.py
Comment thread raiden/transfer/channel.py Outdated
Comment thread raiden/transfer/channel.py Outdated
Comment thread raiden/transfer/channel.py Outdated
hackaugusto and others added 10 commits July 8, 2019 10:39
- The most important change is to consider an expired message *as
  VALID*. Without this change, when nodes go offline queues will get
  out-of-sync. The reason is that a response is expected to clear the
  node's queue. Consider the following case:

1. Alice sends a WithdrawRequest to Bob.
2. Bob goes offline.
3. Enough blocks passes to make Alice's request expired.
4. 1. Bob cames back online and receives Alice's request.
5. At this point the request is expired, if Bob reject the request
   Alice's queue will never move forward, this makes the channel
   unusable.

- Moved signature validation of the withdraw messages to a separate
  function that only depends on the state change. This forces the
  signature to be validated against the message contents only, and don't
  leave margin to mix up the signature validation with the channel
  state. This will prevent hiding errors were the signature is generated
  from the correct values but the message itself is populated with
  invalid values. Note: Ideally the unecessary fields should be removed.
- Instead of handling the withdraw amount at every call site, switched
  to using partner_total_withdraw and our_total_withdraw, which enforces
  the withdraw to be the maximum of the onchain and offchain values.
- Fixed is_valid_action_withdraw overflow check, it should use the
  requested withdraw amount from the action, and not the current
  withdraw amount from our_state.
- Moved the signature errors last. This is a cosmetic change, but it
  should make debugging easier. This was more important when the
  signature was checked against the expected values of the channel,
  because there if any of the values was incorrect the signature would
  also be incorrect, but it would not be known which specific field was
  invalid. By leaving the signature check last, we make sure to have the
  most sepecific error message possible, which is the best for
  understand the error.
- Added the validation checks for the missing fields.
Because an expired withdraw is not considered invalid the processed can
be sent on the `is_valid` branch.

This also avoids sending transaction that are expected to fail, namely
sending an expirable transactions too close to the expiry block.
Consider the following scenarion:

1. Alice sends to Bob a WithdrawRequest
2. Bob goes offline
3. The WithdrawRequest expires, and Alice sends the WithdrawExpired
4. Bob comes back online
5. Bob processes the WithdrawRequest and sends the WithdrawConfirmed
6. Bob processes the WithdrawExpired and sends the Processsed

With the previous code Alice would not send a Processed for the
WithdrawConfirmed, which would make the channel unusable for Bob. This
happened because Alice removed the WithdrawRequest from the withdraws
mapping, and once it received the WithdrawConfirmed messages it was
considered invalid.
Copy link
Copy Markdown
Collaborator

@ulope ulope left a comment

Choose a reason for hiding this comment

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

As requested in chat, approving with only a cursory glance.

Two nitpicks below.

The withdraw has expired if the current block exceeds
the withdraw's expiration + confirmation blocks.
"""
return block_number >= expiration_threshold
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The doc string doesn't match the code. 'Exceeds' suggests > instead of >=.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Maybe "exceeds" should be replaced with "reaches and goes beyond the withdraw expiration".

But the operator is correct, once the expiration block is reached, the withdraw should be considered expired.

return channel_total_withdraw <= UINT256_MAX


def is_valid_withdraw_request_signature(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The next three functions are (apart from parameter names and types) completely identical. That seems like a nice source for future bugs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We plan on a follow up PR to address some of the nitpicks we noticed here and there.

I think @hackaugusto had a goal when he did this. Was it because we can change the signature parameter for each of those messages?

@rakanalh rakanalh dismissed hackaugusto’s stale review July 8, 2019 19:15

I paired with Augusto and resolved all his comments.

@rakanalh rakanalh merged commit c4dfc13 into raiden-network:develop Jul 8, 2019
@rakanalh rakanalh deleted the withdraw-expiry branch July 8, 2019 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Withdraw expiration

4 participants