def test_mediated_transfer(iterations=ITERATIONS): identifier = 1 amount = 1 expiration = 1 hashlock = sha3(ADDRESS) lock = Lock(amount, expiration, hashlock) nonce = 1 asset = ADDRESS balance = 1 recipient = ADDRESS locksroot = sha3(ADDRESS) target = ADDRESS initiator = ADDRESS msg = MediatedTransfer( identifier, nonce, asset, balance, recipient, locksroot, lock, target, initiator, fee=0, ) msg.sign(PRIVKEY, ADDRESS) run_timeit('MediatedTranfer', msg, iterations=iterations)
def test_decode_refund_transfer(settle_timeout, tester_state, tester_token): privatekey0 = tester.DEFAULT_KEY privatekey1 = tester.k1 address0 = privatekey_to_address(privatekey0) address1 = privatekey_to_address(privatekey1) dtester = deploy_decoder_tester(tester_state, tester_token.address, address0, address1, settle_timeout) locksroot = sha3('Mainz') amount = 1337 expiration = 19 lock = Lock(amount, expiration, locksroot) message = RefundTransfer(identifier=321313, nonce=4242452, token=tester_token.address, transferred_amount=amount, recipient=address1, locksroot=locksroot, lock=lock) message.sign(PrivateKey(privatekey0, ctx=GLOBAL_CTX, raw=True), address0) _, publickey = wrap_and_validate(message.encode()) recovered_address = address_from_key(publickey) assert recovered_address == address0 assert dtester.testDecodeTransfer(message.encode(), sender=privatekey1) is True assert dtester.decodedNonce() == 4242452 assert dtester.decodedToken() == tester_token.address.encode('hex') assert dtester.decodedLocksroot() == locksroot
def _update_balance_proof_data(self, partner, amount, expiration, secret): expected = self._get_balance_proof_data(partner) lock = Lock(amount=amount, expiration=expiration, secrethash=sha3(secret)) expected.update(amount, lock.lockhash) return expected
def test_withdraw_twice(tester_registry_address, reveal_timeout, tester_channels, tester_chain): """ A lock can be withdrawn only once, the second try must fail. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] pseudo_random_generator = random.Random() lock_expiration = tester_chain.block.number + reveal_timeout + 5 secret = b'secretsecretsecretsecretsecretse' new_block = Block(tester_chain.block.number) channel.state_transition( channel0, new_block, pseudo_random_generator, new_block.block_number, ) channel.state_transition( channel1, new_block, pseudo_random_generator, new_block.block_number, ) lock = Lock(17, lock_expiration, sha3(secret)) mediated0 = make_mediated_transfer( tester_registry_address, channel1, channel0, privatekey_to_address(pkey1), privatekey_to_address(pkey0), lock, pkey1, secret, ) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey0, ) unlock_proofs = channel.get_known_unlocks(channel0.partner_state) proof = unlock_proofs[0] nettingchannel.withdraw( proof.lock_encoded, b''.join(proof.merkle_proof), proof.secret, sender=pkey0, ) with pytest.raises(TransactionFailed): nettingchannel.withdraw( proof.lock_encoded, b''.join(proof.merkle_proof), proof.secret, sender=pkey0, )
def _(properties, defaults=None) -> LockedTransferSignedState: defaults = defaults or LOCKED_TRANSFER_SIGNED_STATE_DEFAULTS params = _properties_to_dict(properties, defaults) transfer_params = _properties_to_dict(params.pop('transfer'), defaults.transfer) balance_proof_params = _properties_to_dict( transfer_params.pop('balance_proof'), defaults.transfer.balance_proof, ) lock = Lock( amount=transfer_params.pop('amount'), expiration=transfer_params.pop('expiration'), secrethash=sha3(transfer_params.pop('secret')), ) pkey = params.pop('pkey') signer = LocalSigner(pkey) sender = params.pop('sender') params.update(transfer_params) params.update(balance_proof_params) params['token_network_address'] = params.pop('token_network_identifier') if params['locksroot'] == EMPTY_MERKLE_ROOT: params['locksroot'] = lock.lockhash locked_transfer = LockedTransfer(lock=lock, **params) locked_transfer.sign(signer) assert locked_transfer.sender == sender return lockedtransfersigned_from_message(locked_transfer)
def test_mediated_after_direct_transfer(reveal_timeout, settle_timeout, deposit, tester_state, tester_channels, tester_token): """ The transfer types must not change the behavior of the dispute. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) first_amount0 = 90 block_number = tester_state.block.number make_direct_transfer_from_channel( block_number, channel0, channel1, first_amount0, pkey0, ) lock_expiration = tester_state.block.number + reveal_timeout + 5 new_block = Block(tester_state.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock1 = Lock(amount=31, expiration=lock_expiration, hashlock=sha3('lock2')) second_mediated0 = make_mediated_transfer( channel0, channel1, address0, address1, lock1, pkey0, tester_state.block.number, ) nettingchannel.close(sender=pkey0) second_mediated0_hash = sha3(second_mediated0.packed().data[:-65]) nettingchannel.updateTransfer( second_mediated0.nonce, second_mediated0.transferred_amount, second_mediated0.locksroot, second_mediated0_hash, second_mediated0.signature, sender=pkey1, ) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial_balance0 + deposit - first_amount0 balance1 = initial_balance1 + deposit + first_amount0 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey1) == balance1
def test_receive_mediatedtransfer_outoforder(raiden_network, private_keys): alice_app = raiden_network[0] messages = setup_messages_cb() graph = alice_app.raiden.channelgraphs.values()[0] token_address = graph.token_address mt_helper = MediatedTransferTestHelper(raiden_network, graph) initiator_address = alice_app.raiden.address path = mt_helper.get_paths_of_length(initiator_address, 2) # make sure we have no messages before the transfer assert len(messages) == 0 alice_address, bob_address, charlie_address = path amount = 10 result = alice_app.raiden.transfer_async( token_address, amount, charlie_address, ) # check for invitation ping assert len(messages) == 2 # Ping, Ack ping_message = decode(messages[0]) assert isinstance(ping_message, Ping) decoded = decode(messages[1]) assert isinstance(decoded, Ack) assert decoded.echo == sha3(ping_message.encode() + charlie_address) assert result.wait(timeout=10) gevent.sleep(1.) # check that transfer messages were added assert len(messages) == 22 # Ping, Ack + tranfer messages # make sure that the mediated transfer is sent after the invitation ping assert isinstance(decode(messages[2]), MediatedTransfer) # and now send one more mediated transfer with the same nonce, simulating # an out-of-order/resent message that arrives late locksroot = HASH lock = Lock(amount, 1, locksroot) identifier = create_default_identifier( alice_app.raiden.address, graph.token_address, charlie_address, ) mediated_transfer = MediatedTransfer(identifier=identifier, nonce=1, token=token_address, transferred_amount=amount, recipient=bob_address, locksroot=locksroot, lock=lock, target=charlie_address, initiator=initiator_address, fee=0) alice_key = PrivateKey(private_keys[0]) bob_app = mt_helper.get_app_from_address(bob_address) sign_and_send(mediated_transfer, alice_key, alice_address, bob_app)
def test_receive_hashlocktransfer_unknown(raiden_network): app0 = raiden_network[0] # pylint: disable=unbalanced-tuple-unpacking graph0 = app0.raiden.channelgraphs.values()[0] other_key = PrivateKey(HASH2) other_address = privatekey_to_address(HASH2) amount = 10 lock = Lock(amount, 1, HASH) refund_transfer = RefundTransfer( identifier=1, nonce=1, token=graph0.token_address, transferred_amount=amount, recipient=app0.raiden.address, locksroot=HASH, lock=lock ) sign_and_send(refund_transfer, other_key, other_address, app0) secret = Secret(1, HASH, graph0.token_address) sign_and_send(secret, other_key, other_address, app0) secret_request = SecretRequest(1, HASH, 1) sign_and_send(secret_request, other_key, other_address, app0) reveal_secret = RevealSecret(HASH) sign_and_send(reveal_secret, other_key, other_address, app0)
def run_test_receive_lockedtransfer_invalidnonce(raiden_network, number_of_nodes, deposit, token_addresses, reveal_timeout, network_wait): app0, app1, app2 = 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) amount = 10 transfer( initiator_app=app0, target_app=app2, token_address=token_address, amount=amount, identifier=1, timeout=network_wait * number_of_nodes, ) amount = 10 payment_identifier = 1 repeated_nonce = 1 expiration = reveal_timeout * 2 mediated_transfer_message = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, payment_hash_invoice=EMPTY_PAYMENT_HASH_INVOICE, nonce=repeated_nonce, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel0.identifier, transferred_amount=amount, locked_amount=amount, recipient=app1.raiden.address, locksroot=UNIT_SECRETHASH, lock=Lock(amount=amount, expiration=expiration, secrethash=UNIT_SECRETHASH), target=app2.raiden.address, initiator=app0.raiden.address, fee=0, ) sign_and_inject(mediated_transfer_message, app0.raiden.signer, app1) with gevent.Timeout(network_wait): wait_assert( assert_synced_channel_state, token_network_identifier, app0, deposit - amount, [], app1, deposit + amount, [], )
def test_receive_hashlocktransfer_unknown(raiden_network): app0 = raiden_network[0] # pylint: disable=unbalanced-tuple-unpacking token_manager0 = app0.raiden.managers_by_token_address.values()[0] other_key = PrivateKey(HASH2, ctx=GLOBAL_CTX, raw=True) other_address = privatekey_to_address(other_key.private_key) amount = 10 lock = Lock(amount, 1, HASH) refund_transfer = RefundTransfer(identifier=1, nonce=1, token=token_manager0.token_address, transferred_amount=amount, recipient=app0.raiden.address, locksroot=HASH, lock=lock) sign_and_send(refund_transfer, other_key, other_address, app0) secret = Secret(1, HASH, token_manager0.token_address) sign_and_send(secret, other_key, other_address, app0) secret_request = SecretRequest(1, HASH, 1) sign_and_send(secret_request, other_key, other_address, app0) reveal_secret = RevealSecret(HASH) sign_and_send(reveal_secret, other_key, other_address, app0)
def test_merkle_proof_one_lock(tester_chain, tester_nettingchannel_library_address): """ computeMerkleRoot and the python implementation must compute the same value for a merkle tree with a single lock.""" auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address) amount = 10 expiration = 77 secret = sha3(b'test_merkle_proof_one_lock') secrethash = sha3(secret) lock = Lock(amount, expiration, secrethash) layers = compute_layers([lock.lockhash]) merkletree = MerkleTreeState(layers) proof = compute_merkleproof_for(merkletree, lock.lockhash) assert len(proof) == 0, 'with only one element the proof is empty' smart_contact_root = auxiliary.computeMerkleRoot( lock.as_bytes, b''.join(proof), ) assert smart_contact_root == merkleroot(merkletree)
def make_signed_transfer_from_counter(counter): lock = Lock( amount=next(counter), expiration=next(counter), secrethash=sha3(factories.make_secret(next(counter))), ) signed_transfer = factories.make_signed_transfer( amount=next(counter), initiator=factories.make_address(), target=factories.make_address(), expiration=next(counter), secret=factories.make_secret(next(counter)), payment_identifier=next(counter), message_identifier=next(counter), nonce=next(counter), transferred_amount=next(counter), locked_amount=next(counter), locksroot=sha3(lock.as_bytes), recipient=factories.make_address(), channel_identifier=next(counter), token_network_address=factories.make_address(), token=factories.make_address(), pkey=factories.HOP1_KEY, sender=factories.HOP1, ) return signed_transfer
def _(properties, defaults=None) -> LockedTransferSignedState: transfer: LockedTransferSignedStateProperties = create_properties( properties, defaults) params = {key: value for key, value in transfer.__dict__.items()} lock = Lock(amount=transfer.amount, expiration=transfer.expiration, secrethash=sha3(transfer.secret)) pkey = params.pop("pkey") signer = LocalSigner(pkey) sender = params.pop("sender") canonical_identifier = params.pop("canonical_identifier") params["chain_id"] = int(canonical_identifier.chain_identifier) params["channel_identifier"] = int(canonical_identifier.channel_identifier) params[ "token_network_address"] = canonical_identifier.token_network_address if params["locksroot"] == EMPTY_MERKLE_ROOT: params["locksroot"] = lock.lockhash locked_transfer = LockedTransfer(lock=lock, **params) locked_transfer.sign(signer) assert locked_transfer.sender == sender return lockedtransfersigned_from_message(locked_transfer)
def test_receive_hashlocktransfer_unknown(raiden_network): app0 = raiden_network[0] # pylint: disable=unbalanced-tuple-unpacking token_manager0 = app0.raiden.managers_by_token_address.values()[0] other_key = PrivateKey(HASH2, ctx=GLOBAL_CTX, raw=True) other_address = privatekey_to_address(other_key.private_key) amount = 10 lock = Lock(amount, 1, HASH) refund_transfer = RefundTransfer(identifier=1, nonce=1, token=token_manager0.token_address, transferred_amount=amount, recipient=app0.raiden.address, locksroot=HASH, lock=lock) sign_and_send(refund_transfer, other_key, other_address, app0) transfer_timeout = TransferTimeout(HASH, HASH) sign_and_send(transfer_timeout, other_key, other_address, app0) secret = Secret(1, HASH, token_manager0.token_address) sign_and_send(secret, other_key, other_address, app0) secret_request = SecretRequest(1, HASH, 1) sign_and_send(secret_request, other_key, other_address, app0) reveal_secret = RevealSecret(HASH) sign_and_send(reveal_secret, other_key, other_address, app0) # Whenever processing of ConfirmTransfer is implemented test it here # too by removing the expectation of an exception with pytest.raises(KeyError): confirm_transfer = ConfirmTransfer(HASH) sign_and_send(confirm_transfer, other_key, other_address, app0)
def test_settle_with_locked_mediated_transfer_for_counterparty( deposit, settle_timeout, reveal_timeout, tester_chain, tester_channels, tester_token): """ Test settle with a locked mediated transfer for the counter party. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] payment_network_identifier = factories.make_address() address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) transferred_amount0 = 30 increase_transferred_amount( payment_network_identifier, channel0, channel1, transferred_amount0, pkey0, ) expiration0 = tester_chain.block.number + reveal_timeout + 5 new_block = Block(tester_chain.block.number) channel.state_transition(channel0, new_block, new_block.block_number) channel.state_transition(channel1, new_block, new_block.block_number) lock0 = Lock(amount=29, expiration=expiration0, secrethash=sha3(b'lock1')) mediated0 = make_mediated_transfer( channel0, channel1, address0, address1, lock0, pkey0, ) nettingchannel.close(sender=pkey0) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.updateTransfer( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey1) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial0 + deposit - transferred_amount0 balance1 = initial1 + transferred_amount0 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1
def create_lockedtransfer(self, amount, expiration, hashlock): """ Return a LockedTransfer message. This message needs to be signed and registered with the channel before sent. """ if not self.isopen: raise ValueError('The channel is closed') block_number = self.external_state.get_block_number() # expiration is not sufficient for guarantee settling if expiration - block_number >= self.settle_timeout: log.debug( "Transfer expiration doesn't allow for corret settlement.", expiration=expiration, block_number=block_number, settle_timeout=self.settle_timeout, ) raise ValueError('Invalid expiration') if expiration - self.reveal_timeout < block_number: log.debug( 'Expiration smaller than the minimum requried.', expiration=expiration, block_number=block_number, reveal_timeout=self.reveal_timeout, ) raise ValueError('Invalid expiration') from_ = self.our_state to_ = self.partner_state distributable = from_.distributable(to_) if amount <= 0 or amount > distributable: log.debug( 'Insufficient funds', amount=amount, distributable=distributable, ) raise ValueError('Insufficient funds') lock = Lock(amount, expiration, hashlock) # start of critical read section transfered_amount = from_.transfered_amount updated_locksroot = to_.locked.root_with(lock) # end of critical read section return LockedTransfer( nonce=from_.nonce, asset=self.asset_address, transfered_amount=transfered_amount, recipient=to_.address, locksroot=updated_locksroot, lock=lock, )
def test_receive_lockedtransfer_invalidnonce( raiden_network, deposit, token_addresses, reveal_timeout, network_wait ): app0, app1, app2 = 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) amount = 10 mediated_transfer( app0, app2, token_network_identifier, amount, timeout=network_wait, ) amount = 10 payment_identifier = 1 repeated_nonce = 1 expiration = reveal_timeout * 2 mediated_transfer_message = LockedTransfer( message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=repeated_nonce, token_network_address=token_network_identifier, token=token_address, channel=channel0.identifier, transferred_amount=amount, locked_amount=amount, recipient=app1.raiden.address, locksroot=UNIT_SECRETHASH, lock=Lock(amount, expiration, UNIT_SECRETHASH), target=app2.raiden.address, initiator=app0.raiden.address, fee=0, ) sign_and_inject( mediated_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) assert_synched_channel_state( token_network_identifier, app0, deposit - amount, [], app1, deposit + amount, [], )
def make_signed_transfer( amount, initiator, target, expiration, secret, payment_identifier=1, message_identifier=None, nonce=1, transferred_amount=0, locked_amount=None, locksroot=EMPTY_MERKLE_ROOT, recipient=UNIT_TRANSFER_TARGET, channel_identifier=UNIT_CHANNEL_ID, token_network_address=UNIT_TOKEN_NETWORK_ADDRESS, token=UNIT_TOKEN_ADDRESS, pkey=UNIT_TRANSFER_PKEY, sender=UNIT_TRANSFER_SENDER, ): if message_identifier is None: message_identifier = random.randint(0, UINT64_MAX) secrethash = sha3(secret) lock = Lock( amount, expiration, secrethash, ) if locksroot == EMPTY_MERKLE_ROOT: locksroot = sha3(lock.as_bytes) if locked_amount is None: locked_amount = amount else: assert locked_amount >= amount transfer = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=message_identifier, payment_identifier=payment_identifier, nonce=nonce, token_network_address=token_network_address, token=token, channel_identifier=channel_identifier, transferred_amount=transferred_amount, locked_amount=locked_amount, recipient=recipient, locksroot=locksroot, lock=lock, target=target, initiator=initiator, ) transfer.sign(pkey) assert transfer.sender == sender return lockedtransfersigned_from_message(transfer)
def test_withdraw_expired_lock(reveal_timeout, tester_channels, tester_chain): pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] pseudo_random_generator = random.Random() lock_timeout = reveal_timeout + 5 lock_expiration = tester_chain.block.number + lock_timeout secret = b'expiredlockexpiredlockexpiredloc' secrethash = sha3(secret) new_block = Block(tester_chain.block.number) channel.state_transition( channel0, new_block, pseudo_random_generator, new_block.block_number, ) channel.state_transition( channel1, new_block, pseudo_random_generator, new_block.block_number, ) lock1 = Lock(amount=31, expiration=lock_expiration, secrethash=secrethash) mediated0 = make_mediated_transfer( channel1, channel0, privatekey_to_address(pkey0), privatekey_to_address(pkey1), lock1, pkey1, secret, ) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey0, ) # expire the lock tester_chain.mine(number_of_blocks=lock_timeout + 1) unlock_proofs = channel.get_known_unlocks(channel0.partner_state) proof = unlock_proofs[0] with pytest.raises(TransactionFailed): nettingchannel.withdraw( proof.lock_encoded, b''.join(proof.merkle_proof), proof.secret, sender=pkey0, )
def test_unlock(deposit, settle_timeout, reveal_timeout, tester_channels, tester_state, tester_token): pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) lock_amount = 31 lock_expiration = tester_state.block.number + reveal_timeout + 5 secret = 'secretsecretsecretsecretsecretse' hashlock = sha3(secret) new_block = Block(tester_state.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock0 = Lock(lock_amount, lock_expiration, hashlock) mediated0 = make_mediated_transfer( channel0, channel1, address0, address1, lock0, pkey0, tester_state.block.number, secret, ) mediated0_data = str(mediated0.packed().data) proof = channel1.our_state.balance_proof.compute_proof_for_lock( secret, mediated0.lock, ) nettingchannel.close(mediated0_data, sender=pkey1) tester_state.mine(number_of_blocks=1) nettingchannel.unlock( proof.lock_encoded, ''.join(proof.merkle_proof), proof.secret, sender=pkey1, ) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = initial_balance0 + deposit - lock0.amount balance1 = initial_balance1 + deposit + lock0.amount assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_received_lockedtransfer_closedchannel(raiden_network, reveal_timeout, token_addresses, deposit): app0, app1 = raiden_network registry_address = app0.raiden.default_registry.address token_address = token_addresses[0] channel0 = get_channelstate(app0, app1, token_address) RaidenAPI(app1.raiden).channel_close( registry_address, token_address, app0.raiden.address, ) wait_until_block( app0.raiden.chain, app0.raiden.chain.block_number() + 1, ) # Now receive one mediated transfer for the closed channel lock_amount = 10 payment_identifier = 1 expiration = reveal_timeout * 2 mediated_transfer_message = LockedTransfer( message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=1, registry_address=app0.raiden.default_registry.address, token=token_address, channel=channel0.identifier, transferred_amount=0, locked_amount=lock_amount, recipient=app1.raiden.address, locksroot=UNIT_SECRETHASH, lock=Lock(lock_amount, expiration, UNIT_SECRETHASH), target=app1.raiden.address, initiator=app0.raiden.address, fee=0) sign_and_inject( mediated_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) # The local state must not change since the channel is already closed assert_synched_channel_state( token_address, app0, deposit, [], app1, deposit, [], )
def test_receive_lockedtransfer_invalidrecipient( raiden_network, token_addresses, reveal_timeout, deposit, ): 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) payment_identifier = 1 invalid_recipient = make_address() lock_amount = 10 expiration = reveal_timeout * 2 mediated_transfer_message = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel0.identifier, transferred_amount=0, locked_amount=lock_amount, recipient=invalid_recipient, locksroot=UNIT_SECRETHASH, lock=Lock(amount=lock_amount, expiration=expiration, secrethash=UNIT_SECRETHASH), target=app1.raiden.address, initiator=app0.raiden.address, fee=0, ) sign_and_inject( mediated_transfer_message, app0.raiden.signer, app1, ) assert_synced_channel_state( token_network_identifier, app0, deposit, [], app1, deposit, [], )
def test_receive_lockedtransfer_invalidsender( raiden_network, token_addresses, deposit, reveal_timeout, ): app0, app1 = raiden_network token_address = token_addresses[0] other_key, other_address = make_privkey_address() 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) lock_amount = 10 expiration = reveal_timeout * 2 mediated_transfer_message = LockedTransfer( message_identifier=random.randint(0, UINT64_MAX), payment_identifier=1, nonce=1, token_network_address=token_network_identifier, token=token_address, channel=channel0.identifier, transferred_amount=0, locked_amount=lock_amount, recipient=app0.raiden.address, locksroot=UNIT_SECRETHASH, lock=Lock(lock_amount, expiration, UNIT_SECRETHASH), target=app0.raiden.address, initiator=other_address, fee=0, ) sign_and_inject( mediated_transfer_message, other_key, other_address, app0, ) assert_synched_channel_state( token_network_identifier, app0, deposit, [], app1, deposit, [], )
def make_signed_transfer( amount, initiator, target, expiration, secret, payment_identifier=1, message_identifier=None, nonce=1, transferred_amount=0, locked_amount=None, recipient=UNIT_TRANSFER_TARGET, channel_identifier=UNIT_CHANNEL_ADDRESS, token=UNIT_TOKEN_ADDRESS, pkey=UNIT_TRANSFER_PKEY, sender=UNIT_TRANSFER_SENDER, ): if message_identifier is None: message_identifier = random.randint(0, UINT64_MAX) secrethash = sha3(secret) lock = Lock( amount, expiration, secrethash, ) if locked_amount is None: locked_amount = amount else: assert locked_amount >= amount transfer = LockedTransfer( message_identifier, payment_identifier, nonce, UNIT_REGISTRY_IDENTIFIER, token, channel_identifier, transferred_amount, locked_amount, recipient, lock.lockhash, lock, target, initiator, ) transfer.sign(pkey) assert transfer.sender == sender return lockedtransfersigned_from_message(transfer)
def test_receive_mediatedtransfer_invalidnonce(raiden_network, deposit, token_addresses, reveal_timeout, network_wait): app0, app1, app2 = raiden_network token_address = token_addresses[0] channel0 = get_channelstate(app0, app1, token_address) amount = 10 mediated_transfer( app0, app2, token_address, amount, timeout=network_wait, ) amount = 10 identifier = 1 repeated_nonce = 1 expiration = reveal_timeout * 2 mediated_transfer_message = MediatedTransfer( identifier=identifier, nonce=repeated_nonce, token=token_address, channel=channel0.identifier, transferred_amount=amount, recipient=app1.raiden.address, locksroot=UNIT_SECRETHASH, lock=Lock(amount, expiration, UNIT_SECRETHASH), target=app2.raiden.address, initiator=app0.raiden.address, fee=0, ) sign_and_inject( mediated_transfer_message, app0.raiden.private_key, app0.raiden.address, app1, ) assert_synched_channel_state( token_address, app0, deposit - amount, [], app1, deposit + amount, [], )
def create_lockedtransfer(self, block_number, amount, identifier, expiration, hashlock): """ Return a LockedTransfer message. This message needs to be signed and registered with the channel before sent. """ timeout = expiration - block_number if not self.can_transfer: raise ValueError( 'Transfer not possible, no funding or channel closed.') # the expiration cannot be lower than the reveal timeout (otherwise we # dont have enough time to listen for the ChannelSecretRevealed event) if timeout <= self.reveal_timeout: log.debug( 'Lock expiration is lower than reveal timeout.', expiration=expiration, block_number=self.block_number, reveal_timeout=self.reveal_timeout, ) raise ValueError('Invalid expiration.') from_ = self.our_state to_ = self.partner_state distributable = from_.distributable(to_) if amount <= 0 or amount > distributable: log.debug( 'Insufficient funds', amount=amount, distributable=distributable, ) raise ValueError('Insufficient funds') lock = Lock(amount, expiration, hashlock) updated_locksroot = to_.compute_merkleroot_with(include=lock) transferred_amount = from_.transferred_amount return LockedTransfer( identifier=identifier, nonce=from_.nonce, token=self.token_address, transferred_amount=transferred_amount, recipient=to_.address, locksroot=updated_locksroot, lock=lock, )
def test_settle_with_locked_mediated_transfer_for_counterparty( deposit, settle_timeout, reveal_timeout, tester_state, tester_channels, tester_token): """ Test settle with a locked mediated transfer for the counter party. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) transferred_amount0 = 30 increase_transferred_amount(channel0, channel1, transferred_amount0) expiration0 = tester_state.block.number + reveal_timeout + 5 new_block = Block(tester_state.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock0 = Lock(amount=29, expiration=expiration0, hashlock=sha3('lock1')) mediated = make_mediated_transfer( channel0, channel1, address0, address1, lock0, pkey0, tester_state.block.number, ) nettingchannel.close('', sender=pkey0) transfer_data = str(mediated.packed().data) nettingchannel.updateTransfer(transfer_data, sender=pkey1) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey1) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial0 + deposit - transferred_amount0 balance1 = initial1 + transferred_amount0 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1
def test_locked_transfer(iterations=ITERATIONS): amount = 1 expiration = 1 hashlock = sha3(ADDRESS) lock = Lock(amount, expiration, hashlock) nonce = 1 asset = ADDRESS balance = 1 recipient = ADDRESS locksroot = sha3(ADDRESS) msg = LockedTransfer(nonce, asset, balance, recipient, locksroot, lock) msg.sign(PRIVKEY) run_timeit('LockedTransfer', msg, iterations=iterations)
def test_receive_mediatedtransfer_invalid_address(raiden_network, private_keys): alice_app = raiden_network[0] bob_app = raiden_network[1] graph = alice_app.raiden.token_to_channelgraph.values()[0] token_address = graph.token_address channel0 = channel(alice_app, bob_app, token_address) mt_helper = MediatedTransferTestHelper(raiden_network, graph) initiator_address = alice_app.raiden.address path = mt_helper.get_paths_of_length(initiator_address, 2) alice_address, bob_address, charlie_address = path amount = 10 result = alice_app.raiden.mediated_transfer_async( token_address, amount, charlie_address, identifier=1, ) assert result.wait(timeout=10) gevent.sleep(1.) # and now send one more mediated transfer with the same nonce, simulating # an out-of-order/resent message that arrives late lock = Lock(amount, 1, UNIT_HASHLOCK) identifier = create_default_identifier() mediated_transfer = MediatedTransfer( identifier=identifier, nonce=1, token=token_address, channel=channel0.channel_address, transferred_amount=amount, recipient=bob_address, locksroot=UNIT_HASHLOCK, lock=lock, target=charlie_address, initiator=initiator_address, fee=0 ) alice_key = PrivateKey(private_keys[0]) target_app = None for app in raiden_network: if app.raiden.address not in path: target_app = app break sign_and_send(mediated_transfer, alice_key, alice_address, target_app)
def test_withdraw_twice(reveal_timeout, tester_channels, tester_state): """ A lock can be withdrawn only once, the second try must fail. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] lock_expiration = tester_state.block.number + reveal_timeout + 5 secret = 'secretsecretsecretsecretsecretse' new_block = Block(tester_state.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock = Lock(17, lock_expiration, sha3(secret)) mediated0 = make_mediated_transfer( channel1, channel0, privatekey_to_address(pkey1), privatekey_to_address(pkey0), lock, pkey1, tester_state.block.number, secret, ) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey0, ) unlock_proofs = list(channel0.our_state.balance_proof.get_known_unlocks()) proof = unlock_proofs[0] nettingchannel.withdraw( proof.lock_encoded, ''.join(proof.merkle_proof), proof.secret, sender=pkey0, ) with pytest.raises(TransactionFailed): nettingchannel.withdraw( proof.lock_encoded, ''.join(proof.merkle_proof), proof.secret, sender=pkey0, )