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

Can't recover from state loss after close/update and before settle #1370

Open
andrevmatos opened this issue Mar 16, 2020 · 8 comments
Open
Labels
backlog bug Something isn't working

Comments

@andrevmatos
Copy link
Contributor

If a pair of nodes call closeChannel/updateNonClosingBalanceProof, but then for any reason lose the state (namely, transferred_amount, locked_amount & locksroot of each side which produced the balance_hash of the close/update calls), the channel can never be settled, the funds stay forever locked in the contracts, and that pair of nodes can never have a new channel between them on the same TokeNetwork.
Of course we don't expect both nodes to lose state often, but nonetheless IMO this lockout scenario isn't desired in any situation, and maybe we can consider this a bug to be fixed.

@fredo
Copy link

fredo commented May 28, 2020

@andrevmatos is your focus more on not being able to recover the funds or not being able to open a new channel within that pair?

  • Discussion: Is the assumption still valid in the current raiden
  • Is this a problem which we want to cover somehow?
  • If yes, make a proposal how to solve this issue

@andrevmatos
Copy link
Contributor Author

I think both, but on our testnet testings, what was more annoying was not being able to open a new channel within that pair.
The main point of this issue is that closing/updating with hashes, but requiring the actual values to settle, works as an unintended secrecy mechanism between closing and settling. Although settling is expected to be able to be performed by anyone, in practice, current method can only be called by someone who knows the amounts which composed both side's balanceHash.

@fredo
Copy link

fredo commented May 29, 2020

In a discussion with andre he stated that this problem appears to be more relevant in the LC since it only stores the latest balance hashes. This issue is addressed in raiden-network/light-client#1607

@fredo fredo closed this as completed May 29, 2020
@andrevmatos
Copy link
Contributor Author

andrevmatos commented May 29, 2020

That LightClient issue isn't replacing this one. It was just a new issue we discovered about our LC implementation upon thinking more about it in the light of this one, but this is a different issue, which can affect not only the light-client.
It happens if both nodes lose state (e.g delete ~/.raiden) after close/update, but before settling a channel. Of course, it isn't expected for this to happen and surely not advisable, but IMO this doesn't excuse the contracts from holding the funds forever with no way to settle this, and also preventing the peers from connecting again on this token network.
This issue happen because on close/update, the nodes set a balanceHash, which is the hash of 3 fields: transferredAmount, lockedAmount and locksroot, on each other's side of the channel, and this works as a kind of secret. After settleTimeout, anyone can call settleChannel, but need to know the 6 values which generated the hash stored for both sides. If the state is lost and the peers can't know the values which composed the hashes, the SC don't allow anyone in the world, not even the peers accounts, to settle the channel, the funds stays locked forever on it and the peers can never reopen a channel on this network with each other again.

@andrevmatos andrevmatos reopened this May 29, 2020
@karlb
Copy link
Contributor

karlb commented Jun 11, 2020

We could still allow a cooperative settle in that case. That would nicely solve the issue without introducing much additional code to write and test and even allows the nodes to decide on the fair split in this case in a flexible way.
I don't think we need to provide a way for totally uncooperative nodes to resolve this rare case. If the alternative is to not get any funds out, the nodes should be willing to cooperate somehow.

@palango
Copy link
Contributor

palango commented Jun 11, 2020

other options

  • allow to open concurrent channels (n closed, not settled, channels can coexist with one open channel), see Support opening a new channel during a settlement period #916
  • allow for a default settlement (back to initial deposits) after waiting, e.g. 10 * settlement_timeout
  • allow for full balance proofs at closing time
  • don't fix it: addresses are cheap

For this current sprint, we want to come to a decision on the way forward.

@palango palango added the [SP 8] label Jun 11, 2020
@karlb
Copy link
Contributor

karlb commented Jun 18, 2020

Looking through the TokenNetwork code, it seems like withdraws are possible for closed (but not settled) channels. So the tokens are not lost if both participants can agree on the balances. If both participants lost their dbs, I would expect them to revert to the on-chain balances and would thus be in agreement about the balances. This is similar to what I wrote about coop settle above, but more interesting, since we already have working withdraws.

This does not help with the "we can't get an open channel between those participants again"-problem, though.

@karlb karlb self-assigned this Jun 19, 2020
@andrevmatos
Copy link
Contributor Author

andrevmatos commented Jun 19, 2020

Ok, after a call with @karlb , we understand that allowing for a default settle after no matter how long timeout isn't advisable, since the nodes are responsible for settling (there's no MS for settle) and a node which knows their partner will be offline for long can take advantage this to do a unilateral settle.
Full BPs at closing time has the drawback of being less private, since the MSs would need to not only be provided with hashed/shadowed balanceHashes but actually with full values which would reveal too much about the transfer history.
So the best way which don't put user's funds at risk (at least not anymore than they would already be on state loss) would be cooperative settle. Possibly we could have normal coopSettle (like one done without close, to speed up settling, as in commented code in current contracts) but taking care of allowing it also after close/update, but regardless of its values, so a coopSettle can be performed with zeroed/agreed values even on this unexpecter state, at any point in time (before or after close/update, before or after settleTimeout) as long as the both peers agree/sign on the values.
Related #399 and #1383

@karlb karlb removed their assignment Jun 25, 2020
@palango palango removed the [SP 8] label Aug 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants