def test_save_and_load_channel(ms_database): token_network_address = get_random_address() ms_database.conn.execute("INSERT INTO token_network (address) VALUES (?)", [token_network_address]) for update_status in [ None, OnChainUpdateStatus( update_sender_address=Address(get_random_address()), nonce=random.randint(0, UINT256_MAX), ), ]: channel = Channel( token_network_address=TokenNetworkAddress(token_network_address), identifier=ChannelID(random.randint(0, UINT256_MAX)), participant1=Address(get_random_address()), participant2=Address(get_random_address()), settle_timeout=random.randint(0, UINT256_MAX), state=random.choice(list(ChannelState)), closing_block=BlockNumber(random.randint(0, UINT256_MAX)), closing_participant=Address(get_random_address()), closing_tx_hash=TransactionHash('%d' % random.randint(0, UINT64_MAX)), claim_tx_hash=TransactionHash('%d' % random.randint(0, UINT64_MAX)), update_status=update_status, ) ms_database.upsert_channel(channel) loaded_channel = ms_database.get_channel( token_network_address=channel.token_network_address, channel_id=channel.identifier) assert loaded_channel == channel
def populate_token_networks_random( token_networks: List[TokenNetwork], private_keys: List[str], ) -> None: # seed for pseudo-randomness from config constant, that changes from time to time random.seed(NUMBER_OF_CHANNELS) for token_network in token_networks: for channel_id_int in range(NUMBER_OF_CHANNELS): channel_id = ChannelIdentifier(channel_id_int) private_key1, private_key2 = random.sample(private_keys, 2) address1 = Address(private_key_to_address(private_key1)) address2 = Address(private_key_to_address(private_key2)) fee1 = random.randint(100, 10000) fee2 = random.randint(100, 10000) token_network.handle_channel_opened_event(channel_id, address1, address2) # deposit to channels deposit1, deposit2 = random.sample(range(1000), 2) address1, address2 = token_network.channel_id_to_addresses[ channel_id] token_network.handle_channel_new_deposit_event( channel_id, address1, deposit1) token_network.handle_channel_new_deposit_event( channel_id, address2, deposit2) # cuts negative values of probability distribution, fix with > 0 distribution token_network.update_fee(channel_id, address1, channel_id + 1, fee1) token_network.update_fee(channel_id, address2, channel_id + 1, fee2)
def populate_token_network_random( token_network_model: TokenNetwork, private_keys: List[str], ) -> None: # seed for pseudo-randomness from config constant, that changes from time to time random.seed(NUMBER_OF_CHANNELS) for channel_id_int in range(NUMBER_OF_CHANNELS): channel_id = ChannelIdentifier(channel_id_int) private_key1, private_key2 = random.sample(private_keys, 2) address1 = Address(private_key_to_address(private_key1)) address2 = Address(private_key_to_address(private_key2)) token_network_model.handle_channel_opened_event( channel_id, address1, address2, ) # deposit to channels deposit1, deposit2 = random.sample(range(1000), 2) address1, address2 = token_network_model.channel_id_to_addresses[ channel_id] token_network_model.handle_channel_new_deposit_event( channel_id, address1, deposit1, ) token_network_model.handle_channel_new_deposit_event( channel_id, address2, deposit2, )
def pathfinding_service_full_mock( contracts_manager: ContractManager, token_network_model: TokenNetwork, ) -> Generator[PathfindingService, None, None]: with patch('pathfinding_service.service.BlockchainListener', new=Mock), \ patch('pathfinding_service.service.MatrixListener', new=Mock): web3_mock = Mock() web3_mock.net.version = '1' web3_mock.eth.blockNumber = 1 pathfinding_service = PathfindingService( web3=web3_mock, contract_manager=contracts_manager, registry_address=Address( '0xB9633dd9a9a71F22C933bF121d7a22008f66B908'), user_deposit_contract_address=Address('0x' + '1' * 20), private_key= '3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266', db_filename=':memory:', ) pathfinding_service.token_networks = { token_network_model.address: token_network_model, } mock_udc = pathfinding_service.user_deposit_contract mock_udc.functions.effectiveBalance.return_value.call.return_value = 10000 yield pathfinding_service pathfinding_service.stop()
def ms_database(): return Database( filename=":memory:", chain_id=1, msc_address=Address("0x" + "2" * 40), registry_address=Address("0x" + "3" * 40), receiver=Address("0x" + "4" * 40), )
def ms_database(): return Database( filename=':memory:', chain_id=1, msc_address=Address('0x' + '2' * 40), registry_address=Address('0x' + '3' * 40), receiver=Address('0x' + '4' * 40), )
def populate_token_network_random(token_network_model: TokenNetwork, private_keys: List[str]) -> None: # seed for pseudo-randomness from config constant, that changes from time to time random.seed(NUMBER_OF_CHANNELS) for channel_id_int in range(NUMBER_OF_CHANNELS): channel_id = ChannelID(channel_id_int) private_key1, private_key2 = random.sample(private_keys, 2) address1 = Address(private_key_to_address(private_key1)) address2 = Address(private_key_to_address(private_key2)) settle_timeout = 15 token_network_model.handle_channel_opened_event( channel_id, address1, address2, settle_timeout) # deposit to channels deposit1 = TokenAmount(random.randint(0, 1000)) deposit2 = TokenAmount(random.randint(0, 1000)) address1, address2 = token_network_model.channel_id_to_addresses[ channel_id] token_network_model.handle_channel_new_deposit_event( channel_id, address1, deposit1) token_network_model.handle_channel_new_deposit_event( channel_id, address2, deposit2) token_network_model.handle_channel_balance_update_message( UpdatePFS( canonical_identifier=CanonicalIdentifier( chain_identifier=ChainID(1), channel_identifier=channel_id, token_network_address=TokenNetworkAddressBytes( decode_hex(token_network_model.address)), ), updating_participant=decode_hex(address1), other_participant=decode_hex(address2), updating_nonce=Nonce(1), other_nonce=Nonce(1), updating_capacity=deposit1, other_capacity=deposit2, reveal_timeout=2, mediation_fee=FeeAmount(0), )) token_network_model.handle_channel_balance_update_message( UpdatePFS( canonical_identifier=CanonicalIdentifier( chain_identifier=ChainID(1), channel_identifier=channel_id, token_network_address=TokenNetworkAddressBytes( decode_hex(token_network_model.address)), ), updating_participant=decode_hex(address2), other_participant=decode_hex(address1), updating_nonce=Nonce(2), other_nonce=Nonce(1), updating_capacity=deposit2, other_capacity=deposit1, reveal_timeout=2, mediation_fee=FeeAmount(0), ))
def test_balance_proof(): # test balance proof with computed balance hash balance_proof = BalanceProof( channel_identifier=ChannelIdentifier( '0x3131313131313131313131313131313131313131313131313131313131313131', ), token_network_address=Address( '0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'), nonce=1, chain_id=321, transferred_amount=5, locksroot='0x%064x' % 5, additional_hash='0x%064x' % 0, ) serialized = balance_proof.serialize_data() assert serialized['channel_identifier'] == balance_proof.channel_identifier assert is_same_address( serialized['token_network_address'], balance_proof.token_network_address, ) assert serialized['nonce'] == balance_proof.nonce assert serialized['chain_id'] == balance_proof.chain_id assert serialized['additional_hash'] == balance_proof.additional_hash assert serialized['balance_hash'] == balance_proof.balance_hash assert serialized['locksroot'] == balance_proof.locksroot assert serialized['transferred_amount'] == balance_proof.transferred_amount assert serialized['locked_amount'] == balance_proof.locked_amount # test balance proof with balance hash set from constructor balance_proof = BalanceProof( channel_identifier=ChannelIdentifier( '0x3131313131313131313131313131313131313131313131313131313131313131', ), token_network_address=Address( '0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'), nonce=1, chain_id=321, balance_hash='0x%064x' % 5, locked_amount=0, additional_hash='0x%064x' % 0, ) serialized = balance_proof.serialize_data() with pytest.raises(KeyError): serialized['transferred_amount'] assert serialized['channel_identifier'] == balance_proof.channel_identifier assert is_same_address( serialized['token_network_address'], balance_proof.token_network_address, ) assert serialized['nonce'] == balance_proof.nonce assert serialized['chain_id'] == balance_proof.chain_id assert serialized['additional_hash'] == balance_proof.additional_hash assert serialized['balance_hash'] == balance_proof.balance_hash
def populate_token_network_random( token_network_model: TokenNetwork, private_keys: List[str], ) -> None: # seed for pseudo-randomness from config constant, that changes from time to time random.seed(NUMBER_OF_CHANNELS) for channel_id_int in range(NUMBER_OF_CHANNELS): channel_id = ChannelIdentifier(channel_id_int) private_key1, private_key2 = random.sample(private_keys, 2) address1 = Address(private_key_to_address(private_key1)) address2 = Address(private_key_to_address(private_key2)) settle_timeout = 15 token_network_model.handle_channel_opened_event( channel_id, address1, address2, settle_timeout, ) # deposit to channels deposit1, deposit2 = random.sample(range(1000), 2) address1, address2 = token_network_model.channel_id_to_addresses[ channel_id] token_network_model.handle_channel_new_deposit_event( channel_id, address1, deposit1, ) token_network_model.handle_channel_new_deposit_event( channel_id, address2, deposit2, ) token_network_model.handle_channel_balance_update_message( channel_identifier=channel_id, updating_participant=address1, other_participant=address2, updating_nonce=1, other_nonce=1, updating_capacity=deposit1, other_capacity=deposit2, reveal_timeout=2, ) token_network_model.handle_channel_balance_update_message( channel_identifier=channel_id, updating_participant=address2, other_participant=address1, updating_nonce=2, other_nonce=1, updating_capacity=deposit1, other_capacity=deposit2, reveal_timeout=2, )
def test_monitor_new_balance_proof_event_handler_sets_update_status(context: Context,): context = setup_state_with_closed_channel(context) new_balance_event = ReceiveMonitoringNewBalanceProofEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, reward_amount=TokenAmount(1), nonce=Nonce(2), ms_address=Address("C"), raiden_node_address=DEFAULT_PARTICIPANT2, block_number=BlockNumber(23), ) channel = context.db.get_channel( new_balance_event.token_network_address, new_balance_event.channel_identifier ) assert channel assert channel.update_status is None monitor_new_balance_proof_event_handler(new_balance_event, context) assert context.db.channel_count() == 1 channel = context.db.get_channel( new_balance_event.token_network_address, new_balance_event.channel_identifier ) assert channel assert channel.update_status is not None assert channel.update_status.nonce == 2 assert channel.update_status.update_sender_address == "C" new_balance_event2 = ReceiveMonitoringNewBalanceProofEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, reward_amount=TokenAmount(1), nonce=Nonce(5), ms_address=Address("D"), raiden_node_address=DEFAULT_PARTICIPANT2, block_number=BlockNumber(23), ) monitor_new_balance_proof_event_handler(new_balance_event2, context) assert context.db.channel_count() == 1 channel = context.db.get_channel( new_balance_event.token_network_address, new_balance_event.channel_identifier ) assert channel assert channel.update_status is not None assert channel.update_status.nonce == 5 assert channel.update_status.update_sender_address == "D"
def test_balance_proof(): balance_proof = BalanceProof( channel_identifier=ChannelIdentifier(123), token_network_address=Address('0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'), nonce=1, chain_id=321, balance_hash='0x%064x' % 5, transferred_amount=1, locked_amount=0, additional_hash='0x%064x' % 0, ) serialized = balance_proof.serialize_data() assert serialized['channel_identifier'] == balance_proof.channel_identifier assert is_same_address( serialized['token_network_address'], balance_proof.token_network_address ) assert serialized['nonce'] == balance_proof.nonce assert serialized['chain_id'] == balance_proof.chain_id assert serialized['additional_hash'] == balance_proof.additional_hash assert serialized['balance_hash'] == balance_proof.balance_hash with pytest.raises(KeyError): serialized['transferred_amount'] balance_proof = BalanceProof( channel_identifier=ChannelIdentifier(123), token_network_address=Address('0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'), nonce=1, chain_id=321, locksroot='0x%064x' % 5, transferred_amount=1, locked_amount=0, additional_hash='0x%064x' % 0, ) serialized = balance_proof.serialize_data() assert serialized['channel_identifier'] == balance_proof.channel_identifier assert is_same_address( serialized['token_network_address'], balance_proof.token_network_address ) assert serialized['nonce'] == balance_proof.nonce assert serialized['chain_id'] == balance_proof.chain_id assert serialized['additional_hash'] == balance_proof.additional_hash assert serialized['locksroot'] == balance_proof.locksroot assert serialized['transferred_amount'] == balance_proof.transferred_amount assert serialized['locked_amount'] == balance_proof.locked_amount
def __set__(self, obj, value): if not isinstance(value, str): raise ValueError("%s requires a string" % (self.__class__.__name__)) if not is_checksum_address(value): raise ValueError("%s requires a checksummed ethereum address" % (self.__class__.__name__)) setattr(obj, self.private_attribute_name, Address(value))
def test_action_claim_reward_triggered_event_handler_without_update_state_doesnt_trigger_claim_call( # noqa context: Context, ): """ Tests that `claimReward` is called when the ActionMonitoringTriggeredEvent is triggered and user has sufficient balance in user deposit contract """ context = setup_state_with_closed_channel(context) context.db.upsert_monitor_request( get_signed_monitor_request(nonce=Nonce(6), reward_amount=TokenAmount(0))) trigger_event = ActionClaimRewardTriggeredEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, non_closing_participant=DEFAULT_PARTICIPANT2, ) channel = context.db.get_channel(trigger_event.token_network_address, trigger_event.channel_identifier) assert channel assert channel.claim_tx_hash is None # Set update state channel.update_status = OnChainUpdateStatus( update_sender_address=Address('0x' + '1' * 40), nonce=Nonce(6)) context.db.upsert_channel(channel) action_claim_reward_triggered_event_handler(trigger_event, context) # check that the monitor call has been done assert context.monitoring_service_contract.functions.claimReward.called is False
def _setup( self, chain_id: int, receiver: str, sync_start_block: BlockNumber, **contract_addresses: Address, ) -> None: """ Make sure that the db is initialized an matches the given settings """ assert chain_id >= 0 assert is_checksum_address(receiver) for contract, address in contract_addresses.items(): assert is_checksum_address(address), f"Bad {contract}: {address}!" initialized = self.conn.execute( "SELECT name FROM sqlite_master WHERE type='table' AND name='blockchain'" ).fetchone() settings = dict(chain_id=chain_id, receiver=receiver, **contract_addresses) if initialized: self._check_settings(settings, contract_addresses) else: # create db schema with open(self.schema_filename) as schema_file: self.conn.executescript(schema_file.read()) update_stmt = "UPDATE blockchain SET {}".format(",".join( f"{key} = :{key}" for key in ["chain_id", "receiver", "latest_known_block"] + list(contract_addresses))) self.conn.execute( update_stmt, dict(latest_known_block=sync_start_block, **settings))
def check_supplied_token_network_addresses(token_network_addresses: List[str], web3: Web3) -> List[Address]: result = [] for address in token_network_addresses: if not is_checksum_address(address): log.error( f"Token Network address '{address}' is not a checksum address. Ignoring." ) continue if not is_code_at_address(Address(address), web3): log.error(f"Token network at '{address}' has no code. Ignoring.") continue result.append(Address(address)) return result
def test_scheduled_events(ms_database): # Add token network used as foreign key ms_database.conn.execute("INSERT INTO token_network(address) VALUES (?)", ['a']) event1 = ScheduledEvent( trigger_block_number=BlockNumber(23), event=ActionMonitoringTriggeredEvent( token_network_address=TokenNetworkAddress('a'), channel_identifier=ChannelID(1), non_closing_participant=Address('b'), ), ) assert ms_database.scheduled_event_count() == 0 ms_database.upsert_scheduled_event(event=event1) assert ms_database.scheduled_event_count() == 1 event2 = ScheduledEvent( trigger_block_number=BlockNumber(24), event=ActionMonitoringTriggeredEvent( token_network_address=TokenNetworkAddress('a'), channel_identifier=ChannelID(1), non_closing_participant=Address('b'), ), ) ms_database.upsert_scheduled_event(event=event2) assert ms_database.scheduled_event_count() == 2 assert len(ms_database.get_scheduled_events(22)) == 0 assert len(ms_database.get_scheduled_events(23)) == 1 assert len(ms_database.get_scheduled_events(24)) == 2 ms_database.upsert_scheduled_event(event=event1) assert ms_database.scheduled_event_count() == 2 assert len(ms_database.get_scheduled_events(22)) == 0 assert len(ms_database.get_scheduled_events(23)) == 1 assert len(ms_database.get_scheduled_events(24)) == 2 ms_database.remove_scheduled_event(event2) assert len(ms_database.get_scheduled_events(22)) == 0 assert len(ms_database.get_scheduled_events(23)) == 1 assert len(ms_database.get_scheduled_events(24)) == 1
def __init__( self, web3: Web3, contracts: Dict[str, Contract], private_key: str, db_filename: str, sync_start_block: BlockNumber = BlockNumber(0), required_confirmations: int = 8, poll_interval: float = 10, service_fee: int = 0, ): super().__init__() self.web3 = web3 self.registry_address = contracts[CONTRACT_TOKEN_NETWORK_REGISTRY].address self.sync_start_block = sync_start_block self.required_confirmations = required_confirmations self.poll_interval = poll_interval self.chain_id = ChainID(int(web3.net.version)) self.private_key = private_key self.address = private_key_to_address(private_key) self.service_fee = service_fee self.is_running = gevent.event.Event() self.token_networks: Dict[TokenNetworkAddress, TokenNetwork] = {} self.database = PFSDatabase(filename=db_filename, pfs_address=self.address) self.user_deposit_contract = contracts[CONTRACT_USER_DEPOSIT] self.last_known_block = 0 self.blockchain_state = BlockchainState( chain_id=self.chain_id, token_network_registry_address=self.registry_address, monitor_contract_address=Address(''), # FIXME latest_known_block=self.sync_start_block, token_network_addresses=[], ) log.info( 'Listening to token network registry', registry_address=self.registry_address, start_block=sync_start_block, ) try: self.matrix_listener = MatrixListener( private_key=private_key, chain_id=self.chain_id, callback=self.handle_message, service_room_suffix=PATH_FINDING_BROADCASTING_ROOM, ) except ConnectionError as e: log.critical('Could not connect to broadcasting system.', exc=e) sys.exit(1)
def post(self, token_network_address: str): token_network_error = self._validate_token_network_argument( token_network_address) if token_network_error is not None: return token_network_error parser = reqparse.RequestParser() parser.add_argument('from', type=str, help='Payment initiator address.') parser.add_argument('to', type=str, help='Payment target address.') parser.add_argument('value', type=int, help='Maximum payment value.') parser.add_argument( 'max_paths', type=int, help='Number of paths requested.', default=DEFAULT_MAX_PATHS, ) args = parser.parse_args() error = self._validate_args(args) if error is not None: return error json = request.get_json() if not json: raise exceptions.ApiException('JSON payload expected') process_payment(json.get('iou'), self.pathfinding_service) token_network = self.pathfinding_service.token_networks.get( Address(token_network_address), ) # Existence is checked in _validate_token_network_argument assert token_network, 'Requested token network cannot be found' try: paths = token_network.get_paths( source=args['from'], target=args['to'], value=args.value, max_paths=args.max_paths, ) except NetworkXNoPath: return { 'errors': 'No suitable path found for transfer from {} to {}.'.format( args['from'], args['to'], ) }, 400 return {'result': paths}, 200
def test_contract_info_overwrite_defaults(): address1 = Address("0x" + "1" * 40) address2 = Address("0x" + "2" * 40) address3 = Address("0x" + "3" * 40) infos, start_block = get_contract_addresses_and_start_block( chain_id=DEFAULT_CHAIN_ID, contracts_version=DEFAULT_VERSION, contracts=[ CONTRACT_TOKEN_NETWORK_REGISTRY, CONTRACT_MONITORING_SERVICE, CONTRACT_USER_DEPOSIT, ], address_overwrites={ CONTRACT_TOKEN_NETWORK_REGISTRY: address1, CONTRACT_MONITORING_SERVICE: address2, CONTRACT_USER_DEPOSIT: address3, }, ) assert infos is not None assert infos[CONTRACT_TOKEN_NETWORK_REGISTRY] == address1 assert infos[CONTRACT_MONITORING_SERVICE] == address2 assert infos[CONTRACT_USER_DEPOSIT] == address3 assert start_block == 0
def test_save_and_load_token_networks(pathfinding_service_mock_empty): pfs = pathfinding_service_mock_empty token_address = Address("0x" + "1" * 40) token_network_address = TokenNetworkAddress("0x" + "2" * 40) channel_id = ChannelID(1) p1 = Address("0x" + "3" * 40) p2 = Address("0x" + "4" * 40) events = [ ReceiveTokenNetworkCreatedEvent( token_address=token_address, token_network_address=token_network_address, block_number=BlockNumber(1), ), ReceiveChannelOpenedEvent( token_network_address=token_network_address, channel_identifier=channel_id, participant1=p1, participant2=p2, settle_timeout=2** 65, # larger than max_uint64 to check hex storage block_number=BlockNumber(2), ), ] for event in events: pfs.handle_event(event) assert len(pfs.token_networks) == 1 loaded_networks = pfs._load_token_networks() # pylint: disable=protected-access assert len(loaded_networks) == 1 orig = list(pfs.token_networks.values())[0] loaded = list(loaded_networks.values())[0] assert loaded.address == orig.address assert loaded.channel_id_to_addresses == orig.channel_id_to_addresses assert loaded.G.nodes == orig.G.nodes
def test_save_and_load_token_networks(pathfinding_service_mock): pfs = pathfinding_service_mock pfs.token_networks = {} # the mock does not fit this case exactly token_address = Address("0x" + "1" * 40) token_network_address = TokenNetworkAddress("0x" + "2" * 40) channel_id = ChannelID(1) p1 = Address("0x" + "3" * 40) p2 = Address("0x" + "4" * 40) events = [ ReceiveTokenNetworkCreatedEvent( token_address=token_address, token_network_address=token_network_address, block_number=BlockNumber(1), ), ReceiveChannelOpenedEvent( token_network_address=token_network_address, channel_identifier=channel_id, participant1=p1, participant2=p2, settle_timeout=1000, block_number=BlockNumber(2), ), ] for event in events: pfs.handle_event(event) assert len(pfs.token_networks) == 1 loaded_networks = pfs._load_token_networks() assert len(loaded_networks) == 1 orig = list(pfs.token_networks.values())[0] loaded = list(loaded_networks.values())[0] assert loaded.address == orig.address assert loaded.channel_id_to_addresses == orig.channel_id_to_addresses assert loaded.G.nodes == orig.G.nodes
def test_monitor_reward_claimed_event_handler(context: Context, log): context = setup_state_with_closed_channel(context) claim_event = ReceiveMonitoringRewardClaimedEvent( ms_address=context.ms_state.address, amount=TokenAmount(1), reward_identifier="REWARD", block_number=BlockNumber(23), ) monitor_reward_claim_event_handler(claim_event, context) assert log.has("Successfully claimed reward") claim_event.ms_address = Address("C") monitor_reward_claim_event_handler(claim_event, context) assert log.has("Another MS claimed reward")
def _process_new_blocks(self, last_block: BlockNumber) -> None: _, events = get_blockchain_events( web3=self.web3, contract_manager=CONTRACT_MANAGER, chain_state=BlockchainState( latest_known_block=self.database.get_latest_known_block(), token_network_addresses=list(self.token_networks.keys()), token_network_registry_address=self.registry_address, monitor_contract_address=Address(""), # FIXME chain_id=self.chain_id, ), to_block=last_block, query_ms=False, ) for event in events: self.handle_event(event)
def get_contract_addresses_and_start_block( chain_id: ChainID, contracts: List[str], address_overwrites: Dict[str, Address], contracts_version: str = None, ) -> Tuple[Dict[str, Address], BlockNumber]: """ Returns contract addresses and start query block for a given chain and contracts version. The default contracts can be overwritten by the additional parameters. Args: chain_id: The chain id to look for deployed contracts. contracts: The list of contracts which should be considered address_overwrites: Dict of addresses which should be used instead of the ones in the requested deployment. contracts_version: The version of the contracts to use. Returns: A dictionary with the contract addresses and start block for the given information """ try: contract_data = get_contracts_deployment_info( chain_id=chain_id, version=contracts_version) except ValueError: log.error( 'No deployed contracts were found at the default registry', contracts_version=contracts_version, ) sys.exit(1) # Get deployed addresses for those contracts which have no overwrites addresses = { c: address_overwrites.get( c, Address(contract_data['contracts'][c]['address'])) for c in contracts } # Set start block to zero if any contract addresses are overwritten if any(address_overwrites.values()): start_block = BlockNumber(0) else: start_block = BlockNumber( max( 0, min(contract_data['contracts'][c]['block_number'] for c in contracts))) return addresses, start_block
def on_fee_info_message(self, fee_info: FeeInfo): try: self._check_chain_id(fee_info.chain_id) except ValueError as error: log.error('FeeInfo chain_id does not match: %s', str(error)) return token_network = self._get_token_network(fee_info.token_network_address) if token_network is None: return log.debug('Received FeeInfo message for token network {}'.format( token_network.address)) token_network.update_fee(fee_info.channel_identifier, Address(to_checksum_address(fee_info.signer)), fee_info.nonce, fee_info.relative_fee)
def pathfinding_service_mocked_listeners( contracts_manager: ContractManager, web3: Web3, user_deposit_contract: Contract, ) -> Generator[PathfindingService, None, None]: """ Returns a PathfindingService with mocked blockchain listeners. """ with patch('pathfinding_service.service.BlockchainListener', new=BlockchainListenerMock), \ patch('pathfinding_service.service.MatrixListener', new=Mock): pathfinding_service = PathfindingService( web3=web3, contract_manager=contracts_manager, registry_address=Address(''), user_deposit_contract_address=user_deposit_contract.address, private_key= '3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266', db_filename=':memory:', ) yield pathfinding_service
def test_action_monitoring_triggered_event_handler_does_not_trigger_monitor_call_when_nonce_to_small( # noqa context: Context, ): context = setup_state_with_closed_channel(context) event3 = ReceiveMonitoringNewBalanceProofEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, reward_amount=TokenAmount(1), nonce=Nonce(5), ms_address=Address('C'), raiden_node_address=DEFAULT_PARTICIPANT2, block_number=BlockNumber(23), ) channel = context.db.get_channel(event3.token_network_address, event3.channel_identifier) assert channel assert channel.update_status is None monitor_new_balance_proof_event_handler(event3, context) # add MR to DB, with nonce being smaller than in event3 context.db.upsert_monitor_request( get_signed_monitor_request(nonce=Nonce(4))) event4 = ActionMonitoringTriggeredEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, non_closing_participant=DEFAULT_PARTICIPANT2, ) channel = context.db.get_channel(event4.token_network_address, event4.channel_identifier) assert channel assert channel.update_status is not None assert channel.closing_tx_hash is None action_monitoring_triggered_event_handler(event4, context) assert context.db.channel_count() == 1 assert channel assert channel.closing_tx_hash is None
def get(self, token_network_address: str): token_network_error = self._validate_token_network_argument( token_network_address) if token_network_error is not None: return token_network_error parser = reqparse.RequestParser() parser.add_argument('from', type=str, help='Payment initiator address.') parser.add_argument('to', type=str, help='Payment target address.') parser.add_argument('value', type=int, help='Maximum payment value.') parser.add_argument('num_paths', type=int, help='Number of paths requested.') args = parser.parse_args() error = self._validate_args(args) if error is not None: return error token_network = self.pathfinding_service.token_networks.get( Address(token_network_address)) if not token_network: return { 'error': 'Token network {} not found.'.format(token_network_address) }, 400 try: paths = token_network.get_paths(source=args['from'], target=args['to'], value=args.value, k=args.num_paths) except NetworkXNoPath: return { 'error': 'No suitable path found for transfer from {} to {}.'.format( args['from'], args['to']) }, 400 return {'result': paths}, 200
def _validate_token_network_argument( self, token_network_address: str) -> Optional[Tuple[Dict, int]]: if not is_address(token_network_address): no_address_message = 'Invalid token network address: {}' return { 'error': no_address_message.format(token_network_address) }, 400 if not is_checksum_address(token_network_address): address_error = 'Token network address not checksummed: {}' return {'error': address_error.format(token_network_address)}, 400 token_network = self.pathfinding_service.token_networks.get( Address(token_network_address)) if token_network is None: return { 'error': 'Unsupported token network: {}'.format(token_network_address) }, 400 return None
def test_token_network_created(pathfinding_service_mock): token_address = Address("0x" + "1" * 40) token_network_address = TokenNetworkAddress("0x" + "2" * 40) network_event = ReceiveTokenNetworkCreatedEvent( token_address=token_address, token_network_address=token_network_address, block_number=BlockNumber(1), ) assert not pathfinding_service_mock.follows_token_network( token_network_address) assert len(pathfinding_service_mock.token_networks) == 1 pathfinding_service_mock.handle_event(network_event) assert pathfinding_service_mock.follows_token_network( token_network_address) assert len(pathfinding_service_mock.token_networks) == 2 # Test idempotency pathfinding_service_mock.handle_event(network_event) assert pathfinding_service_mock.follows_token_network( token_network_address) assert len(pathfinding_service_mock.token_networks) == 2