raiden-contracts icon indicating copy to clipboard operation
raiden-contracts copied to clipboard

Proposal for a new type of refund/cancellation

Open hackaugusto opened this issue 5 years ago • 61 comments

This is a rough sketch, it is by no means correct. I'm opening the issue so that we don't lose this proposal:

All values bellow are monotonic increasing.

## Settlement computation on-chain

Node's values set on the smart contract:
D = confirmed deposit
W = withdraw

Partner's balance proof values sent by the node:
L = locked
U = unlocked
E = expired
R = refund

Node's balance proof values sent by the partner:
R' = refund
U' = unlocked

Computed
N = net
P = pending

Constraints:
L,U,E,R,R',U',D,W >= 0
L >= U + E

Formulas:

N = D - W - U + U'
P = L - max(R', E) - U

The idea here is: For a channel A-B, the above definition would allow B to send a balance proof that changes the locked amount of A, with this balance proof A could prove to the smart contract that the tokens have been returned by B to A, so no backwards transfer would be required.

The biggest question that I have with the above is that if a locksroot is also required, or if just a returned amount is sufficient.

hackaugusto avatar Sep 03 '19 15:09 hackaugusto

max in max(R', E) looks weird to me. You don't care about the value of R' when you have lots of expired locks?

pirapira avatar Sep 04 '19 13:09 pirapira

The biggest question that I have with the above is that if a locksroot is also required, or if just a returned amount is sufficient.

I think a locksroot is required. Say two transfers with two different secret hashes were refunded. And say only one of the secrets has been revealed. Now it matters a lot which lock was refunded and which lock is alive.

pirapira avatar Sep 04 '19 13:09 pirapira

max in max(R', E) looks weird to me. You don't care about the value of R' when you have lots of expired locks?

I don't understand. How does max(R', E) mean that expired locks are ignored? (I'm assuming that is what you meant by don't care).

The core idea here is that both participants will be changing the same value. To avoid synchronization among the parties the value is made monotonic and max is used, otherwise we would require some sort of synchronization among the nodes to change this value. The next thing is to make sure the result of max(R', E) is semantically correct and not exploitable.

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

max(0,100) is equal to max(20,100). So when E is 100, you don't care whether R' is 0 or 20.

pirapira avatar Sep 04 '19 17:09 pirapira

That's weird. When the channel is very young, E is still zero, so every change in R' matters. When the channel is very old after many expired locks of some value, E would be big, and you don't care about small R's anymore.

I think E can grow big while R' can stay at zero.

pirapira avatar Sep 04 '19 17:09 pirapira

max(0,100) is equal to max(20,100). So when E is 100, you don't care whether R' is 0 or 20.

Yes, that is intentional.

It has to possibilities, R' < E or E < R'. The value of R' is controlled by the partner node, while the value of E is controlled by the local node. For the case R' < E the result would be E, this means the local node does not have to wait for the partner to send a RemovedExpiredLock message. E < R' is the opposite, the partner does not have to wait for the local node to send a RefundTransfer

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

@hackaugusto

  1. I send locked transfers but never reveal secrets. So E == 100 or something.

  2. I send a payment through this channel but the routing fails, so I get a refund R' == 20.

  3. The max computation kills my refund.

pirapira avatar Sep 04 '19 17:09 pirapira

@pirapira That would be an invalid message, it does not refund anything, the correct value for R' is the previous E in addition to the new refund amount, so it should be 120.

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

Refunds include expired locks?

pirapira avatar Sep 04 '19 17:09 pirapira

With this definition, yes. Pretty much a refund message would be the partner node saying it's okay for the local node to use the tokens from a given lock, because the partner is "anticipating" the expiration.

Edit: Perhaps refund is a bad name for this approach, but I didn't think much about alternative names and this is a proposal for a new approach to refunds after all.

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

I see definitions:

R' = refund
E = expired

but I see no equations between refund and expired.

pirapira avatar Sep 04 '19 17:09 pirapira

Are they somehow related?

pirapira avatar Sep 04 '19 17:09 pirapira

Is it intentional that

U' = unlock

Has unlock instead of unlocked?

pirapira avatar Sep 04 '19 17:09 pirapira

Are they somehow related?

Yes, they are "the same value" from the settlement algorithm perspective. This happens because the max is used in formula P = L - max(R', E) - U.

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

So, R' and E supposed to be equal in a completely synchronous world?

pirapira avatar Sep 04 '19 17:09 pirapira

Still max is weird.

Let's say we have an event 1 that inceases R'. And event 2 that increases E. Both events increase the value by 10. In total the increase should be 20.

Event 1 happened on the peer's side so I see R' == 10. Event 2 happened on my side so I see E == 10. These two ten's come from different causes so the perfectly synchronous world I should see 20 already, but the max calculation only gives me 10.

pirapira avatar Sep 04 '19 17:09 pirapira

Yes, they are "the same value" from the settlement algorithm perspective. This happens because the max is used in formula P = L - max(R', E) - U.

Now you've put me in a loop. I asked why max and you answered it's because the same value. It's the same value because the max is used?

pirapira avatar Sep 04 '19 17:09 pirapira

I need to see what kind of event increases which variable.

pirapira avatar Sep 04 '19 17:09 pirapira

Here are two examples:

A -> B; LockedTransfer; locked_amount = 10 B -> A; Refund; refund_amount = 10

With the above, there is nothing pending, so P = L - max(R', E) - U would be P = 0 - max(10, 0) - 0, and there is not transfer of value. Which means the partner did a refund without locking additional funds.

Let's add some interaction:

A -> B; LockedTransfer; locked_amount = 10 A -> B; LockedTransfer; locked_amount = 20 B -> A; Refund; refund_amount = 10 A -> B; Unlock; unlocked_amount = 10

In this case, there is nothing pending P = L - max(R', E) - U would be P = 20 - max(10, 0) - 10, and the partner get the 10 tokens, because it had a net positive of 10 token from the formula N = D - W - U' + U, which would be N = D - 0 - 0 + 10 (Note: I had to fix the net formula)

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

This is a hard case for me:

  1. A->B; LockedTransfer
  2. A->B; LockedTransfer
  3. Time passes
  4. B->A; RefundTransfer for 1
  5. A->B; RemoveExpiredLock for 2

I don't really know how to fix that race.

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

A -> B; LockedTransfer; locked_amount = 10 A -> B; LockedTransfer; locked_amount = 20 B -> A; Refund; refund_amount = 10 A -> B; Unlock; unlocked_amount = 10

So the two parties disagree on the first lock, whether it's refunded or unlocked?

pirapira avatar Sep 04 '19 17:09 pirapira

When you send RemoveExpiredLock, do you write a bigger E?

When you receive Refund, do you expect a bigger R'?

pirapira avatar Sep 04 '19 17:09 pirapira

1. A->B; LockedTransfer
2. A->B; LockedTransfer
3. Time passes
4. B->A; RefundTransfer for 1
5. A->B; RemoveExpiredLock for 2

What's hard about this? I see no conflicting information.

pirapira avatar Sep 04 '19 17:09 pirapira

So the two parties disagree on the first lock, whether it's refunded or unlocked?

No, the values are monotonic, so a locked_amount of 20 means a second lock of 10. I didn't specify which lock was unlocked an which was refunded in the example for simplicity's sake.

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

When you send RemoveExpiredLock, do you write a bigger E? When you receive Refund, do you expect a bigger R'?

Yes

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

Then why do E and R' grow together?

pirapira avatar Sep 04 '19 17:09 pirapira

Then why do E and R' grow together?

They are changed by different computers separated by a network in between.

Edit: By "together", do you mean atomically?

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

I heard E and R' are "the same value" (in the synchronous world).

pirapira avatar Sep 04 '19 17:09 pirapira

What's hard about this? I see no conflicting information.

One of the messages will be invalid, and then we have to reprocess the queue of messages. The whole point of using monotonically increasing values is to avoid synchronization, we need a policy on how to move forward even if that happens without having to synchronize.

hackaugusto avatar Sep 04 '19 17:09 hackaugusto

Is there a rule like, "When you receive Refund, you have to send RemoveExpiredLock"?

pirapira avatar Sep 04 '19 17:09 pirapira