def test_channel_must_accept_expired_locks(): """ A node may go offline for an undetermined period of time, and when it comes back online it must accept the messages that are waiting, otherwise the partner node won't make progress with its queue. If a N node goes offline for a number B of blocks, and the partner does not close the channel, when N comes back online some of the messages from its partner may become expired. Neverthless these messages are ordered and must be accepted for the partner to make progress with its queue. Note: Accepting a message with an expired lock does *not* imply the token transfer happened, and the receiver node must *not* forward the transfer, only accept the message allowing the partner to progress with its message queue. """ balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 privkey1, address1 = make_privkey_address() privkey2, address2 = make_privkey_address() token_address = make_address() our_state = ChannelEndState( address1, balance1, None, EMPTY_MERKLE_TREE, ) partner_state = ChannelEndState( address2, balance2, None, EMPTY_MERKLE_TREE, ) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) block_number = 10 transfer = make_mediated_transfer( nonce=test_channel.get_next_nonce(), token=test_channel.token_address, channel=test_channel.channel_address, expiration=block_number + settle_timeout, recipient=address1, ) transfer.sign(privkey2, address2) test_channel.register_transfer( block_number + settle_timeout + 1, transfer, )
def test_channel_must_accept_expired_locks(): """ A node may go offline for an undetermined period of time, and when it comes back online it must accept the messages that are waiting, otherwise the partner node won't make progress with its queue. If a N node goes offline for a number B of blocks, and the partner does not close the channel, when N comes back online some of the messages from its partner may become expired. Neverthless these messages are ordered and must be accepted for the partner to make progress with its queue. Note: Accepting a message with an expired lock does *not* imply the token transfer happened, and the receiver node must *not* forward the transfer, only accept the message allowing the partner to progress with its message queue. """ balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 privkey1, address1 = make_privkey_address() privkey2, address2 = make_privkey_address() token_address = make_address() our_state = ChannelEndState( address1, balance1, None, EMPTY_MERKLE_TREE, ) partner_state = ChannelEndState( address2, balance2, None, EMPTY_MERKLE_TREE, ) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) block_number = 10 transfer = make_mediated_transfer( nonce=test_channel.get_next_nonce(), token=test_channel.token_address, channel=test_channel.channel_address, expiration=block_number + settle_timeout, recipient=address1, ) transfer.sign(privkey2, address2) test_channel.register_transfer( block_number + settle_timeout + 1, transfer, )
def initialize(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.block_hash = factories.make_block_hash() self.random = random self.private_key, self.address = factories.make_privkey_address() self.chain_state = ChainState( pseudo_random_generator=self.random, block_number=self.block_number, block_hash=self.block_hash, our_address=self.address, chain_id=factories.UNIT_CHAIN_ID, ) self.token_network_id = factories.UNIT_TOKEN_NETWORK_ADDRESS self.token_id = factories.UNIT_TOKEN_ADDRESS self.token_network_state = TokenNetworkState(self.token_network_id, self.token_id) self.payment_network_id = factories.make_payment_network_identifier() self.payment_network_state = PaymentNetworkState( self.payment_network_id, [self.token_network_state]) self.chain_state.identifiers_to_paymentnetworks[ self.payment_network_id] = self.payment_network_state self.chain_state.tokennetworkaddresses_to_paymentnetworkaddresses[ self.token_network_id] = self.payment_network_id channels = [ self.new_channel_with_transaction() for _ in range(self.initial_number_of_channels) ] return multiple(*channels)
def test_signature_split(tester_chain, tester_nettingchannel_library_address): auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address) privkey, address = make_privkey_address() message_identifier = random.randint(0, UINT64_MAX) msg = DirectTransfer(message_identifier=message_identifier, payment_identifier=1, nonce=1, registry_address='x' * 20, token='x' * 20, channel=auxiliary.address, transferred_amount=10, recipient='y' * 20, locksroot=HASH) msg.sign(privkey, address) msg = msg.encode() # signature = len(msg) - 65 signature = msg[len(msg) - 65:] signature = signature[:-1] + chr(27).encode() r, s, v = auxiliary.signatureSplit(signature) assert v == 27 assert r == signature[:32] assert s == signature[32:64] signature = signature[:-1] + chr(28).encode() _, _, v = auxiliary.signatureSplit(signature) assert v == 28 with pytest.raises(TransactionFailed): signature = signature[:-1] + chr(4).encode() r, s, v = auxiliary.signatureSplit(signature)
def test_recoverAddressFromSignature(tester_chain, tester_nettingchannel_library_address): auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address) privkey, address = make_privkey_address() message_identifier = random.randint(0, UINT64_MAX) msg = DirectTransfer(message_identifier=message_identifier, payment_identifier=1, nonce=1, registry_address='x' * 20, token='x' * 20, channel=auxiliary.address, transferred_amount=10, recipient='y' * 20, locksroot=HASH) msg.sign(privkey, address) data = msg.encode() signature = data[-65:] extra_hash = sha3(data[:-65]) computed_address = auxiliary.recoverAddressFromSignature( msg.nonce, msg.transferred_amount, msg.locksroot, extra_hash, signature) assert normalize_address(computed_address) == msg.sender
def initialize(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.block_hash = factories.make_block_hash() self.random = random self.private_key, self.address = factories.make_privkey_address() self.chain_state = ChainState( pseudo_random_generator=self.random, block_number=self.block_number, block_hash=self.block_hash, our_address=self.address, chain_id=factories.UNIT_CHAIN_ID, ) self.token_network_id = factories.make_address() self.token_id = factories.make_address() self.token_network_state = TokenNetworkState(self.token_network_id, self.token_id) self.payment_network_id = factories.make_payment_network_identifier() self.payment_network_state = PaymentNetworkState( self.payment_network_id, [self.token_network_state], ) self.chain_state.identifiers_to_paymentnetworks[ self.payment_network_id] = self.payment_network_state return self.new_channel_with_transaction()
def test_signature_split(tester_chain, tester_nettingchannel_library_address): auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address) privkey, address = make_privkey_address() msg = DirectTransfer( identifier=1, nonce=1, token='x' * 20, channel=auxiliary.address, transferred_amount=10, recipient='y' * 20, locksroot=HASH ) msg.sign(privkey, address) msg = msg.encode() # signature = len(msg) - 65 signature = msg[len(msg) - 65:] signature = signature[:-1] + chr(27).encode() r, s, v = auxiliary.signatureSplit(signature) assert v == 27 assert r == signature[:32] assert s == signature[32:64] signature = signature[:-1] + chr(28).encode() _, _, v = auxiliary.signatureSplit(signature) assert v == 28 with pytest.raises(TransactionFailed): signature = signature[:-1] + chr(4).encode() r, s, v = auxiliary.signatureSplit(signature)
def initialize(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.random = random self.private_key, self.address = factories.make_privkey_address() self.chain_state = ChainState( self.random, self.block_number, self.address, factories.UNIT_CHAIN_ID, ) self.token_network_id = factories.make_address() self.token_id = factories.make_address() self.token_network_state = TokenNetworkState(self.token_network_id, self.token_id) self.payment_network_id = factories.make_payment_network_identifier() self.payment_network_state = PaymentNetworkState( self.payment_network_id, [self.token_network_state], ) self.chain_state.identifiers_to_paymentnetworks[ self.payment_network_id ] = self.payment_network_state return self.new_channel_with_transaction()
def __init__(self, message_handler=None, state_transition=None, private_key=None): if private_key is None: self.private_key, self.address = factories.make_privkey_address() else: self.private_key = private_key self.address = privatekey_to_address(private_key) self.chain = MockChain(network_id=17, node_address=self.address) self.signer = LocalSigner(self.private_key) self.message_handler = message_handler self.user_deposit = Mock() if state_transition is None: state_transition = node.state_transition serializer = JSONSerializer state_manager = StateManager(state_transition, None) storage = SerializedSQLiteStorage(":memory:", serializer) self.wal = WriteAheadLog(state_manager, storage) state_change = ActionInitChain( pseudo_random_generator=random.Random(), block_number=0, block_hash=factories.make_block_hash(), our_address=self.chain.node_address, chain_id=self.chain.network_id, ) self.wal.log_and_dispatch(state_change)
def test_recoverAddressFromSignature(tester_chain, tester_nettingchannel_library_address): auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address) privkey, address = make_privkey_address() msg = DirectTransfer( identifier=1, nonce=1, token='x' * 20, channel=auxiliary.address, transferred_amount=10, recipient='y' * 20, locksroot=HASH ) msg.sign(privkey, address) data = msg.encode() signature = data[-65:] extra_hash = sha3(data[:-65]) computed_address = auxiliary.recoverAddressFromSignature( msg.nonce, msg.transferred_amount, msg.locksroot, extra_hash, signature ) assert normalize_address(computed_address) == msg.sender
def test_receive_directtransfer_invalidsender(raiden_network, deposit, token_addresses): app0, app1 = raiden_network registry = app0.raiden.default_registry.address token_address = token_addresses[0] other_key, other_address = make_privkey_address() channel0 = get_channelstate(app0, app1, token_address) channel_identifier = channel0.identifier message_identifier = random.randint(0, UINT64_MAX) direct_transfer_message = DirectTransfer( message_identifier=message_identifier, payment_identifier=1, nonce=1, registry_address=registry, token=token_address, channel=channel_identifier, transferred_amount=10, recipient=app0.raiden.address, locksroot=EMPTY_MERKLE_ROOT, ) sign_and_inject( direct_transfer_message, other_key, other_address, app0, ) assert_synched_channel_state(token_address, app0, deposit, [], app1, deposit, [])
def test_refund_transfer_no_more_routes(): amount = UNIT_TRANSFER_AMOUNT block_number = 1 refund_pkey, refund_address = factories.make_privkey_address() channel1 = factories.make_channel( our_balance=amount, partner_balance=amount, our_address=UNIT_TRANSFER_INITIATOR, partner_address=refund_address, token_address=UNIT_TOKEN_ADDRESS, ) channelmap = {channel1.identifier: channel1} available_routes = [factories.route_from_channel(channel1)] current_state = make_initiator_state( available_routes, factories.UNIT_TRANSFER_DESCRIPTION, channelmap, block_number, ) original_transfer = current_state.initiator.transfer channel_identifier = current_state.initiator.channel_identifier channel_state = channelmap[channel_identifier] expiration = original_transfer.lock.expiration - channel_state.reveal_timeout - TRANSIT_BLOCKS refund_transfer = factories.make_signed_transfer( amount, original_transfer.initiator, original_transfer.target, expiration, UNIT_SECRET, identifier=original_transfer.identifier, channel_identifier=channel1.identifier, pkey=refund_pkey, sender=refund_address, ) state_change = ReceiveTransferRefundCancelRoute( sender=channel_state.partner_state.address, routes=available_routes, transfer=refund_transfer, secret=random_secret(), ) iteration = initiator_manager.state_transition( current_state, state_change, channelmap, block_number, ) assert iteration.new_state is None assert len(iteration.events) == 2 unlocked_failed = next(e for e in iteration.events if isinstance(e, EventUnlockFailed)) sent_failed = next(e for e in iteration.events if isinstance(e, EventTransferSentFailed)) assert unlocked_failed assert sent_failed
def test_waiting_messages(pathfinding_service_mock): participant1_privkey, participant1 = make_privkey_address() token_network_address = TokenNetworkAddress(b"1" * 20) channel_id = ChannelID(1) # register token network internally database = pathfinding_service_mock.database database.conn.execute( "INSERT INTO token_network(address) VALUES (?)", [to_checksum_address(token_network_address)], ) fee_update = PFSFeeUpdate( canonical_identifier=CanonicalIdentifier( chain_identifier=ChainID(1), token_network_address=token_network_address, channel_identifier=channel_id, ), updating_participant=participant1, fee_schedule=FeeScheduleState(), timestamp=datetime.utcnow(), signature=EMPTY_SIGNATURE, ) fee_update.sign(LocalSigner(participant1_privkey)) capacity_update = PFSCapacityUpdate( canonical_identifier=CanonicalIdentifier( chain_identifier=ChainID(1), token_network_address=token_network_address, channel_identifier=channel_id, ), updating_participant=make_address(), other_participant=make_address(), updating_nonce=Nonce(1), other_nonce=Nonce(1), updating_capacity=TokenAmount(100), other_capacity=TokenAmount(111), reveal_timeout=50, signature=EMPTY_SIGNATURE, ) capacity_update.sign(LocalSigner(participant1_privkey)) for message in (fee_update, capacity_update): database.insert_waiting_message(message) recovered_messages = list( database.pop_waiting_messages( token_network_address=token_network_address, channel_id=channel_id ) ) assert len(recovered_messages) == 1 assert message == recovered_messages[0] recovered_messages2 = list( database.pop_waiting_messages( token_network_address=token_network_address, channel_id=channel_id ) ) assert len(recovered_messages2) == 0
def channel_properties(our_address, token_network_state): partner_privkey, address = factories.make_privkey_address() properties = factories.NettingChannelStateProperties( our_state=factories.NettingChannelEndStateProperties(balance=80, address=our_address), partner_state=factories.NettingChannelEndStateProperties(balance=80, address=address), canonical_identifier=factories.make_canonical_identifier( token_network_address=token_network_state.address ), ) return properties, partner_privkey
def test_channel_close_called_only_once(): class MockCheckCallsToClose(): def __init__(self): self.address = 'mockcheckcallstoclosemockcheckcallstoclo' self.close_calls = 0 def opened(self): return 1 def closed(self): return 0 def settled(self): return 0 def close(self, nonce, transferred_amount, locksroot, extra_hash, signature): self.close_calls += 1 netting_channel = NettingChannelMock() token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 our_state = ChannelEndState(address1, balance1, netting_channel.opened()) partner_state = ChannelEndState(address2, balance2, netting_channel.opened()) channel_for_hashlock = list() netting_channel = MockCheckCallsToClose() external_state = ChannelExternalState( lambda *args: channel_for_hashlock.append(args), netting_channel, ) test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) test_channel.external_state.close('') test_channel.external_state.close('') assert netting_channel.close_calls == 1
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( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=1, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel0.identifier, transferred_amount=0, locked_amount=lock_amount, recipient=app0.raiden.address, locksroot=UNIT_SECRETHASH, lock=Lock(amount=lock_amount, expiration=expiration, secrethash=UNIT_SECRETHASH), target=app0.raiden.address, initiator=other_address, fee=0, ) sign_and_inject( mediated_transfer_message, LocalSigner(other_key), app0, ) assert_synced_channel_state( token_network_identifier, app0, deposit, [], app1, deposit, [], )
def test_initiator_handle_contract_receive_secret_reveal(): """ Make sure the initiator handles ContractReceiveSecretReveal and checks the existence of the transfer's secrethash in secrethashes_to_lockedlocks and secrethashes_to_onchain_unlockedlocks. """ amount = UNIT_TRANSFER_AMOUNT * 2 block_number = 1 refund_pkey, refund_address = factories.make_privkey_address() pseudo_random_generator = random.Random() channel1 = factories.make_channel( our_balance=amount, token_address=UNIT_TOKEN_ADDRESS, token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS, ) pseudo_random_generator = random.Random() channel_map = { channel1.identifier: channel1, } available_routes = [ factories.route_from_channel(channel1), ] block_number = 10 current_state = make_initiator_manager_state( routes=available_routes, transfer_description=factories.UNIT_TRANSFER_DESCRIPTION, channel_map=channel_map, pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) transfer = current_state.initiator.transfer assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=UNIT_SECRET, ) initiator_manager.handle_onchain_secretreveal( payment_state=current_state, state_change=state_change, channelidentifiers_to_channels=channel_map, pseudo_random_generator=pseudo_random_generator, ) assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_onchain_unlockedlocks
def test_channel_close_called_only_once(): class MockCheckCallsToClose: def __init__(self): self.address = 'mockcheckcallstoclosemockcheckcallstoclo' self.close_calls = 0 def opened(self): return 1 def closed(self): return 0 def close(self, nonce, transferred_amount, locksroot, extra_hash, signature): self.close_calls += 1 netting_channel = NettingChannelMock() token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE) partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE) channel_for_hashlock = list() netting_channel = MockCheckCallsToClose() external_state = ChannelExternalState( lambda *args: channel_for_hashlock.append(args), netting_channel, ) test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) test_channel.external_state.close(None) test_channel.external_state.close(None) assert netting_channel.close_calls == 1
def create_model(balance): privkey, address = factories.make_privkey_address() our_model = PartnerStateModel( participant_address=address, amount_locked=0, balance=balance, distributable=balance, next_nonce=1, merkletree_leaves=[], contract_balance=balance, ) return our_model, privkey
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( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=1, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=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_synced_channel_state( token_network_identifier, app0, deposit, [], app1, deposit, [], )
def test_update_pfs(): properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY) balance_proof = factories.create(properties) channel_state = factories.create(factories.NettingChannelStateProperties()) channel_state.our_state.balance_proof = balance_proof channel_state.partner_state.balance_proof = balance_proof message = UpdatePFS.from_channel_state(channel_state=channel_state) assert message.signature == b"" privkey2, address2 = factories.make_privkey_address() signer2 = LocalSigner(privkey2) message.sign(signer2) assert recover(message._data_to_sign(), message.signature) == address2 assert message == UpdatePFS.from_dict(message.to_dict())
def test_update_pfs(): balance_proof = make_balance_proof(signer=signer, amount=1) channel_state = make_channel_state() channel_state.our_state.balance_proof = balance_proof channel_state.partner_state.balance_proof = balance_proof message = UpdatePFS.from_channel_state(channel_state=channel_state) assert message.signature == b'' privkey2, address2 = make_privkey_address() signer2 = LocalSigner(privkey2) message.sign(signer2) assert recover(message._data_to_sign(), message.signature) == address2 assert message == UpdatePFS.from_dict(message.to_dict())
def test_receive_directtransfer_unknown(raiden_network): app0 = raiden_network[0] # pylint: disable=unbalanced-tuple-unpacking graph0 = app0.raiden.token_to_channelgraph.values()[0] other_key, other_address = make_privkey_address() direct_transfer_message = DirectTransfer( identifier=1, nonce=1, token=graph0.token_address, channel=other_address, transferred_amount=10, recipient=app0.raiden.address, locksroot=UNIT_HASHLOCK, ) sign_and_send(direct_transfer_message, other_key, other_address, app0)
def test_receive_directtransfer_unknown(raiden_network): app0 = raiden_network[0] # pylint: disable=unbalanced-tuple-unpacking graph0 = list(app0.raiden.token_to_channelgraph.values())[0] other_key, other_address = make_privkey_address() direct_transfer_message = DirectTransfer( identifier=1, nonce=1, token=graph0.token_address, channel=other_address, transferred_amount=10, recipient=app0.raiden.address, locksroot=UNIT_HASHLOCK, ) sign_and_send(direct_transfer_message, other_key, other_address, app0)
def test_update_pfs(): properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY) balance_proof = factories.create(properties) channel_state = factories.create(factories.NettingChannelStateProperties()) channel_state.our_state.balance_proof = balance_proof channel_state.partner_state.balance_proof = balance_proof message = PFSCapacityUpdate.from_channel_state(channel_state=channel_state) assert message.signature == EMPTY_SIGNATURE privkey2, address2 = factories.make_privkey_address() signer2 = LocalSigner(privkey2) message.sign(signer2) assert recover(message._data_to_sign(), message.signature) == address2 assert message == DictSerializer.deserialize(DictSerializer.serialize(message))
def initialize_all(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.block_hash = factories.make_block_hash() self.random = random self.token_network_address = factories.UNIT_TOKEN_NETWORK_ADDRESS self.token_id = factories.UNIT_TOKEN_ADDRESS self.token_network_state = TokenNetworkState( address=self.token_network_address, token_address=self.token_id, network_graph=TokenNetworkGraphState(self.token_network_address), ) self.token_network_registry_address = factories.make_token_network_registry_address() self.token_network_registry_state = TokenNetworkRegistryState( self.token_network_registry_address, [self.token_network_state] ) channels = [] for _ in range(self.number_of_clients): private_key, address = factories.make_privkey_address() self.address_to_privkey[address] = private_key chain_state = ChainState( pseudo_random_generator=self.random, block_number=self.block_number, block_hash=self.block_hash, our_address=address, chain_id=factories.UNIT_CHAIN_ID, ) chain_state.identifiers_to_tokennetworkregistries[ self.token_network_registry_address ] = self.token_network_registry_state chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[ self.token_network_address ] = self.token_network_registry_address self.address_to_client[address] = Client(chain_state=chain_state) channels.extend( self.new_channel_with_transaction(client_address=address) for _ in range(self.initial_number_of_channels) ) return multiple(*channels)
def __init__(self, message_handler=None, state_transition=None, private_key=None): if private_key is None: self.privkey, self.address = factories.make_privkey_address() else: self.privkey = private_key self.address = privatekey_to_address(private_key) self.rpc_client = MockJSONRPCClient(self.address) self.proxy_manager = MockProxyManager(node_address=self.address) self.signer = LocalSigner(self.privkey) self.message_handler = message_handler self.routing_mode = RoutingMode.PRIVATE self.config = RaidenConfig(chain_id=self.rpc_client.chain_id, environment_type=Environment.DEVELOPMENT) self.default_user_deposit = Mock() self.default_registry = Mock() self.default_registry.address = factories.make_address() self.default_one_to_n_address = factories.make_address() self.default_msc_address = factories.make_address() self.targets_to_identifiers_to_statuses: Dict[Address, dict] = defaultdict(dict) self.route_to_feedback_token: dict = {} if state_transition is None: state_transition = node.state_transition serializer = JSONSerializer() state_manager = StateManager(state_transition, None) storage = SerializedSQLiteStorage(":memory:", serializer) self.wal = WriteAheadLog(state_manager, storage) state_change = ActionInitChain( pseudo_random_generator=random.Random(), block_number=BlockNumber(0), block_hash=factories.make_block_hash(), our_address=self.rpc_client.address, chain_id=self.rpc_client.chain_id, ) with self.wal.process_state_change_atomically() as dispatcher: dispatcher.dispatch(state_change) self.transport = Mock()
def initialize(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.random = random self.private_key, self.address = factories.make_privkey_address() self.chain_state = ChainState( self.random, self.block_number, self.address, factories.UNIT_CHAIN_ID, ) self.token_network_id = factories.make_address() self.token_id = factories.make_address() self.token_network_state = TokenNetworkState(self.token_network_id, self.token_id) self.payment_network_id = factories.make_payment_network_identifier() self.payment_network_state = PaymentNetworkState( self.payment_network_id, [self.token_network_state], ) self.chain_state.identifiers_to_paymentnetworks[ self.payment_network_id] = self.payment_network_state self.channels = list() for partner_address in self.channels_with: channel = factories.make_channel( our_balance=1000, partner_balance=1000, token_network_identifier=self.token_network_id, our_address=self.address, partner_address=partner_address, ) channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), self.token_network_id, channel, self.block_number, ) node.state_transition(self.chain_state, channel_new_state_change) self.channels.append(channel)
def __init__(self, message_handler=None, state_transition=None, private_key=None, config=None): if private_key is None: self.privkey, self.address = factories.make_privkey_address() else: self.privkey = private_key self.address = privatekey_to_address(private_key) self.rpc_client = MockJSONRPCClient(self.address) self.proxy_manager = MockProxyManager(node_address=self.address) self.signer = LocalSigner(self.privkey) self.message_handler = message_handler self.routing_mode = RoutingMode.PRIVATE self.config = config self.user_deposit = Mock() self.default_registry = Mock() self.default_registry.address = factories.make_address() self.default_one_to_n_address = factories.make_address() self.default_msc_address = factories.make_address() self.targets_to_identifiers_to_statuses = defaultdict(dict) self.route_to_feedback_token = {} if state_transition is None: state_transition = node.state_transition serializer = JSONSerializer state_manager = StateManager(state_transition, None) storage = SerializedSQLiteStorage(":memory:", serializer) self.wal = WriteAheadLog(state_manager, storage) state_change = ActionInitChain( pseudo_random_generator=random.Random(), block_number=0, block_hash=factories.make_block_hash(), our_address=self.rpc_client.address, chain_id=self.rpc_client.chain_id, ) self.wal.log_and_dispatch([state_change])
def test_receive_directtransfer_invalidsender(raiden_network, deposit, token_addresses): 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) 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=1, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel_identifier, transferred_amount=10, locked_amount=0, recipient=app0.raiden.address, locksroot=EMPTY_MERKLE_ROOT, ) sign_and_inject( direct_transfer_message, other_key, other_address, app0, ) assert_synched_channel_state( token_network_identifier, app0, deposit, [], app1, deposit, [], )
def test_channel_increase_nonce_and_transferred_amount(): """ The nonce must increase with each new transfer. """ token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE) partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) previous_nonce = test_channel.get_next_nonce() previous_transferred = test_channel.transferred_amount amount = 7 block_number = 1 for _ in range(10): direct_transfer = test_channel.create_directtransfer(amount, identifier=1) direct_transfer.sign(privkey1, address1) test_channel.register_transfer(block_number, direct_transfer) new_nonce = test_channel.get_next_nonce() new_transferred = test_channel.transferred_amount assert new_nonce == previous_nonce + 1 assert new_transferred == previous_transferred + amount previous_nonce = new_nonce previous_transferred = new_transferred
def test_receive_mediatedtransfer_unknown(raiden_network): app0 = raiden_network[0] # pylint: disable=unbalanced-tuple-unpacking graph0 = app0.raiden.token_to_channelgraph.values()[0] other_key, other_address = make_privkey_address() amount = 10 mediated_transfer = MediatedTransfer(identifier=1, nonce=1, token=graph0.token_address, channel=other_address, transferred_amount=amount, recipient=app0.raiden.address, locksroot=UNIT_HASHLOCK, lock=Lock(amount, 1, UNIT_HASHLOCK), target=make_address(), initiator=other_address, fee=0) sign_and_send(mediated_transfer, other_key, other_address, app0)
def new_channel(self): """Create a new partner address with private key and channel. The private key and channels are listed in the instance's dictionaries, the address is returned and should be added to the partners Bundle. """ partner_privkey, partner_address = factories.make_privkey_address() self.address_to_privkey[partner_address] = partner_privkey self.address_to_channel[partner_address] = factories.make_channel( our_balance=1000, partner_balance=1000, token_network_identifier=self.token_network_id, our_address=self.address, partner_address=partner_address, ) return partner_address
def new_channel(self): """Create a new partner address with private key and channel. The private key and channels are listed in the instance's dictionaries, the address is returned and should be added to the partners Bundle. """ partner_privkey, partner_address = factories.make_privkey_address() self.address_to_privkey[partner_address] = partner_privkey self.address_to_channel[partner_address] = factories.make_channel( our_balance=1000, partner_balance=1000, token_network_identifier=self.token_network_id, our_address=self.address, partner_address=partner_address, ) return partner_address
def test_refund_transfer_no_more_routes(): amount = UNIT_TRANSFER_AMOUNT refund_pkey, refund_address = factories.make_privkey_address() setup = setup_initiator_tests( amount=amount, partner_balance=amount, our_address=UNIT_TRANSFER_INITIATOR, partner_address=refund_address, ) original_transfer = setup.current_state.initiator.transfer refund_transfer = factories.make_signed_transfer( amount, original_transfer.initiator, original_transfer.target, original_transfer.lock.expiration, UNIT_SECRET, payment_identifier=original_transfer.payment_identifier, channel_identifier=setup.channel.identifier, pkey=refund_pkey, sender=refund_address, ) state_change = ReceiveTransferRefundCancelRoute( routes=setup.available_routes, transfer=refund_transfer, secret=random_secret(), ) iteration = initiator_manager.state_transition( setup.current_state, state_change, setup.channel_map, setup.prng, setup.block_number, ) assert iteration.new_state is None unlocked_failed = next(e for e in iteration.events if isinstance(e, EventUnlockFailed)) sent_failed = next(e for e in iteration.events if isinstance(e, EventPaymentSentFailed)) assert unlocked_failed assert sent_failed
def test_channel_increase_nonce_and_transferred_amount(): """ The nonce must increase with each new transfer. """ token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE) partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) previous_nonce = test_channel.get_next_nonce() previous_transferred = test_channel.transferred_amount amount = 7 block_number = 1 for _ in range(10): direct_transfer = test_channel.create_directtransfer(amount, identifier=1) direct_transfer.sign(privkey1, address1) test_channel.register_transfer(block_number, direct_transfer) new_nonce = test_channel.get_next_nonce() new_transferred = test_channel.transferred_amount assert new_nonce == previous_nonce + 1 assert new_transferred == previous_transferred + amount previous_nonce = new_nonce previous_transferred = new_transferred
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() channel0 = get_channelstate(app0, app1, token_address) lock_amount = 10 expiration = reveal_timeout * 2 mediated_transfer_message = LockedTransfer( message_identifier=random.randint(0, UINT64_MAX), payment_identifier=1, nonce=1, registry_address=app0.raiden.default_registry.address, 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_address, app0, deposit, [], app1, deposit, [], )
def new_channel(self): """Create a new partner address with private key and channel. The private key and channels are listed in the instance's dictionaries, the address is returned and should be added to the partners Bundle. """ partner_privkey, partner_address = factories.make_privkey_address() self.address_to_privkey[partner_address] = partner_privkey self.address_to_channel[partner_address] = factories.create( factories.NettingChannelStateProperties( our_state=factories.NettingChannelEndStateProperties( balance=1000, address=self.address), partner_state=factories.NettingChannelEndStateProperties( balance=1000, address=partner_address), canonical_identifier=factories.make_canonical_identifier( token_network_address=self.token_network_address), )) return partner_address
def test_receive_mediatedtransfer_unknown(raiden_network): app0 = raiden_network[0] # pylint: disable=unbalanced-tuple-unpacking graph0 = list(app0.raiden.token_to_channelgraph.values())[0] other_key, other_address = make_privkey_address() amount = 10 mediated_transfer = MediatedTransfer( identifier=1, nonce=1, token=graph0.token_address, channel=other_address, transferred_amount=amount, recipient=app0.raiden.address, locksroot=UNIT_HASHLOCK, lock=Lock(amount, 1, UNIT_HASHLOCK), target=make_address(), initiator=other_address, fee=0 ) sign_and_send(mediated_transfer, other_key, other_address, app0)
def test_receive_directtransfer_invalidsender(raiden_network, deposit, token_addresses): 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) 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=1, nonce=1, token_network_address=token_network_identifier, token=token_address, channel_identifier=channel_identifier, transferred_amount=10, locked_amount=0, recipient=app0.raiden.address, locksroot=EMPTY_MERKLE_ROOT, ) sign_and_inject( direct_transfer_message, other_key, other_address, app0, ) assert_synched_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_address = views.get_token_network_address_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address) assert token_network_address channel0 = get_channelstate(app0, app1, token_network_address) lock_amount = TokenAmount(10) expiration = reveal_timeout * 2 mediated_transfer_message = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=make_message_identifier(), payment_identifier=PaymentID(1), nonce=Nonce(1), token_network_address=token_network_address, token=token_address, channel_identifier=channel0.identifier, transferred_amount=TokenAmount(0), locked_amount=lock_amount, recipient=app0.raiden.address, locksroot=make_locksroot(), lock=Lock( amount=PaymentWithFeeAmount(lock_amount), expiration=expiration, secrethash=UNIT_SECRETHASH, ), target=app0.raiden.address, initiator=InitiatorAddress(other_address), signature=EMPTY_SIGNATURE, metadata=Metadata(routes=[RouteMetadata(route=[app0.raiden.address])]), ) sign_and_inject(mediated_transfer_message, LocalSigner(other_key), app0) assert_synced_channel_state(token_network_address, app0, deposit, [], app1, deposit, [])
def test_routing_priority( chain_state, payment_network_state, token_network_state, our_address, ): open_block_number = 10 pseudo_random_generator = random.Random() pkey1, address1 = factories.make_privkey_address() pkey2, address2 = factories.make_privkey_address() pkey3, address3 = factories.make_privkey_address() pkey4, address4 = factories.make_privkey_address() # Create a network with the following topology # # our ----- 1/1 ----> (1) # | | # | | # 2/0 x # | | # v v # (2) ----- x -----> (3) # | | # | | # x x # | | # v v # (4) (4) channel_state1 = factories.make_channel( our_balance=1, our_address=our_address, partner_balance=1, partner_address=address1, ) channel_state2 = factories.make_channel( our_balance=2, our_address=our_address, partner_balance=0, partner_address=address2, ) # create new channels as participant channel_new_state_change1 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_state=channel_state1, block_number=open_block_number, ) channel_new_state_change2 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_state=channel_state2, block_number=open_block_number, ) channel_new_iteration1 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=token_network_state, state_change=channel_new_state_change1, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number, ) channel_new_iteration2 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration1.new_state, state_change=channel_new_state_change2, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number, ) # create new channels without being participant channel_new_state_change3 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=3, participant1=address2, participant2=address3, block_number=open_block_number, ) channel_new_iteration3 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration2.new_state, state_change=channel_new_state_change3, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) channel_new_state_change4 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=4, participant1=address3, participant2=address1, block_number=open_block_number, ) channel_new_iteration4 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration3.new_state, state_change=channel_new_state_change4, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) channel_new_state_change5 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=4, participant1=address3, participant2=address4, block_number=open_block_number, ) channel_new_iteration5 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration4.new_state, state_change=channel_new_state_change5, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) channel_new_state_change6 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=4, participant1=address2, participant2=address4, block_number=open_block_number, ) token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration5.new_state, state_change=channel_new_state_change6, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) # test routing priority with all nodes available chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_REACHABLE, address2: NODE_NETWORK_REACHABLE, address3: NODE_NETWORK_REACHABLE, } routes = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address3, amount=1, previous_address=None, config={}, ) assert routes[0].node_address == address1 assert routes[1].node_address == address2 # number of hops overwrites refunding capacity (route over node 2 involves less hops) chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_REACHABLE, address2: NODE_NETWORK_REACHABLE, address3: NODE_NETWORK_REACHABLE, address4: NODE_NETWORK_REACHABLE, } routes = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address4, amount=1, previous_address=None, config={}, ) assert routes[0].node_address == address2 assert routes[1].node_address == address1 # sufficient routing capacity overwrites refunding capacity chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_REACHABLE, address2: NODE_NETWORK_REACHABLE, address3: NODE_NETWORK_REACHABLE, } routes = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address3, amount=2, previous_address=None, config={}, ) assert routes[0].node_address == address2 # availability overwrites refunding capacity (node 1 offline) chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_UNREACHABLE, address2: NODE_NETWORK_REACHABLE, address3: NODE_NETWORK_REACHABLE, } routes = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address3, amount=1, previous_address=None, config={}, ) assert routes[0].node_address == address2
def test_routing_issue2663( chain_state, payment_network_state, token_network_state, our_address, ): open_block_number = 10 pseudo_random_generator = random.Random() pkey1, address1 = factories.make_privkey_address() pkey2, address2 = factories.make_privkey_address() pkey3, address3 = factories.make_privkey_address() # Create a network with the following topology # # our ----- 50 ----> (1) # | ^ # | | # 100 100 # | | # v | # (2) ----- 100 ---> (3) channel_state1 = factories.make_channel( our_balance=50, our_address=our_address, partner_balance=0, partner_address=address1, ) channel_state2 = factories.make_channel( our_balance=100, our_address=our_address, partner_balance=0, partner_address=address2, ) # create new channels as participant channel_new_state_change1 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_state=channel_state1, block_number=open_block_number, ) channel_new_state_change2 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_state=channel_state2, block_number=open_block_number, ) channel_new_iteration1 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=token_network_state, state_change=channel_new_state_change1, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number, ) channel_new_iteration2 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration1.new_state, state_change=channel_new_state_change2, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number, ) graph_state = channel_new_iteration2.new_state.network_graph assert len(graph_state.channel_identifier_to_participants) == 2 assert len(graph_state.network.edges()) == 2 # create new channels without being participant channel_new_state_change3 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=3, participant1=address2, participant2=address3, block_number=open_block_number, ) channel_new_iteration3 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration2.new_state, state_change=channel_new_state_change3, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) graph_state = channel_new_iteration3.new_state.network_graph assert len(graph_state.channel_identifier_to_participants) == 3 assert len(graph_state.network.edges()) == 3 channel_new_state_change4 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=4, participant1=address3, participant2=address1, block_number=open_block_number, ) channel_new_iteration4 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration3.new_state, state_change=channel_new_state_change4, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) graph_state = channel_new_iteration4.new_state.network_graph assert len(graph_state.channel_identifier_to_participants) == 4 assert len(graph_state.network.edges()) == 4 # test routing with all nodes available chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_REACHABLE, address2: NODE_NETWORK_REACHABLE, address3: NODE_NETWORK_REACHABLE, } routes1 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=50, previous_address=None, config={}, ) assert routes1[0].node_address == address1 assert routes1[1].node_address == address2 routes2 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=51, previous_address=None, config={}, ) assert routes2[0].node_address == address2 # test routing with node 2 offline chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_REACHABLE, address2: NODE_NETWORK_UNREACHABLE, address3: NODE_NETWORK_REACHABLE, } routes1 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=50, previous_address=None, config={}, ) assert routes1[0].node_address == address1 routes2 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=51, previous_address=None, config={}, ) assert routes2 == [] # test routing with node 3 offline # the routing doesn't care as node 3 is not directly connected chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_REACHABLE, address2: NODE_NETWORK_REACHABLE, address3: NODE_NETWORK_UNREACHABLE, } routes1 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=50, previous_address=None, config={}, ) assert routes1[0].node_address == address1 assert routes1[1].node_address == address2 routes2 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=51, previous_address=None, config={}, ) assert routes2[0].node_address == address2 # test routing with node 1 offline chain_state.nodeaddresses_to_networkstates = { address1: NODE_NETWORK_UNREACHABLE, address2: NODE_NETWORK_REACHABLE, address3: NODE_NETWORK_REACHABLE, } routes1 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=50, previous_address=None, config={}, ) # right now the channel to 1 gets filtered out as it is offline assert routes1[0].node_address == address2 routes2 = get_best_routes( chain_state=chain_state, token_network_id=token_network_state.address, from_address=our_address, to_address=address1, amount=51, previous_address=None, config={}, ) assert routes2[0].node_address == address2
def test_routing_updates( token_network_state, our_address, ): open_block_number = 10 pseudo_random_generator = random.Random() pkey1, address1 = factories.make_privkey_address() pkey2, address2 = factories.make_privkey_address() pkey3, address3 = factories.make_privkey_address() amount = 30 our_balance = amount + 50 channel_state = factories.make_channel( our_balance=our_balance, our_address=our_address, partner_balance=our_balance, partner_address=address1, ) payment_network_identifier = factories.make_payment_network_identifier() # create a new channel as participant, check graph update channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_state=channel_state, block_number=open_block_number, ) channel_new_iteration1 = token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=token_network_state, state_change=channel_new_state_change, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number, ) graph_state = channel_new_iteration1.new_state.network_graph assert channel_state.identifier in graph_state.channel_identifier_to_participants assert len(graph_state.channel_identifier_to_participants) == 1 assert graph_state.network[our_address][address1] is not None assert len(graph_state.network.edges()) == 1 # create a new channel without being participant, check graph update new_channel_identifier = factories.make_channel_identifier() channel_new_state_change = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=new_channel_identifier, participant1=address2, participant2=address3, block_number=open_block_number, ) channel_new_iteration2 = token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=channel_new_iteration1.new_state, state_change=channel_new_state_change, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) graph_state = channel_new_iteration2.new_state.network_graph assert channel_state.identifier in graph_state.channel_identifier_to_participants assert new_channel_identifier in graph_state.channel_identifier_to_participants assert len(graph_state.channel_identifier_to_participants) == 2 assert graph_state.network[our_address][address1] is not None assert graph_state.network[address2][address3] is not None assert len(graph_state.network.edges()) == 2 # close the channel the node is a participant of, check edge is removed from graph closed_block_number = open_block_number + 20 channel_close_state_change1 = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.partner_state.address, token_network_identifier=token_network_state.address, channel_identifier=channel_state.identifier, block_number=closed_block_number, ) channel_closed_iteration1 = token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=channel_new_iteration2.new_state, state_change=channel_close_state_change1, pseudo_random_generator=pseudo_random_generator, block_number=closed_block_number, ) # Check that a second ContractReceiveChannelClosed events is handled properly # This might have been sent from the other participant of the channel # See issue #2449 channel_close_state_change2 = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.our_state.address, token_network_identifier=token_network_state.address, channel_identifier=channel_state.identifier, block_number=closed_block_number, ) channel_closed_iteration2 = token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=channel_closed_iteration1.new_state, state_change=channel_close_state_change2, pseudo_random_generator=pseudo_random_generator, block_number=closed_block_number, ) graph_state = channel_closed_iteration2.new_state.network_graph assert channel_state.identifier not in graph_state.channel_identifier_to_participants assert new_channel_identifier in graph_state.channel_identifier_to_participants assert len(graph_state.channel_identifier_to_participants) == 1 assert graph_state.network[address2][address3] is not None assert len(graph_state.network.edges()) == 1 # close the channel the node is not a participant of, check edge is removed from graph channel_close_state_change3 = ContractReceiveRouteClosed( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=new_channel_identifier, block_number=closed_block_number, ) channel_closed_iteration3 = token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=channel_closed_iteration2.new_state, state_change=channel_close_state_change3, pseudo_random_generator=pseudo_random_generator, block_number=closed_block_number + 10, ) # Check that a second ContractReceiveRouteClosed events is handled properly. # This might have been sent from the second participant of the channel # See issue #2449 channel_close_state_change4 = ContractReceiveRouteClosed( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=new_channel_identifier, block_number=closed_block_number + 10, ) channel_closed_iteration4 = token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=channel_closed_iteration3.new_state, state_change=channel_close_state_change4, pseudo_random_generator=pseudo_random_generator, block_number=closed_block_number + 10, ) graph_state = channel_closed_iteration4.new_state.network_graph assert channel_state.identifier not in graph_state.channel_identifier_to_participants assert new_channel_identifier not in graph_state.channel_identifier_to_participants assert len(graph_state.channel_identifier_to_participants) == 0 assert len(graph_state.network.edges()) == 0
def test_multiple_channel_states( chain_state, token_network_state, our_address, ): open_block_number = 10 pseudo_random_generator = random.Random() pkey, address = factories.make_privkey_address() amount = 30 our_balance = amount + 50 channel_state = factories.make_channel( our_balance=our_balance, our_address=our_address, partner_balance=our_balance, partner_address=address, token_network_identifier=token_network_state.address, ) payment_network_identifier = factories.make_payment_network_identifier() channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, channel_state, open_block_number, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b'test_end_state') lock_secrethash = sha3(lock_secret) lock = HashTimeLockState( lock_amount, lock_expiration, lock_secrethash, ) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock, ) from_route = factories.route_from_channel(channel_state) init_target = ActionInitTarget( from_route, mediated_transfer, ) node.state_transition(chain_state, init_target) closed_block_number = open_block_number + 10 channel_close_state_change = ContractReceiveChannelClosed( factories.make_transaction_hash(), channel_state.partner_state.address, token_network_state.address, channel_state.identifier, closed_block_number, ) channel_closed_iteration = token_network.state_transition( payment_network_identifier, channel_new_iteration.new_state, channel_close_state_change, pseudo_random_generator, closed_block_number, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( factories.make_transaction_hash(), token_network_state.address, channel_state.identifier, settle_block_number, ) channel_settled_iteration = token_network.state_transition( payment_network_identifier, channel_closed_iteration.new_state, channel_settled_state_change, pseudo_random_generator, closed_block_number, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels # Create new channel while the previous one is pending unlock new_channel_state = factories.make_channel( our_balance=our_balance, partner_balance=our_balance, partner_address=address, ) channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, new_channel_state, closed_block_number + 1, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) token_network_state_after_new_open = channel_new_iteration.new_state ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels assert len(ids_to_channels) == 2 assert channel_state.identifier in ids_to_channels
def test_mediator_clear_pairs_after_batch_unlock( chain_state, token_network_state, our_address, ): """ Regression test for https://github.com/raiden-network/raiden/issues/2932 The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where he is a participant is received. """ open_block_number = 10 pseudo_random_generator = random.Random() pkey, address = factories.make_privkey_address() amount = 30 our_balance = amount + 50 channel_state = factories.make_channel( our_balance=our_balance, our_address=our_address, partner_balance=our_balance, partner_address=address, token_network_identifier=token_network_state.address, ) payment_network_identifier = factories.make_payment_network_identifier() channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, channel_state, open_block_number, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b'test_end_state') lock_secrethash = sha3(lock_secret) lock = HashTimeLockState( lock_amount, lock_expiration, lock_secrethash, ) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock, ) from_route = factories.route_from_channel(channel_state) init_mediator = ActionInitMediator( routes=[from_route], from_route=from_route, from_transfer=mediated_transfer, ) node.state_transition(chain_state, init_mediator) closed_block_number = open_block_number + 10 channel_close_state_change = ContractReceiveChannelClosed( factories.make_transaction_hash(), channel_state.partner_state.address, token_network_state.address, channel_state.identifier, closed_block_number, ) channel_closed_iteration = token_network.state_transition( payment_network_identifier, channel_new_iteration.new_state, channel_close_state_change, pseudo_random_generator, closed_block_number, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( factories.make_transaction_hash(), token_network_state.address, channel_state.identifier, settle_block_number, ) channel_settled_iteration = token_network.state_transition( payment_network_identifier, channel_closed_iteration.new_state, channel_settled_state_change, pseudo_random_generator, closed_block_number, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels block_number = closed_block_number + 1 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, participant=our_address, partner=address, locksroot=lock_secrethash, unlocked_amount=lock_amount, returned_tokens=0, block_number=block_number, ) channel_unlock_iteration = node.state_transition( chain_state=chain_state, state_change=channel_batch_unlock_state_change, ) chain_state = channel_unlock_iteration.new_state token_network_state = views.get_token_network_by_identifier( chain_state=chain_state, token_network_id=token_network_state.address, ) ids_to_channels = token_network_state.channelidentifiers_to_channels assert len(ids_to_channels) == 0 # Make sure that all is fine in the next block block = Block( block_number=block_number + 1, gas_limit=1, block_hash=factories.make_transaction_hash(), ) iteration = node.state_transition( chain_state=chain_state, state_change=block, ) assert iteration.new_state # Make sure that mediator task was cleared during the next block processing # since the channel was removed mediator_task = chain_state.payment_mapping.secrethashes_to_task.get(lock_secrethash) assert not mediator_task
def test_python_channel(): token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 block_number = 10 our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE) partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) assert test_channel.contract_balance == our_state.contract_balance assert test_channel.transferred_amount == our_state.transferred_amount assert test_channel.distributable == our_state.contract_balance assert test_channel.outstanding == our_state.amount_locked assert test_channel.outstanding == 0 assert test_channel.locked == partner_state.amount_locked assert test_channel.our_state.amount_locked == 0 assert test_channel.partner_state.amount_locked == 0 assert test_channel.get_next_nonce() == 1 with pytest.raises(ValueError): test_channel.create_directtransfer( -10, identifier=1, ) with pytest.raises(ValueError): test_channel.create_directtransfer( balance1 + 10, identifier=1, ) amount1 = 10 directtransfer = test_channel.create_directtransfer( amount1, identifier=1, ) directtransfer.sign(privkey1, address1) test_channel.register_transfer( block_number, directtransfer, ) assert test_channel.contract_balance == balance1 assert test_channel.balance == balance1 - amount1 assert test_channel.transferred_amount == amount1 assert test_channel.distributable == balance1 - amount1 assert test_channel.outstanding == 0 assert test_channel.locked == 0 assert test_channel.our_state.amount_locked == 0 assert test_channel.partner_state.amount_locked == 0 assert test_channel.get_next_nonce() == 2 secret = sha3(b'test_channel') hashlock = sha3(secret) amount2 = 10 fee = 0 expiration = block_number + settle_timeout - 5 identifier = 1 mediatedtransfer = test_channel.create_mediatedtransfer( address1, address2, fee, amount2, identifier, expiration, hashlock, ) mediatedtransfer.sign(privkey1, address1) test_channel.register_transfer( block_number, mediatedtransfer, ) assert test_channel.contract_balance == balance1 assert test_channel.balance == balance1 - amount1 assert test_channel.transferred_amount == amount1 assert test_channel.distributable == balance1 - amount1 - amount2 assert test_channel.outstanding == 0 assert test_channel.locked == amount2 assert test_channel.our_state.amount_locked == amount2 assert test_channel.partner_state.amount_locked == 0 assert test_channel.get_next_nonce() == 3 secret_message = test_channel.create_secret(identifier, secret) secret_message.sign(privkey1, address1) test_channel.register_transfer(block_number, secret_message) assert test_channel.contract_balance == balance1 assert test_channel.balance == balance1 - amount1 - amount2 assert test_channel.transferred_amount == amount1 + amount2 assert test_channel.distributable == balance1 - amount1 - amount2 assert test_channel.outstanding == 0 assert test_channel.locked == 0 assert test_channel.our_state.amount_locked == 0 assert test_channel.partner_state.amount_locked == 0 assert test_channel.get_next_nonce() == 4
def test_refund_transfer_next_route(): amount = UNIT_TRANSFER_AMOUNT our_address = factories.ADDR refund_pkey, refund_address = factories.make_privkey_address() pseudo_random_generator = random.Random() channel1 = factories.make_channel( our_balance=amount, partner_balance=amount, our_address=our_address, partner_address=refund_address, token_address=UNIT_TOKEN_ADDRESS, token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS, ) channel2 = factories.make_channel( our_balance=0, our_address=our_address, token_address=UNIT_TOKEN_ADDRESS, token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS, ) channel3 = factories.make_channel( our_balance=amount, our_address=our_address, token_address=UNIT_TOKEN_ADDRESS, token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS, ) channel_map = { channel1.identifier: channel1, channel2.identifier: channel2, channel3.identifier: channel3, } available_routes = [ factories.route_from_channel(channel1), factories.route_from_channel(channel2), factories.route_from_channel(channel3), ] block_number = 10 current_state = make_initiator_manager_state( available_routes, factories.UNIT_TRANSFER_DESCRIPTION, channel_map, pseudo_random_generator, block_number, ) original_transfer = current_state.initiator.transfer refund_transfer = factories.make_signed_transfer( amount, our_address, original_transfer.target, original_transfer.lock.expiration, UNIT_SECRET, payment_identifier=original_transfer.payment_identifier, channel_identifier=channel1.identifier, pkey=refund_pkey, sender=refund_address, ) assert channel1.partner_state.address == refund_address state_change = ReceiveTransferRefundCancelRoute( routes=available_routes, transfer=refund_transfer, secret=random_secret(), ) iteration = initiator_manager.state_transition( current_state, state_change, channel_map, pseudo_random_generator, block_number, ) assert iteration.new_state is not None route_cancelled = next(e for e in iteration.events if isinstance(e, EventUnlockFailed)) new_transfer = next(e for e in iteration.events if isinstance(e, SendLockedTransfer)) assert route_cancelled, 'The previous transfer must be cancelled' assert new_transfer, 'No mediated transfer event emitted, should have tried a new route' msg = 'the new transfer must use a new secret / secrethash' assert new_transfer.transfer.lock.secrethash != refund_transfer.lock.secrethash, msg assert iteration.new_state.initiator is not None
def test_refund_transfer_no_more_routes(): amount = UNIT_TRANSFER_AMOUNT refund_pkey, refund_address = factories.make_privkey_address() setup = setup_initiator_tests( amount=amount, partner_balance=amount, our_address=UNIT_TRANSFER_INITIATOR, partner_address=refund_address, ) original_transfer = setup.current_state.initiator.transfer refund_transfer = factories.make_signed_transfer( amount, original_transfer.initiator, original_transfer.target, original_transfer.lock.expiration, UNIT_SECRET, payment_identifier=original_transfer.payment_identifier, channel_identifier=setup.channel.identifier, pkey=refund_pkey, sender=refund_address, ) state_change = ReceiveTransferRefundCancelRoute( routes=setup.available_routes, transfer=refund_transfer, secret=random_secret(), ) iteration = initiator_manager.state_transition( setup.current_state, state_change, setup.channel_map, setup.prng, setup.block_number, ) current_state = iteration.new_state # As per the description of the issue here: # https://github.com/raiden-network/raiden/issues/3146#issuecomment-447378046 # We can fail the payment but can't delete the payment task if there are no # more routes, but we have to wait for the lock expiration assert iteration.new_state is not None unlocked_failed = next(e for e in iteration.events if isinstance(e, EventUnlockFailed)) sent_failed = next(e for e in iteration.events if isinstance(e, EventPaymentSentFailed)) assert unlocked_failed assert sent_failed invalid_balance_proof = factories.make_signed_balance_proof( nonce=2, transferred_amount=original_transfer.balance_proof.transferred_amount, locked_amount=0, token_network_address=original_transfer.balance_proof.token_network_identifier, channel_identifier=setup.channel.identifier, locksroot=EMPTY_MERKLE_ROOT, extra_hash=original_transfer.lock.secrethash, sender_address=refund_address, ) balance_proof = factories.make_signed_balance_proof( nonce=2, transferred_amount=original_transfer.balance_proof.transferred_amount, locked_amount=0, token_network_address=original_transfer.balance_proof.token_network_identifier, channel_identifier=setup.channel.identifier, locksroot=EMPTY_MERKLE_ROOT, extra_hash=original_transfer.lock.secrethash, sender_address=refund_address, private_key=refund_pkey, ) invalid_lock_expired_state_change = ReceiveLockExpired( invalid_balance_proof, secrethash=original_transfer.lock.secrethash, message_identifier=5, ) lock_expired_state_change = ReceiveLockExpired( balance_proof, secrethash=original_transfer.lock.secrethash, message_identifier=5, ) before_expiry_block = original_transfer.lock.expiration - 1 expiry_block = channel.get_sender_expiration_threshold(original_transfer.lock) # a block before lock expiration, no events should be emitted current_state = iteration.new_state state_change = Block( block_number=before_expiry_block, gas_limit=1, block_hash=factories.make_transaction_hash(), ) iteration = initiator_manager.state_transition( current_state, state_change, setup.channel_map, setup.prng, expiry_block, ) assert not iteration.events assert iteration.new_state, 'payment task should not be deleted at this block' # process an invalid lock expired message before lock expiration current_state = iteration.new_state iteration = initiator_manager.state_transition( current_state, invalid_lock_expired_state_change, setup.channel_map, setup.prng, before_expiry_block, ) assert iteration.new_state, 'payment task should not be deleted at this lock expired' # should not be accepted assert not events.must_contain_entry(iteration.events, SendProcessed, {}) assert events.must_contain_entry(iteration.events, EventInvalidReceivedLockExpired, {}) # process a valid lock expired message before lock expiration current_state = iteration.new_state iteration = initiator_manager.state_transition( current_state, lock_expired_state_change, setup.channel_map, setup.prng, before_expiry_block, ) assert iteration.new_state, 'payment task should not be deleted at this lock expired' # should not be accepted assert not events.must_contain_entry(iteration.events, SendProcessed, {}) # now we get to the lock expiration block current_state = iteration.new_state state_change = Block( block_number=expiry_block, gas_limit=1, block_hash=factories.make_transaction_hash(), ) iteration = initiator_manager.state_transition( current_state, state_change, setup.channel_map, setup.prng, expiry_block, ) assert events.must_contain_entry(iteration.events, SendLockExpired, {}) # Since there was a refund transfer the payment task must not have been deleted assert iteration.new_state is not None # process the lock expired message after lock expiration current_state = iteration.new_state iteration = initiator_manager.state_transition( current_state, lock_expired_state_change, setup.channel_map, setup.prng, expiry_block, ) # should be accepted assert events.must_contain_entry(iteration.events, SendProcessed, {}) assert iteration.new_state, 'payment task should be there waiting for next block' # process the the block after lock expiration current_state = iteration.new_state state_change = Block( block_number=expiry_block + 1, gas_limit=1, block_hash=factories.make_transaction_hash(), ) iteration = initiator_manager.state_transition( current_state, state_change, setup.channel_map, setup.prng, expiry_block + 1, ) assert iteration.new_state is None, 'from this point on the payment task should go'
def test_end_state(): token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() channel_address = make_address() balance1 = 70 balance2 = 110 lock_secret = sha3(b'test_end_state') lock_amount = 30 lock_expiration = 10 lock_hashlock = sha3(lock_secret) state1 = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE) state2 = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE) assert state1.contract_balance == balance1 assert state2.contract_balance == balance2 assert state1.balance(state2) == balance1 assert state2.balance(state1) == balance2 assert state1.is_locked(lock_hashlock) is False assert state2.is_locked(lock_hashlock) is False assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT assert state1.nonce is None assert state2.nonce is None lock = Lock( lock_amount, lock_expiration, lock_hashlock, ) lock_hash = sha3(lock.as_bytes) transferred_amount = 0 locksroot = state2.compute_merkleroot_with(lock) locked_transfer = LockedTransfer( 1, nonce=1, token=token_address, channel=channel_address, transferred_amount=transferred_amount, recipient=state2.address, locksroot=locksroot, lock=lock, ) transfer_target = make_address() transfer_initiator = make_address() fee = 0 mediated_transfer = locked_transfer.to_mediatedtransfer( transfer_target, transfer_initiator, fee, ) mediated_transfer.sign(privkey1, address1) state1.register_locked_transfer(mediated_transfer) assert state1.contract_balance == balance1 assert state2.contract_balance == balance2 assert state1.balance(state2) == balance1 assert state2.balance(state1) == balance2 assert state1.distributable(state2) == balance1 - lock_amount assert state2.distributable(state1) == balance2 assert state1.amount_locked == lock_amount assert state2.amount_locked == 0 assert state1.is_locked(lock_hashlock) is True assert state2.is_locked(lock_hashlock) is False assert merkleroot(state1.merkletree) == lock_hash assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT assert state1.nonce is 1 assert state2.nonce is None with pytest.raises(ValueError): state1.update_contract_balance(balance1 - 10) state1.update_contract_balance(balance1 + 10) assert state1.contract_balance == balance1 + 10 assert state2.contract_balance == balance2 assert state1.balance(state2) == balance1 + 10 assert state2.balance(state1) == balance2 assert state1.distributable(state2) == balance1 - lock_amount + 10 assert state2.distributable(state1) == balance2 assert state1.amount_locked == lock_amount assert state2.amount_locked == 0 assert state1.is_locked(lock_hashlock) is True assert state2.is_locked(lock_hashlock) is False assert merkleroot(state1.merkletree) == lock_hash assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT assert state1.nonce is 1 assert state2.nonce is None # registering the secret should not change the locked amount state1.register_secret(lock_secret) assert state1.contract_balance == balance1 + 10 assert state2.contract_balance == balance2 assert state1.balance(state2) == balance1 + 10 assert state2.balance(state1) == balance2 assert state1.is_locked(lock_hashlock) is False assert state2.is_locked(lock_hashlock) is False assert merkleroot(state1.merkletree) == lock_hash assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT assert state1.nonce is 1 assert state2.nonce is None secret_message = Secret( identifier=1, nonce=2, channel=channel_address, transferred_amount=transferred_amount + lock_amount, locksroot=EMPTY_MERKLE_ROOT, secret=lock_secret, ) secret_message.sign(privkey1, address1) state1.register_secretmessage(secret_message) assert state1.contract_balance == balance1 + 10 assert state2.contract_balance == balance2 assert state1.balance(state2) == balance1 + 10 - lock_amount assert state2.balance(state1) == balance2 + lock_amount assert state1.distributable(state2) == balance1 + 10 - lock_amount assert state2.distributable(state1) == balance2 + lock_amount assert state1.amount_locked == 0 assert state2.amount_locked == 0 assert state1.is_locked(lock_hashlock) is False assert state2.is_locked(lock_hashlock) is False assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT assert state1.nonce is 2 assert state2.nonce is None
def test_receiver_cannot_spend_locked_amount(): token_address = make_address() privkey1, address1 = make_privkey_address() privkey2, address2 = make_privkey_address() balance1 = 33 balance2 = 11 reveal_timeout = 7 settle_timeout = 21 block_number = 7 our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE) partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) amount1 = balance2 expiration = block_number + settle_timeout receive_mediated_transfer0 = test_channel.create_mediatedtransfer( address1, address2, fee=0, amount=amount1, identifier=1, expiration=expiration, hashlock=sha3(b'test_locked_amount_cannot_be_spent'), ) receive_mediated_transfer0.sign(privkey2, address2) test_channel.register_transfer( block_number, receive_mediated_transfer0, ) # trying to send one unit of the locked token amount2 = balance1 + 1 lock2 = Lock( amount=amount2, expiration=expiration, hashlock=sha3(b'test_locked_amount_cannot_be_spent2'), ) layers = compute_layers([sha3(lock2.as_bytes)]) tree2 = MerkleTreeState(layers) locksroot2 = merkleroot(tree2) send_mediated_transfer0 = MediatedTransfer( identifier=1, nonce=1, token=token_address, channel=test_channel.channel_address, transferred_amount=0, recipient=address2, locksroot=locksroot2, lock=lock2, target=address2, initiator=address1, fee=0, ) send_mediated_transfer0.sign(privkey1, address1) # address1 balance is all locked with pytest.raises(InsufficientBalance): test_channel.register_transfer( block_number, send_mediated_transfer0, )
def create_square_network_topology( payment_network_state, token_network_state, our_address, ) -> typing.Tuple[ TokenNetworkState, typing.List[typing.Address], typing.List[NettingChannelState], ]: open_block_number = 10 pseudo_random_generator = random.Random() pkey1, address1 = factories.make_privkey_address() pkey2, address2 = factories.make_privkey_address() pkey3, address3 = factories.make_privkey_address() # Create a network with the following topology # # our ----- 50 ----> (1) # | ^ # | | # 100 100 # | | # v | # (2) ----- 100 ---> (3) channel_state1 = factories.make_channel( our_balance=50, our_address=our_address, partner_balance=0, partner_address=address1, ) channel_state2 = factories.make_channel( our_balance=100, our_address=our_address, partner_balance=0, partner_address=address2, ) # create new channels as participant channel_new_state_change1 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_state=channel_state1, block_number=open_block_number, ) channel_new_state_change2 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_state=channel_state2, block_number=open_block_number, ) channel_new_iteration1 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=token_network_state, state_change=channel_new_state_change1, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number, ) channel_new_iteration2 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration1.new_state, state_change=channel_new_state_change2, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number, ) graph_state = channel_new_iteration2.new_state.network_graph assert len(graph_state.channel_identifier_to_participants) == 2 assert len(graph_state.network.edges()) == 2 # create new channels without being participant channel_new_state_change3 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=3, participant1=address2, participant2=address3, block_number=open_block_number, ) channel_new_iteration3 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration2.new_state, state_change=channel_new_state_change3, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) graph_state = channel_new_iteration3.new_state.network_graph assert len(graph_state.channel_identifier_to_participants) == 3 assert len(graph_state.network.edges()) == 3 channel_new_state_change4 = ContractReceiveRouteNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, channel_identifier=4, participant1=address3, participant2=address1, block_number=open_block_number, ) channel_new_iteration4 = token_network.state_transition( payment_network_identifier=payment_network_state.address, token_network_state=channel_new_iteration3.new_state, state_change=channel_new_state_change4, pseudo_random_generator=pseudo_random_generator, block_number=open_block_number + 10, ) graph_state = channel_new_iteration4.new_state.network_graph assert len(graph_state.channel_identifier_to_participants) == 4 assert len(graph_state.network.edges()) == 4 return ( channel_new_iteration4.new_state, [address1, address2, address3], (channel_state1, channel_state2), )
def test_sender_cannot_overspend(): token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 block_number = 10 our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE) partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) amount = balance1 expiration = block_number + settle_timeout sent_mediated_transfer0 = test_channel.create_mediatedtransfer( address1, address2, fee=0, amount=amount, identifier=1, expiration=expiration, hashlock=sha3(b'test_locked_amount_cannot_be_spent'), ) sent_mediated_transfer0.sign(privkey1, address1) test_channel.register_transfer( block_number, sent_mediated_transfer0, ) lock2 = Lock( amount=amount, expiration=expiration, hashlock=sha3(b'test_locked_amount_cannot_be_spent2'), ) leaves = [ sha3(sent_mediated_transfer0.lock.as_bytes), sha3(lock2.as_bytes), ] tree2 = MerkleTreeState(compute_layers(leaves)) locksroot2 = merkleroot(tree2) sent_mediated_transfer1 = MediatedTransfer( identifier=2, nonce=sent_mediated_transfer0.nonce + 1, token=token_address, channel=test_channel.channel_address, transferred_amount=0, recipient=address2, locksroot=locksroot2, lock=lock2, target=address2, initiator=address1, fee=0, ) sent_mediated_transfer1.sign(privkey1, address1) # address1 balance is all locked with pytest.raises(InsufficientBalance): test_channel.register_transfer( block_number, sent_mediated_transfer1, )
UINT64_MAX, UINT256_MAX, ) from raiden.utils import sha3 from raiden.tests.utils.tests import fixture_all_combinations from raiden.tests.utils.factories import make_privkey_address, UNIT_CHAIN_ID from raiden.transfer.state import EMPTY_MERKLE_ROOT from raiden.messages import ( DirectTransfer, Lock, LockedTransfer, RefundTransfer, ) PRIVKEY, ADDRESS = make_privkey_address() CHANNEL_ID = keccak(b'somechannel') INVALID_ADDRESSES = [ b' ', b' ' * 19, b' ' * 21, ] VALID_SECRETS = [ letter.encode() * 32 for letter in string.ascii_uppercase[:7] ] SECRETHASHES_SECRESTS = { sha3(secret): secret for secret in VALID_SECRETS }