def test_new_channel_state(private_keys, tester_chain, tester_channelmanager): """ Tests the state of a newly created netting channel. """ pkey0, pkey1 = private_keys events = list() settle_timeout = 10 channel = new_nettingcontract( pkey0, pkey1, tester_chain, events.append, tester_channelmanager, settle_timeout, ) # pylint: disable=no-member assert channel.settleTimeout(sender=pkey0) == settle_timeout assert channel.tokenAddress(sender=pkey0) == tester_channelmanager.tokenAddress(sender=pkey0) assert channel.opened(sender=pkey0) == tester_chain.block.number - 1 assert channel.closed(sender=pkey0) == 0 address_and_balances = channel.addressAndBalance(sender=pkey0) address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) assert address_and_balances[0] == address_encoder(address0) assert address_and_balances[1] == 0 assert address_and_balances[2] == address_encoder(address1) assert address_and_balances[3] == 0
def test_channelnew_event( settle_timeout, tester_channelmanager, private_keys, tester_events): """ When a new channel is created the channel new event must be emitted. """ pkey0 = private_keys[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(private_keys[1]) # pylint: disable=no-member netting_channel_address1_hex = tester_channelmanager.newChannel( address1, settle_timeout, sender=pkey0, ) last_event = event_decoder(tester_events[-1], tester_channelmanager.translator) assert last_event == { '_event_type': b'ChannelNew', 'netting_channel': netting_channel_address1_hex, 'participant1': address_encoder(address0), 'participant2': address_encoder(address1), 'settle_timeout': settle_timeout, }
def test_channelmanager(private_keys, settle_timeout, tester_channelmanager): pkey0 = private_keys[0] address0 = privatekey_to_address(private_keys[0]) address1 = privatekey_to_address(private_keys[1]) address2 = privatekey_to_address(private_keys[2]) total_pairs = 0 for addr in [address1, address2]: channel_address_hex = tester_channelmanager.newChannel( addr, settle_timeout, sender=pkey0, ) assert tester_channelmanager.getChannelWith(addr, sender=pkey0) == channel_address_hex total_pairs += 2 participant_pairs = tester_channelmanager.getChannelsParticipants(sender=pkey0) assert len(participant_pairs) == total_pairs # pylint: disable=no-member addr0_channels = tester_channelmanager.nettingContractsByAddress(address0, sender=pkey0) addr1_channels = tester_channelmanager.nettingContractsByAddress(address1, sender=pkey0) nonexisting_address = sha3(b'this_does_not_exist')[:20] nonaddr_channels = tester_channelmanager.nettingContractsByAddress( nonexisting_address, sender=pkey0, ) assert len(addr0_channels) == 2 assert len(addr1_channels) == 1 assert not nonaddr_channels
def geth_wait_and_check(privatekeys, rpc_ports): """ Wait until the geth cluster is ready. """ address = address_encoder(privatekey_to_address(privatekeys[0])) jsonrpc_running = False tries = 5 rpc_port = rpc_ports[0] jsonrpc_client = JSONRPCClient(host="0.0.0.0", port=rpc_port, privkey=privatekeys[0], print_communication=False) while not jsonrpc_running and tries > 0: try: jsonrpc_client.call("eth_getBalance", address, "latest") jsonrpc_running = True except ConnectionError: gevent.sleep(0.5) tries -= 1 if jsonrpc_running is False: raise ValueError("geth didnt start the jsonrpc interface") for key in set(privatekeys): address = address_encoder(privatekey_to_address(key)) jsonrpc_client = JSONRPCClient(host="0.0.0.0", port=rpc_port, privkey=key, print_communication=False) tries = 10 balance = "0x0" while balance == "0x0" and tries > 0: balance = jsonrpc_client.call("eth_getBalance", address, "latest") gevent.sleep(1) tries -= 1 if balance == "0x0": raise ValueError("account is with a balance of 0")
def test_two_direct_transfers( settle_timeout, deposit, tester_chain, tester_channels, tester_token): """ The value of both transfers must be account for. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) first_amount0 = 90 block_number = tester_chain.block.number make_direct_transfer_from_channel( block_number, channel0, channel1, first_amount0, pkey0, ) second_amount0 = 90 block_number = tester_chain.block.number second_direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, second_amount0, pkey0, ) nettingchannel.close(sender=pkey0) second_direct0_hash = sha3(second_direct0.packed().data[:-65]) nettingchannel.updateTransfer( second_direct0.nonce, second_direct0.transferred_amount, second_direct0.locksroot, second_direct0_hash, second_direct0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = initial0 + deposit - first_amount0 - second_amount0 balance1 = initial1 + deposit + first_amount0 + second_amount0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_settle_with_locked_mediated_transfer_for_counterparty( deposit, settle_timeout, reveal_timeout, tester_chain, tester_channels, tester_token): """ Test settle with a locked mediated transfer for the counter party. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) transferred_amount0 = 30 increase_transferred_amount(channel0, channel1, transferred_amount0) expiration0 = tester_chain.block.number + reveal_timeout + 5 new_block = Block(tester_chain.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock0 = Lock(amount=29, expiration=expiration0, hashlock=sha3(b'lock1')) mediated0 = make_mediated_transfer( channel0, channel1, address0, address1, lock0, pkey0, tester_chain.block.number, ) nettingchannel.close(sender=pkey0) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.updateTransfer( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey1) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial0 + deposit - transferred_amount0 balance1 = initial1 + transferred_amount0 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1
def __init__(self, private_key, tester_chain): self.tester_chain = tester_chain self.address = privatekey_to_address(private_key) self.private_key = private_key self.node_address = privatekey_to_address(private_key) self.address_to_token = dict() self.address_to_discovery = dict() self.address_to_nettingchannel = dict() self.address_to_registry = dict() self.client = ClientMock()
def test_reopen_channel( private_keys, settle_timeout, tester_channelmanager, tester_chain): """ A new channel can be opened after the old one is settled. When this happens the channel manager must update its internal data structures to point to the new channel address. """ log = list() pkey = private_keys[0] channels = list() old_channel_addresses = list() for partner_pkey in private_keys[1:]: nettingcontract = new_nettingcontract( pkey, partner_pkey, tester_chain, log.append, tester_channelmanager, settle_timeout, ) channels.append(nettingcontract) address = privatekey_to_address(partner_pkey) channel_address = tester_channelmanager.getChannelWith( address, sender=pkey, ) old_channel_addresses.append(channel_address) for nettingchannel in channels: netting_channel_settled( tester_chain, nettingchannel, pkey, settle_timeout, ) channels = list() for partner_pkey in private_keys[1:]: nettingcontract = new_nettingcontract( pkey, partner_pkey, tester_chain, log.append, tester_channelmanager, settle_timeout, ) channels.append(nettingcontract) # there must be a single entry for each participant for partner_pkey in private_keys[1:]: address = privatekey_to_address(partner_pkey) channel_address = tester_channelmanager.getChannelWith( address, sender=pkey, ) assert channel_address assert channel_address not in old_channel_addresses
def test_deposit(private_keys, tester_channelmanager, tester_chain, tester_token): """ A call to deposit must increase the available token amount in the netting channel. """ pkey0 = private_keys[0] pkey1 = private_keys[1] address0 = address_encoder(privatekey_to_address(pkey0)) address1 = address_encoder(privatekey_to_address(pkey1)) settle_timeout = 10 events = list() # not using the tester_nettingcontracts fixture because it has a set balance channel = new_nettingcontract( pkey0, pkey1, tester_chain, events.append, tester_channelmanager, settle_timeout, ) deposit = 100 # cannot deposit without approving assert channel.deposit(deposit, sender=pkey0) is False assert tester_token.approve(channel.address, deposit, sender=pkey0) is True # cannot deposit negative values with pytest.raises(abi.ValueOutOfBounds): channel.deposit(-1, sender=pkey0) zero_state = (address0, 0, address1, 0) assert tuple(channel.addressAndBalance(sender=pkey0)) == zero_state assert channel.deposit(deposit, sender=pkey0) is True deposit_state = (address0, deposit, address1, 0) assert tuple(channel.addressAndBalance(sender=pkey0)) == deposit_state assert tester_token.balanceOf(channel.address, sender=pkey0) == deposit # cannot over deposit (the allowance is depleted) assert channel.deposit(deposit, sender=pkey0) is False assert tester_token.approve(channel.address, deposit, sender=pkey0) is True assert channel.deposit(deposit, sender=pkey0) is True second_deposit_state = (address0, deposit * 2, address1, 0) assert tuple(channel.addressAndBalance(sender=pkey0)) == second_deposit_state
def test_withdraw_twice(reveal_timeout, tester_channels, tester_chain): """ A lock can be withdrawn only once, the second try must fail. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] lock_expiration = tester_chain.block.number + reveal_timeout + 5 secret = b'secretsecretsecretsecretsecretse' new_block = Block(tester_chain.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock = Lock(17, lock_expiration, sha3(secret)) mediated0 = make_mediated_transfer( channel1, channel0, privatekey_to_address(pkey1), privatekey_to_address(pkey0), lock, pkey1, tester_chain.block.number, secret, ) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey0, ) unlock_proofs = list(channel0.partner_state.get_known_unlocks()) proof = unlock_proofs[0] nettingchannel.withdraw( proof.lock_encoded, b''.join(proof.merkle_proof), proof.secret, sender=pkey0, ) with pytest.raises(TransactionFailed): nettingchannel.withdraw( proof.lock_encoded, b''.join(proof.merkle_proof), proof.secret, sender=pkey0, )
def test_for_issue_892( private_keys, settle_timeout, tester_channelmanager, tester_chain, tester_events): """ This is a regression test for issue #892 (https://github.com/raiden-network/raiden/issues/892) where the `getChannelsParticipants()` call was returning an empty list if one channel from the channel manager has been settled """ pairs = itertools.combinations(private_keys, 2) participant_pairs = [] first_pair = True for pkey0, pkey1 in pairs: address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) channel_address_hex = tester_channelmanager.newChannel( address1, settle_timeout, sender=pkey0, ) tester_chain.mine() assert tester_channelmanager.getChannelWith(address1, sender=pkey0) == channel_address_hex assert tester_channelmanager.getChannelWith(address0, sender=pkey1) == channel_address_hex if first_pair: first_pair = False nettingchannel = create_nettingchannel_proxy( tester_chain, channel_address_hex, tester_events.append, ) nettingchannel.close(sender=pkey0) tester_chain.mine(number_of_blocks=settle_timeout + 2) nettingchannel.settle(sender=pkey1) else: # this is brittle, relying on an implicit ordering of addresses participant_pairs.extend(( address_encoder(address0), address_encoder(address1), )) assert participant_pairs == tester_channelmanager.getChannelsParticipants(sender=pkey0)
def test_update_must_fail_with_a_channel_address(tester_channels, private_keys): """ updateTransfer must not accept a transfer signed with the wrong channel address. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] opened_block = nettingchannel.opened(sender=pkey0) wrong_channel = make_address() # make a transfer where pkey1 is the target transfer_wrong_recipient = DirectTransfer( identifier=1, nonce=1 + (opened_block * (2 ** 32)), token=channel0.token_address, channel=wrong_channel, transferred_amount=10, recipient=channel1.our_address, locksroot=EMPTY_MERKLE_ROOT, ) our_address = privatekey_to_address(pkey0) our_sign_key = PrivateKey(pkey0) transfer_wrong_recipient.sign(our_sign_key, our_address) nettingchannel.close(sender=pkey0) transfer_wrong_recipient_hash = sha3(transfer_wrong_recipient.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer_wrong_recipient.nonce, transfer_wrong_recipient.transferred_amount, transfer_wrong_recipient.locksroot, transfer_wrong_recipient_hash, transfer_wrong_recipient.signature, sender=pkey1, )
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 detail(self): """ FIXME: 'our_address' is only needed for the pure python mock implementation """ self._check_exists() data = self.proxy.addressAndBalance() settle_timeout = self.proxy.settleTimeout() our_address = privatekey_to_address(self.private_key) if address_decoder(data[0]) == our_address: return { 'our_address': address_decoder(data[0]), 'our_balance': data[1], 'partner_address': address_decoder(data[2]), 'partner_balance': data[3], 'settle_timeout': settle_timeout, } if address_decoder(data[2]) == our_address: return { 'our_address': address_decoder(data[2]), 'our_balance': data[3], 'partner_address': address_decoder(data[0]), 'partner_balance': data[1], 'settle_timeout': settle_timeout, } raise ValueError('We [{}] are not a participant of the given channel ({}, {})'.format( pex(our_address), data[0], data[2], ))
def __init__( self, jsonrpc_client, secret_registry_address, contract_manager: ContractManager, ): if not is_binary_address(secret_registry_address): raise InvalidAddress('Expected binary address format for secret registry') self.contract_manager = contract_manager check_address_has_code(jsonrpc_client, secret_registry_address, CONTRACT_SECRET_REGISTRY) proxy = jsonrpc_client.new_contract_proxy( self.contract_manager.get_contract_abi(CONTRACT_SECRET_REGISTRY), to_normalized_address(secret_registry_address), ) compare_contract_versions( proxy=proxy, expected_version=contract_manager.contracts_version, contract_name=CONTRACT_SECRET_REGISTRY, address=secret_registry_address, ) 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_manager: ContractManager, ): 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') compare_contract_versions( proxy=proxy, expected_version=contract_manager.contracts_version, contract_name=CONTRACT_ENDPOINT_REGISTRY, address=discovery_address, ) self.address = discovery_address self.node_address = privatekey_to_address(jsonrpc_client.privkey) self.client = jsonrpc_client self.not_found_address = NULL_ADDRESS self.proxy = proxy
def make_direct_transfer_from_channel(block_number, from_channel, partner_channel, amount, pkey): """ Helper to create and register a direct transfer from `from_channel` to `partner_channel`. """ identifier = from_channel.get_next_nonce() direct_transfer_msg = from_channel.create_directtransfer( amount, identifier=identifier, ) address = privatekey_to_address(pkey) sign_key = PrivateKey(pkey) direct_transfer_msg.sign(sign_key, address) # if this fails it's not the right key for the current `from_channel` assert direct_transfer_msg.sender == from_channel.our_state.address from_channel.register_transfer( block_number, direct_transfer_msg, ) partner_channel.register_transfer( block_number, direct_transfer_msg, ) return direct_transfer_msg
def test_close_accepts_only_transfer_from_participants(tester_channels, private_keys): """ Close must not accept a transfer signed by a non participant. """ pkey0, _, nettingchannel, channel0, _ = tester_channels[0] nonparticipant_key = private_keys[2] opened_block = nettingchannel.opened(sender=pkey0) # make a transfer where pkey0 is the target transfer_nonparticipant = DirectTransfer( identifier=1, nonce=1 + (opened_block * (2 ** 32)), token=channel0.token_address, channel=channel0.channel_address, transferred_amount=10, recipient=channel0.our_address, locksroot=EMPTY_MERKLE_ROOT, ) nonparticipant_address = privatekey_to_address(nonparticipant_key) nonparticipant_sign_key = PrivateKey(nonparticipant_key) transfer_nonparticipant.sign(nonparticipant_sign_key, nonparticipant_address) transfer_nonparticipant_hash = sha3(transfer_nonparticipant.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( transfer_nonparticipant.nonce, transfer_nonparticipant.transferred_amount, transfer_nonparticipant.locksroot, transfer_nonparticipant_hash, transfer_nonparticipant.signature, sender=pkey0, )
def test_close_wrong_channel(tester_channels): """ Close must not accept a transfer aimed at a different channel. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] opened_block = nettingchannel.opened(sender=pkey0) wrong_address = make_address() # make a transfer where the recipient is totally wrong transfer_wrong_channel = DirectTransfer( identifier=1, nonce=1 + (opened_block * (2 ** 32)), token=channel0.token_address, channel=wrong_address, transferred_amount=10, recipient=channel0.our_address, locksroot=EMPTY_MERKLE_ROOT, ) transfer_wrong_channel.sign(PrivateKey(pkey1), privatekey_to_address(pkey1)) transfer_wrong_channel_hash = sha3(transfer_wrong_channel.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( transfer_wrong_channel.nonce, transfer_wrong_channel.transferred_amount, transfer_wrong_channel.locksroot, transfer_wrong_channel_hash, transfer_wrong_channel.signature, sender=pkey0, )
def test_endpointregistry(private_keys, blockchain_services, contract_manager): chain = blockchain_services.blockchain_services[0] my_address = privatekey_to_address(private_keys[0]) endpointregistry_address = deploy_contract_web3( contract_name=CONTRACT_ENDPOINT_REGISTRY, deploy_client=chain.client, contract_manager=contract_manager, ) discovery_proxy = chain.discovery(endpointregistry_address) contract_discovery = ContractDiscovery(my_address, discovery_proxy) unregistered_address = make_address() # get should raise for unregistered addresses with pytest.raises(UnknownAddress): contract_discovery.get(my_address) with pytest.raises(UnknownAddress): contract_discovery.get(unregistered_address) contract_discovery.register(my_address, '127.0.0.1', 44444) assert contract_discovery.get(my_address) == ('127.0.0.1', 44444) contract_discovery.register(my_address, '127.0.0.1', 88888) assert contract_discovery.get(my_address) == ('127.0.0.1', 88888) with pytest.raises(UnknownAddress): contract_discovery.get(unregistered_address)
def new_nettingcontract( our_key, partner_key, tester_chain, log_listener, channelmanager, settle_timeout): invalid_timeout = ( settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX ) if invalid_timeout: raise ValueError('settle_timeout must be in range [{}, {}]'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX )) netting_channel_address0_hex = channelmanager.newChannel( privatekey_to_address(partner_key), settle_timeout, sender=our_key, ) tester_chain.mine(number_of_blocks=1) nettingchannel = create_nettingchannel_proxy( tester_chain, netting_channel_address0_hex, log_listener, ) return nettingchannel
def test_endpointregistry(private_keys, blockchain_services): chain = blockchain_services.blockchain_services[0] my_address = privatekey_to_address(private_keys[0]) endpointregistry_address = chain.deploy_contract( 'EndpointRegistry', get_contract_path('EndpointRegistry.sol'), ) discovery_proxy = chain.discovery(endpointregistry_address) contract_discovery = ContractDiscovery(my_address, discovery_proxy) unregistered_address = make_address() # get should raise for unregistered addresses with pytest.raises(UnknownAddress): contract_discovery.get(my_address) with pytest.raises(UnknownAddress): contract_discovery.get(unregistered_address) assert contract_discovery.nodeid_by_host_port(('127.0.0.1', 44444)) is None contract_discovery.register(my_address, '127.0.0.1', 44444) assert contract_discovery.nodeid_by_host_port(('127.0.0.1', 44444)) == my_address assert contract_discovery.get(my_address) == ('127.0.0.1', 44444) contract_discovery.register(my_address, '127.0.0.1', 88888) assert contract_discovery.nodeid_by_host_port(('127.0.0.1', 88888)) == my_address assert contract_discovery.get(my_address) == ('127.0.0.1', 88888) with pytest.raises(UnknownAddress): contract_discovery.get(unregistered_address)
def new_netting_channel(self, peer1, peer2, settle_timeout): """ Creates a new netting contract between peer1 and peer2. Raises: ValueError: If peer1 or peer2 is not a valid address. """ if not isaddress(peer1): raise ValueError('The pee1 must be a valid address') if not isaddress(peer2): raise ValueError('The peer2 must be a valid address') if privatekey_to_address(self.private_key) == peer1: other = peer2 else: other = peer1 netting_channel_address_hex = self.proxy.newChannel(other, settle_timeout) self.tester_state.mine(number_of_blocks=1) channel = NettingChannelTesterMock( self.tester_state, self.private_key, netting_channel_address_hex, ) return decode_hex(channel.address)
def geth_bare_genesis(genesis_path, private_keys, random_marker): """Writes a bare genesis to `genesis_path`. Args: genesis_path (str): the path in which the genesis block is written. private_keys list(str): iterable list of privatekeys whose corresponding accounts will have a premined balance available. """ account_addresses = [ privatekey_to_address(key) for key in sorted(set(private_keys)) ] alloc = { address_encoder(address): { 'balance': DEFAULT_BALANCE_BIN, } for address in account_addresses } genesis = GENESIS_STUB.copy() genesis['alloc'].update(alloc) genesis['config']['clique'] = {'period': 1, 'epoch': 30000} genesis['extraData'] = clique_extradata( random_marker, address_encoder(account_addresses[0])[2:], ) with open(genesis_path, 'w') as handler: json.dump(genesis, handler)
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 hostport_to_privkeyaddr(host, port): """ Return `(private key, address)` deterministically generated. """ myip_port = '{}:{}'.format(host, port) privkey = sha3(myip_port.encode()) addr = privatekey_to_address(privkey) return privkey, addr
def test_token( deploy_client, token_proxy, private_keys, blockchain_rpc_ports, web3, ): privkey = private_keys[1] address = privatekey_to_address(privkey) address = to_canonical_address(address) other_client = JSONRPCClient( '0.0.0.0', blockchain_rpc_ports[0], privkey, web3=web3, ) other_token_proxy = Token( other_client, to_canonical_address(token_proxy.proxy.contract.address), ) # send some funds from deployer to generated address transfer_funds = 100 token_proxy.transfer(address, transfer_funds) assert transfer_funds == token_proxy.balance_of(address) allow_funds = 100 token_proxy.approve(address, allow_funds) assert allow_funds == token_proxy.proxy.contract.functions.allowance( to_checksum_address(deploy_client.sender), to_checksum_address(address), ).call() other_token_proxy.transfer(deploy_client.sender, transfer_funds) assert token_proxy.balance_of(address) == 0
def geth_wait_and_check(deploy_client, privatekeys, random_marker): """ Wait until the geth cluster is ready. """ jsonrpc_running = False tries = 5 while not jsonrpc_running and tries > 0: try: block = deploy_client.call('eth_getBlockByNumber', '0x0', True) except ConnectionError: gevent.sleep(0.5) tries -= 1 else: jsonrpc_running = True running_marker = block['extraData'][2:len(random_marker) + 2] if running_marker != random_marker: raise RuntimeError( 'the test marker does not match, maybe two tests are running in ' 'parallel with the same port?' ) if jsonrpc_running is False: raise ValueError('geth didnt start the jsonrpc interface') for key in sorted(set(privatekeys)): address = address_encoder(privatekey_to_address(key)) tries = 10 balance = '0x0' while balance == '0x0' and tries > 0: balance = deploy_client.call('eth_getBalance', address, 'latest') gevent.sleep(1) tries -= 1 if balance == '0x0': raise ValueError('account is with a balance of 0')
def token_addresses( token_amount, number_of_tokens, private_keys, deploy_service, token_network_registry_address, register_tokens, contract_manager, ) -> typing.List[typing.Address]: """ Fixture that yields `number_of_tokens` ERC20 token addresses, where the `token_amount` (per token) is distributed among the addresses behind `deploy_client` and potentially pre-registered with the raiden Registry. The following arguments can control the behavior: Args: token_amount (int): the overall number of units minted per token number_of_tokens (int): the number of token instances register_tokens (bool): controls if tokens will be registered with raiden Registry """ participants = [privatekey_to_address(key) for key in private_keys] token_addresses = deploy_tokens_and_fund_accounts( token_amount=token_amount, number_of_tokens=number_of_tokens, deploy_service=deploy_service, participants=participants, contract_manager=contract_manager, ) if register_tokens: for token in token_addresses: deploy_service.token_network_registry(token_network_registry_address).add_token(token) return token_addresses
def create_node_configuration(miner=True, port=30301, rpcport=8101, host='127.0.0.1', node_key_seed=0): """ Create configuration (ports, keys, etc...) for one node. :param miner: if True, setup to be a mining node :param port: the p2p port to assign :param rpcport: the port to assign :param host: the host for the node to run on :return: node configuration dict """ node = dict() if miner: node['minerthreads'] = 1 # conservative node['unlock'] = 0 node['nodekey'] = sha3('node:{}'.format(node_key_seed).encode()) node['nodekeyhex'] = encode_hex(node['nodekey']) node['pub'] = encode_hex(privtopub_enode(node['nodekey'])) node['address'] = privatekey_to_address(node['nodekey']) node['host'] = host node['port'] = port node['rpcport'] = rpcport node['enode'] = 'enode://{pub}@{host}:{port}'.format(**node) return node
def cached_genesis(request, blockchain_type): """ Deploy all contracts that are required by the fixtures into a tester and then serialize the accounts into a genesis block. Returns: dict: A dictionary representing the genesis block. """ if not request.config.option.blockchain_cache: return if blockchain_type != 'geth': return # this will create the tester _and_ deploy the Registry deploy_key = request.getfixturevalue('deploy_key') private_keys = request.getfixturevalue('private_keys') registry, deploy_service, blockchain_services = _tester_services( deploy_key, private_keys, request.getfixturevalue('tester_blockgas_limit'), ) registry_address = registry.address # create_network only registers the tokens, # the contracts must be deployed previously register = True participants = [ privatekey_to_address(privatekey) for privatekey in private_keys ] token_contract_addresses = _token_addresses( request.getfixturevalue('token_amount'), request.getfixturevalue('number_of_tokens'), deploy_service, registry, participants, register) endpoint_discovery_address = deploy_service.deploy_contract( 'EndpointRegistry', get_contract_path('EndpointRegistry.sol'), ) endpoint_discovery_services = [ ContractDiscovery( chain.node_address, chain.discovery(endpoint_discovery_address), ) for chain in blockchain_services ] raiden_apps = create_apps( blockchain_services, endpoint_discovery_services, registry_address, request.getfixturevalue('raiden_udp_ports'), DummyTransport, # Do not use a UDP server to avoid port reuse in MacOSX request.getfixturevalue('reveal_timeout'), request.getfixturevalue('settle_timeout'), request.getfixturevalue('database_paths'), request.getfixturevalue('retry_interval'), request.getfixturevalue('retries_before_backoff'), request.getfixturevalue('throttle_capacity'), request.getfixturevalue('throttle_fill_rate'), request.getfixturevalue('nat_invitation_timeout'), request.getfixturevalue('nat_keepalive_retries'), request.getfixturevalue('nat_keepalive_timeout'), ) if 'raiden_network' in request.fixturenames: create_network_channels( raiden_apps, token_contract_addresses, request.getfixturevalue('channels_per_node'), request.getfixturevalue('deposit'), request.getfixturevalue('settle_timeout'), ) elif 'raiden_chain' in request.fixturenames: create_sequential_channels( raiden_apps, token_contract_addresses[0], request.getfixturevalue('channels_per_node'), request.getfixturevalue('deposit'), request.getfixturevalue('settle_timeout'), ) # else: a test that is not creating channels for app in raiden_apps: app.stop(leave_channels=False) # save the state from the last block into a genesis dict tester = blockchain_services[0].tester_state tester.mine() genesis_alloc = dict() for account_address in tester.block.state.to_dict(): account_alloc = tester.block.account_to_dict(account_address) # Both keys and values of the account storage associative array # must now be encoded with 64 hex digits if account_alloc['storage']: account_alloc['storage'] = fix_tester_storage( account_alloc['storage']) # code must be hex encoded with 0x prefix account_alloc['code'] = account_alloc.get('code', '') # account_to_dict returns accounts with nonce=0 and the nonce must # be encoded with 16 hex digits account_alloc['nonce'] = '0x%016x' % tester.block.get_nonce( account_address) genesis_alloc[account_address] = account_alloc all_keys = set(private_keys) all_keys.add(deploy_key) all_keys = sorted(all_keys) account_addresses = [privatekey_to_address(key) for key in all_keys] for address in account_addresses: genesis_alloc[address]['balance'] = DEFAULT_BALANCE_BIN alloc = { address_encoder(address_maybe_bin): data for address_maybe_bin, data in genesis_alloc.iteritems() } genesis = GENESIS_STUB.copy() genesis['config']['clique'] = {'period': 1, 'epoch': 30000} random_marker = request.getfixturevalue('random_marker') genesis['extraData'] = clique_extradata( random_marker, address_encoder(account_addresses[0])[2:], ) genesis['alloc'] = alloc genesis['config']['defaultDiscoveryAddress'] = address_encoder( endpoint_discovery_address) genesis['config']['defaultRegistryAddress'] = address_encoder( registry_address) genesis['config']['tokenAddresses'] = [ address_encoder(token_address) for token_address in token_contract_addresses ] return genesis
def test_two_messages_mediated_transfer(deposit, settle_timeout, tester_state, tester_channels, tester_token, tester_events): privatekey0, privatekey1, nettingchannel, channel0, channel1 = tester_channels[ 0] address0 = privatekey_to_address(privatekey0) address1 = privatekey_to_address(privatekey1) unknow_key = tester.k3 initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0) initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1) lock_amount0 = 29 lock_expiration0 = tester_state.block.number + DEFAULT_REVEAL_TIMEOUT + 3 hashlock0 = sha3(tester.k0) mediated_transfer0 = channel0.create_mediatedtransfer( transfer_initiator=address0, transfer_target=address1, fee=0, amount=lock_amount0, expiration=lock_expiration0, hashlock=hashlock0, ) mediated_transfer0.sign(privatekey0) lock_amount1 = 29 lock_expiration1 = tester_state.block.number + DEFAULT_REVEAL_TIMEOUT + 5 hashlock1 = sha3(tester.k1) mediated_transfer1 = channel1.create_mediatedtransfer( transfer_initiator=address1, transfer_target=address0, fee=0, amount=lock_amount1, expiration=lock_expiration1, hashlock=hashlock1, ) mediated_transfer1.sign(privatekey1) with pytest.raises(TransactionFailed): nettingchannel.close( str(mediated_transfer0.packed().data), str(mediated_transfer1.packed().data), sender=unknow_key, ) previous_events = list(tester_events) nettingchannel.close( str(mediated_transfer0.packed().data), str(mediated_transfer1.packed().data), sender=privatekey0, ) assert len(previous_events) + 1 == len(tester_events) block_number = tester_state.block.number close_event = tester_events[-1] assert close_event == { '_event_type': 'ChannelClosed', 'closingAddress': encode_hex(address0), 'blockNumber': block_number, } assert nettingchannel.closed(sender=privatekey0) == block_number assert nettingchannel.closingAddress( sender=privatekey0) == encode_hex(address0) tester_state.mine(number_of_blocks=settle_timeout + 1) previous_events = list(tester_events) nettingchannel.settle(sender=privatekey0) block_number = tester_state.block.number assert len(previous_events) + 3 == len(tester_events) transfer0_event = tester_events[-3] assert transfer0_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address0), '_value': deposit, } transfer1_event = tester_events[-2] assert transfer1_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address1), '_value': deposit, } settle_event = tester_events[-1] assert settle_event == { '_event_type': 'ChannelSettled', 'blockNumber': block_number, } assert tester_token.balanceOf( address0, sender=privatekey0) == initial_balance0 + deposit # noqa assert tester_token.balanceOf( address1, sender=privatekey1) == initial_balance1 + deposit # noqa assert tester_token.balanceOf(nettingchannel.address, sender=privatekey1) == 0
def test_new_netting_contract(raiden_network, token_amount, settle_timeout): # pylint: disable=line-too-long,too-many-statements,too-many-locals app0, app1, app2 = raiden_network peer0_address = app0.raiden.address peer1_address = app1.raiden.address peer2_address = app2.raiden.address blockchain_service0 = app0.raiden.chain token_address = blockchain_service0.deploy_and_register_token( contract_name='HumanStandardToken', contract_file='HumanStandardToken.sol', constructor_parameters=(token_amount, 'raiden', 2, 'Rd'), ) token0 = blockchain_service0.token(token_address) for transfer_to in raiden_network[1:]: token0.transfer( privatekey_to_address(transfer_to.raiden.privkey), token_amount // len(raiden_network), ) manager0 = blockchain_service0.manager_by_token(token_address) # sanity assert manager0.channels_addresses() == [] assert manager0.channels_by_participant(peer0_address) == [] assert manager0.channels_by_participant(peer1_address) == [] assert manager0.channels_by_participant(peer2_address) == [] # create one channel netting_address_01 = manager0.new_netting_channel( peer0_address, peer1_address, settle_timeout, ) # check contract state netting_channel_01 = blockchain_service0.netting_channel( netting_address_01) assert netting_channel_01.isopen() is False assert netting_channel_01.partner(peer0_address) == peer1_address assert netting_channel_01.partner(peer1_address) == peer0_address # check channels channel_list = manager0.channels_addresses() assert sorted(channel_list[0]) == sorted([peer0_address, peer1_address]) assert manager0.channels_by_participant(peer0_address) == [ netting_address_01 ] assert manager0.channels_by_participant(peer1_address) == [ netting_address_01 ] assert manager0.channels_by_participant(peer2_address) == [] # create other chanel netting_address_02 = manager0.new_netting_channel( peer0_address, peer2_address, settle_timeout, ) netting_channel_02 = blockchain_service0.netting_channel( netting_address_02) assert netting_channel_02.isopen() is False assert netting_channel_02.partner(peer0_address) == peer2_address assert netting_channel_02.partner(peer2_address) == peer0_address channel_list = manager0.channels_addresses() expected_channels = [ sorted([peer0_address, peer1_address]), sorted([peer0_address, peer2_address]), ] for channel in channel_list: assert sorted(channel) in expected_channels result0 = sorted(manager0.channels_by_participant(peer0_address)) result1 = sorted([netting_address_01, netting_address_02]) assert result0 == result1 assert manager0.channels_by_participant(peer1_address) == [ netting_address_01 ] assert manager0.channels_by_participant(peer2_address) == [ netting_address_02 ] # deposit without approve should fail netting_channel_01.deposit(peer0_address, 100) assert netting_channel_01.isopen() is False assert netting_channel_02.isopen() is False assert netting_channel_01.detail(peer0_address)['our_balance'] == 0 assert netting_channel_01.detail(peer1_address)['our_balance'] == 0 # single-funded channel app0.raiden.chain.token(token_address).approve(netting_address_01, 100) netting_channel_01.deposit(peer0_address, 100) assert netting_channel_01.isopen() is True assert netting_channel_02.isopen() is False assert netting_channel_01.detail(peer0_address)['our_balance'] == 100 assert netting_channel_01.detail(peer1_address)['our_balance'] == 0 # double-funded channel app0.raiden.chain.token(token_address).approve(netting_address_02, 70) netting_channel_02.deposit(peer0_address, 70) assert netting_channel_01.isopen() is True assert netting_channel_02.isopen() is True assert netting_channel_02.detail(peer0_address)['our_balance'] == 70 assert netting_channel_02.detail(peer2_address)['our_balance'] == 0 app2.raiden.chain.token(token_address).approve(netting_address_02, 130) app2.raiden.chain.netting_channel(netting_address_02).deposit( peer2_address, 130) assert netting_channel_01.isopen() is True assert netting_channel_02.isopen() is True assert netting_channel_02.detail(peer0_address)['our_balance'] == 70 assert netting_channel_02.detail(peer2_address)['our_balance'] == 130
def test_withdraw_at_settlement_block(deposit, settle_timeout, tester_nettingcontracts, tester_chain, tester_token): """ It must be possible to unlock a lock up to and including the settlment block. """ pkey0, pkey1, nettingchannel = tester_nettingcontracts[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) lock_amount = 31 lock_expiration = tester_chain.block.number + settle_timeout secret = b'settlementsettlementsettlementse' hashlock = sha3(secret) lock0 = Lock( amount=lock_amount, expiration=lock_expiration, hashlock=hashlock, ) lock0_bytes = bytes(lock0.as_bytes) lock0_hash = sha3(lock0_bytes) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2**32)) mediated0 = MediatedTransfer( identifier=1, nonce=nonce, token=tester_token.address, channel=normalize_address(nettingchannel.address), transferred_amount=0, recipient=address1, locksroot=lock0_hash, lock=lock0, target=address1, initiator=address0, fee=0, ) sign_key0 = PrivateKey(pkey0) mediated0.sign(sign_key0, address0) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey1, ) block_until_settlement_end = lock_expiration - tester_chain.block.number tester_chain.mine(number_of_blocks=block_until_settlement_end) assert lock_expiration == tester_chain.block.number nettingchannel.withdraw( lock0_bytes, b'', # the lock itself it the root, the proof is empty secret, sender=pkey1, ) tester_chain.mine(number_of_blocks=1) nettingchannel.settle(sender=pkey0) balance0 = initial_balance0 + deposit - lock0.amount balance1 = initial_balance1 + deposit + lock0.amount assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def channel_from_nettingcontract(our_key, netting_contract, reveal_timeout): """ Create a `channel.Channel` for the `netting_contract`. Use this to make sure that both implementations (the smart contract and the python code) work in tandem.""" our_address = privatekey_to_address(our_key) token_address_hex = netting_contract.tokenAddress(sender=our_key) settle_timeout = netting_contract.settleTimeout(sender=our_key) address_balance = netting_contract.addressAndBalance(sender=our_key) address1_hex, balance1, address2_hex, balance2 = address_balance opened_block_number = netting_contract.opened(sender=our_key) closed_block_number = netting_contract.closed(sender=our_key) settled_block_number = None identifier = address_decoder(netting_contract.address) token_address = normalize_address(token_address_hex) address1 = normalize_address(address1_hex) address2 = normalize_address(address2_hex) if our_address == address1: our_balance = balance1 partner_address = address2 partner_balance = balance2 else: our_balance = balance2 partner_address = address1 partner_balance = balance1 our_state = NettingChannelEndState( our_address, our_balance, ) partner_state = NettingChannelEndState( partner_address, partner_balance, ) open_transaction = TransactionExecutionStatus( None, opened_block_number, TransactionExecutionStatus.SUCCESS, ) close_transaction = None if closed_block_number: close_transaction = TransactionExecutionStatus( None, closed_block_number, TransactionExecutionStatus.SUCCESS, ) settle_transaction = None if settled_block_number: settle_transaction = TransactionExecutionStatus( None, settled_block_number, TransactionExecutionStatus.SUCCESS, ) channel = NettingChannelState( identifier, token_address, reveal_timeout, settle_timeout, our_state, partner_state, open_transaction, close_transaction, settle_transaction, ) return channel
def test_withdraw_both_participants( deposit, settle_timeout, reveal_timeout, tester_channels, tester_chain, tester_token): pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) secret = b'secretsecretsecretsecretsecretse' hashlock = sha3(secret) lock_amount = 31 lock01_expiration = tester_chain.block.number + settle_timeout - 1 * reveal_timeout lock10_expiration = tester_chain.block.number + settle_timeout - 2 * reveal_timeout new_block = Block(tester_chain.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) # using the same hashlock and amount is intentional lock01 = Lock(lock_amount, lock01_expiration, hashlock) lock10 = Lock(lock_amount, lock10_expiration, hashlock) mediated01 = make_mediated_transfer( channel0, channel1, address0, address1, lock01, pkey0, tester_chain.block.number, secret, ) mediated10 = make_mediated_transfer( channel1, channel0, address1, address0, lock10, pkey1, tester_chain.block.number, secret, ) mediated01_hash = sha3(mediated01.packed().data[:-65]) nettingchannel.close( mediated01.nonce, mediated01.transferred_amount, mediated01.locksroot, mediated01_hash, mediated01.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=1) mediated10_hash = sha3(mediated10.packed().data[:-65]) nettingchannel.updateTransfer( mediated10.nonce, mediated10.transferred_amount, mediated10.locksroot, mediated10_hash, mediated10.signature, sender=pkey0, ) tester_chain.mine(number_of_blocks=1) proof01 = channel1.partner_state.compute_proof_for_lock( secret, mediated01.lock, ) nettingchannel.withdraw( proof01.lock_encoded, b''.join(proof01.merkle_proof), proof01.secret, sender=pkey1, ) proof10 = channel0.partner_state.compute_proof_for_lock( secret, mediated10.lock, ) nettingchannel.withdraw( proof10.lock_encoded, b''.join(proof10.merkle_proof), proof10.secret, sender=pkey0, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = initial_balance0 + deposit - lock01.amount + lock10.amount balance1 = initial_balance1 + deposit + lock01.amount - lock10.amount assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def register_endpoint(self, node_address, endpoint): if node_address != privatekey_to_address(self.private_key): raise ValueError('node_address doesnt match this node address') self.proxy.registerEndpoint(endpoint) self.tester_state.mine(number_of_blocks=1)
def test_unlock(reveal_timeout, tester_token, tester_channels, tester_events, tester_state): privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[ 0] privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True) address0 = privatekey_to_address(privatekey0_raw) target = tester.a0 initiator = tester.a1 lock_amount0 = 5 lock_timeout0 = reveal_timeout + 5 lock_expiration0 = tester_state.block.number + lock_timeout0 secret0 = 'expiredlockexpiredlockexpiredloc' lock_hashlock0 = sha3(secret0) mediated_transfer0 = channel0.create_mediatedtransfer( transfer_initiator=initiator, transfer_target=target, fee=0, amount=lock_amount0, identifier=1, # TODO: fill in identifier expiration=lock_expiration0, hashlock=lock_hashlock0, ) mediated_transfer0.sign(privatekey0, address0) channel0.register_transfer(mediated_transfer0) channel1.register_transfer(mediated_transfer0) # expire the first lock tester_state.mine(number_of_blocks=lock_timeout0 + 1) lock_amount1 = 5 lock_timeout1 = reveal_timeout + 3 lock_expiration1 = tester_state.block.number + lock_timeout1 secret1 = 'secretsecretsecretsecretsecretse' lock_hashlock1 = sha3(secret1) mediated_transfer1 = channel0.create_mediatedtransfer( transfer_initiator=initiator, transfer_target=target, fee=0, amount=lock_amount1, identifier=1, # TODO: fill in identifier expiration=lock_expiration1, hashlock=lock_hashlock1, ) mediated_transfer1.sign(privatekey0, address0) mediated_transfer1_data = str(mediated_transfer1.packed().data) channel0.register_transfer(mediated_transfer1) channel1.register_transfer(mediated_transfer1) channel1.register_secret(secret1) nettingchannel.close( mediated_transfer1_data, "", sender=privatekey1_raw, ) unlockproof0 = channel1.our_state.balance_proof.compute_proof_for_lock( secret0, mediated_transfer0.lock, ) # expiration has passed, should fail with pytest.raises(TransactionFailed): nettingchannel.unlock( str(unlockproof0.lock_encoded), ''.join(unlockproof0.merkle_proof), unlockproof0.secret, sender=privatekey1_raw, ) unlock_proofs = list(channel1.our_state.balance_proof.get_known_unlocks()) assert len(unlock_proofs) == 1 channel1.external_state.unlock(channel1.our_state.address, unlock_proofs) # already unlock, shoud fail with pytest.raises(TransactionFailed): proof = unlock_proofs[0] nettingchannel.unlock( proof.lock_encoded, ''.join(proof.merkle_proof), proof.secret, sender=privatekey0_raw, )
def test_update_mediated_transfer(settle_timeout, reveal_timeout, tester_state, tester_channels, tester_events): privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[ 0] privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True) privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True) address0 = privatekey_to_address(privatekey0_raw) address1 = privatekey_to_address(privatekey1_raw) transfer_amount = 3 direct_transfer0 = channel0.create_directtransfer( transfer_amount, 1 # TODO: fill in identifier ) direct_transfer0.sign(privatekey0, address0) direct_transfer0_data = str(direct_transfer0.packed().data) channel0.register_transfer(direct_transfer0) channel1.register_transfer(direct_transfer0) target = tester.a0 initiator = tester.a1 lock_amount = 5 lock_expiration = tester_state.block.number + reveal_timeout + 3 lock_hashlock = sha3('secret') mediated_transfer0 = channel0.create_mediatedtransfer( transfer_initiator=initiator, transfer_target=target, fee=0, amount=lock_amount, identifier=1, # TODO: fill in identifier expiration=lock_expiration, hashlock=lock_hashlock, ) mediated_transfer0.sign(privatekey0, address0) mediated_transfer0_data = str(mediated_transfer0.packed().data) channel0.register_transfer(mediated_transfer0) channel1.register_transfer(mediated_transfer0) transfer_amount = 13 direct_transfer1 = channel1.create_directtransfer( transfer_amount, 1 # TODO: fill in identifier ) direct_transfer1.sign(privatekey1, address1) direct_transfer1_data = str(direct_transfer1.packed().data) channel0.register_transfer(direct_transfer1) channel1.register_transfer(direct_transfer1) nettingchannel.close( direct_transfer0_data, direct_transfer1_data, sender=privatekey1_raw, ) nettingchannel.updateTransfer( mediated_transfer0_data, sender=privatekey0_raw, ) tester_state.mine(number_of_blocks=settle_timeout + 1)
def test_update_direct_transfer(settle_timeout, tester_state, tester_channels, tester_events): privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[ 0] privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True) privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True) address0 = privatekey_to_address(privatekey0_raw) address1 = privatekey_to_address(privatekey1_raw) transfer_amount = 3 first_direct_transfer0 = channel0.create_directtransfer( transfer_amount, 1 # TODO: fill in identifier ) first_direct_transfer0.sign(privatekey0, address0) first_direct_transfer0_data = str(first_direct_transfer0.packed().data) channel0.register_transfer(first_direct_transfer0) channel1.register_transfer(first_direct_transfer0) transfer_amount = 5 second_direct_transfer0 = channel0.create_directtransfer( transfer_amount, 1 # TODO: fill in identifier ) second_direct_transfer0.sign(privatekey0, address0) second_direct_transfer0_data = str(second_direct_transfer0.packed().data) channel0.register_transfer(second_direct_transfer0) channel1.register_transfer(second_direct_transfer0) transfer_amount = 7 third_direct_transfer0 = channel0.create_directtransfer( transfer_amount, 1 # TODO: fill in identifier ) third_direct_transfer0.sign(privatekey0, address0) third_direct_transfer0_data = str(third_direct_transfer0.packed().data) channel0.register_transfer(third_direct_transfer0) channel1.register_transfer(third_direct_transfer0) transfer_amount = 11 fourth_direct_transfer0 = channel0.create_directtransfer( transfer_amount, 1 # TODO: fill in identifier ) fourth_direct_transfer0.sign(privatekey0, address0) fourth_direct_transfer0_data = str(fourth_direct_transfer0.packed().data) channel0.register_transfer(fourth_direct_transfer0) channel1.register_transfer(fourth_direct_transfer0) transfer_amount = 13 direct_transfer1 = channel1.create_directtransfer( transfer_amount, 1 # TODO: fill in identifier ) direct_transfer1.sign(privatekey1, address1) direct_transfer1_data = str(direct_transfer1.packed().data) channel0.register_transfer(direct_transfer1) channel1.register_transfer(direct_transfer1) # not yet closed with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( second_direct_transfer0_data, sender=privatekey0_raw, ) nettingchannel.close( second_direct_transfer0_data, direct_transfer1_data, sender=privatekey1_raw, ) # who closes the channel cannot call updateTransfer with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( third_direct_transfer0_data, sender=privatekey1_raw, ) # nonce too low with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( first_direct_transfer0_data, sender=privatekey0_raw, ) nettingchannel.updateTransfer( third_direct_transfer0_data, sender=privatekey0_raw, ) transfer1_event = tester_events[-1] assert transfer1_event == { '_event_type': 'TransferUpdated', 'node_address': address0.encode('hex'), 'block_number': tester_state.block.number, } tester_state.mine(number_of_blocks=settle_timeout + 1) # settle time passed with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( fourth_direct_transfer0_data, sender=privatekey0_raw, )
def test_close_settle(deposit, settle_timeout, tester_state, tester_channels, tester_events, tester_token): privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[ 0] privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True) privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True) address0 = privatekey_to_address(privatekey0_raw) address1 = privatekey_to_address(privatekey1_raw) unknown_key = tester.k3 initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0_raw) initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1_raw) transfer_amount0 = 10 direct_transfer0 = channel0.create_directtransfer( transfer_amount0, 1 # TODO: fill in identifier ) direct_transfer0.sign(privatekey0, address0) transfer_amount1 = 30 direct_transfer1 = channel1.create_directtransfer( transfer_amount1, 1 # TODO: fill in identifier ) direct_transfer1.sign(privatekey1, address1) # random people can't close the channel with pytest.raises(TransactionFailed): nettingchannel.close( str(direct_transfer0.packed().data), str(direct_transfer1.packed().data), sender=unknown_key, ) # the closing party should be the one that provides the first transfer with pytest.raises(TransactionFailed): nettingchannel.close( str(direct_transfer0.packed().data), str(direct_transfer1.packed().data), sender=privatekey0_raw, ) previous_events = list(tester_events) nettingchannel.close( str(direct_transfer0.packed().data), str(direct_transfer1.packed().data), sender=privatekey1_raw, ) assert len(previous_events) + 1 == len(tester_events) block_number = tester_state.block.number close_event = tester_events[-1] assert close_event == { '_event_type': 'ChannelClosed', 'closing_address': encode_hex(address1), 'block_number': block_number, } assert nettingchannel.closed(sender=privatekey0_raw) == block_number assert nettingchannel.closingAddress( sender=privatekey0_raw) == encode_hex(address1) tester_state.mine(number_of_blocks=settle_timeout + 1) previous_events = list(tester_events) nettingchannel.settle(sender=privatekey0_raw) assert len(previous_events) + 3 == len(tester_events) block_number = tester_state.block.number transfer0_event = tester_events[-3] assert transfer0_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address0), '_value': deposit - transfer_amount0 + transfer_amount1, } transfer1_event = tester_events[-2] assert transfer1_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address1), '_value': deposit + transfer_amount0 - transfer_amount1, } settle_event = tester_events[-1] assert settle_event == { '_event_type': 'ChannelSettled', 'block_number': block_number, } assert tester_token.balanceOf( address0, sender=privatekey0_raw ) == initial_balance0 + deposit - transfer_amount0 + transfer_amount1 # noqa assert tester_token.balanceOf( address1, sender=privatekey1_raw ) == initial_balance1 + deposit + transfer_amount0 - transfer_amount1 # noqa assert tester_token.balanceOf(nettingchannel.address, sender=privatekey1_raw) == 0
def test_closewithouttransfer_settle(deposit, settle_timeout, tester_state, tester_events, tester_nettingcontracts, tester_token): privatekey0, privatekey1, nettingchannel = tester_nettingcontracts[0] address0 = privatekey_to_address(privatekey0) address1 = privatekey_to_address(privatekey1) unknown_key = tester.k3 initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0) initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1) with pytest.raises(TransactionFailed): nettingchannel.close(sender=unknown_key) previous_events = list(tester_events) nettingchannel.close("", "", sender=privatekey0) assert len(previous_events) + 1 == len(tester_events) block_number = tester_state.block.number close_event = tester_events[-1] assert close_event == { '_event_type': 'ChannelClosed', 'closing_address': encode_hex(address0), 'block_number': block_number, } assert nettingchannel.closed(sender=privatekey0) == block_number assert nettingchannel.closingAddress( sender=privatekey0) == encode_hex(address0) tester_state.mine(number_of_blocks=settle_timeout + 1) previous_events = list(tester_events) # Anyone can call settle(), not just channel participants nettingchannel.settle(sender=unknown_key) block_number = tester_state.block.number assert len(previous_events) + 3 == len(tester_events) transfer0_event = tester_events[-3] assert transfer0_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address1), '_value': deposit, } transfer1_event = tester_events[-2] assert transfer1_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address0), '_value': deposit, } settle_event = tester_events[-1] assert settle_event == { '_event_type': 'ChannelSettled', 'block_number': block_number, } assert tester_token.balanceOf( address0, sender=privatekey0) == initial_balance0 + deposit assert tester_token.balanceOf( address1, sender=privatekey1) == initial_balance1 + deposit assert tester_token.balanceOf(nettingchannel.address, sender=privatekey1) == 0
def geth_create_blockchain(deploy_key, private_keys, blockchain_private_keys, rpc_ports, p2p_ports, base_datadir, verbosity, genesis_path=None, logdirectory=None): # pylint: disable=too-many-locals,too-many-statements,too-many-arguments nodes_configuration = [] key_p2p_rpc = zip(blockchain_private_keys, p2p_ports, rpc_ports) for pos, (key, p2p_port, rpc_port) in enumerate(key_p2p_rpc): config = dict() address = privatekey_to_address(key) # make the first node miner if pos == 0: config['unlock'] = 0 config['nodekey'] = key config['nodekeyhex'] = encode_hex(key) config['pub'] = encode_hex(privtopub(key)) config['address'] = address config['port'] = p2p_port config['rpcport'] = rpc_port config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format( pub=config['pub'], port=config['port'], ) nodes_configuration.append(config) for config in nodes_configuration: config['bootnodes'] = ','.join(node['enode'] for node in nodes_configuration) all_keys = set(private_keys) all_keys.add(deploy_key) all_keys = sorted(all_keys) cmds = [] for i, config in enumerate(nodes_configuration): # HACK: Use only the first 8 characters to avoid golang's issue # https://github.com/golang/go/issues/6895 (IPC bind fails with path # longer than 108 characters). nodekey_part = config['nodekeyhex'][:8] nodedir = os.path.join(base_datadir, nodekey_part) node_genesis_path = os.path.join(nodedir, 'custom_genesis.json') assert len(nodedir + '/geth.ipc') < 108, 'geth data path is too large' os.makedirs(nodedir) if genesis_path is None: geth_bare_genesis(node_genesis_path, all_keys) else: shutil.copy(genesis_path, node_genesis_path) geth_init_datadir(nodedir, node_genesis_path) if 'unlock' in config: geth_create_account(nodedir, all_keys[i]) commandline = geth_to_cmd(config, nodedir, verbosity) cmds.append(commandline) # save current term settings before running geth if isinstance(sys.stdin, file): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) stdout = None stderr = None processes_list = [] for pos, cmd in enumerate(cmds): if logdirectory: log_path = os.path.join(logdirectory, str(pos)) logfile = open(log_path, 'w') stdout = logfile stderr = logfile if '--unlock' in cmd: cmd.append('--mine') process = subprocess.Popen( cmd, universal_newlines=True, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, ) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen( cmd, universal_newlines=True, stdout=stdout, stderr=stderr, ) processes_list.append(process) assert process.returncode is None geth_wait_and_check(private_keys, rpc_ports) # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, file): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) return processes_list
UNIT_CHANNEL_ADDRESS = b'channelchannelchanne' UNIT_TRANSFER_IDENTIFIER = 37 UNIT_TRANSFER_INITIATOR = b'initiatorinitiatorin' UNIT_TRANSFER_TARGET = b'targettargettargetta' UNIT_TRANSFER_DESCRIPTION = TransferDescriptionWithSecretState( UNIT_TRANSFER_IDENTIFIER, UNIT_TRANSFER_AMOUNT, UNIT_TOKEN_NETWORK_ADDRESS, UNIT_TRANSFER_INITIATOR, UNIT_TRANSFER_TARGET, UNIT_SECRET, ) UNIT_TRANSFER_PKEY_BIN = sha3(b'transfer pkey') UNIT_TRANSFER_PKEY = PrivateKey(UNIT_TRANSFER_PKEY_BIN) UNIT_TRANSFER_SENDER = privatekey_to_address(sha3(b'transfer pkey')) HOP1_KEY = PrivateKey(b'11111111111111111111111111111111') HOP2_KEY = PrivateKey(b'22222222222222222222222222222222') HOP3_KEY = PrivateKey(b'33333333333333333333333333333333') HOP4_KEY = PrivateKey(b'44444444444444444444444444444444') HOP5_KEY = PrivateKey(b'55555555555555555555555555555555') HOP6_KEY = PrivateKey(b'66666666666666666666666666666666') HOP1 = privatekey_to_address(b'11111111111111111111111111111111') HOP2 = privatekey_to_address(b'22222222222222222222222222222222') HOP3 = privatekey_to_address(b'33333333333333333333333333333333') HOP4 = privatekey_to_address(b'44444444444444444444444444444444') HOP5 = privatekey_to_address(b'55555555555555555555555555555555') HOP6 = privatekey_to_address(b'66666666666666666666666666666666') ADDR = b'addraddraddraddraddr'
def web3( blockchain_p2p_ports, blockchain_private_keys, blockchain_rpc_ports, blockchain_type, deploy_key, private_keys, random_marker, request, tmpdir, chain_id, ): """ Starts a private chain with accounts funded. """ # include the deploy key in the list of funded accounts keys_to_fund = set(private_keys) keys_to_fund.add(deploy_key) keys_to_fund = sorted(keys_to_fund) if blockchain_type == 'geth': host = '0.0.0.0' rpc_port = blockchain_rpc_ports[0] endpoint = f'http://{host}:{rpc_port}' web3 = Web3(HTTPProvider(endpoint)) assert len(blockchain_private_keys) == len(blockchain_rpc_ports) assert len(blockchain_private_keys) == len(blockchain_p2p_ports) geth_nodes = [ GethNodeDescription( key, rpc, p2p, miner=(pos == 0), ) for pos, (key, rpc, p2p) in enumerate( zip( blockchain_private_keys, blockchain_rpc_ports, blockchain_p2p_ports, )) ] accounts_to_fund = [privatekey_to_address(key) for key in keys_to_fund] geth_processes = geth_run_private_blockchain( web3, accounts_to_fund, geth_nodes, str(tmpdir), chain_id, request.config.option.verbose, random_marker, ) yield web3 for process in geth_processes: process.terminate() cleanup_tasks() else: raise ValueError(f'unknown blockchain_type {blockchain_type}')
CONTRACT_SECRET_REGISTRY, CONTRACT_TOKEN_NETWORK_REGISTRY, NETWORKNAME_TO_ID, TEST_SETTLE_TIMEOUT_MAX, TEST_SETTLE_TIMEOUT_MIN, ) from raiden_contracts.contract_manager import ContractManager, contracts_precompiled_path # the smoketest will assert that a different endpoint got successfully registered TEST_ENDPOINT = '9.9.9.9:9999' TEST_PARTNER_ADDRESS = '2' * 40 TEST_DEPOSIT_AMOUNT = 5 TEST_PRIVKEY = (b'\xad\xd4\xd3\x10\xba\x04$hy\x1d\xd7\xbf\x7fn\xae\x85\xac' b'\xc4\xdd\x14?\xfa\x81\x0e\xf1\x80\x9aj\x11\xf2\xbcD') TEST_ACCOUNT_ADDRESS = privatekey_to_address(TEST_PRIVKEY) RST_DATADIR = tempfile.mkdtemp() os.environ['RST_DATADIR'] = RST_DATADIR def ensure_executable(cmd): """look for the given command and make sure it can be executed""" if not shutil.which(cmd): print( 'Error: unable to locate %s binary.\n' 'Make sure it is installed and added to the PATH variable.' % cmd, ) sys.exit(1)
def __init__( self, chain: BlockChainService, query_start_block: typing.BlockNumber, default_registry: TokenNetworkRegistry, default_secret_registry: SecretRegistry, private_key_bin, transport, config, discovery=None, ): super().__init__() if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') self.tokennetworkids_to_connectionmanagers = dict() self.identifier_to_results: typing.Dict[typing.PaymentID, AsyncResult, ] = dict() self.chain: BlockChainService = chain self.default_registry = default_registry self.query_start_block = query_start_block self.default_secret_registry = default_secret_registry self.config = config self.privkey = private_key_bin self.address = privatekey_to_address(private_key_bin) self.discovery = discovery self.private_key = PrivateKey(private_key_bin) self.pubkey = self.private_key.public_key.format(compressed=False) self.transport = transport self.blockchain_events = BlockchainEvents() self.alarm = AlarmTask(chain) self.stop_event = Event() self.stop_event.set() # inits as stopped self.wal = None self.snapshot_group = 0 # This flag will be used to prevent the service from processing # state changes events until we know that pending transactions # have been dispatched. self.dispatch_events_lock = Semaphore(1) self.database_path = config['database_path'] if self.database_path != ':memory:': database_dir = os.path.dirname(config['database_path']) os.makedirs(database_dir, exist_ok=True) self.database_dir = database_dir # Prevent concurrent access to the same db self.lock_file = os.path.join(self.database_dir, '.lock') self.db_lock = filelock.FileLock(self.lock_file) else: self.database_path = ':memory:' self.database_dir = None self.lock_file = None self.serialization_file = None self.db_lock = None self.event_poll_lock = gevent.lock.Semaphore()
def test_channelnewbalance_event(private_keys, settle_timeout, tester_state, tester_events, tester_token, tester_registry): """ Check the correct events are generated for deposit calls. """ privatekey0 = private_keys[0] privatekey1 = private_keys[1] address0 = privatekey_to_address(privatekey0) address1 = privatekey_to_address(privatekey1) channel_manager = new_channelmanager( privatekey0, tester_state, tester_events.append, tester_registry, tester_token, ) nettingchannel = new_nettingcontract( privatekey0, privatekey1, tester_state, tester_events.append, channel_manager, settle_timeout, ) initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0) deposit_amount = initial_balance0 // 10 assert tester_token.approve( nettingchannel.address, deposit_amount, sender=privatekey0) is True assert tester_token.approve( nettingchannel.address, deposit_amount, sender=privatekey1) is True previous_events = list(tester_events) assert nettingchannel.deposit(deposit_amount, sender=privatekey0) is True assert len(previous_events) + 2 == len(tester_events) block_number = tester_state.block.number transfer_event = tester_events[-2] assert transfer_event == { '_event_type': 'Transfer', '_from': encode_hex(address0), '_to': nettingchannel.address, '_value': deposit_amount, } newbalance_event = tester_events[-1] assert newbalance_event == { '_event_type': 'ChannelNewBalance', 'assetAddress': encode_hex(tester_token.address), 'participant': encode_hex(address0), 'balance': deposit_amount, 'blockNumber': block_number, } previous_events = list(tester_events) assert nettingchannel.deposit(deposit_amount, sender=privatekey1) is True assert len(previous_events) + 2 == len(tester_events) block_number = tester_state.block.number transfer_event = tester_events[-2] assert transfer_event == { '_event_type': 'Transfer', '_from': encode_hex(address1), '_to': nettingchannel.address, '_value': deposit_amount, } newbalance_event = tester_events[-1] assert newbalance_event == { '_event_type': 'ChannelNewBalance', 'assetAddress': encode_hex(tester_token.address), 'participant': encode_hex(address1), 'balance': deposit_amount, 'blockNumber': block_number, }
def test_withdraw( deposit, settle_timeout, reveal_timeout, tester_channels, tester_chain, tester_token): pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) lock_amount = 31 lock_expiration = tester_chain.block.number + reveal_timeout + 5 secret = b'secretsecretsecretsecretsecretse' hashlock = sha3(secret) new_block = Block(tester_chain.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock0 = Lock(lock_amount, lock_expiration, hashlock) mediated0 = make_mediated_transfer( channel0, channel1, address0, address1, lock0, pkey0, tester_chain.block.number, secret, ) # withdraw the pending transfer sent to us by our partner proof = channel1.partner_state.compute_proof_for_lock( secret, mediated0.lock, ) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=1) nettingchannel.withdraw( proof.lock_encoded, b''.join(proof.merkle_proof), proof.secret, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = initial_balance0 + deposit - lock0.amount balance1 = initial_balance1 + deposit + lock0.amount assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_withdraw_tampered_lock_amount(tree, tester_channels, tester_chain, tester_token, settle_timeout): """ withdraw must fail if the lock amonut is tampered. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_chain.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] leaves = [sha3(lock.as_bytes) for lock in locks] layers = compute_layers(leaves) merkle_tree = MerkleTreeState(layers) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2**32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.identifier, locksroot=merkleroot(merkle_tree), token=tester_token.address, recipient=privatekey_to_address(pkey1)) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded)) tampered_lock = make_lock( amount=lock.amount * 100, hashlock=lock.hashlock, expiration=lock.expiration, ) tampered_lock_encoded = sha3(tampered_lock.as_bytes) with pytest.raises(TransactionFailed): nettingchannel.withdraw( tampered_lock_encoded, b''.join(merkle_proof), secret, sender=pkey1, )
def test_withdraw_tampered_merkle_proof(tree, tester_channels, tester_chain, settle_timeout): """ withdraw must fail if the proof is tampered. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_chain.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] leaves = [sha3(lock.as_bytes) for lock in locks] layers = compute_layers(leaves) merkle_tree = MerkleTreeState(layers) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.channel_address, locksroot=merkleroot(merkle_tree), recipient=privatekey_to_address(pkey1) ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded)) # withdraw must fail regardless of which part of the proof is tampered for pos, hash_ in enumerate(merkle_proof): # changing arbitrary bytes from the proof tampered_hash = bytearray(hash_) tampered_hash[6], tampered_hash[7] = tampered_hash[7], tampered_hash[6] tampered_proof = list(merkle_proof) tampered_proof[pos] = tampered_hash joiner = b'' with pytest.raises(TransactionFailed): nettingchannel.withdraw( lock_encoded, joiner.join(tampered_proof), secret, sender=pkey1, )
def test_withdraw_lock_with_a_large_expiration(deposit, tester_channels, tester_chain, tester_token, settle_timeout): """ Withdraw must accept a lock that expires after the settlement period. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) # use a really large expiration lock_expiration = tester_chain.block.number + settle_timeout * 5 # work around for the python expiration validation bad_block_number = lock_expiration - 10 channel.state_transition(channel0, Block(bad_block_number), bad_block_number) lock_amount = 29 secret = sha3(b'test_withdraw_lock_with_a_large_expiration') lock_hashlock = sha3(secret) lock = Lock( amount=lock_amount, expiration=lock_expiration, hashlock=lock_hashlock, ) mediated0 = make_mediated_transfer( channel0, channel1, address0, address1, lock, pkey0, secret, ) nettingchannel.close(sender=pkey0) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.updateTransfer( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey1, ) unlock_proofs = channel.get_known_unlocks(channel1.partner_state) proof = unlock_proofs[0] nettingchannel.withdraw( proof.lock_encoded, b''.join(proof.merkle_proof), proof.secret, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = initial_balance0 + deposit - lock_amount balance1 = initial_balance1 + deposit + lock_amount assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def __init__( self, chain: BlockChainService, default_registry, private_key_bin, transport, config, discovery=None, ): if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') invalid_timeout = ( config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or config['settle_timeout'] > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX ) if invalid_timeout: raise ValueError('settle_timeout must be in range [{}, {}]'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX, )) self.tokens_to_connectionmanagers = dict() self.identifier_to_results = defaultdict(list) self.chain: BlockChainService = chain self.default_registry = default_registry self.config = config self.privkey = private_key_bin self.address = privatekey_to_address(private_key_bin) if config['transport_type'] == 'udp': endpoint_registration_event = gevent.spawn( discovery.register, self.address, config['external_ip'], config['external_port'], ) endpoint_registration_event.link_exception(endpoint_registry_exception_handler) self.private_key = PrivateKey(private_key_bin) self.pubkey = self.private_key.public_key.format(compressed=False) self.transport = transport self.blockchain_events = BlockchainEvents() self.alarm = AlarmTask(chain) self.shutdown_timeout = config['shutdown_timeout'] self.stop_event = Event() self.start_event = Event() self.chain.client.inject_stop_event(self.stop_event) self.wal = None self.database_path = config['database_path'] if self.database_path != ':memory:': database_dir = os.path.dirname(config['database_path']) os.makedirs(database_dir, exist_ok=True) self.database_dir = database_dir # Prevent concurrent acces to the same db self.lock_file = os.path.join(self.database_dir, '.lock') self.db_lock = filelock.FileLock(self.lock_file) else: self.database_path = ':memory:' self.database_dir = None self.lock_file = None self.serialization_file = None self.db_lock = None if config['transport_type'] == 'udp': # If the endpoint registration fails the node will quit, this must # finish before starting the transport endpoint_registration_event.join() self.event_poll_lock = gevent.lock.Semaphore() self.start()
def create_apps( blockchain_services, endpoint_discovery_services, registry_address, raiden_udp_ports, reveal_timeout, settle_timeout, database_paths, retry_interval, retries_before_backoff, throttle_capacity, throttle_fill_rate, nat_invitation_timeout, nat_keepalive_retries, nat_keepalive_timeout, use_matrix=False, local_matrix_url=None, ): """ Create the apps.""" # pylint: disable=too-many-locals services = zip(blockchain_services, endpoint_discovery_services) apps = [] for idx, (blockchain, discovery) in enumerate(services): port = raiden_udp_ports[idx] private_key = blockchain.private_key nodeid = privatekey_to_address(private_key) host = '127.0.0.1' discovery.register(nodeid, host, port) config = { 'host': host, 'port': port, 'external_ip': host, 'external_port': port, 'privatekey_hex': hexlify(private_key), 'reveal_timeout': reveal_timeout, 'settle_timeout': settle_timeout, 'database_path': database_paths[idx], 'protocol': { 'retry_interval': retry_interval, 'retries_before_backoff': retries_before_backoff, 'throttle_capacity': throttle_capacity, 'throttle_fill_rate': throttle_fill_rate, 'nat_invitation_timeout': nat_invitation_timeout, 'nat_keepalive_retries': nat_keepalive_retries, 'nat_keepalive_timeout': nat_keepalive_timeout, }, 'rpc': True, 'console': False, } config_copy = App.DEFAULT_CONFIG.copy() config_copy.update(config) if use_matrix: if local_matrix_url is not None: matrix_config = { 'server': local_matrix_url, } else: matrix_config = { 'client_class': MockMatrixClient, 'server': 'http://matrix.mock', } config.update({ 'transport_type': 'matrix', 'matrix': matrix_config }) registry = blockchain.registry(registry_address) if use_matrix: transport = MatrixTransport(config['matrix']) else: throttle_policy = TokenBucket( config['protocol']['throttle_capacity'], config['protocol']['throttle_fill_rate']) transport = UDPTransport( discovery, server._udp_socket((host, port)), # pylint: disable=protected-access throttle_policy, config['protocol'], ) app = App( config_copy, blockchain, registry, transport, discovery, ) apps.append(app) return apps
def test_channeldeposit(private_keys, settle_timeout, tester_state, tester_token, tester_events, tester_registry): """ Guarantee the correct tracking of each participant deposits, checks the initial state (pre-deposit) and state changes for each deposits. """ # not using the tester_nettingcontracts fixture to control the # transfer/deposits privatekey0 = private_keys[0] privatekey1 = private_keys[1] address0 = privatekey_to_address(privatekey0) address1 = privatekey_to_address(privatekey1) unknow_key = tester.k3 channel_manager = new_channelmanager( privatekey0, tester_state, tester_events.append, tester_registry, tester_token, ) channel = new_nettingcontract( privatekey0, privatekey1, tester_state, tester_events.append, channel_manager, settle_timeout, ) # check initial state, needs to be zeroed out assert channel.settleTimeout(sender=privatekey0) == settle_timeout assert channel.assetAddress(sender=privatekey0) == encode_hex( tester_token.address) assert channel.opened(sender=privatekey0) == 0 assert channel.closed(sender=privatekey0) == 0 assert channel.settled(sender=privatekey0) == 0 assert channel.addressAndBalance( sender=privatekey0)[0] == encode_hex(address0) assert channel.addressAndBalance(sender=privatekey0)[1] == 0 assert channel.addressAndBalance( sender=privatekey0)[2] == encode_hex(address1) assert channel.addressAndBalance(sender=privatekey0)[3] == 0 initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0) deposit_amount = initial_balance0 // 10 # try to make invalid deposits with pytest.raises(TransactionFailed): channel.deposit(1, sender=unknow_key) # not participant assert tester_token.approve( channel.address, deposit_amount * 2, sender=privatekey0) is True assert channel.deposit(deposit_amount * 2 + 1, sender=privatekey0) is False with pytest.raises(abi.ValueOutOfBounds): channel.deposit(-1, sender=privatekey0) # create a first deposit with half of the allowance assert channel.deposit(deposit_amount, sender=privatekey0) is True assert tester_token.balanceOf(channel.address, sender=privatekey0) == deposit_amount assert tester_token.balanceOf( address0, sender=privatekey0) == initial_balance0 - deposit_amount # noqa assert channel.opened(sender=privatekey0) == tester_state.block.number assert channel.addressAndBalance( sender=privatekey0)[0] == encode_hex(address0) assert channel.addressAndBalance(sender=privatekey0)[1] == deposit_amount assert channel.addressAndBalance( sender=privatekey0)[2] == encode_hex(address1) assert channel.addressAndBalance(sender=privatekey0)[3] == 0 # check a second depoist with the rest of the allowance assert channel.deposit(deposit_amount, sender=privatekey0) is True assert tester_token.balanceOf(channel.address, sender=privatekey0) == deposit_amount * 2 assert tester_token.balanceOf( address0, sender=privatekey0) == initial_balance0 - deposit_amount * 2 # noqa assert channel.opened(sender=privatekey0) == tester_state.block.number assert channel.addressAndBalance( sender=privatekey0)[0] == encode_hex(address0) assert channel.addressAndBalance( sender=privatekey0)[1] == deposit_amount * 2 assert channel.addressAndBalance( sender=privatekey0)[2] == encode_hex(address1) assert channel.addressAndBalance(sender=privatekey0)[3] == 0 # allowance zeroed, we cant make a new deposit assert channel.deposit(deposit_amount, sender=privatekey0) is False # needs to be able to add aditional asset assert tester_token.approve( channel.address, deposit_amount, sender=privatekey0) is True assert channel.deposit(deposit_amount, sender=privatekey0) is True assert tester_token.balanceOf(channel.address, sender=privatekey0) == deposit_amount * 3 assert tester_token.balanceOf( address0, sender=privatekey0) == initial_balance0 - deposit_amount * 3 # noqa assert channel.opened(sender=privatekey0) == tester_state.block.number assert channel.addressAndBalance( sender=privatekey0)[0] == encode_hex(address0) assert channel.addressAndBalance( sender=privatekey0)[1] == deposit_amount * 3 assert channel.addressAndBalance( sender=privatekey0)[2] == encode_hex(address1) assert channel.addressAndBalance(sender=privatekey0)[3] == 0
def __init__(self, chain, default_registry, private_key_bin, transport, discovery, config): if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') invalid_timeout = ( config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or config['settle_timeout'] > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX) if invalid_timeout: raise ValueError('settle_timeout must be in range [{}, {}]'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)) self.token_to_channelgraph = dict() self.tokens_to_connectionmanagers = dict() self.manager_to_token = dict() self.swapkey_to_tokenswap = dict() self.swapkey_to_greenlettask = dict() self.identifier_to_statemanagers = defaultdict(list) self.identifier_to_results = defaultdict(list) # This is a map from a hashlock to a list of channels, the same # hashlock can be used in more than one token (for tokenswaps), a # channel should be removed from this list only when the lock is # released/withdrawn but not when the secret is registered. self.token_to_hashlock_to_channels = defaultdict( lambda: defaultdict(list)) self.chain = chain self.default_registry = default_registry self.config = config self.privkey = private_key_bin self.address = privatekey_to_address(private_key_bin) endpoint_registration_event = gevent.spawn( discovery.register, self.address, config['external_ip'], config['external_port'], ) endpoint_registration_event.link_exception( endpoint_registry_exception_handler) self.private_key = PrivateKey(private_key_bin) self.pubkey = self.private_key.public_key.format(compressed=False) self.protocol = RaidenProtocol( transport, discovery, self, config['protocol']['retry_interval'], config['protocol']['retries_before_backoff'], config['protocol']['nat_keepalive_retries'], config['protocol']['nat_keepalive_timeout'], config['protocol']['nat_invitation_timeout'], ) # TODO: remove this cyclic dependency transport.protocol = self.protocol self.message_handler = RaidenMessageHandler(self) self.state_machine_event_handler = StateMachineEventHandler(self) self.pyethapp_blockchain_events = PyethappBlockchainEvents() self.greenlet_task_dispatcher = GreenletTasksDispatcher() self.on_message = self.message_handler.on_message self.alarm = AlarmTask(chain) self._blocknumber = None self.transaction_log = StateChangeLog( storage_instance=StateChangeLogSQLiteBackend( database_path=config['database_path'])) if config['database_path'] != ':memory:': self.database_dir = os.path.dirname(config['database_path']) self.lock_file = os.path.join(self.database_dir, '.lock') self.snapshot_dir = os.path.join(self.database_dir, 'snapshots') self.serialization_file = os.path.join(self.snapshot_dir, 'data.pickle') if not os.path.exists(self.snapshot_dir): os.makedirs(self.snapshot_dir) # Prevent concurrent acces to the same db self.db_lock = filelock.FileLock(self.lock_file) else: self.database_dir = None self.lock_file = None self.snapshot_dir = None self.serialization_file = None self.db_lock = None # If the endpoint registration fails the node will quit, this must # finish before starting the protocol endpoint_registration_event.join() self.start()
def test_closewithouttransfer_settle(deposit, settle_timeout, tester_state, tester_events, tester_nettingcontracts, tester_token): privatekey0, privatekey1, nettingchannel = tester_nettingcontracts[0] address0 = privatekey_to_address(privatekey0) address1 = privatekey_to_address(privatekey1) unknow_key = tester.k3 initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0) initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1) with pytest.raises(TransactionFailed): nettingchannel.closeWithoutTransfers(sender=unknow_key) # this method needs to be implemented, the name could be changed previous_events = list(tester_events) nettingchannel.closeWithoutTransfers(sender=privatekey0) assert len(previous_events) + 1 == len(tester_events) block_number = tester_state.block.number close_event = tester_events[-1] assert close_event == { '_event_type': 'ChannelClosed', 'closingAddress': encode_hex(address0), 'blockNumber': block_number, } assert nettingchannel.closed() == block_number assert nettingchannel.closingAddress() == encode_hex(address0) tester_state.mine(number_of_blocks=settle_timeout + 1) previous_events = list(tester_events) nettingchannel.settle(sender=privatekey0) block_number = tester_state.block.number assert len(previous_events) + 3 == len(tester_events) transfer0_event = tester_events[-3] assert transfer0_event == { '_from': nettingchannel.address, '_to': encode_hex(address0), '_value': deposit, } transfer1_event = tester_events[-2] assert transfer1_event == { '_from': nettingchannel.address, '_to': encode_hex(address1), '_value': deposit, } settle_event = tester_events[-1] assert settle_event == { '_event_type': 'ChannelSettled', 'blockNumber': block_number, } assert tester_token.balanceOf( address0, sender=privatekey0) == initial_balance0 + deposit assert tester_token.balanceOf( address1, sender=privatekey1) == initial_balance1 + deposit assert tester_token.balanceOf(nettingchannel.address, sender=privatekey1) == 0
def test_close_settle(deposit, settle_timeout, tester_state, tester_channels, tester_events, tester_token): privatekey0, privatekey1, nettingchannel, channel0, channel1 = tester_channels[ 0] address0 = privatekey_to_address(privatekey0) address1 = privatekey_to_address(privatekey1) unknow_key = tester.k3 initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0) initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1) transfer_amount0 = 10 direct_transfer0 = channel0.create_directtransfer(transfer_amount0) direct_transfer0.sign(privatekey0) transfer_amount1 = 30 direct_transfer1 = channel1.create_directtransfer(transfer_amount1) direct_transfer1.sign(privatekey1) with pytest.raises(TransactionFailed): nettingchannel.close( str(direct_transfer0.packed().data), str(direct_transfer1.packed().data), sender=unknow_key, ) previous_events = list(tester_events) nettingchannel.close( str(direct_transfer0.packed().data), str(direct_transfer1.packed().data), sender=privatekey0, ) assert len(previous_events) + 1 == len(tester_events) block_number = tester_state.block.number close_event = tester_events[-1] assert close_event == { '_event_type': 'ChannelClosed', 'closingAddress': encode_hex(address0), 'blockNumber': block_number, } assert nettingchannel.closed(sender=privatekey0) == block_number assert nettingchannel.closingAddress( sender=privatekey0) == encode_hex(address0) tester_state.mine(number_of_blocks=settle_timeout + 1) previous_events = list(tester_events) nettingchannel.settle(sender=privatekey0) assert len(previous_events) + 3 == len(tester_events) block_number = tester_state.block.number transfer0_event = tester_events[-3] assert transfer0_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address0), '_value': deposit - transfer_amount0 + transfer_amount1, } transfer1_event = tester_events[-2] assert transfer1_event == { '_event_type': 'Transfer', '_from': nettingchannel.address, '_to': encode_hex(address1), '_value': deposit + transfer_amount0 - transfer_amount1, } settle_event = tester_events[-1] assert settle_event == { '_event_type': 'ChannelSettled', 'blockNumber': block_number, } assert tester_token.balanceOf( address0, sender=privatekey0 ) == initial_balance0 + deposit - transfer_amount0 + transfer_amount1 # noqa assert tester_token.balanceOf( address1, sender=privatekey1 ) == initial_balance1 + deposit + transfer_amount0 - transfer_amount1 # noqa assert tester_token.balanceOf(nettingchannel.address, sender=privatekey1) == 0
def __init__(self, chain, default_registry, private_key_bin, transport, discovery, config): if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') invalid_timeout = ( config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or config['settle_timeout'] > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX) if invalid_timeout: raise ValueError('settle_timeout must be in range [{}, {}]'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)) self.tokens_to_connectionmanagers = dict() self.identifier_to_results = defaultdict(list) # This is a map from a secrethash to a list of channels, the same # secrethash can be used in more than one token (for tokenswaps), a # channel should be removed from this list only when the lock is # released/withdrawn but not when the secret is registered. self.token_to_secrethash_to_channels = defaultdict( lambda: defaultdict(list)) self.chain = chain self.default_registry = default_registry self.config = config self.privkey = private_key_bin self.address = privatekey_to_address(private_key_bin) endpoint_registration_event = gevent.spawn( discovery.register, self.address, config['external_ip'], config['external_port'], ) endpoint_registration_event.link_exception( endpoint_registry_exception_handler) self.private_key = PrivateKey(private_key_bin) self.pubkey = self.private_key.public_key.format(compressed=False) self.protocol = RaidenProtocol( transport, discovery, self, config['protocol']['retry_interval'], config['protocol']['retries_before_backoff'], config['protocol']['nat_keepalive_retries'], config['protocol']['nat_keepalive_timeout'], config['protocol']['nat_invitation_timeout'], ) # TODO: remove this cyclic dependency transport.protocol = self.protocol self.blockchain_events = BlockchainEvents() self.alarm = AlarmTask(chain) self.shutdown_timeout = config['shutdown_timeout'] self._block_number = None self.stop_event = Event() self.start_event = Event() self.chain.client.inject_stop_event(self.stop_event) self.wal = None self.database_path = config['database_path'] if self.database_path != ':memory:': database_dir = os.path.dirname(config['database_path']) os.makedirs(database_dir, exist_ok=True) self.database_dir = database_dir # Prevent concurrent acces to the same db self.lock_file = os.path.join(self.database_dir, '.lock') self.db_lock = filelock.FileLock(self.lock_file) else: self.database_path = ':memory:' self.database_dir = None self.lock_file = None self.serialization_file = None self.db_lock = None # If the endpoint registration fails the node will quit, this must # finish before starting the protocol endpoint_registration_event.join() # Lock used to serialize calls to `poll_blockchain_events`, this is # important to give a consistent view of the node state. self.event_poll_lock = gevent.lock.Semaphore() self.start()
def test_blockchain( blockchain_type, blockchain_backend, # required to start the geth backend blockchain_rpc_ports, private_keys, poll_timeout): # pylint: disable=too-many-locals # this test is for interaction with a blockchain using json-rpc, so it # doesnt make sense to execute it against mock or tester if blockchain_type not in ('geth', ): return addresses = [privatekey_to_address(priv) for priv in private_keys] privatekey = private_keys[0] address = privatekey_to_address(privatekey) total_token = 100 jsonrpc_client = JSONRPCClient( port=blockchain_rpc_ports[0], privkey=privatekey, print_communication=False, ) patch_send_transaction(jsonrpc_client) patch_send_message(jsonrpc_client) humantoken_path = get_contract_path('HumanStandardToken.sol') humantoken_contracts = compile_file(humantoken_path, libraries=dict()) token_proxy = jsonrpc_client.deploy_solidity_contract( address, 'HumanStandardToken', humantoken_contracts, dict(), (total_token, 'raiden', 2, 'Rd'), contract_path=humantoken_path, gasprice=default_gasprice, timeout=poll_timeout, ) registry_path = get_contract_path('Registry.sol') registry_contracts = compile_file(registry_path) registry_proxy = jsonrpc_client.deploy_solidity_contract( address, 'Registry', registry_contracts, dict(), tuple(), contract_path=registry_path, gasprice=default_gasprice, timeout=poll_timeout, ) log_list = jsonrpc_client.call( 'eth_getLogs', { 'fromBlock': '0x0', 'toBlock': 'latest', 'topics': [], }, ) assert len(log_list) == 0 # pylint: disable=no-member assert token_proxy.balanceOf(address) == total_token transaction_hash = registry_proxy.addToken.transact( token_proxy.address, gasprice=denoms.wei, ) jsonrpc_client.poll(transaction_hash.decode('hex'), timeout=poll_timeout) assert len(registry_proxy.tokenAddresses.call()) == 1 log_list = jsonrpc_client.call( 'eth_getLogs', { 'fromBlock': '0x0', 'toBlock': 'latest', 'topics': [], }, ) assert len(log_list) == 1 channel_manager_address_encoded = registry_proxy.channelManagerByToken.call( token_proxy.address, ) channel_manager_address = channel_manager_address_encoded.decode('hex') log = log_list[0] log_topics = [ decode_topic(topic) for topic in log['topics'] # pylint: disable=invalid-sequence-index ] log_data = log['data'] event = registry_proxy.translator.decode_event( log_topics, log_data[2:].decode('hex'), ) assert channel_manager_address == event['channel_manager_address'].decode( 'hex') assert token_proxy.address == event['token_address'].decode('hex') channel_manager_proxy = jsonrpc_client.new_contract_proxy( CHANNEL_MANAGER_ABI, channel_manager_address, ) transaction_hash = channel_manager_proxy.newChannel.transact( addresses[1], 10, gasprice=denoms.wei, ) jsonrpc_client.poll(transaction_hash.decode('hex'), timeout=poll_timeout) log_list = jsonrpc_client.call( 'eth_getLogs', { 'fromBlock': '0x0', 'toBlock': 'latest', 'topics': [], }, ) assert len(log_list) == 2