raiden-network / raiden

Raiden Network
https://developer.raiden.network
Other
1.84k stars 376 forks source link

AssertionError: The balance can never be negative, that would be equivalent to a loan or a double spend. #6987

Open istankovic opened 3 years ago

istankovic commented 3 years ago

After deleting my node's database, I started raiden again and got the following exception:

Traceback (most recent call last):
  File "/home/ivan/src/raiden/raiden/ui/cli.py", line 724, in _run
    run_services(kwargs)
  File "/home/ivan/src/raiden/raiden/ui/runners.py", line 18, in run_services
    raiden_service = run_raiden_service(**options)
  File "/home/ivan/src/raiden/raiden/ui/app.py", line 455, in run_raiden_service
    raiden_service.start()
  File "/home/ivan/src/raiden/raiden/raiden_service.py", line 461, in start
    self._synchronize_with_blockchain()
  File "/home/ivan/src/raiden/raiden/raiden_service.py", line 801, in _synchronize_with_blockchain
    synchronization_state = self._best_effort_synchronize(latest_block)
  File "/home/ivan/src/raiden/raiden/raiden_service.py", line 1113, in _best_effort_synchronize
    return self._best_effort_synchronize_with_confirmed_head(
  File "/home/ivan/src/raiden/raiden/raiden_service.py", line 1187, in _best_effort_synchronize_with_confirmed_head
    events = dispatcher.dispatch(maybe_state_change)
  File "/home/ivan/src/raiden/raiden/storage/wal.py", line 221, in dispatch
    self.state, events = dispatch(self.state, self.state_transition, state_change)
  File "/home/ivan/src/raiden/raiden/storage/wal.py", line 169, in dispatch
    iteration = state_transition(state, state_change)
  File "/home/ivan/src/raiden/raiden/transfer/node.py", line 1034, in state_transition
    iteration = handle_state_change(chain_state, state_change)
  File "/home/ivan/src/raiden/raiden/transfer/node.py", line 769, in handle_state_change
    iteration = func(chain_state, state_change, *args)
  File "/home/ivan/src/raiden/raiden/transfer/node.py", line 499, in handle_token_network_action
    iteration = token_network.state_transition(
  File "/home/ivan/src/raiden/raiden/transfer/token_network.py", line 360, in state_transition
    iteration = handle_withdraw(
  File "/home/ivan/src/raiden/raiden/transfer/token_network.py", line 170, in handle_withdraw
    return subdispatch_to_channel_by_id(
  File "/home/ivan/src/raiden/raiden/transfer/token_network.py", line 54, in subdispatch_to_channel_by_id
    result = channel.state_transition(
  File "/home/ivan/src/raiden/raiden/transfer/channel.py", line 2637, in state_transition
    sanity_check(iteration.new_state)
  File "/home/ivan/src/raiden/raiden/transfer/channel.py", line 2495, in sanity_check
    assert our_balance >= 0, msg
AssertionError: The balance can never be negative, that would be equivalent to a loan or a double spend.

This is most likely because there was a channel open at the time of database deletion and some transfers were made prior to that so that when the node saw the withdraw event it assumed the balance would be negative due to the empty channel state.

ulope commented 3 years ago

Yes, you should never delete a node DB, unless you delete the DB of all nodes involved in a channel. But even then a withdraw could still be invalid if there was no initial balance and only incoming transfers (which are of course gone after deleting the DB)...