def get_netting_channel_settled_events( chain: BlockChainService, token_network_address: Address, netting_channel_identifier: ChannelID, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ) -> List[Dict]: settled_event_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_TOKEN_NETWORK, ChannelEvent.SETTLED, ) topic_set = construct_event_topic_set( event_abi=settled_event_abi, arguments={'channel_identifier': netting_channel_identifier}, ) if len(topic_set) == 1 and is_list_like(topic_set[0]): topics = topic_set[0] else: topics = topic_set return get_contract_events( chain, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), token_network_address, topics, from_block, to_block, )
def run(self): try: from solc import compile_files # noqa except ModuleNotFoundError: print('py-solc is not installed, skipping contracts compilation') return from raiden_contracts.contract_manager import CONTRACT_MANAGER compiled = CONTRACT_MANAGER.precompile_contracts( 'raiden_contracts/contracts/', CONTRACT_MANAGER.get_mappings(), ) with open(COMPILED_CONTRACTS, 'w') as compiled_json: compiled_json.write(json.dumps(compiled))
def __init__( self, token_network: TokenNetwork, channel_identifier: typing.ChannelID, ): filter_args = get_filter_args_for_specific_event_from_channel( token_network_address=token_network.address, channel_identifier=channel_identifier, event_name=EVENT_CHANNEL_OPENED, ) events = token_network.proxy.contract.web3.eth.getLogs(filter_args) if not len(events) > 0: raise ValueError('Channel is non-existing.') event = decode_event(CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[-1]) participant1 = decode_hex(event['args']['participant1']) participant2 = decode_hex(event['args']['participant2']) if token_network.node_address not in (participant1, participant2): raise ValueError('One participant must be the node address') if token_network.node_address == participant2: participant1, participant2 = participant2, participant1 self.channel_identifier = channel_identifier self.channel_operations_lock = RLock() self.participant1 = participant1 self.participant2 = participant2 self.token_network = token_network
def deploy_contract_web3( contract_name: str, deploy_client: JSONRPCClient, num_confirmations: int = None, constructor_arguments: typing.Tuple[typing.Any, ...] = (), ) -> typing.Address: contract_interface = CONTRACT_MANAGER.get_contract(contract_name) contract = deploy_client.web3.eth.contract( abi=contract_interface['abi'], bytecode=contract_interface['bin'], ) transaction = contract.constructor(*constructor_arguments).buildTransaction() transaction['nonce'] = deploy_client.nonce() signed_txn = deploy_client.web3.eth.account.signTransaction( transaction, deploy_client.privkey, ) tx_hash = deploy_client.web3.eth.sendRawTransaction(signed_txn.rawTransaction) deploy_client.poll(transaction_hash=tx_hash, confirmations=num_confirmations) receipt = deploy_client.get_transaction_receipt(tx_hash) if receipt.get('status', 0) == 0: raise RuntimeError('contract was not sucessfully deployed') return typing.Address( unhexlify(remove_0x_prefix(receipt['contractAddress'])), )
def create_token_network_for_address( self, token_network_address: Address, token_address: Address, block_number: int = 0, ): # get token infos token_contract = self.web3.eth.contract( address=token_address, abi=CONTRACT_MANAGER.get_contract_abi(CONTRACT_HUMAN_STANDARD_TOKEN), ) token_infos = get_token_info(token_contract) token_network = TokenNetwork(token_network_address, token_infos) self.token_networks[token_network_address] = token_network log.info('Creating token network for %s, token=%r', token_network_address, token_infos) token_network_listener = BlockchainListener( web3=self.web3, contract_manager=self.contract_manager, contract_address=token_network_address, contract_name=CONTRACT_TOKEN_NETWORK, sync_start_block=block_number, required_confirmations=self.required_confirmations, ) # subscribe to event notifications from blockchain listener token_network_listener.add_confirmed_listener( create_channel_event_topics(), self.handle_channel_event, ) token_network_listener.start() self.token_network_listeners.append(token_network_listener)
def test_filter(generate_raiden_client, web3): """test if filter returns past events""" c1 = generate_raiden_client() c2 = generate_raiden_client() c3 = generate_raiden_client() channel_id = c1.open_channel(c2.address) bp = c2.get_balance_proof(c1.address, transferred_amount=1, nonce=1) c1.close_channel(c2.address, bp) gevent.sleep(0) abi = CONTRACT_MANAGER.get_event_abi('TokenNetwork', 'ChannelClosed') assert abi is not None f = make_filter(web3, abi, fromBlock=0) entries = f.get_new_entries() assert len([ x for x in entries if (encode_hex(x['args']['channel_identifier']) == channel_id) and ( x['address'] == c1.contract.address) ]) == 1 channel_id = c1.open_channel(c3.address) bp = c3.get_balance_proof(c1.address, transferred_amount=1, nonce=1) c1.close_channel(c3.address, bp) entries = f.get_new_entries() assert len([ x for x in entries if (encode_hex(x['args']['channel_identifier']) == channel_id) and ( x['address'] == c1.contract.address) ]) == 1 assert len(f.get_all_entries()) > 0
def __init__( self, jsonrpc_client, manager_address, poll_timeout=DEFAULT_POLL_TIMEOUT, ): # pylint: disable=too-many-arguments if not is_binary_address(manager_address): raise InvalidAddress('Expected binary address format for token nework') check_address_has_code(jsonrpc_client, manager_address, 'Channel Manager') proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), to_normalized_address(manager_address), ) # TODO: add this back # CONTRACT_MANAGER.check_contract_version( # proxy.functions.contract_version().call(), # CONTRACT_TOKEN_NETWORK # ) self.address = manager_address self.proxy = proxy self.client = jsonrpc_client self.node_address = privatekey_to_address(self.client.privkey) self.poll_timeout = poll_timeout # Prevents concurrent deposit, withdraw, close, or settle operations on the same channel self.channel_operations_lock = dict() self.open_channel_transactions = dict()
def __init__( self, jsonrpc_client, registry_address, ): if not is_binary_address(registry_address): raise InvalidAddress('Expected binary address format for token network registry') check_address_has_code(jsonrpc_client, registry_address, CONTRACT_TOKEN_NETWORK_REGISTRY) proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK_REGISTRY), to_normalized_address(registry_address), ) is_valid_version = compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ) if not is_valid_version: raise ContractVersionMismatch('Incompatible ABI for TokenNetworkRegistry') self.address = registry_address self.proxy = proxy self.client = jsonrpc_client self.node_address = privatekey_to_address(self.client.privkey)
def __init__( self, jsonrpc_client, manager_address, ): if not is_binary_address(manager_address): raise InvalidAddress('Expected binary address format for token nework') check_address_has_code(jsonrpc_client, manager_address, CONTRACT_TOKEN_NETWORK) proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), to_normalized_address(manager_address), ) is_good_version = compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ) if not is_good_version: raise ContractVersionMismatch('Incompatible ABI for TokenNetwork') self.address = manager_address self.proxy = proxy self.client = jsonrpc_client self.node_address = privatekey_to_address(self.client.privkey) self.open_channel_transactions = dict() # Forbids concurrent operations on the same channel self.channel_operations_lock = defaultdict(RLock) # Serializes concurent deposits on this token network. This must be an # exclusive lock, since we need to coordinate the approve and # setTotalDeposit calls. self.deposit_lock = Semaphore()
def __init__( self, jsonrpc_client, registry_address, ): if not is_binary_address(registry_address): raise InvalidAddress( 'Expected binary address format for token network registry') check_address_has_code(jsonrpc_client, registry_address, CONTRACT_TOKEN_NETWORK_REGISTRY) proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK_REGISTRY), to_normalized_address(registry_address), ) try: is_valid_version = compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ) except BadFunctionCallOutput: raise AddressWrongContract('') if not is_valid_version: raise ContractVersionMismatch( 'Incompatible ABI for TokenNetworkRegistry') self.address = registry_address self.proxy = proxy self.client = jsonrpc_client self.node_address = privatekey_to_address(self.client.privkey)
def deploy_contract_web3( contract_name: str, deploy_client: JSONRPCClient, num_confirmations: int = None, constructor_arguments: typing.Tuple[typing.Any, ...] = (), ) -> typing.Address: contract_interface = CONTRACT_MANAGER.get_contract(contract_name) contract = deploy_client.web3.eth.contract( abi=contract_interface['abi'], bytecode=contract_interface['bin'], ) transaction = contract.constructor( *constructor_arguments).buildTransaction() transaction['nonce'] = deploy_client.nonce() signed_txn = deploy_client.web3.eth.account.signTransaction( transaction, deploy_client.privkey, ) tx_hash = deploy_client.web3.eth.sendRawTransaction( signed_txn.rawTransaction) deploy_client.poll(transaction_hash=tx_hash, confirmations=num_confirmations) receipt = deploy_client.get_transaction_receipt(tx_hash) if receipt.get('status', 0) == 0: raise RuntimeError('contract was not sucessfully deployed') return typing.Address( unhexlify(remove_0x_prefix(receipt['contractAddress'])), )
def __init__( self, jsonrpc_client, secret_registry_address, poll_timeout=DEFAULT_POLL_TIMEOUT, ): # pylint: disable=too-many-arguments if not is_binary_address(secret_registry_address): raise InvalidAddress( 'Expected binary address format for secret registry') check_address_has_code(jsonrpc_client, secret_registry_address, 'Registry') proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_SECRET_REGISTRY), to_normalized_address(secret_registry_address), ) # TODO: add this back # CONTRACT_MANAGER.check_contract_version( # proxy.functions.contract_version().call(), # CONTRACT_SECRET_REGISTRY # ) self.address = secret_registry_address self.proxy = proxy self.client = jsonrpc_client self.poll_timeout = poll_timeout self.node_address = privatekey_to_address(self.client.privkey)
def __init__( self, jsonrpc_client, discovery_address, ): contract = jsonrpc_client.new_contract( CONTRACT_MANAGER.get_contract_abi(CONTRACT_ENDPOINT_REGISTRY), to_normalized_address(discovery_address), ) proxy = ContractProxy(jsonrpc_client, contract) if not is_binary_address(discovery_address): raise ValueError('discovery_address must be a valid address') check_address_has_code(jsonrpc_client, discovery_address, 'Discovery') is_valid_version = compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ) if not is_valid_version: raise ContractVersionMismatch('Incompatible ABI for Discovery') self.address = discovery_address self.client = jsonrpc_client self.not_found_address = NULL_ADDRESS self.proxy = proxy
def make_filters(self): ret = [] for event_name in self.event_handlers.keys(): abi = CONTRACT_MANAGER.get_event_abi('TokenNetwork', event_name) assert abi is not None ret.append(make_filter(self.web3, abi)) return ret
def __init__( self, jsonrpc_client, manager_address, ): if not is_binary_address(manager_address): raise InvalidAddress( 'Expected binary address format for token nework') check_address_has_code(jsonrpc_client, manager_address, 'Channel Manager') proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), to_normalized_address(manager_address), ) if not compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ): raise ContractVersionMismatch('Incompatible ABI for TokenNetwork') self.address = manager_address self.proxy = proxy self.client = jsonrpc_client self.node_address = privatekey_to_address(self.client.privkey) # Prevents concurrent deposit, withdraw, close, or settle operations on the same channel self.channel_operations_lock = dict() self.open_channel_transactions = dict()
def __init__( self, token_network: TokenNetwork, channel_identifier: typing.ChannelID, ): filter_args = get_filter_args_for_specific_event_from_channel( token_network_address=token_network.address, channel_identifier=channel_identifier, event_name=EVENT_CHANNEL_OPENED, ) events = token_network.proxy.contract.web3.eth.getLogs(filter_args) if not len(events) > 0: raise ValueError('Channel is non-existing.') event = decode_event( CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[-1]) participant1 = decode_hex(event['args']['participant1']) participant2 = decode_hex(event['args']['participant2']) if token_network.node_address not in (participant1, participant2): raise ValueError('One participant must be the node address') if token_network.node_address == participant2: participant1, participant2 = participant2, participant1 self.channel_identifier = channel_identifier self.channel_operations_lock = RLock() self.participant1 = participant1 self.participant2 = participant2 self.token_network = token_network
def get_filter_args_for_channel_from_token_network( token_network_address: Address, channel_identifier: ChannelID, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ) -> Dict: event_abi = CONTRACT_MANAGER.get_event_abi(CONTRACT_TOKEN_NETWORK, EVENT_CHANNEL_OPENED) # Here the topics for a specific event are created # The first entry of the topics list is the event name, then the first parameter is encoded, # in the case of a token network, the first parameter is always the channel identifier data_filter_set, event_filter_params = construct_event_filter_params( event_abi=event_abi, contract_address=to_checksum_address(token_network_address), argument_filters={ 'channel_identifier': channel_identifier, }, fromBlock=from_block, toBlock=to_block, ) # As we want to get all events for a certain channel we remove the event specific code here # and filter just for the channel identifier # We also have to remove the trailing topics to get all filters event_filter_params['topics'] = [None, event_filter_params['topics'][1]] return event_filter_params
def get_all_netting_channel_events( chain: BlockChainService, token_network_address: Address, netting_channel_identifier: ChannelID, events: List[str] = ALL_EVENTS, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ) -> List[Dict]: """ Helper to get all events of a NettingChannelContract. """ filter_args = get_filter_args_for_all_events_from_channel( token_network_address=token_network_address, channel_identifier=netting_channel_identifier, from_block=from_block, to_block=to_block, ) return get_contract_events( chain, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), token_network_address, filter_args['topics'], from_block, to_block, )
def __init__( self, jsonrpc_client, secret_registry_address, ): if not is_binary_address(secret_registry_address): raise InvalidAddress('Expected binary address format for secret registry') check_address_has_code(jsonrpc_client, secret_registry_address, CONTRACT_SECRET_REGISTRY) proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_SECRET_REGISTRY), to_normalized_address(secret_registry_address), ) if not compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ): raise ContractVersionMismatch('Incompatible ABI for SecretRegistry') self.address = secret_registry_address self.proxy = proxy self.client = jsonrpc_client self.node_address = privatekey_to_address(self.client.privkey) self.open_secret_transactions = dict()
def get_filter_args_for_specific_event_from_channel( token_network_address: Address, channel_identifier: ChannelID, event_name: str, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ): """ Return the filter params for a specific event of a given channel. """ if not event_name: raise ValueError('Event name must be given') event_abi = CONTRACT_MANAGER.get_event_abi(CONTRACT_TOKEN_NETWORK, event_name) # Here the topics for a specific event are created # The first entry of the topics list is the event name, then the first parameter is encoded, # in the case of a token network, the first parameter is always the channel identifier _, event_filter_params = construct_event_filter_params( event_abi=event_abi, contract_address=to_checksum_address(token_network_address), argument_filters={ 'channel_identifier': channel_identifier, }, fromBlock=from_block, toBlock=to_block, ) return event_filter_params
def __init__( self, jsonrpc_client, secret_registry_address, ): if not is_binary_address(secret_registry_address): raise InvalidAddress( 'Expected binary address format for secret registry') check_address_has_code(jsonrpc_client, secret_registry_address, CONTRACT_SECRET_REGISTRY) proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_SECRET_REGISTRY), to_normalized_address(secret_registry_address), ) try: if not compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ): raise ContractVersionMismatch( 'Incompatible ABI for SecretRegistry') except BadFunctionCallOutput: raise AddressWrongContract('') self.address = secret_registry_address self.proxy = proxy self.client = jsonrpc_client self.node_address = privatekey_to_address(self.client.privkey) self.open_secret_transactions = dict()
def __init__( self, jsonrpc_client, discovery_address, ): contract = jsonrpc_client.new_contract( CONTRACT_MANAGER.get_contract_abi(CONTRACT_ENDPOINT_REGISTRY), to_normalized_address(discovery_address), ) proxy = ContractProxy(jsonrpc_client, contract) if not is_binary_address(discovery_address): raise ValueError('discovery_address must be a valid address') check_address_has_code(jsonrpc_client, discovery_address, 'Discovery') try: is_valid_version = compare_versions( proxy.contract.functions.contract_version().call(), EXPECTED_CONTRACTS_VERSION, ) if not is_valid_version: raise ContractVersionMismatch('Incompatible ABI for Discovery') except BadFunctionCallOutput: raise AddressWrongContract('') self.address = discovery_address self.client = jsonrpc_client self.not_found_address = NULL_ADDRESS self.proxy = proxy
def is_service_registered( web3: Web3, msc_contract_address: str, service_address: str ) -> bool: """Returns true if service is registered in the Monitoring service contract""" assert is_checksum_address(msc_contract_address) assert is_checksum_address(service_address) monitor_contract_abi = CONTRACT_MANAGER.get_contract_abi('MonitoringService') monitor_contract = web3.eth.contract(abi=monitor_contract_abi, address=msc_contract_address) bundle_contract_abi = CONTRACT_MANAGER.get_contract_abi('RaidenServiceBundle') raiden_service_bundle_address = to_checksum_address(monitor_contract.functions.rsb().call()) bundle_contract = web3.eth.contract( abi=bundle_contract_abi, address=raiden_service_bundle_address ) return bundle_contract.functions.deposits(service_address).call() > 0
def test_deploy(generate_raiden_client, ethereum_tester): c1, c2 = generate_raiden_client(), generate_raiden_client() c3 = generate_raiden_client() web3 = c1.web3 # make filter for ChannelClosed event # get event ABI abi = CONTRACT_MANAGER.get_event_abi('TokenNetwork', 'ChannelClosed') event_filter = make_filter(web3, abi) # deposit some funds to the channel channel_id = c1.open_channel(c2.address) c1.deposit_to_channel(c2.address, 100) channel_id_c2 = c2.open_channel(c1.address) c2.deposit_to_channel(c1.address, 100) assert channel_id == channel_id_c2 # initialy it should be empty transfer_events = event_filter.get_new_entries() assert transfer_events == [] # now close a channel and check if we got the entry c1_balance_proof = c2.get_balance_proof(c1.address, transferred_amount=10, nonce=5) c1.close_channel(c2.address, c1_balance_proof) transfer_events = event_filter.get_new_entries() assert transfer_events != [] assert is_same_address(transfer_events[0]['args']['closing_participant'], c1.address) assert transfer_events[0]['args']['channel_identifier'] == channel_id # no new entries transfer_events = event_filter.get_new_entries() assert transfer_events == [] # open/close another channel, get new entry channel_id = c3.open_channel(c1.address) c1.open_channel(c3.address) c1_balance_proof = c1.get_balance_proof(c3.address, transferred_amount=10, nonce=3) c3.close_channel(c1.address, c1_balance_proof) transfer_events = [ event for event in event_filter.get_new_entries() if is_same_address(event['args']['closing_participant'], c3.address) ] assert transfer_events != [] assert is_same_address(transfer_events[0]['args']['closing_participant'], c3.address) assert transfer_events[0]['args']['channel_identifier'] == channel_id with pytest.raises(TransactionFailed): c1.settle_channel(c2.address) ethereum_tester.mine_blocks(num_blocks=10) with pytest.raises(TransactionFailed): c1.settle_channel(c2.address) ethereum_tester.mine_blocks(num_blocks=10) c1.settle_channel(c2.address)
def handle_event(self, event, callback: Callable): tx = self.web3.eth.getTransaction(event['transactionHash']) log.info(str(event) + str(tx)) abi = CONTRACT_MANAGER.get_contract_abi('TokenNetwork') assert abi is not None method_params = decode_contract_call(abi, tx['data']) if method_params is not None: return callback(event, method_params) else: return None
def all_events_filter( self, from_block: typing.BlockSpecification = None, to_block: typing.BlockSpecification = None, ) -> typing.Tuple[Filter, Filter]: channel_topics = [ None, # event topic is any encode_hex(encode_single('bytes32', self.channel_identifier)), # channel_id ] # This will match the events: # ChannelOpened, ChannelNewDeposit, ChannelWithdraw, ChannelClosed, # NonClosingBalanceProofUpdated, ChannelSettled channel_filter = self.token_network.client.new_filter( contract_address=self.token_network.address, topics=channel_topics, from_block=from_block, to_block=to_block, ) # This will match the events: # ChannelUnlocked # # These topics must not be joined with the channel_filter, otherwise # the filter ChannelSettled wont match (observed with geth # 1.8.11-stable-dea1ce05) event_unlock_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_TOKEN_NETWORK, EVENT_CHANNEL_UNLOCKED, ) event_unlock_topic = encode_hex( event_abi_to_log_topic(event_unlock_abi)) participant1_topic = encode_hex(self.participant1.rjust(32, b'\0')) participant2_topic = encode_hex(self.participant2.rjust(32, b'\0')) unlock_topics = [ event_unlock_topic, [participant1_topic, participant2_topic], # event participant1 is us or them [participant2_topic, participant1_topic], # event participant2 is us or them ] unlock_filter = self.token_network.client.new_filter( contract_address=self.token_network.address, topics=unlock_topics, from_block=from_block, to_block=to_block, ) return channel_filter, unlock_filter
def handle_event(self, event): tx = self.web3.eth.getTransaction(event['transactionHash']) abi = CONTRACT_MANAGER.get_contract_abi('TokenNetwork') s = decode_contract_call(abi, tx['data']) assert s is not None handlers = self.event_handlers.get(event['event'], None) log.info(event) if handlers is None: log.warning('unhandled event type: %s' % str(event)) return [x(event, s) for x in handlers]
def f(contract_name: str, args=None): if args is None: args = [] compiled = { contract_name: CONTRACT_MANAGER.get_contract(contract_name), } return deploy_client.deploy_solidity_contract( contract_name, compiled, constructor_parameters=args, )
def register_service( web3: Web3, msc_contract_address: str, private_key: str, deposit: int = 10 # any amount works now ): """Register service with a Monitor service contract""" service_address = private_key_to_address(private_key) assert is_checksum_address(msc_contract_address) assert is_checksum_address(service_address) monitor_contract_abi = CONTRACT_MANAGER.get_contract_abi('MonitoringService') monitor_contract = PrivateContract(web3.eth.contract( abi=monitor_contract_abi, address=msc_contract_address )) bundle_contract_abi = CONTRACT_MANAGER.get_contract_abi('RaidenServiceBundle') raiden_service_bundle_address = to_checksum_address(monitor_contract.functions.rsb().call()) bundle_contract = PrivateContract(web3.eth.contract( abi=bundle_contract_abi, address=raiden_service_bundle_address )) # approve funds for MSC token_address = to_checksum_address(monitor_contract.functions.token().call()) token_abi = CONTRACT_MANAGER.get_contract_abi('Token') token_contract = web3.eth.contract(abi=token_abi, address=token_address) token_contract = PrivateContract(token_contract) tx = token_contract.functions.approve(raiden_service_bundle_address, deposit).transact( private_key=private_key ) wait_for_transaction_receipt(web3, tx) # register MS tx = bundle_contract.functions.deposit(deposit).transact( private_key=private_key ) # check if MS is really registered wait_for_transaction_receipt(web3, tx) return bundle_contract.functions.deposits(service_address).call() > 0
def add_token_network_listener( self, token_network_proxy, from_block: typing.BlockSpecification = 'latest', ): channel_new_filter = token_network_proxy.channelnew_filter(from_block=from_block) token_network_address = token_network_proxy.address self.add_event_listener( 'TokenNetwork {}'.format(pex(token_network_address)), channel_new_filter, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), )
def add_token_network_listener( self, token_network_proxy, from_block: typing.BlockSpecification = 'latest', ): _filter = token_network_proxy.all_events_filter(from_block=from_block) token_network_address = token_network_proxy.address self.add_event_listener( 'TokenNetwork {}'.format(pex(token_network_address)), _filter, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), )
def add_token_network_registry_listener( self, token_network_registry_proxy, from_block: typing.BlockSpecification = 'latest', ): token_new_filter = token_network_registry_proxy.tokenadded_filter(from_block=from_block) token_network_registry_address = token_network_registry_proxy.address self.add_event_listener( 'TokenNetwork {}'.format(pex(token_network_registry_address)), token_new_filter, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK_REGISTRY), )
def add_secret_registry_listener( self, secret_registry_proxy: SecretRegistry, from_block: typing.BlockSpecification = 'latest', ): secret_registry_filter = secret_registry_proxy.secret_registered_filter( from_block=from_block, ) secret_registry_address = secret_registry_proxy.address self.add_event_listener( 'SecretRegistry {}'.format(pex(secret_registry_address)), secret_registry_filter, CONTRACT_MANAGER.get_contract_abi(CONTRACT_SECRET_REGISTRY), )
def get_netting_channel_settled_events( chain: BlockChainService, token_network_address: Address, netting_channel_identifier: ChannelID, events: List[str] = ALL_EVENTS, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ) -> List[Dict]: settled_event_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_TOKEN_NETWORK, EVENT_CHANNEL_SETTLED, ) settled_event_id = encode_hex(event_abi_to_log_topic(settled_event_abi)) settled_topics = [settled_event_id] return get_contract_events( chain, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), token_network_address, settled_topics, from_block, to_block, )
def tokenadded_filter(self, from_block=None, to_block=None) -> Filter: event_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_TOKEN_NETWORK_REGISTRY, EVENT_TOKEN_NETWORK_CREATED, ) topics = [encode_hex(event_abi_to_log_topic(event_abi))] registry_address_bin = self.proxy.contract_address return self.client.new_filter( registry_address_bin, topics=topics, from_block=from_block, to_block=to_block, )
def get_netting_channel_deposit_events( chain: BlockChainService, token_network_address: Address, netting_channel_identifier: ChannelID, events: List[str] = ALL_EVENTS, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ) -> List[Dict]: deposit_event_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_TOKEN_NETWORK, ChannelEvent.DEPOSIT, ) deposit_event_id = encode_hex(event_abi_to_log_topic(deposit_event_abi)) deposit_topics = [deposit_event_id] return get_contract_events( chain, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), token_network_address, deposit_topics, from_block, to_block, )
def all_events_filter( self, from_block: typing.BlockSpecification = None, to_block: typing.BlockSpecification = None, ) -> typing.Tuple[Filter, Filter]: channel_topics = [ None, # event topic is any encode_hex(encode_single('bytes32', self.channel_identifier)), # channel_id ] # This will match the events: # ChannelOpened, ChannelNewDeposit, ChannelWithdraw, ChannelClosed, # NonClosingBalanceProofUpdated, ChannelSettled channel_filter = self.token_network.client.new_filter( contract_address=self.token_network.address, topics=channel_topics, from_block=from_block, to_block=to_block, ) # This will match the events: # ChannelUnlocked # # These topics must not be joined with the channel_filter, otherwise # the filter ChannelSettled wont match (observed with geth # 1.8.11-stable-dea1ce05) event_unlock_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_TOKEN_NETWORK, EVENT_CHANNEL_UNLOCKED, ) event_unlock_topic = encode_hex(event_abi_to_log_topic(event_unlock_abi)) participant1_topic = encode_hex(self.participant1.rjust(32, b'\0')) participant2_topic = encode_hex(self.participant2.rjust(32, b'\0')) unlock_topics = [ event_unlock_topic, [participant1_topic, participant2_topic], # event participant1 is us or them [participant2_topic, participant1_topic], # event participant2 is us or them ] unlock_filter = self.token_network.client.new_filter( contract_address=self.token_network.address, topics=unlock_topics, from_block=from_block, to_block=to_block, ) return channel_filter, unlock_filter
def get_token_network_registry_events( chain: BlockChainService, token_network_registry_address: Address, events: List[str] = ALL_EVENTS, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ) -> List[Dict]: """ Helper to get all events of the Registry contract at `registry_address`. """ return get_contract_events( chain, CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK_REGISTRY), token_network_registry_address, events, from_block, to_block, )
def settle_timeout(self) -> int: """ Returns the channels settle_timeout. """ # There is no way to get the settle timeout after the channel has been closed as # we're saving gas. Therefore get the ChannelOpened event and get the timeout there. filter_args = get_filter_args_for_specific_event_from_channel( token_network_address=self.token_network.address, channel_identifier=self.channel_identifier, event_name=EVENT_CHANNEL_OPENED, ) events = self.token_network.proxy.contract.web3.eth.getLogs(filter_args) assert len(events) > 0, 'No matching ChannelOpen event found.' # we want the latest event here, there might have been multiple channels event = decode_event(CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[-1]) return event['args']['settle_timeout']
def secret_registered_filter( self, from_block: typing.BlockSpecification = 0, to_block: typing.BlockSpecification = 'latest', ) -> Filter: event_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_SECRET_REGISTRY, EVENT_SECRET_REVEALED, ) topics = [encode_hex(event_abi_to_log_topic(event_abi))] return self.client.new_filter( self.address, topics=topics, from_block=from_block, to_block=to_block, )
def tokenadded_filter( self, from_block: typing.BlockSpecification = 0, to_block: typing.BlockSpecification = 'latest', ) -> Filter: event_abi = CONTRACT_MANAGER.get_event_abi( CONTRACT_TOKEN_NETWORK_REGISTRY, EVENT_TOKEN_NETWORK_CREATED, ) topics = [encode_hex(event_abi_to_log_topic(event_abi))] registry_address_bin = self.proxy.contract_address return self.client.new_filter( registry_address_bin, topics=topics, from_block=from_block, to_block=to_block, )
def channelnew_filter( self, from_block: typing.BlockSpecification = 0, to_block: typing.BlockSpecification = 'latest', ) -> Filter: """ Install a new filter for ChannelNew events. Args: from_block: Create filter starting from this block number (default: 0). to_block: Create filter stopping at this block number (default: 'latest'). Return: The filter instance. """ event_abi = CONTRACT_MANAGER.get_event_abi(CONTRACT_TOKEN_NETWORK, EVENT_CHANNEL_OPENED) event_id = encode_hex(event_abi_to_log_topic(event_abi)) topics = [event_id] return self.events_filter(topics, from_block, to_block)
def get_all_secret_registry_events( chain: BlockChainService, secret_registry_address: Address, events: List[str] = ALL_EVENTS, from_block: BlockSpecification = 0, to_block: BlockSpecification = 'latest', ) -> List[Dict]: """ Helper to get all events of a SecretRegistry. """ return get_contract_events( chain, CONTRACT_MANAGER.get_contract_abi( CONTRACT_SECRET_REGISTRY, ), secret_registry_address, events, from_block, to_block, )
def __init__( self, jsonrpc_client, token_address, ): contract = jsonrpc_client.new_contract( CONTRACT_MANAGER.get_contract_abi(CONTRACT_HUMAN_STANDARD_TOKEN), to_normalized_address(token_address), ) proxy = ContractProxy(jsonrpc_client, contract) if not is_binary_address(token_address): raise ValueError('token_address must be a valid address') check_address_has_code(jsonrpc_client, token_address, 'Token') self.address = token_address self.client = jsonrpc_client self.proxy = proxy
def validate_solc(): if get_solc_version() is None: raise RuntimeError( "Couldn't find the solc in the current $PATH.\n" "Make sure the solidity compiler is installed and available on your $PATH.", ) try: compile_files( [CONTRACT_MANAGER.get_contract_path(CONTRACT_HUMAN_STANDARD_TOKEN)], 'HumanStandardToken', optimize=False, ) except subprocess.CalledProcessError as e: msg = ( 'The solidity compiler failed to execute. Please make sure that you\n' 'are using the binary version of the compiler (solc-js is not compatible)\n' 'and that the version is >= {}'.format(MIN_REQUIRED_SOLC) ) if e.output: msg += ( '\n' 'Output: ' + e.output ) raise RuntimeError(msg) except OSError as e: msg = ( 'The solidity compiler failed to execute. Please make sure the\n' 'binary is compatible with your architecture and you can execute it.' ) child_traceback = getattr(e, 'child_traceback', None) if child_traceback: msg += ( '\n' 'Traceback: ' + child_traceback ) raise RuntimeError(msg)
def add_payment_channel_listener( self, payment_channel_proxy: PaymentChannel, from_block: typing.BlockSpecification = 'latest', ): payment_channel_filter, unlock_filter = payment_channel_proxy.all_events_filter( from_block=from_block, ) channel_identifier = payment_channel_proxy.channel_identifier token_network_id = payment_channel_proxy.token_network.address token_network_abi = CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK) self.add_event_listener( f'PaymentChannel event {channel_identifier} {token_network_id}', payment_channel_filter, token_network_abi, ) self.add_event_listener( f'PaymentChannel unlock event {channel_identifier} {token_network_id}', unlock_filter, token_network_abi, )