def test_receive_directtransfer_invalidlocksroot(raiden_network, token_addresses): app0, app1 = raiden_network token_address = token_addresses[0] channel0 = get_channelstate(app0, app1, token_address) balance0 = channel.get_balance(channel0.our_state, channel0.partner_state) balance1 = channel.get_balance(channel0.partner_state, channel0.our_state) payment_identifier = 1 invalid_locksroot = UNIT_SECRETHASH channel_identifier = channel0.identifier message_identifier = random.randint(0, UINT64_MAX) direct_transfer_message = DirectTransfer( message_identifier=message_identifier, payment_identifier=payment_identifier, nonce=1, token=token_address, channel=channel_identifier, transferred_amount=0, recipient=app1.raiden.address, locksroot=invalid_locksroot, ) sign_and_inject( direct_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) assert_synched_channel_state(token_address, app0, balance0, [], app1, balance1, [])
def assert_channel_values( channel0: NettingChannelState, balance0: Balance, pending_locks0: List[HashTimeLockState], channel1: NettingChannelState, balance1: Balance, pending_locks1: List[HashTimeLockState], ) -> None: total_token = channel0.our_state.contract_balance + channel1.our_state.contract_balance our_balance0 = channel.get_balance(channel0.our_state, channel0.partner_state) partner_balance0 = channel.get_balance(channel0.partner_state, channel0.our_state) assert our_balance0 + partner_balance0 == total_token our_balance1 = channel.get_balance(channel1.our_state, channel1.partner_state) partner_balance1 = channel.get_balance(channel1.partner_state, channel1.our_state) assert our_balance1 + partner_balance1 == total_token locked_amount0 = LockedAmount(sum(lock.amount for lock in pending_locks0)) locked_amount1 = LockedAmount(sum(lock.amount for lock in pending_locks1)) assert_balance(channel0, balance0, locked_amount0) assert_balance(channel1, balance1, locked_amount1) # a participant's outstanding is the other's pending locks. assert_locked(channel0, pending_locks0) assert_locked(channel1, pending_locks1) assert_mirror(channel0, channel1) assert_mirror(channel1, channel0)
def test_receive_directtransfer_invalidlocksroot(raiden_network, token_addresses): app0, app1 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address, ) channel0 = get_channelstate(app0, app1, token_network_identifier) balance0 = channel.get_balance(channel0.our_state, channel0.partner_state) balance1 = channel.get_balance(channel0.partner_state, channel0.our_state) payment_identifier = 1 invalid_locksroot = UNIT_SECRETHASH channel_identifier = channel0.identifier message_identifier = random.randint(0, UINT64_MAX) direct_transfer_message = DirectTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=message_identifier, payment_identifier=payment_identifier, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel_identifier, transferred_amount=0, locked_amount=0, recipient=app1.raiden.address, locksroot=invalid_locksroot, ) sign_and_inject( direct_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) assert_synced_channel_state( token_network_identifier, app0, balance0, [], app1, balance1, [], )
def get_initial_amount_for_amount_after_fees( amount_after_fees: PaymentAmount, channels: List[Tuple[NettingChannelState, NettingChannelState]], ) -> Optional[FeesCalculation]: """ Calculates the payment amount including fees to be supplied to the given channel configuration, so that `amount_after_fees` arrives at the target. Note: The channels have to be from the view of the mediator, so for the case A -> B -> C this should be [(B->A, B->C)] """ assert len(channels) >= 1, "Need at least one channel pair" # Backpropagate fees in mediation scenario total = PaymentWithFeeAmount(amount_after_fees) fees: List[FeeAmount] = [] try: for channel_in, channel_out in reversed(channels): assert isinstance(channel_in, NettingChannelState) assert isinstance(channel_out, NettingChannelState) balance_in = get_balance(channel_in.our_state, channel_in.partner_state) balance_out = get_balance(channel_out.our_state, channel_out.partner_state) receivable_amount = TokenAmount(channel_in.our_total_deposit + channel_in.partner_total_deposit - balance_in) before_fees = get_amount_with_fees( amount_without_fees=total, balance_in=balance_in, balance_out=balance_out, schedule_in=channel_in.fee_schedule, schedule_out=channel_out.fee_schedule, receivable_amount=receivable_amount, ) if before_fees is None: return None fee = FeeAmount(before_fees - total) total = PaymentWithFeeAmount(total + fee) fees.append(fee) except UndefinedMediationFee: return None return FeesCalculation(total_amount=PaymentWithFeeAmount(total), mediation_fees=fees)
def assert_synced_channel_state( token_network_identifier, app0, balance0, pending_locks0, app1, balance1, pending_locks1, ): """ Assert the values of two synced channels. Note: This assert does not work for an intermediate state, where one message hasn't been delivered yet or has been completely lost.""" # pylint: disable=too-many-arguments channel0 = get_channelstate(app0, app1, token_network_identifier) channel1 = get_channelstate(app1, app0, token_network_identifier) assert channel0.our_state.contract_balance == channel1.partner_state.contract_balance assert channel0.partner_state.contract_balance == channel1.our_state.contract_balance total_token = channel0.our_state.contract_balance + channel1.our_state.contract_balance our_balance0 = channel.get_balance(channel0.our_state, channel0.partner_state) partner_balance0 = channel.get_balance(channel0.partner_state, channel0.our_state) assert our_balance0 + partner_balance0 == total_token our_balance1 = channel.get_balance(channel1.our_state, channel1.partner_state) partner_balance1 = channel.get_balance(channel1.partner_state, channel1.our_state) assert our_balance1 + partner_balance1 == total_token locked_amount0 = sum(lock.amount for lock in pending_locks0) locked_amount1 = sum(lock.amount for lock in pending_locks1) assert_balance(channel0, balance0, locked_amount0) assert_balance(channel1, balance1, locked_amount1) # a participant's outstanding is the other's pending locks. assert_locked(channel0, pending_locks0) assert_locked(channel1, pending_locks1) assert_mirror(channel0, channel1) assert_mirror(channel1, channel0)
def assert_balance(from_channel: NettingChannelState, balance: Balance, locked: LockedAmount) -> None: """ Assert the from_channel overall token values. """ assert balance >= 0 assert locked >= 0 distributable = balance - locked channel_distributable = channel.get_distributable( from_channel.our_state, from_channel.partner_state) channel_balance = channel.get_balance(from_channel.our_state, from_channel.partner_state) channel_locked_amount = channel.get_amount_locked(from_channel.our_state) msg = f"channel balance does not match. Expected: {balance} got: {channel_balance}" assert channel_balance == balance, msg msg = (f"channel distributable amount does not match. " f"Expected: {distributable} got: {channel_distributable}") assert channel_distributable == distributable, msg msg = f"channel locked amount does not match. Expected: {locked} got: {channel_locked_amount}" assert channel_locked_amount == locked, msg msg = (f"locked_amount ({locked}) + distributable ({distributable}) " f"did not equal the balance ({balance})") assert balance == locked + distributable, msg
def get_node_balances( chain_state, token_network_address: TokenNetworkAddress) -> List[Tuple[Any]]: channels = views.list_all_channelstate(chain_state) channels = [ channel for channel in channels if channel.canonical_identifier.token_network_address == to_canonical_address(token_network_address) ] balances = [( channel_state.partner_state.address, channel.get_balance(channel_state.our_state, channel_state.partner_state), channel.get_balance(channel_state.partner_state, channel_state.our_state), ) for channel_state in channels] return balances
def assert_mirror(original, mirror): """ Assert that `mirror` has a correct `partner_state` to represent `original`.""" original_locked_amount = channel.get_amount_locked(original.our_state) mirror_locked_amount = channel.get_amount_locked(mirror.partner_state) assert original_locked_amount == mirror_locked_amount balance0 = channel.get_balance(original.our_state, original.partner_state) balance1 = channel.get_balance(mirror.partner_state, mirror.our_state) assert balance0 == balance1 balanceproof0 = channel.get_current_balanceproof(original.our_state) balanceproof1 = channel.get_current_balanceproof(mirror.partner_state) assert balanceproof0 == balanceproof1 distributable0 = channel.get_distributable(original.our_state, original.partner_state) distributable1 = channel.get_distributable(mirror.partner_state, mirror.our_state) assert distributable0 == distributable1
def assert_mirror(original, mirror): """ Assert that `mirror` has a correct `partner_state` to represent `original`.""" original_locked_amount = channel.get_amount_locked(original.our_state) mirror_locked_amount = channel.get_amount_locked(mirror.partner_state) assert original_locked_amount == mirror_locked_amount balance0 = channel.get_balance(original.our_state, original.partner_state) balance1 = channel.get_balance(mirror.partner_state, mirror.our_state) assert balance0 == balance1 balanceproof0 = channel.get_current_balanceproof(original.our_state) balanceproof1 = channel.get_current_balanceproof(mirror.partner_state) assert balanceproof0 == balanceproof1 distributable0 = channel.get_distributable(original.our_state, original.partner_state) distributable1 = channel.get_distributable(mirror.partner_state, mirror.our_state) assert distributable0 == distributable1
def update_monitoring_service_from_balance_proof( raiden: 'RaidenService', chain_state: 'ChainState', new_balance_proof: BalanceProofSignedState, ) -> None: if raiden.config['services']['monitoring_enabled'] is False: return channel_state = views.get_channelstate_by_canonical_identifier( chain_state=chain_state, canonical_identifier=new_balance_proof.canonical_identifier, ) msg = ( f'Failed to update monitoring service due to inability to find ' f'channel: {new_balance_proof.channel_identifier} ' f'token_network_address: {pex(new_balance_proof.token_network_identifier)}.' ) assert channel_state, msg balance = channel.get_balance( sender=channel_state.our_state, receiver=channel_state.partner_state, ) if balance < MONITORING_MIN_CAPACITY: log.warn( f'Skipping update to Monitoring service. ' f'Available balance of {balance} is less than configured ' f'minimum capacity of {MONITORING_MIN_CAPACITY}', ) return rei_balance = raiden.user_deposit.effective_balance( raiden.address, 'latest') if rei_balance < MONITORING_REWARD: rdn_balance = to_rdn(rei_balance) rdn_reward = to_rdn(MONITORING_REWARD) log.warn( f'Skipping update to Monitoring service. ' f'Your deposit balance {rdn_balance} is less than ' f'the required monitoring service reward of {rdn_reward}', ) return log.info( 'Received new balance proof, creating message for Monitoring Service.', balance_proof=new_balance_proof, ) monitoring_message = RequestMonitoring.from_balance_proof_signed_state( new_balance_proof, MONITORING_REWARD, ) monitoring_message.sign(raiden.signer) raiden.transport.send_global( constants.MONITORING_BROADCASTING_ROOM, monitoring_message, )
def assert_partner_state(end_state, partner_state, model): """Checks that the stored data for both ends correspond to the model.""" assert end_state.address == model.participant_address assert channel.get_amount_locked(end_state) == model.amount_locked assert channel.get_balance(end_state, partner_state) == model.balance assert channel.get_distributable(end_state, partner_state) == model.distributable assert channel.get_next_nonce(end_state) == model.next_nonce assert set(end_state.merkletree.layers[LEAVES]) == set(model.merkletree_leaves) assert end_state.contract_balance == model.contract_balance
def test_receive_directtransfer_invalidlocksroot(raiden_network, token_addresses): app0, app1 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address, ) channel0 = get_channelstate(app0, app1, token_network_identifier) balance0 = channel.get_balance(channel0.our_state, channel0.partner_state) balance1 = channel.get_balance(channel0.partner_state, channel0.our_state) payment_identifier = 1 invalid_locksroot = UNIT_SECRETHASH channel_identifier = channel0.identifier message_identifier = random.randint(0, UINT64_MAX) direct_transfer_message = DirectTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=message_identifier, payment_identifier=payment_identifier, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel_identifier, transferred_amount=0, locked_amount=0, recipient=app1.raiden.address, locksroot=invalid_locksroot, ) sign_and_inject( direct_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) assert_synched_channel_state( token_network_identifier, app0, balance0, [], app1, balance1, [], )
def channel_state_invariants(self): """ Check the invariants for the channel state given in the Raiden specification """ for netting_channel in self.address_to_channel.values(): our_state = netting_channel.our_state partner_state = netting_channel.partner_state our_transferred_amount = 0 if our_state.balance_proof: our_transferred_amount = our_state.balance_proof.transferred_amount assert our_transferred_amount >= 0 partner_transferred_amount = 0 if partner_state.balance_proof: partner_transferred_amount = partner_state.balance_proof.transferred_amount assert partner_transferred_amount >= 0 assert channel.get_distributable(our_state, partner_state) >= 0 assert channel.get_distributable(partner_state, our_state) >= 0 our_deposit = netting_channel.our_total_deposit partner_deposit = netting_channel.partner_total_deposit total_deposit = our_deposit + partner_deposit our_amount_locked = channel.get_amount_locked(our_state) our_balance = channel.get_balance(our_state, partner_state) partner_amount_locked = channel.get_amount_locked(partner_state) partner_balance = channel.get_balance(partner_state, our_state) # invariant (5.1R), add withdrawn amounts when implemented assert 0 <= our_amount_locked <= our_balance assert 0 <= partner_amount_locked <= partner_balance assert our_amount_locked <= total_deposit assert partner_amount_locked <= total_deposit our_transferred = partner_transferred_amount - our_transferred_amount netted_transferred = our_transferred + partner_amount_locked - our_amount_locked # invariant (6R), add withdrawn amounts when implemented assert 0 <= our_deposit + our_transferred - our_amount_locked <= total_deposit assert 0 <= partner_deposit - our_transferred - partner_amount_locked <= total_deposit # invariant (7R), add withdrawn amounts when implemented assert - our_deposit <= netted_transferred <= partner_deposit
def channel_state_invariants(self): """ Check the invariants for the channel state given in the Raiden specification """ for netting_channel in self.address_to_channel.values(): our_state = netting_channel.our_state partner_state = netting_channel.partner_state our_transferred_amount = 0 if our_state.balance_proof: our_transferred_amount = our_state.balance_proof.transferred_amount assert our_transferred_amount >= 0 partner_transferred_amount = 0 if partner_state.balance_proof: partner_transferred_amount = partner_state.balance_proof.transferred_amount assert partner_transferred_amount >= 0 assert channel.get_distributable(our_state, partner_state) >= 0 assert channel.get_distributable(partner_state, our_state) >= 0 our_deposit = netting_channel.our_total_deposit partner_deposit = netting_channel.partner_total_deposit total_deposit = our_deposit + partner_deposit our_amount_locked = channel.get_amount_locked(our_state) our_balance = channel.get_balance(our_state, partner_state) partner_amount_locked = channel.get_amount_locked(partner_state) partner_balance = channel.get_balance(partner_state, our_state) # invariant (5.1R), add withdrawn amounts when implemented assert 0 <= our_amount_locked <= our_balance assert 0 <= partner_amount_locked <= partner_balance assert our_amount_locked <= total_deposit assert partner_amount_locked <= total_deposit our_transferred = partner_transferred_amount - our_transferred_amount netted_transferred = our_transferred + partner_amount_locked - our_amount_locked # invariant (6R), add withdrawn amounts when implemented assert 0 <= our_deposit + our_transferred - our_amount_locked <= total_deposit assert 0 <= partner_deposit - our_transferred - partner_amount_locked <= total_deposit # invariant (7R), add withdrawn amounts when implemented assert -our_deposit <= netted_transferred <= partner_deposit
def assert_synched_channel_state( token_network_identifier, app0, balance0, pending_locks0, app1, balance1, pending_locks1, ): """ Assert the values of two synched channels. Note: This assert does not work for an intermediate state, where one message hasn't been delivered yet or has been completely lost.""" # pylint: disable=too-many-arguments channel0 = get_channelstate(app0, app1, token_network_identifier) channel1 = get_channelstate(app1, app0, token_network_identifier) assert channel0.our_state.contract_balance == channel1.partner_state.contract_balance assert channel0.partner_state.contract_balance == channel1.our_state.contract_balance total_token = channel0.our_state.contract_balance + channel1.our_state.contract_balance our_balance0 = channel.get_balance(channel0.our_state, channel0.partner_state) partner_balance0 = channel.get_balance(channel0.partner_state, channel0.our_state) assert our_balance0 + partner_balance0 == total_token our_balance1 = channel.get_balance(channel1.our_state, channel1.partner_state) partner_balance1 = channel.get_balance(channel1.partner_state, channel1.our_state) assert our_balance1 + partner_balance1 == total_token locked_amount0 = sum(lock.amount for lock in pending_locks0) locked_amount1 = sum(lock.amount for lock in pending_locks1) assert_balance(channel0, balance0, locked_amount0) assert_balance(channel1, balance1, locked_amount1) # a participant's outstanding is the other's pending locks. assert_locked(channel0, pending_locks0) assert_locked(channel1, pending_locks1) assert_mirror(channel0, channel1) assert_mirror(channel1, channel0)
def get_initial_payment_for_final_target_amount( final_amount: PaymentAmount, channels: List[NettingChannelState] ) -> Optional[FeesCalculation]: """ Calculates the payment amount including fees to be supplied to the given channel configuration, so that `final_amount` arrived at the target. Note: The channels have to be from the view of the mediator, so for the case A -> B -> C this should be [B->A, B->C] """ assert len(channels) >= 1, "Need at least one channel" # No fees in direct transfer if len(channels) == 1: return FeesCalculation(total_amount=PaymentWithFeeAmount(final_amount), mediation_fees=[]) # Backpropagate fees in mediation scenario total = PaymentWithFeeAmount(final_amount) fees: List[FeeAmount] = [] try: for channel_in, channel_out in reversed(list(window(channels, 2))): assert isinstance(channel_in, NettingChannelState) fee_schedule_out = channel_out.fee_schedule assert isinstance(channel_out, NettingChannelState) fee_schedule_in = channel_in.fee_schedule balance_out = get_balance(channel_out.our_state, channel_out.partner_state) fee_out = fee_sender(fee_schedule=fee_schedule_out, balance=balance_out, amount=total) total += fee_out # type: ignore balance_in = get_balance(channel_in.our_state, channel_in.partner_state) fee_in = fee_receiver(fee_schedule=fee_schedule_in, balance=balance_in, amount=total) total += fee_in # type: ignore fees.append(FeeAmount(fee_out + fee_in)) except UndefinedMediationFee: return None return FeesCalculation(total_amount=PaymentWithFeeAmount(total), mediation_fees=fees)
def assert_balance(from_channel, balance, locked): """ Assert the from_channel overall token values. """ assert balance >= 0 assert locked >= 0 distributable = balance - locked channel_distributable = channel.get_distributable( from_channel.our_state, from_channel.partner_state, ) assert channel.get_balance(from_channel.our_state, from_channel.partner_state) == balance assert channel_distributable == distributable assert channel.get_amount_locked(from_channel.our_state) == locked amount_locked = channel.get_amount_locked(from_channel.our_state) assert balance == amount_locked + distributable
def assert_balance(from_channel, balance, locked): """ Assert the from_channel overall token values. """ assert balance >= 0 assert locked >= 0 distributable = balance - locked channel_distributable = channel.get_distributable( from_channel.our_state, from_channel.partner_state, ) assert channel.get_balance(from_channel.our_state, from_channel.partner_state) == balance assert channel_distributable == distributable assert channel.get_amount_locked(from_channel.our_state) == locked amount_locked = channel.get_amount_locked(from_channel.our_state) assert balance == amount_locked + distributable
def get_balance(self, channel_state): # pylint: disable=no-self-use return channel.get_balance( channel_state.our_state, channel_state.partner_state, )
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_config): node1, node2 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address, ) api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED event_list1 = api1.get_channel_events( token_address, channel12.partner_state.address, channel12.open_transaction.finished_block_number, ) assert any( ( event['event'] == EVENT_CHANNEL_OPENED and is_same_address( event['args']['participant1'], to_normalized_address(api1.address), ) and is_same_address( event['args']['participant2'], to_normalized_address(api2.address), ) ) for event in event_list1 ) token_events = api1.get_token_network_events( token_address, channel12.open_transaction.finished_block_number, ) assert token_events[0]['event'] == EVENT_CHANNEL_OPENED registry_address = api1.raiden.default_registry.address # Load the new state with the deposit api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) # let's make sure it's idempotent api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_channel_events( token_address, channel12.partner_state.address, channel12.open_transaction.finished_block_number, ) assert any( ( event['event'] == EVENT_CHANNEL_DEPOSIT and is_same_address( event['args']['participant'], to_normalized_address(api1.address), ) and event['args']['total_deposit'] == deposit ) for event in event_list2 ) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_identifier) event_list3 = api1.get_channel_events( token_address, channel12.partner_state.address, channel12.open_transaction.finished_block_number, ) assert len(event_list3) > len(event_list2) assert any( ( event['event'] == EVENT_CHANNEL_CLOSED and is_same_address( event['args']['closing_participant'], to_normalized_address(api1.address), ) ) for event in event_list3 ) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED settlement_block = ( channel12.close_transaction.finished_block_number + channel12.settle_timeout + 10 # arbitrary number of additional blocks, used to wait for the settle() call ) wait_until_block(node1.raiden.chain, settlement_block) # Load the new state with the channel settled channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_SETTLED
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_config): node1, node2 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address, ) api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED event_list1 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert any((event['event'] == ChannelEvent.OPENED and is_same_address( event['args']['participant1'], to_normalized_address(api1.address), ) and is_same_address( event['args']['participant2'], to_normalized_address(api2.address), )) for event in event_list1) token_events = api1.get_blockchain_events_token_network(token_address, ) assert token_events[0]['event'] == ChannelEvent.OPENED registry_address = api1.raiden.default_registry.address # Load the new state with the deposit api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit with pytest.raises(DepositMismatch): api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert any((event['event'] == ChannelEvent.DEPOSIT and is_same_address( event['args']['participant'], to_normalized_address(api1.address), ) and event['args']['total_deposit'] == deposit) for event in event_list2) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_identifier) event_list3 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert len(event_list3) > len(event_list2) assert any((event['event'] == ChannelEvent.CLOSED and is_same_address( event['args']['closing_participant'], to_normalized_address(api1.address), )) for event in event_list3) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED settlement_block = ( channel12.close_transaction.finished_block_number + channel12.settle_timeout + 10 # arbitrary number of additional blocks, used to wait for the settle() call ) wait_until_block(node1.raiden.chain, settlement_block) state_changes = node1.raiden.wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) assert must_contain_entry( state_changes, ContractReceiveChannelSettled, { 'token_network_identifier': token_network_identifier, 'channel_identifier': channel12.identifier, })
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_config): node1, node2 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address, ) api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address if transport_config.protocol == TransportProtocol.UDP: # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state( api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state( api1.address) == NODE_NETWORK_UNKNOWN elif transport_config.protocol == TransportProtocol.MATRIX: # with Matrix nodes do not need a health check to know each others reachability assert api1.get_node_network_state( api2.address) == NODE_NETWORK_UNREACHABLE assert api2.get_node_network_state( api1.address) == NODE_NETWORK_UNREACHABLE assert not api1.get_channel_list(registry_address, token_address, api2.address) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED event_list1 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert event_list1 == [] token_events = api1.get_token_network_events( token_address, channel12.open_transaction.finished_block_number, ) assert token_events[0]['event'] == EVENT_CHANNEL_NEW registry_address = api1.raiden.default_registry.address # Load the new state with the deposit api1.channel_deposit( registry_address, token_address, api2.address, deposit, ) channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert any( (event['event'] == EVENT_CHANNEL_NEW_BALANCE and is_same_address( event['args']['registry_address'], to_normalized_address(registry_address), ) and is_same_address( event['args']['participant'], to_normalized_address(api1.address), )) for event in event_list2) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_identifier) event_list3 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert len(event_list3) > len(event_list2) assert any((event['event'] == EVENT_CHANNEL_CLOSED and is_same_address( event['args']['registry_address'], to_normalized_address(registry_address), ) and is_same_address( event['args']['closing_address'], to_normalized_address(api1.address), )) for event in event_list3) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED settlement_block = ( channel12.close_transaction.finished_block_number + channel12.settle_timeout + 10 # arbitrary number of additional blocks, used to wait for the settle() call ) wait_until_block(node1.raiden.chain, settlement_block) # Load the new state with the channel settled channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_SETTLED
def test_raidenapi_channel_lifecycle( raiden_network: List[RaidenService], token_addresses, deposit, retry_timeout, settle_timeout_max, ): """Uses RaidenAPI to go through a complete channel lifecycle.""" app1, app2 = raiden_network token_address = token_addresses[0] token_network_address = views.get_token_network_address_by_token_address( views.state_from_raiden(app1), app1.default_registry.address, token_address) assert token_network_address api1 = RaidenAPI(app1) api2 = RaidenAPI(app2) registry_address = app1.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NetworkState.UNKNOWN assert api2.get_node_network_state(api1.address) == NetworkState.UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # Make sure invalid arguments to get_channel_list are caught with pytest.raises(UnknownTokenAddress): api1.get_channel_list(registry_address=registry_address, token_address=None, partner_address=api2.address) address_for_lowest_settle_timeout = make_address() lowest_valid_settle_timeout = app1.config.reveal_timeout * 2 # Make sure a small settle timeout is not accepted when opening a channel with pytest.raises(InvalidSettleTimeout): api1.channel_open( registry_address=app1.default_registry.address, token_address=token_address, partner_address=address_for_lowest_settle_timeout, settle_timeout=BlockTimeout(lowest_valid_settle_timeout - 1), ) # Make sure the smallest settle timeout is accepted api1.channel_open( registry_address=app1.default_registry.address, token_address=token_address, partner_address=address_for_lowest_settle_timeout, settle_timeout=BlockTimeout(lowest_valid_settle_timeout), ) address_for_highest_settle_timeout = make_address() highest_valid_settle_timeout = settle_timeout_max # Make sure a large settle timeout is not accepted when opening a channel with pytest.raises(InvalidSettleTimeout): api1.channel_open( registry_address=app1.default_registry.address, token_address=token_address, partner_address=address_for_highest_settle_timeout, settle_timeout=highest_valid_settle_timeout + 1, ) # Make sure the highest settle timeout is accepted api1.channel_open( registry_address=app1.default_registry.address, token_address=token_address, partner_address=address_for_highest_settle_timeout, settle_timeout=highest_valid_settle_timeout, ) # open is a synchronous api api1.channel_open(app1.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(app1, app2, token_network_address) assert channel.get_status(channel12) == ChannelState.STATE_OPENED registry_address = api1.raiden.default_registry.address # Check that giving a 0 total deposit is not accepted with pytest.raises(DepositMismatch): api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=TokenAmount(0), ) # Load the new state with the deposit api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=deposit, ) # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit with pytest.raises(DepositMismatch): api1.set_total_channel_deposit(registry_address, token_address, api2.address, deposit) channel12 = get_channelstate(app1, app2, token_network_address) assert channel.get_status(channel12) == ChannelState.STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NetworkState.REACHABLE assert api2.get_node_network_state(api1.address) == NetworkState.REACHABLE api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(app1, app2, token_network_address) assert channel.get_status(channel12) == ChannelState.STATE_CLOSED with pytest.raises(UnexpectedChannelState): api1.set_total_channel_deposit(registry_address, token_address, api2.address, deposit + 100) assert wait_for_state_change( app1, ContractReceiveChannelSettled, { "canonical_identifier": { "token_network_address": token_network_address, "channel_identifier": channel12.identifier, } }, retry_timeout, )
def test_channel_lifecycle(raiden_network, token_addresses, deposit): node1, node2 = raiden_network token_address = token_addresses[0] api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN assert not api1.get_channel_list(token_address, api2.address) # open is a synchronous api api1.channel_open(token_address, api2.address) channels = api1.get_channel_list(token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_address) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED event_list1 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert event_list1 == [] # Load the new state with the deposit api1.channel_deposit(token_address, api2.address, deposit) channel12 = get_channelstate(node1, node2, token_address) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert any((event['_event_type'] == b'ChannelNewBalance' and event['participant'] == address_encoder(api1.address)) for event in event_list2) api1.channel_close(token_address, api2.address) node1.raiden.poll_blockchain_events() # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_address) event_list3 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert len(event_list3) > len(event_list2) assert any((event['_event_type'] == b'ChannelClosed' and event['closing_address'] == address_encoder(api1.address)) for event in event_list3) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED settlement_block = ( channel12.close_transaction.finished_block_number + channel12.settle_timeout + 10 # arbitrary number of additional blocks, used to wait for the settle() call ) wait_until_block(node1.raiden.chain, settlement_block) # Load the new state with the channel settled channel12 = get_channelstate(node1, node2, token_address) node1.raiden.poll_blockchain_events() assert channel.get_status(channel12) == CHANNEL_STATE_SETTLED
def test_raidenapi_channel_lifecycle(raiden_network, token_addresses, deposit, retry_timeout, settle_timeout_max): """Uses RaidenAPI to go through a complete channel lifecycle.""" node1, node2 = raiden_network token_address = token_addresses[0] token_network_address = views.get_token_network_address_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address) assert token_network_address api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NetworkState.UNKNOWN assert api2.get_node_network_state(api1.address) == NetworkState.UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # Make sure invalid arguments to get_channel_list are caught with pytest.raises(UnknownTokenAddress): api1.get_channel_list(registry_address=registry_address, token_address=None, partner_address=api2.address) address_for_lowest_settle_timeout = make_address() lowest_valid_settle_timeout = node1.raiden.config.reveal_timeout * 2 # Make sure a small settle timeout is not accepted when opening a channel with pytest.raises(InvalidSettleTimeout): api1.channel_open( registry_address=node1.raiden.default_registry.address, token_address=token_address, partner_address=address_for_lowest_settle_timeout, settle_timeout=lowest_valid_settle_timeout - 1, ) # Make sure the smallest settle timeout is accepted api1.channel_open( registry_address=node1.raiden.default_registry.address, token_address=token_address, partner_address=address_for_lowest_settle_timeout, settle_timeout=lowest_valid_settle_timeout, ) address_for_highest_settle_timeout = make_address() highest_valid_settle_timeout = settle_timeout_max # Make sure a large settle timeout is not accepted when opening a channel with pytest.raises(InvalidSettleTimeout): api1.channel_open( registry_address=node1.raiden.default_registry.address, token_address=token_address, partner_address=address_for_highest_settle_timeout, settle_timeout=highest_valid_settle_timeout + 1, ) # Make sure the highest settle timeout is accepted api1.channel_open( registry_address=node1.raiden.default_registry.address, token_address=token_address, partner_address=address_for_highest_settle_timeout, settle_timeout=highest_valid_settle_timeout, ) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_address) assert channel.get_status(channel12) == ChannelState.STATE_OPENED channel_event_list1 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address) assert must_have_event( channel_event_list1, { "event": ChannelEvent.OPENED, "args": { "participant1": to_checksum_address(api1.address), "participant2": to_checksum_address(api2.address), }, }, ) network_event_list1 = api1.get_blockchain_events_token_network( token_address) assert must_have_event(network_event_list1, {"event": ChannelEvent.OPENED}) registry_address = api1.raiden.default_registry.address # Check that giving a 0 total deposit is not accepted with pytest.raises(DepositMismatch): api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=TokenAmount(0), ) # Load the new state with the deposit api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=deposit, ) # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit with pytest.raises(DepositMismatch): api1.set_total_channel_deposit(registry_address, token_address, api2.address, deposit) channel12 = get_channelstate(node1, node2, token_network_address) assert channel.get_status(channel12) == ChannelState.STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NetworkState.REACHABLE assert api2.get_node_network_state(api1.address) == NetworkState.REACHABLE event_list2 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address) assert must_have_event( event_list2, { "event": ChannelEvent.DEPOSIT, "args": { "participant": to_checksum_address(api1.address), "total_deposit": deposit }, }, ) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_address) event_list3 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address) assert len(event_list3) > len(event_list2) assert must_have_event( event_list3, { "event": ChannelEvent.CLOSED, "args": { "closing_participant": to_checksum_address(api1.address) }, }, ) assert channel.get_status(channel12) == ChannelState.STATE_CLOSED with pytest.raises(UnexpectedChannelState): api1.set_total_channel_deposit(registry_address, token_address, api2.address, deposit + 100) assert wait_for_state_change( node1.raiden, ContractReceiveChannelSettled, { "canonical_identifier": { "token_network_address": token_network_address, "channel_identifier": channel12.identifier, } }, retry_timeout, )
def get_balance(self, channel_state): # pylint: disable=no-self-use return channel.get_balance( channel_state.our_state, channel_state.partner_state, )
def run_test_raidenapi_channel_lifecycle(raiden_network, token_addresses, deposit, retry_timeout): node1, node2 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address) api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # Make sure invalid arguments to get_channel_list are caught with pytest.raises(UnknownTokenAddress): api1.get_channel_list(registry_address=registry_address, token_address=None, partner_address=api2.address) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED channel_event_list1 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address) assert must_have_event( channel_event_list1, { "event": ChannelEvent.OPENED, "args": { "participant1": to_checksum_address(api1.address), "participant2": to_checksum_address(api2.address), }, }, ) network_event_list1 = api1.get_blockchain_events_token_network( token_address) assert must_have_event(network_event_list1, {"event": ChannelEvent.OPENED}) registry_address = api1.raiden.default_registry.address # Check that giving a 0 total deposit is not accepted with pytest.raises(DepositMismatch): api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=0, ) # Load the new state with the deposit api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=deposit, ) # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit with pytest.raises(DepositMismatch): api1.set_total_channel_deposit(registry_address, token_address, api2.address, deposit) channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address) assert must_have_event( event_list2, { "event": ChannelEvent.DEPOSIT, "args": { "participant": to_checksum_address(api1.address), "total_deposit": deposit }, }, ) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_identifier) event_list3 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address) assert len(event_list3) > len(event_list2) assert must_have_event( event_list3, { "event": ChannelEvent.CLOSED, "args": { "closing_participant": to_checksum_address(api1.address) }, }, ) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED assert wait_for_state_change( node1.raiden, ContractReceiveChannelSettled, { "token_network_identifier": token_network_identifier, "channel_identifier": channel12.identifier, }, retry_timeout, )
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_protocol): node1, node2 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address, ) api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # Make sure invalid arguments to get_channel_list are caught with pytest.raises(UnknownTokenAddress): api1.get_channel_list( registry_address=registry_address, token_address=None, partner_address=api2.address, ) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED event_list1 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert any( ( event['event'] == ChannelEvent.OPENED and is_same_address( event['args']['participant1'], to_normalized_address(api1.address), ) and is_same_address( event['args']['participant2'], to_normalized_address(api2.address), ) ) for event in event_list1 ) token_events = api1.get_blockchain_events_token_network( token_address, ) assert token_events[0]['event'] == ChannelEvent.OPENED registry_address = api1.raiden.default_registry.address # Load the new state with the deposit api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit with pytest.raises(DepositMismatch): api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert any( ( event['event'] == ChannelEvent.DEPOSIT and is_same_address( event['args']['participant'], to_normalized_address(api1.address), ) and event['args']['total_deposit'] == deposit ) for event in event_list2 ) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_identifier) event_list3 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert len(event_list3) > len(event_list2) assert any( ( event['event'] == ChannelEvent.CLOSED and is_same_address( event['args']['closing_participant'], to_normalized_address(api1.address), ) ) for event in event_list3 ) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED settlement_block = ( channel12.close_transaction.finished_block_number + channel12.settle_timeout + 10 # arbitrary number of additional blocks, used to wait for the settle() call ) wait_until_block(node1.raiden.chain, settlement_block + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS) state_changes = node1.raiden.wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) assert must_contain_entry(state_changes, ContractReceiveChannelSettled, { 'token_network_identifier': token_network_identifier, 'channel_identifier': channel12.identifier, })
def get_balance(channel_state: NettingChannelState) -> int: return channel.get_balance(channel_state.our_state, channel_state.partner_state)
def update_monitoring_service_from_balance_proof( raiden: "RaidenService", chain_state: ChainState, new_balance_proof: BalanceProofSignedState, non_closing_participant: Address, ) -> None: if raiden.config.services.monitoring_enabled is False: return msg = "Monitoring is enabled but the default monitoring service address is None." assert raiden.default_msc_address is not None, msg channel_state = views.get_channelstate_by_canonical_identifier( chain_state=chain_state, canonical_identifier=new_balance_proof.canonical_identifier) msg = ( f"Failed to update monitoring service due to inability to find " f"channel: {new_balance_proof.channel_identifier} " f"token_network_address: {to_checksum_address(new_balance_proof.token_network_address)}." ) assert channel_state, msg msg = "Monitoring is enabled but the `UserDeposit` contract is None." assert raiden.default_user_deposit is not None, msg rei_balance = raiden.default_user_deposit.effective_balance( raiden.address, BLOCK_ID_LATEST) if rei_balance < MONITORING_REWARD: rdn_balance = to_rdn(rei_balance) rdn_reward = to_rdn(MONITORING_REWARD) log.warning(f"Skipping update to Monitoring service. " f"Your deposit balance {rdn_balance} is less than " f"the required monitoring service reward of {rdn_reward}") return # In production there should be no MonitoringRequest if # channel balance is below a certain threshold. This is # a naive approach that needs to be worked on in the future if raiden.config.environment_type == Environment.PRODUCTION: message = ("Skipping update to Monitoring service. " "Your channel balance {channel_balance} is less than " "the required minimum balance of {min_balance} ") dai_token_network_address = views.get_token_network_address_by_token_address( chain_state=chain_state, token_network_registry_address=raiden.default_registry.address, token_address=DAI_TOKEN_ADDRESS, ) weth_token_network_address = views.get_token_network_address_by_token_address( chain_state=chain_state, token_network_registry_address=raiden.default_registry.address, token_address=WETH_TOKEN_ADDRESS, ) channel_balance = get_balance( sender=channel_state.our_state, receiver=channel_state.partner_state, ) if channel_state.canonical_identifier.token_network_address == dai_token_network_address: if channel_balance < MIN_MONITORING_AMOUNT_DAI: data = dict( channel_balance=channel_balance, min_balance=MIN_MONITORING_AMOUNT_DAI, channel_id=channel_state.canonical_identifier. channel_identifier, token_address=to_checksum_address(DAI_TOKEN_ADDRESS), ) log.warning(message.format(**data), **data) return if channel_state.canonical_identifier.token_network_address == weth_token_network_address: if channel_balance < MIN_MONITORING_AMOUNT_WETH: data = dict( channel_balance=channel_balance, min_balance=MIN_MONITORING_AMOUNT_WETH, channel_id=channel_state.canonical_identifier. channel_identifier, token_address=to_checksum_address(WETH_TOKEN_ADDRESS), ) log.warning(message.format(**data), **data) return log.info( "Received new balance proof, creating message for Monitoring Service.", node=to_checksum_address(raiden.address), balance_proof=new_balance_proof, ) monitoring_message = RequestMonitoring.from_balance_proof_signed_state( balance_proof=new_balance_proof, non_closing_participant=non_closing_participant, reward_amount=MONITORING_REWARD, monitoring_service_contract_address=raiden.default_msc_address, ) monitoring_message.sign(raiden.signer) raiden.transport.broadcast(constants.MONITORING_BROADCASTING_ROOM, monitoring_message)
def set_total_channel_withdraw( self, registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, partner_address: Address, total_withdraw: WithdrawAmount, retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> None: """ Set the `total_withdraw` in the channel with the peer at `partner_address` and the given `token_address`. Raises: InvalidBinaryAddress: If either token_address or partner_address is not 20 bytes long. RaidenUnrecoverableError: May happen for multiple reasons: - During preconditions checks, if the channel was not open at the time of the approve_and_set_total_deposit call. - If the transaction fails during gas estimation or if a previous withdraw transaction with the same value was already mined. DepositMismatch: The total withdraw amount did not increase. """ chain_state = views.state_from_raiden(self.raiden) token_addresses = views.get_token_identifiers(chain_state, registry_address) channel_state = views.get_channelstate_for( chain_state=chain_state, token_network_registry_address=registry_address, token_address=token_address, partner_address=partner_address, ) if not is_binary_address(token_address): raise InvalidBinaryAddress( "Expected binary address format for token in channel deposit") if not is_binary_address(partner_address): raise InvalidBinaryAddress( "Expected binary address format for partner in channel deposit" ) if token_address not in token_addresses: raise UnknownTokenAddress("Unknown token address") if channel_state is None: raise NonexistingChannel( "No channel with partner_address for the given token") if total_withdraw <= channel_state.our_total_withdraw: raise WithdrawMismatch( f"Total withdraw {total_withdraw} did not increase") current_balance = channel.get_balance( sender=channel_state.our_state, receiver=channel_state.partner_state) amount_to_withdraw = total_withdraw - channel_state.our_total_withdraw if amount_to_withdraw > current_balance: raise InsufficientFunds( "The withdraw of {} is bigger than the current balance of {}". format(amount_to_withdraw, current_balance)) self.raiden.withdraw( canonical_identifier=channel_state.canonical_identifier, total_withdraw=total_withdraw) waiting.wait_for_withdraw_complete( raiden=self.raiden, canonical_identifier=channel_state.canonical_identifier, total_withdraw=total_withdraw, retry_timeout=retry_timeout, )