def test_channelstate_send_direct_transfer(): """Sending a direct transfer must update the participant state. This tests only the state of the sending node, without synchronisation. """ our_model1, _ = create_model(70) partner_model1, _ = create_model(100) channel_state = create_channel_from_models(our_model1, partner_model1) amount = 30 payment_identifier = 1 message_identifier = random.randint(0, UINT64_MAX) channel.send_directtransfer( channel_state, amount, message_identifier, payment_identifier, ) our_model2 = our_model1._replace( distributable=our_model1.distributable - amount, balance=our_model1.balance - amount, next_nonce=2, ) partner_model2 = partner_model1._replace( distributable=partner_model1.distributable + amount, balance=partner_model1.balance + amount, ) assert_partner_state(channel_state.our_state, channel_state.partner_state, our_model2) assert_partner_state(channel_state.partner_state, channel_state.our_state, partner_model2)
def test_contract_receive_channelnew_must_be_idempotent(): block_number = 10 pseudo_random_generator = random.Random() token_network_id = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState(token_network_id, token_id) amount = 30 our_balance = amount + 50 channel_state1 = factories.make_channel(our_balance=our_balance) channel_state2 = copy.deepcopy(channel_state1) state_change1 = ContractReceiveChannelNew(token_network_id, channel_state1) token_network.state_transition( token_network_state, state_change1, pseudo_random_generator, block_number, ) # change the existing channel payment_identifier = 1 message_identifier = random.randint(0, UINT64_MAX) channel.send_directtransfer( channel_state1, amount, message_identifier, payment_identifier, ) state_change2 = ContractReceiveChannelNew(token_network_id, channel_state2) # replay the ContractReceiveChannelNew state change iteration = token_network.state_transition( token_network_state, state_change2, pseudo_random_generator, block_number, ) msg = 'the channel must not been overwritten' channelmap_by_id = iteration.new_state.channelidentifiers_to_channels assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg channelmap_by_address = iteration.new_state.partneraddresses_to_channels assert channelmap_by_address[ channel_state1.partner_state.address] == channel_state1, msg
def test_contract_receive_channelnew_must_be_idempotent(): block_number = 10 pseudo_random_generator = random.Random() token_network_id = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState(token_network_id, token_id) amount = 30 our_balance = amount + 50 channel_state1 = factories.make_channel(our_balance=our_balance) channel_state2 = copy.deepcopy(channel_state1) state_change1 = ContractReceiveChannelNew(token_network_id, channel_state1) token_network.state_transition( token_network_state, state_change1, pseudo_random_generator, block_number, ) # change the existing channel payment_identifier = 1 message_identifier = random.randint(0, UINT64_MAX) channel.send_directtransfer( channel_state1, amount, message_identifier, payment_identifier, ) state_change2 = ContractReceiveChannelNew(token_network_id, channel_state2) # replay the ContractReceiveChannelNew state change iteration = token_network.state_transition( token_network_state, state_change2, pseudo_random_generator, block_number, ) msg = 'the channel must not been overwritten' channelmap_by_id = iteration.new_state.channelidentifiers_to_channels assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg channelmap_by_address = iteration.new_state.partneraddresses_to_channels assert channelmap_by_address[channel_state1.partner_state.address] == channel_state1, msg
def test_receive_directtransfer_invalidnonce(raiden_network, deposit, token_addresses): app0, app1 = raiden_network registry_address = app0.raiden.default_registry.address token_address = token_addresses[0] channel0 = get_channelstate(app0, app1, token_address) transferred_amount = 10 same_payment_identifier = 1 message_identifier = random.randint(0, UINT64_MAX) event = channel.send_directtransfer( registry_address, channel0, transferred_amount, message_identifier, same_payment_identifier, ) direct_transfer_message = DirectTransfer.from_event(event) sign_and_inject( direct_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) # Send a *different* direct transfer with the *same nonce* invalid_transferred_amount = transferred_amount // 2 message_identifier = random.randint(0, UINT64_MAX) invalid_direct_transfer_message = DirectTransfer( message_identifier=message_identifier, payment_identifier=same_payment_identifier, nonce=1, registry_address=registry_address, token=token_address, channel=channel0.identifier, transferred_amount=invalid_transferred_amount, recipient=app1.raiden.address, locksroot=EMPTY_MERKLE_ROOT, ) sign_and_inject( invalid_direct_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) assert_synched_channel_state( token_address, app0, deposit - transferred_amount, [], app1, deposit + transferred_amount, [], )
def test_receive_directtransfer_invalidnonce(raiden_network, deposit, 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) transferred_amount = 10 same_payment_identifier = 1 message_identifier = random.randint(0, UINT64_MAX) event = channel.send_directtransfer( channel0, transferred_amount, message_identifier, same_payment_identifier, ) direct_transfer_message = DirectTransfer.from_event(event) sign_and_inject( direct_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) # Send a *different* direct transfer with the *same nonce* invalid_transferred_amount = transferred_amount // 2 message_identifier = random.randint(0, UINT64_MAX) invalid_direct_transfer_message = DirectTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=message_identifier, payment_identifier=same_payment_identifier, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel0.identifier, transferred_amount=invalid_transferred_amount, locked_amount=0, recipient=app1.raiden.address, locksroot=EMPTY_MERKLE_ROOT, ) sign_and_inject( invalid_direct_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) assert_synched_channel_state( token_network_identifier, app0, deposit - transferred_amount, [], app1, deposit + transferred_amount, [], )
def increase_transferred_amount( payment_network_identifier, from_channel, partner_channel, amount, pkey, ): # increasing the transferred amount by a value larger than distributable # would put one end of the channel in a negative balance, which is forbidden distributable_from_to = channel.get_distributable( from_channel.our_state, from_channel.partner_state, ) assert distributable_from_to >= amount, 'operation would end up in a incosistent state' message_identifier = random.randint(0, UINT64_MAX) payment_identifier = 1 registry_address = make_address() event = channel.send_directtransfer( registry_address, from_channel, amount, payment_identifier, message_identifier, ) direct_transfer_message = DirectTransfer.from_event(event) address = privatekey_to_address(pkey) sign_key = PrivateKey(pkey) direct_transfer_message.sign(sign_key, address) # if this fails it's not the right key for the current `from_channel` assert direct_transfer_message.sender == from_channel.our_state.address balance_proof = balanceproof_from_envelope(direct_transfer_message) receive_direct = ReceiveTransferDirect( payment_network_identifier, from_channel.token_address, message_identifier, payment_identifier, balance_proof, ) channel.handle_receive_directtransfer( partner_channel, receive_direct, ) return direct_transfer_message