def main( rpc_provider: HTTPProvider, private_key: str, private_key_password_file: str, state_file: str, channel_manager_address: str, minimum_amount: int, gas_price: int, ): if minimum_amount <= 0: click.echo('Minimum amount need to be at least 1') sys.exit(1) private_key = utils.get_private_key(private_key, private_key_password_file) if private_key is None: sys.exit(1) receiver_address = utils.privkey_to_addr(private_key) web3 = Web3(HTTPProvider(rpc_provider, request_kwargs={'timeout': 60})) config.NETWORK_CFG.set_defaults(int(web3.version.network)) web3.eth.defaultAccount = receiver_address channel_manager_address = ( channel_manager_address or config.NETWORK_CFG.channel_manager_address ) channel_manager_contract = make_channel_manager_contract(web3, channel_manager_address) if not state_file: state_file_name = "%s_%s.db" % ( channel_manager_address[:10], receiver_address[:10] ) app_dir = click.get_app_dir('microraiden') if not os.path.exists(app_dir): click.echo('No state file or directory found!') sys.exit(1) state_file = os.path.join(app_dir, state_file_name) try: click.echo('Loading state file from {}'.format(state_file)) state = ChannelManagerState.load(state_file) except StateFileException: click.echo('Error reading state file') traceback.print_exc() sys.exit(1) if not is_same_address(state.receiver, receiver_address): click.echo('Private key does not match receiver address in state file') sys.exit(1) elif not is_same_address(state.contract_address, channel_manager_address): click.echo('Channel manager contract address mismatch') sys.exit(1) click.echo('Withdrawing all paid tokens with at least {} due from ' 'receiver {}'.format(minimum_amount, receiver_address)) withdraw_from_channels( private_key, state, channel_manager_contract, minimum_amount, gas_price * denoms.gwei if gas_price else None, )
def __init__( self, web3: Web3, channel_manager_contract: Contract, token_contract: Contract, private_key: str, state_filename: str = None, n_confirmations=1 ) -> None: gevent.Greenlet.__init__(self) self.blockchain = Blockchain( web3, channel_manager_contract, self, n_confirmations=n_confirmations ) self.receiver = privkey_to_addr(private_key) self.private_key = private_key self.channel_manager_contract = channel_manager_contract self.token_contract = token_contract self.n_confirmations = n_confirmations self.log = logging.getLogger('channel_manager') network_id = int(web3.version.network) assert is_same_address(privkey_to_addr(self.private_key), self.receiver) # check contract version self.check_contract_version() if state_filename not in (None, ':memory:') and os.path.isfile(state_filename): self.state = ChannelManagerState.load(state_filename) else: self.state = ChannelManagerState(state_filename) self.state.setup_db( network_id, channel_manager_contract.address, self.receiver ) assert self.state is not None if state_filename not in (None, ':memory:'): self.lock_state = filelock.FileLock(state_filename + '.lock') try: self.lock_state.acquire(timeout=0) except filelock.Timeout: raise StateFileLocked("state file %s is locked by another process" % state_filename) if network_id != self.state.network_id: raise NetworkIdMismatch("Network id mismatch: state=%d, backend=%d" % ( self.state.network_id, network_id)) if not is_same_address(self.receiver, self.state.receiver): raise StateReceiverAddrMismatch('%s != %s' % (self.receiver, self.state.receiver)) if not is_same_address(self.state.contract_address, channel_manager_contract.address): raise StateContractAddrMismatch('%s != %s' % ( channel_manager_contract.address, self.state.contract_address)) self.log.debug('setting up channel manager, receiver=%s channel_contract=%s' % (self.receiver, channel_manager_contract.address))
def test_cooperative( channel_manager: ChannelManager, confirmed_open_channel: Channel, receiver_address: str, web3: Web3, token_contract: Contract, wait_for_blocks, sender_address: str ): blockchain = channel_manager.blockchain channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block) sig1 = encode_hex(confirmed_open_channel.create_transfer(5)) channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig1) receiver_sig = channel_manager.sign_close(sender_address, confirmed_open_channel.block, 5) channel_rec = channel_manager.channels[channel_id] assert channel_rec.is_closed is True block_before = web3.eth.blockNumber confirmed_open_channel.close_cooperatively(receiver_sig) wait_for_blocks(blockchain.n_confirmations) gevent.sleep(blockchain.poll_interval) logs = get_logs(token_contract, 'Transfer', from_block=block_before - 1) assert len([l for l in logs if is_same_address(l['args']['_to'], receiver_address) and l['args']['_value'] == 5]) == 1 assert len([l for l in logs if is_same_address(l['args']['_to'], sender_address) and l['args']['_value'] == 5]) == 1 wait_for_blocks(blockchain.n_confirmations) gevent.sleep(blockchain.poll_interval) assert channel_id not in channel_manager.channels
def test_cooperative_close_call_receiver( channel_params, get_accounts, uraiden_instance, get_channel, print_gas): (sender, receiver, open_block_number, balance_msg_sig, closing_sig) = get_channel() balance = channel_params['balance'] sender_verified = uraiden_instance.call().extractBalanceProofSignature( receiver, open_block_number, balance, balance_msg_sig ) assert is_same_address(sender_verified, sender) receiver_verified = uraiden_instance.call().extractClosingSignature( sender, open_block_number, balance, closing_sig ) assert is_same_address(receiver_verified, receiver) # Cooperative close can be called by anyone txn_hash = uraiden_instance.transact({"from": receiver}).cooperativeClose( receiver, open_block_number, balance, balance_msg_sig, closing_sig ) print_gas(txn_hash, 'cooperativeClose')
def test_cooperative_close_call_delegate( channel_params, get_accounts, uraiden_instance, get_channel): A = get_accounts(1, 5)[0] (sender, receiver, open_block_number, balance_msg_sig, closing_sig) = get_channel() balance = channel_params['balance'] sender_verified = uraiden_instance.call().extractBalanceProofSignature( receiver, open_block_number, balance, balance_msg_sig ) assert is_same_address(sender_verified, sender) receiver_verified = uraiden_instance.call().extractClosingSignature( sender, open_block_number, balance, closing_sig ) assert is_same_address(receiver_verified, receiver) # Cooperative close can be called by anyone uraiden_instance.transact({"from": A}).cooperativeClose( receiver, open_block_number, balance, balance_msg_sig, closing_sig )
def test_variable_access(owner, uraiden_contract, token_instance, contract_params): uraiden = uraiden_contract(token_instance) assert is_same_address(uraiden.call().owner_address(), owner) assert is_same_address(uraiden.call().token(), token_instance.address) assert uraiden.call().challenge_period() == contract_params['challenge_period'] assert uraiden.call().version() == uraiden_contract_version assert uraiden.call().channel_deposit_bugbounty_limit() == channel_deposit_bugbounty_limit
def test_set_address_equivalence(ens, name, equivalent, TEST_ADDRESS): assert ens.address(name) is None ens.setup_address(name, TEST_ADDRESS) assert is_same_address(ens.address(name), TEST_ADDRESS) assert is_same_address(ens.address(equivalent), TEST_ADDRESS) ens.setup_address(name, None) assert ens.address(name) is None
def test_pre_EIP155_transaction_sender_extraction(transaction_class, txn_fixture): if txn_fixture['chainId'] is not None: pytest.skip("Only testng non-EIP155 transactions") key = keys.PrivateKey(decode_hex(txn_fixture['key'])) transaction = rlp.decode(decode_hex(txn_fixture['signed']), sedes=transaction_class) sender = extract_transaction_sender(transaction) assert is_same_address(sender, transaction.sender) assert is_same_address(sender, key.public_key.to_canonical_address())
def test_token_network_registry( deploy_client, contract_manager, token_network_registry_proxy: TokenNetworkRegistry, ): assert token_network_registry_proxy.settlement_timeout_min() == TEST_SETTLE_TIMEOUT_MIN assert token_network_registry_proxy.settlement_timeout_max() == TEST_SETTLE_TIMEOUT_MAX bad_token_address = make_address() # try to register non-existing token network with pytest.raises(RaidenUnrecoverableError): token_network_registry_proxy.add_token(bad_token_address) # create token network & register it test_token = deploy_token( deploy_client=deploy_client, contract_manager=contract_manager, initial_amount=1000, decimals=0, token_name='TKN', token_symbol='TKN', ) test_token_address = to_canonical_address(test_token.contract.address) event_filter = token_network_registry_proxy.tokenadded_filter() token_network_address = token_network_registry_proxy.add_token( test_token_address, ) with pytest.raises(RaidenRecoverableError) as exc: token_network_address = token_network_registry_proxy.add_token( test_token_address, ) assert 'Token already registered' in str(exc) logs = event_filter.get_all_entries() assert len(logs) == 1 decoded_event = token_network_registry_proxy.proxy.decode_event(logs[0]) assert is_same_address(decoded_event['args']['token_address'], test_token.contract.address) assert is_same_address( decoded_event['args']['token_network_address'], token_network_address, ) # test other getters assert token_network_registry_proxy.get_token_network(bad_token_address) is None assert is_same_address( token_network_registry_proxy.get_token_network(test_token_address), token_network_address, ) with pytest.raises(ValueError): assert token_network_registry_proxy.get_token_network(None) is None assert token_network_registry_proxy.get_token_network(bad_token_address) is None assert token_network_registry_proxy.get_token_network(token_network_address) is None assert token_network_registry_proxy.get_token_network(test_token_address) is not None
def test_balance_remaining_big( channel_params, get_accounts, uraiden_instance, get_channel): (sender, receiver, open_block_number) = get_channel()[:3] balance1 = 30 balance2_big = channel_params['deposit'] + 1 balance2_ok = channel_params['deposit'] balance_message_hash1 = balance_proof_hash( receiver, open_block_number, balance1, uraiden_instance.address ) balance_msg_sig1, addr = sign.check(balance_message_hash1, tester.k2) assert is_same_address(addr, sender) balance_message_hash2_big = balance_proof_hash( receiver, open_block_number, balance2_big, uraiden_instance.address ) balance_msg_sig2_big, addr = sign.check(balance_message_hash2_big, tester.k2) assert is_same_address(addr, sender) balance_message_hash2_ok = balance_proof_hash( receiver, open_block_number, balance2_ok, uraiden_instance.address ) balance_msg_sig2_ok, addr = sign.check(balance_message_hash2_ok, tester.k2) assert is_same_address(addr, sender) uraiden_instance.transact({"from": receiver}).withdraw( open_block_number, balance1, balance_msg_sig1 ) with pytest.raises(tester.TransactionFailed): uraiden_instance.transact({"from": receiver}).withdraw( open_block_number, balance2_big, balance_msg_sig2_big ) uraiden_instance.transact({"from": receiver}).withdraw( open_block_number, balance2_ok, balance_msg_sig2_ok )
def get_open_channels(self, receiver: str = None) -> List[Channel]: """ Returns all open channels to the given receiver. If no receiver is specified, all open channels are returned. """ return [ c for c in self.channels if is_same_address(c.sender, self.context.address) and (not receiver or is_same_address(c.receiver, receiver)) and c.state == Channel.State.open ]
def test_challenge( channel_manager: ChannelManager, confirmed_open_channel: Channel, receiver_address: str, sender_address: str, wait_for_blocks, web3: Web3, client: Client ): blockchain = channel_manager.blockchain channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block) sig = encode_hex(confirmed_open_channel.create_transfer(5)) channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig) # hack channel to decrease balance confirmed_open_channel.update_balance(0) sig = confirmed_open_channel.create_transfer(3) block_before = web3.eth.blockNumber confirmed_open_channel.close() # should challenge and immediately settle for waited_blocks in count(): logs = get_logs(client.context.token, 'Transfer', from_block=block_before - 1) if logs: break wait_for_blocks(1) assert waited_blocks < 10 assert len([l for l in logs if is_same_address(l['args']['_to'], receiver_address) and l['args']['_value'] == 5]) == 1 assert len([l for l in logs if is_same_address(l['args']['_to'], sender_address) and l['args']['_value'] == 5]) == 1 wait_for_blocks(blockchain.n_confirmations) gevent.sleep(blockchain.poll_interval) assert channel_id not in channel_manager.channels # update channel state so that it will not be closed twice client.sync_channels() new_state = None for channel in client.channels: if all(channel.sender == confirmed_open_channel.sender, channel.receiver == confirmed_open_channel.receiver, channel.block == confirmed_open_channel.block): new_state = channel.state if new_state is None: confirmed_open_channel.state = confirmed_open_channel.State.closed else: confirmed_open_channel.state = new_state
def test_withdraw_event( channel_params, uraiden_instance, get_channel, event_handler): (sender, receiver, open_block_number) = get_channel()[:3] ev_handler = event_handler(uraiden_instance) balance = 30 balance_message_hash = balance_proof_hash( receiver, open_block_number, balance, uraiden_instance.address ) balance_msg_sig, addr = sign.check(balance_message_hash, tester.k2) assert is_same_address(addr, sender) txn_hash = uraiden_instance.transact({"from": receiver}).withdraw( open_block_number, balance, balance_msg_sig ) ev_handler.add(txn_hash, uraiden_events['withdraw'], checkWithdrawEvent( sender, receiver, open_block_number, balance) ) ev_handler.check()
def test_dynamic_length_argument_extraction(web3, emitter, wait_for_transaction, emitter_log_topics, emitter_event_ids): string_0 = "this-is-the-first-string-which-exceeds-32-bytes-in-length" string_1 = "this-is-the-second-string-which-exceeds-32-bytes-in-length" txn_hash = emitter.functions.logDynamicArgs(string_0, string_1).transact() txn_receipt = wait_for_transaction(web3, txn_hash) assert len(txn_receipt['logs']) == 1 log_entry = txn_receipt['logs'][0] event_abi = emitter._find_matching_event_abi('LogDynamicArgs') event_topic = emitter_log_topics.LogDynamicArgs assert event_topic in log_entry['topics'] string_0_topic = web3.keccak(text=string_0) assert string_0_topic in log_entry['topics'] event_data = get_event_data(event_abi, log_entry) expected_args = { "arg0": string_0_topic, "arg1": string_1, } assert event_data['args'] == expected_args assert event_data['blockHash'] == txn_receipt['blockHash'] assert event_data['blockNumber'] == txn_receipt['blockNumber'] assert event_data['transactionIndex'] == txn_receipt['transactionIndex'] assert is_same_address(event_data['address'], emitter.address) assert event_data['event'] == 'LogDynamicArgs'
def test_event_data_extraction(web3, emitter, wait_for_transaction, emitter_log_topics, emitter_event_ids, contract_fn, event_name, call_args, expected_args): emitter_fn = emitter.functions[contract_fn] event_id = getattr(emitter_event_ids, event_name) txn_hash = emitter_fn(event_id, *call_args).transact() txn_receipt = wait_for_transaction(web3, txn_hash) assert len(txn_receipt['logs']) == 1 log_entry = txn_receipt['logs'][0] event_abi = emitter._find_matching_event_abi(event_name) event_topic = getattr(emitter_log_topics, event_name) is_anonymous = event_abi['anonymous'] if is_anonymous: assert event_topic not in log_entry['topics'] else: assert event_topic in log_entry['topics'] event_data = get_event_data(event_abi, log_entry) assert event_data['args'] == expected_args assert event_data['blockHash'] == txn_receipt['blockHash'] assert event_data['blockNumber'] == txn_receipt['blockNumber'] assert event_data['transactionIndex'] == txn_receipt['transactionIndex'] assert is_same_address(event_data['address'], emitter.address) assert event_data['event'] == event_name
def test_ecrecover_output(web3, ecverify_test_contract): (A, B) = web3.eth.accounts[:2] block = 4804175 balance = 22000000000000000000 balance_message_hash = balance_proof_hash(B, block, balance, ecverify_test_contract.address) balance_msg_sig, addr = sign.check(balance_message_hash, tester.k0) assert is_same_address(addr, A) r = bytes.fromhex('12d99ba7bd20ac17bac65bfd646146c1ddbeb607519db6e7935684334d891ed6') s = bytes.fromhex('5d4ea3a13697c1d506f7bdb8cd672b944e2053d6d6bd87d4aa512fdc29ed9ae4') v = 28 with pytest.raises(tester.TransactionFailed): ecverify_test_contract.call().verify_ecrecover_output(balance_message_hash, r, s, 0) # We have to simulate mining because ecrecover consumes a lot of gas for precompiled contracts # on private chains. web3.testing.mine(30) ecverify_test_contract.call().verify_ecrecover_output( balance_message_hash, r, s, v )
def test_withdraw_fail_in_challenge_period( channel_params, get_accounts, uraiden_instance, get_channel): (sender, receiver, open_block_number) = get_channel()[:3] balance = 30 balance_message_hash = balance_proof_hash( receiver, open_block_number, balance, uraiden_instance.address ) balance_msg_sig, addr = sign.check(balance_message_hash, tester.k2) assert is_same_address(addr, sender) # Should fail if the channel is already in a challenge period uraiden_instance.transact({"from": sender}).uncooperativeClose( receiver, open_block_number, balance ) channel_info = uraiden_instance.call().getChannelInfo(sender, receiver, open_block_number) assert channel_info[2] > 0 # settle_block_number with pytest.raises(tester.TransactionFailed): uraiden_instance.transact({"from": receiver}).withdraw( open_block_number, balance, balance_msg_sig )
def test_verify_balance_proof(channel_manager_address: str): sig = sign_balance_proof( SENDER_PRIVATE_KEY, RECEIVER_ADDR, 315123, 8, channel_manager_address ) assert is_same_address(verify_balance_proof( RECEIVER_ADDR, 315123, 8, sig, channel_manager_address ), SENDER_ADDR)
def test_eth_sendTransaction(self, web3, unlocked_account): txn_params = { 'from': unlocked_account, 'to': unlocked_account, 'value': 1, 'gas': 21000, 'gas_price': web3.eth.gasPrice, } txn_hash = web3.eth.sendTransaction(txn_params) txn = web3.eth.getTransaction(txn_hash) assert is_same_address(txn['from'], txn_params['from']) assert is_same_address(txn['to'], txn_params['to']) assert txn['value'] == 1 assert txn['gas'] == 21000 assert txn['gasPrice'] == txn_params['gas_price']
def verify_balance_proof(self, sender, open_block_number, balance, signature): """Verify that a balance proof is valid and return the sender. This method just verifies if the balance proof is valid - no state update is performed. :returns: Channel, if it exists """ assert is_checksum_address(sender) if (sender, open_block_number) in self.unconfirmed_channels: raise InsufficientConfirmations( 'Insufficient confirmations for the channel ' '(sender=%s, open_block_number=%d)' % (sender, open_block_number)) try: c = self.channels[sender, open_block_number] except KeyError: raise NoOpenChannel('Channel does not exist or has been closed' '(sender=%s, open_block_number=%s)' % (sender, open_block_number)) if c.is_closed: raise NoOpenChannel('Channel closing has been requested already.') if not is_same_address( verify_balance_proof( self.receiver, open_block_number, balance, decode_hex(signature), self.channel_manager_contract.address ), sender ): raise InvalidBalanceProof('Recovered signer does not match the sender') return c
def test_extract_closing_signature(get_accounts, token_instance, uraiden_instance): (A, B) = get_accounts(2) token = token_instance uraiden = uraiden_instance sender = '0x5601Ea8445A5d96EEeBF89A67C4199FbB7a43Fbb' block = 4804175 balance = 22000000000000000000 message_hash = closing_message_hash(sender, block, balance, uraiden.address) balance_msg_sig, signer = sign.check(message_hash, tester.k2) assert is_same_address(signer, A) signature_address = uraiden.call().extractClosingSignature( sender, block, balance, balance_msg_sig ) assert is_same_address(signature_address, signer) # Wrong sender signature_address = uraiden.call().extractClosingSignature( B, block, balance, balance_msg_sig ) assert not is_same_address(signature_address, signer) # Wrong block signature_address = uraiden.call().extractClosingSignature( sender, 10, balance, balance_msg_sig ) assert not is_same_address(signature_address, signer) # Wrong balance signature_address = uraiden.call().extractClosingSignature( sender, block, 20, balance_msg_sig ) assert not is_same_address(signature_address, signer)
def test_sign_balance_proof_contract(channel_manager_contract: Contract): sig = sign_balance_proof( SENDER_PRIVATE_KEY, RECEIVER_ADDR, 37, 15, channel_manager_contract.address ) sender_recovered = channel_manager_contract.call().extractBalanceProofSignature( RECEIVER_ADDR, 37, 15, sig ) assert is_same_address(sender_recovered, SENDER_ADDR)
def test_sign(): msg = b'32' * 16 assert len(msg) == 32 sig = sign(SENDER_PRIVATE_KEY, msg) pubkey = PublicKey.from_signature_and_message(sig, msg, hasher=None) pubkey = pubkey.format(compressed=False) assert len(sig) == 65 assert is_same_address(pubkey_to_addr(pubkey), SENDER_ADDR)
def test_sign_close_contract(channel_manager_contract: Contract): sig = sign_close( RECEIVER_PRIVATE_KEY, SENDER_ADDR, 315832, 13, channel_manager_contract.address ) receiver_recovered = channel_manager_contract.call().extractClosingSignature( SENDER_ADDR, 315832, 13, sig ) assert is_same_address(receiver_recovered, RECEIVER_ADDR)
def test_personal_importRawKey_as_bytes(web3, account_private_key, account_password, account_public_key): address = web3.personal.importRawKey(account_private_key, account_password) # sanity check assert is_same_address(address, account_public_key) assert web3.personal.unlockAccount(address, account_password) is True
def test_verify_balance_proof_v0(channel_manager_address: str): sig = sign_balance_proof( SENDER_PRIVATE_KEY, RECEIVER_ADDR, 312524, 11, channel_manager_address ) sig = sig[:-1] + bytes([sig[-1] % 27]) assert is_same_address(verify_balance_proof( RECEIVER_ADDR, 312524, 11, sig, channel_manager_address ), SENDER_ADDR)
def test_personal_sign_and_ecrecover(self, web3, unlockable_account, unlockable_account_pw): message = 'test-web3-personal-sign' signature = web3.personal.sign(message, unlockable_account, unlockable_account_pw) signer = web3.personal.ecRecover(message, signature) assert is_same_address(signer, unlockable_account)
def test_withdraw_fail_no_channel( channel_params, get_accounts, uraiden_instance, get_channel): A = get_accounts(1, 5)[0] (sender, receiver, open_block_number) = get_channel()[:3] balance = 10 balance_message_hash_A = balance_proof_hash( A, open_block_number, balance, uraiden_instance.address ) balance_msg_sig_A, addr = sign.check(balance_message_hash_A, tester.k5) assert is_same_address(addr, A) balance_message_hash = balance_proof_hash( receiver, open_block_number, balance, uraiden_instance.address ) balance_msg_sig, addr = sign.check(balance_message_hash, tester.k2) assert is_same_address(addr, sender) with pytest.raises(tester.TransactionFailed): uraiden_instance.transact({"from": sender}).withdraw( open_block_number, balance, balance_msg_sig ) with pytest.raises(tester.TransactionFailed): uraiden_instance.transact({"from": A}).withdraw( open_block_number, balance, balance_msg_sig ) with pytest.raises(tester.TransactionFailed): uraiden_instance.transact({"from": receiver}).withdraw( open_block_number, balance, balance_msg_sig_A )
def is_account_locked(web3, account): if isinstance(web3.providers[0], (EthereumTesterProvider, TestRPCProvider)): return not any((is_same_address(account, a) for a in web3.eth.accounts[:10])) try: web3.eth.sign(account, 'simple-test-data') except ValueError as err: return 'account is locked' in str(err) else: return False
def assert_contains_log(result): assert len(result) == 1 log_entry = result[0] assert log_entry['blockNumber'] == block_with_txn_with_log['number'] assert log_entry['blockHash'] == block_with_txn_with_log['hash'] assert log_entry['logIndex'] == 0 assert is_same_address(log_entry['address'], emitter_contract.address) assert log_entry['transactionIndex'] == 0 assert log_entry['transactionHash'] == HexBytes(txn_hash_with_log)
def test_blockchain( init_blockchain, web3, blockchain_rpc_ports, private_keys, poll_timeout): # pylint: disable=too-many-locals addresses = [ privatekey_to_address(priv) for priv in private_keys ] privatekey = private_keys[0] address = privatekey_to_address(privatekey) total_token = 100 host = '127.0.0.1' jsonrpc_client = JSONRPCClient( host, blockchain_rpc_ports[0], privatekey, web3=web3, ) humantoken_path = get_contract_path('HumanStandardToken.sol') humantoken_contracts = compile_files_cwd([humantoken_path]) token_proxy = jsonrpc_client.deploy_solidity_contract( 'HumanStandardToken', humantoken_contracts, list(), (total_token, 'raiden', 2, 'Rd'), contract_path=humantoken_path, timeout=poll_timeout, ) token_proxy = Token(jsonrpc_client, to_canonical_address(token_proxy.contract.address)) registry_path = get_contract_path('Registry.sol') registry_contracts = compile_files_cwd([registry_path]) registry_proxy = jsonrpc_client.deploy_solidity_contract( 'Registry', registry_contracts, list(), tuple(), contract_path=registry_path, timeout=poll_timeout, ) registry_proxy = Registry( jsonrpc_client, to_canonical_address(registry_proxy.contract.address), ) log_list = jsonrpc_client.web3.eth.getLogs( { 'fromBlock': 0, 'toBlock': 'latest', 'topics': [], }, ) assert not log_list assert token_proxy.balance_of(address) == total_token manager_address = registry_proxy.add_token( to_canonical_address(token_proxy.proxy.contract.address), ) assert is_address(manager_address) assert len(registry_proxy.token_addresses()) == 1 log_list = jsonrpc_client.web3.eth.getLogs( { 'fromBlock': 0, 'toBlock': 'latest', 'topics': [], }, ) assert len(log_list) == 1 channel_manager_address_encoded = registry_proxy.manager_address_by_token( token_proxy.proxy.contract.address, ) channel_manager_address = to_canonical_address(channel_manager_address_encoded) log = log_list[0] event = decode_event(CONTRACT_MANAGER.get_contract_abi(CONTRACT_REGISTRY), log) event_args = event['args'] assert channel_manager_address == to_canonical_address(event_args['channel_manager_address']) assert is_same_address(token_proxy.proxy.contract.address, event_args['token_address']) channel_manager_proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_contract_abi(CONTRACT_CHANNEL_MANAGER), channel_manager_address, ) channel_manager_proxy = ChannelManager( jsonrpc_client, to_canonical_address(channel_manager_proxy.contract.address), ) channel_address = channel_manager_proxy.new_netting_channel( addresses[1], 10, ) assert is_address(channel_address) log_list = jsonrpc_client.web3.eth.getLogs( { 'fromBlock': 0, 'toBlock': 'latest', 'topics': [], }, ) assert len(log_list) == 2
def test_sign_v0(): msg = keccak256('hello v=0') sig = sign(SENDER_PRIVATE_KEY, msg) assert sig[-1] == 1 assert is_same_address(addr_from_sig(sig, msg), SENDER_ADDR)
def test_sign(web3, ecverify_test_contract): (A, B) = web3.eth.accounts[:2] block = 4804175 balance = 22000000000000000000 balance_message_hash = balance_proof_hash(B, block, balance, ecverify_test_contract.address) balance_message_hash2 = balance_proof_hash(B, block, balance + 1000, ecverify_test_contract.address) signed_message, addr = sign.check(balance_message_hash, tester.k0) signed_message_false, addr1 = sign.check(balance_message_hash, tester.k1) assert is_same_address(addr, A) assert is_same_address(addr1, B) assert len(signed_message) == 65 assert len(signed_message_false) == 65 with pytest.raises(tester.TransactionFailed): verified_address = ecverify_test_contract.call().verify( balance_message_hash, encode_hex(bytearray()) ) web3.testing.mine(30) with pytest.raises(tester.TransactionFailed): verified_address = ecverify_test_contract.call().verify( balance_message_hash, encode_hex(bytearray(64)) ) web3.testing.mine(30) with pytest.raises(tester.TransactionFailed): verified_address = ecverify_test_contract.call().verify( balance_message_hash, encode_hex(bytearray(66)) ) web3.testing.mine(30) verified_address = ecverify_test_contract.call().verify( balance_message_hash2, signed_message ) assert not is_same_address(verified_address, A) verified_address = ecverify_test_contract.call().verify( balance_message_hash, signed_message ) assert is_same_address(verified_address, A) verified_address_false = ecverify_test_contract.call().verify( balance_message_hash, signed_message_false ) assert not is_same_address(verified_address_false, A) assert is_same_address(verified_address_false, B) signer = '0x5601Ea8445A5d96EEeBF89A67C4199FbB7a43Fbb' value = 1000 value2 = 2000 _address = '0x5601Ea8445A5d96EEeBF89A67C4199FbB7a43Fbb' signed_message = '0x0adc437691e266072e9aa1763329062a6b2fa1d7f94034f1b1e691218fe9fd285f4f20132fa00230f591571a3575456bb382040e02e93ff0f32544907748a9821c' signed_message = bytes.fromhex(signed_message[2:]) verified_address = ecverify_test_contract.call().verifyEthSignedTypedData( _address, value, value2, signed_message ) assert is_same_address(verified_address, signer)
def on_new_balance_sig(self, command: str, customer: str, sender: str, open_block_number: int, balance_message_hash: bytes, round_number: int, signature: str, customer_sig: str): #print('\nbalance sig') #debug_print([customer, sender, open_block_number, balance_message_hash, signature]) customer = to_checksum_address(customer) sender = to_checksum_address(sender) if not self.verify_customer_deposit(customer): return NO_CONTRACT_DEPOSIT current_round_number = self.jobs[customer, sender, open_block_number].round_number try: assert self.jobs[ customer, sender, open_block_number].round_number == round_number - 1 except AssertionError: print( bcolors.OKBLUE + 'gave incorrent monitor number (current %d, expected %d, received %d)' % (current_round_number, current_round_number + 1, round_number) + bcolors.ENDC) return try: assert self.jobs[customer, sender, open_block_number].last_signature != signature self.log.info('Signature is different') self.log.info( 'Current round number %d, state hash round number %d', self.jobs[customer, sender, open_block_number].round_number, round_number) final_hash = monitor_balance_message_from_state( balance_message_hash, round_number) #self.log.info('Monitors hash: (balanace message hash %s)', encode_hex(balance_message_hash)) self.log.info( 'Monitors hash: (round number %s, balanace message hash %s, final hash %s)', round_number, encode_hex(balance_message_hash), encode_hex(final_hash)) """regular""" #sig_addr = addr_from_sig(decode_hex(signature), balance_message_hash) """with receipt""" sig_addr = addr_from_sig(decode_hex(signature), final_hash) if not is_same_address(sig_addr, sender): self.log.info('balance message not signed by correct sender') return BALANCE_SIG_NOT_ACCEPTED """regular""" #customer_sig_addr = addr_from_sig(decode_hex(customer_sig), balance_message_hash) """with receipt""" customer_sig_addr = addr_from_sig(decode_hex(customer_sig), final_hash) if not is_same_address(customer_sig_addr, customer): self.log.info('customers balance sig is wrong. address: %s', customer_sig_addr) return BALANCE_SIG_NOT_ACCEPTED self.jobs[customer, sender, open_block_number].round_number += 1 receipt = self.create_signed_receipt(customer, sender, open_block_number, balance_message_hash, signature, round_number) #receipt = self.create_signed_receipt(customer, sender, open_block_number, balance_message_hash, round_number, signature) #self.customer_fair_exchange(customer, sender, open_block_number, balance_message_hash, signature) self.jobs[customer, sender, open_block_number].last_signature = signature self.jobs[customer, sender, open_block_number].last_hash = balance_message_hash self.jobs[customer, sender, open_block_number].last_customer_sig = customer_sig self.jobs[customer, sender, open_block_number].last_round_number = round_number self.jobs[customer, sender, open_block_number].all_signatures.append(signature) self.jobs[customer, sender, open_block_number].all_customer_signatures.append( customer_sig) self.jobs[customer, sender, open_block_number].all_hashes.append( balance_message_hash) self.jobs[customer, sender, open_block_number].all_round_numbers.append(round_number) self.log.info( 'Accepting new balance signature (customer %s, sender %s, open block number %d)', customer, sender, open_block_number) # self.log.info('Accepting new balance signature (customer %s, sender %s, open block number %d, \n\told hash %s, \n\tnew hash %s)', # customer, # sender, # open_block_number, # encode_hex(self.jobs[customer,sender,open_block_number].last_hash), # encode_hex(balance_message_hash) # ) self.jobs[customer, sender, open_block_number].sent_receipt = True self.log.debug( 'accepted balance signature (customer %s, sender %s, open_block_number %s\n', customer, sender, open_block_number) # self.log.info('TYPE OF RECEIPT %s', str(type(receipt))) # self.log.info('RECEIPT %s', str(receipt)) return receipt except KeyError: self.log.info('balance sig for job not being watched\n') return IGNORE_BALANCE_SIG except AssertionError: self.log.info('customer sent the same signature as before: %s\n', encode_hex(signature)) return IGNORE_SAME_BALANCE_SIG
def __init__( self, privkey: str = None, key_path: str = None, key_password_path: str = None, datadir: str = click.get_app_dir('microraiden'), channel_manager_address: str = CHANNEL_MANAGER_ADDRESS, web3: Web3 = None, channel_manager_proxy: ChannelContractProxy = None, token_proxy: ContractProxy = None, contract_metadata: dict = CONTRACT_METADATA ) -> None: assert privkey or key_path assert not privkey or isinstance(privkey, str) # Plain copy initializations. self.privkey = privkey self.datadir = datadir self.channel_manager_address = channel_manager_address self.web3 = web3 self.channel_manager_proxy = channel_manager_proxy self.token_proxy = token_proxy # Load private key from file if none is specified on command line. if not privkey: self.privkey = get_private_key(key_path, key_password_path) assert self.privkey is not None os.makedirs(datadir, exist_ok=True) assert os.path.isdir(datadir) self.account = privkey_to_addr(self.privkey) self.channels = [] # type: List[Channel] # Create web3 context if none is provided, either by using the proxies' context or creating # a new one. if not web3: if channel_manager_proxy: self.web3 = channel_manager_proxy.web3 self.channel_manager_address = channel_manager_proxy.address elif token_proxy: self.web3 = token_proxy.web3 else: self.web3 = Web3(RPCProvider()) # Create missing contract proxies. if not channel_manager_proxy: channel_manager_abi = contract_metadata[CHANNEL_MANAGER_ABI_NAME]['abi'] self.channel_manager_proxy = ChannelContractProxy( self.web3, self.privkey, channel_manager_address, channel_manager_abi, GAS_PRICE, GAS_LIMIT ) token_address = self.channel_manager_proxy.contract.call().token() if not token_proxy: token_abi = contract_metadata[TOKEN_ABI_NAME]['abi'] self.token_proxy = ContractProxy( self.web3, self.privkey, token_address, token_abi, GAS_PRICE, GAS_LIMIT ) else: assert is_same_address(self.token_proxy.address, token_address) assert self.web3 assert self.channel_manager_proxy assert self.token_proxy assert self.channel_manager_proxy.web3 == self.web3 == self.token_proxy.web3 netid = self.web3.version.network self.balances_filename = 'balances_{}_{}.json'.format( NETWORK_NAMES.get(netid, netid), self.account[:10] ) self.filelock = filelock.FileLock(os.path.join(self.datadir, self.balances_filename)) self.filelock.acquire(timeout=0) self.load_channels() self.sync_channels()
def address_in(address, addresses): return any(is_same_address(address, item) for item in addresses)
def test_configure_pfs(service_registry_address, private_keys, web3, contract_manager): chain_id = ChainID(int(web3.net.version)) service_registry, urls = deploy_service_registry_and_set_urls( private_keys=private_keys, web3=web3, contract_manager=contract_manager, service_registry_address=service_registry_address, ) json_data = { "price_info": 0, "network_info": { "chain_id": chain_id, "token_network_registry_address": to_checksum_address( token_network_registry_address_test_default ), "user_deposit_address": to_checksum_address(privatekey_to_address(private_keys[1])), }, "message": "This is your favorite pathfinding service", "operator": "John Doe", "version": "0.0.1", "payment_address": to_checksum_address(privatekey_to_address(private_keys[0])), } response = mocked_json_response(response_data=json_data) # With local routing configure_pfs should raise assertion with pytest.raises(AssertionError): _ = configure_pfs_or_exit( pfs_url="", routing_mode=RoutingMode.LOCAL, service_registry=service_registry, node_network_id=chain_id, token_network_registry_address=token_network_registry_address_test_default, pathfinding_max_fee=DEFAULT_PATHFINDING_MAX_FEE, ) # With private routing configure_pfs should raise assertion with pytest.raises(AssertionError): _ = configure_pfs_or_exit( pfs_url="", routing_mode=RoutingMode.PRIVATE, service_registry=service_registry, node_network_id=chain_id, token_network_registry_address=token_network_registry_address_test_default, pathfinding_max_fee=DEFAULT_PATHFINDING_MAX_FEE, ) # Asking for auto address # To make this deterministic we need to patch the random selection function patch_random = patch("raiden.network.pathfinding.get_random_pfs", return_value="http://foo") with patch.object(requests, "get", return_value=response), patch_random: config = configure_pfs_or_exit( pfs_url="auto", routing_mode=RoutingMode.PFS, service_registry=service_registry, node_network_id=chain_id, token_network_registry_address=token_network_registry_address_test_default, pathfinding_max_fee=DEFAULT_PATHFINDING_MAX_FEE, ) assert config.url in urls assert is_canonical_address(config.payment_address) # Configuring a valid given address given_address = "http://foo" with patch.object(requests, "get", return_value=response): config = configure_pfs_or_exit( pfs_url=given_address, routing_mode=RoutingMode.PFS, service_registry=service_registry, node_network_id=chain_id, token_network_registry_address=token_network_registry_address_test_default, pathfinding_max_fee=DEFAULT_PATHFINDING_MAX_FEE, ) assert config.url == given_address assert is_same_address(config.payment_address, json_data["payment_address"]) assert config.price == json_data["price_info"] # Bad address, should exit the program bad_address = "http://badaddress" with pytest.raises(RaidenError): with patch.object(requests, "get", side_effect=requests.RequestException()): # Configuring a given address _ = configure_pfs_or_exit( pfs_url=bad_address, routing_mode=RoutingMode.PFS, service_registry=service_registry, node_network_id=chain_id, token_network_registry_address=token_network_registry_address_test_default, pathfinding_max_fee=DEFAULT_PATHFINDING_MAX_FEE, ) # Addresses of token network registries of pfs and client conflict, should exit the client response = mocked_json_response(response_data=json_data) with pytest.raises(RaidenError): with patch.object(requests, "get", return_value=response): _ = configure_pfs_or_exit( pfs_url="http://foo", routing_mode=RoutingMode.PFS, service_registry=service_registry, node_network_id=chain_id, token_network_registry_address=TokenNetworkRegistryAddress( to_canonical_address("0x2222222222222222222222222222222222222221") ), pathfinding_max_fee=DEFAULT_PATHFINDING_MAX_FEE, ) # ChainIDs of pfs and client conflict, should exit the client response = mocked_json_response(response_data=json_data) with pytest.raises(RaidenError): with patch.object(requests, "get", return_value=response): configure_pfs_or_exit( pfs_url="http://foo", routing_mode=RoutingMode.PFS, service_registry=service_registry, node_network_id=ChainID(chain_id + 1), token_network_registry_address=token_network_registry_address_test_default, pathfinding_max_fee=DEFAULT_PATHFINDING_MAX_FEE, )
def test_eth_sign_v27(): sig = eth_sign(SENDER_PRIVATE_KEY, 'hello v=27') assert sig[-1] == 27 assert is_same_address(eth_verify(sig, 'hello v=27'), SENDER_ADDR)
def is_signature_valid(self) -> bool: try: recovered_address = recover(self.packed_data(), self.signature) except InvalidSignature: return False return is_same_address(recovered_address, self.sender)
def test_EIP155_transaction_sender_extraction(txn_fixture): key = keys.PrivateKey(decode_hex(txn_fixture['key'])) transaction = rlp.decode(decode_hex(txn_fixture['signed']), sedes=SpuriousDragonTransaction) sender = extract_transaction_sender(transaction) assert is_same_address(sender, transaction.sender) assert is_same_address(sender, key.public_key.to_canonical_address())
def test_get_authorized_address(keyfile, keyfile_auth): _, expected_address, _ = keyfile_auth actual_address = get_authorized_address() assert is_same_address(actual_address, expected_address)
def test_token_network_registry( deploy_client, contract_manager, token_network_registry_address, ): registry_address = to_canonical_address(token_network_registry_address) token_network_registry_proxy = TokenNetworkRegistry( jsonrpc_client=deploy_client, registry_address=registry_address, contract_manager=contract_manager, ) assert token_network_registry_proxy.settlement_timeout_min( ) == TEST_SETTLE_TIMEOUT_MIN assert token_network_registry_proxy.settlement_timeout_max( ) == TEST_SETTLE_TIMEOUT_MAX bad_token_address = make_address() # try to register non-existing token network with pytest.raises(AddressWithoutCode): token_network_registry_proxy.add_token_with_limits( token_address=bad_token_address, channel_participant_deposit_limit= RED_EYES_PER_CHANNEL_PARTICIPANT_LIMIT, token_network_deposit_limit=RED_EYES_PER_TOKEN_NETWORK_LIMIT, ) # create token network & register it test_token = deploy_token( deploy_client=deploy_client, contract_manager=contract_manager, initial_amount=1000, decimals=0, token_name='TKN', token_symbol='TKN', ) test_token_address = to_canonical_address(test_token.contract.address) # try to register a token network not following ERC20 protocol with patch.object(Token, 'total_supply', return_value=''): with pytest.raises(InvalidToken): token_network_registry_proxy.add_token_with_limits( token_address=test_token_address, channel_participant_deposit_limit= RED_EYES_PER_CHANNEL_PARTICIPANT_LIMIT, token_network_deposit_limit=RED_EYES_PER_TOKEN_NETWORK_LIMIT, ) event_filter = token_network_registry_proxy.tokenadded_filter() token_network_address = token_network_registry_proxy.add_token_with_limits( token_address=test_token_address, channel_participant_deposit_limit= RED_EYES_PER_CHANNEL_PARTICIPANT_LIMIT, token_network_deposit_limit=RED_EYES_PER_TOKEN_NETWORK_LIMIT, ) with pytest.raises(RaidenRecoverableError) as exc: token_network_address = token_network_registry_proxy.add_token_with_limits( token_address=test_token_address, channel_participant_deposit_limit= RED_EYES_PER_CHANNEL_PARTICIPANT_LIMIT, token_network_deposit_limit=RED_EYES_PER_TOKEN_NETWORK_LIMIT, ) assert 'Token already registered' in str(exc) logs = event_filter.get_all_entries() assert len(logs) == 1 decoded_event = token_network_registry_proxy.proxy.decode_event(logs[0]) assert is_same_address(decoded_event['args']['token_address'], test_token.contract.address) assert is_same_address( decoded_event['args']['token_network_address'], token_network_address, ) # test other getters assert token_network_registry_proxy.get_token_network( bad_token_address) is None assert is_same_address( token_network_registry_proxy.get_token_network(test_token_address), token_network_address, ) with pytest.raises(ValueError): assert token_network_registry_proxy.get_token_network(None) is None assert token_network_registry_proxy.get_token_network( bad_token_address) is None assert token_network_registry_proxy.get_token_network( token_network_address) is None assert token_network_registry_proxy.get_token_network( test_token_address) is not None
def setup_chain_state(web3): coinbase = web3.eth.coinbase assert is_same_address(coinbase, common.COINBASE) # # Math Contract # math_contract_factory = web3.eth.contract( abi=MATH_ABI, bytecode=MATH_BYTECODE, ) math_deploy_receipt = common.deploy_contract(web3, 'math', math_contract_factory) assert is_dict(math_deploy_receipt) # # Emitter Contract # emitter_contract_factory = web3.eth.contract( abi=EMITTER_ABI, bytecode=EMITTER_BYTECODE, ) emitter_deploy_receipt = common.deploy_contract(web3, 'emitter', emitter_contract_factory) emitter_contract = emitter_contract_factory( emitter_deploy_receipt['contractAddress']) txn_hash_with_log = emitter_contract.functions.logDouble( which=EMITTER_ENUM['LogDoubleWithIndex'], arg0=12345, arg1=54321, ).transact({ 'from': web3.eth.coinbase, }) print('TXN_HASH_WITH_LOG:', txn_hash_with_log) txn_receipt_with_log = common.mine_transaction_hash( web3, txn_hash_with_log) block_with_log = web3.eth.getBlock(txn_receipt_with_log['blockHash']) print('BLOCK_HASH_WITH_LOG:', block_with_log['hash']) # # Empty Block # empty_block_number = common.mine_block(web3) print('MINED_EMPTY_BLOCK') empty_block = web3.eth.getBlock(empty_block_number) assert is_dict(empty_block) assert not empty_block['transactions'] print('EMPTY_BLOCK_HASH:', empty_block['hash']) # # Block with Transaction # web3.personal.unlockAccount(coinbase, common.KEYFILE_PW) web3.miner.start(1) mined_txn_hash = web3.eth.sendTransaction({ 'from': coinbase, 'to': coinbase, 'value': 1, 'gas': 21000, 'gas_price': web3.eth.gasPrice, }) mined_txn_receipt = common.mine_transaction_hash(web3, mined_txn_hash) print('MINED_TXN_HASH:', mined_txn_hash) block_with_txn = web3.eth.getBlock(mined_txn_receipt['blockHash']) print('BLOCK_WITH_TXN_HASH:', block_with_txn['hash']) geth_fixture = { 'math_deploy_txn_hash': math_deploy_receipt['transactionHash'], 'math_address': math_deploy_receipt['contractAddress'], 'emitter_deploy_txn_hash': emitter_deploy_receipt['transactionHash'], 'emitter_address': emitter_deploy_receipt['contractAddress'], 'txn_hash_with_log': txn_hash_with_log, 'block_hash_with_log': block_with_log['hash'], 'empty_block_hash': empty_block['hash'], 'mined_txn_hash': mined_txn_hash, 'block_with_txn_hash': block_with_txn['hash'], } return geth_fixture
def test_verify_balance_proof(channel_manager_address: str): sig = sign_balance_proof(SENDER_PRIVATE_KEY, RECEIVER_ADDR, 315123, 8, channel_manager_address) assert is_same_address( verify_balance_proof(RECEIVER_ADDR, 315123, 8, sig, channel_manager_address), SENDER_ADDR)
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_protocol): node1, node2 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address, ) api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # Make sure invalid arguments to get_channel_list are caught with pytest.raises(UnknownTokenAddress): api1.get_channel_list( registry_address=registry_address, token_address=None, partner_address=api2.address, ) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED event_list1 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert any((event['event'] == ChannelEvent.OPENED and is_same_address( event['args']['participant1'], to_normalized_address(api1.address), ) and is_same_address( event['args']['participant2'], to_normalized_address(api2.address), )) for event in event_list1) token_events = api1.get_blockchain_events_token_network(token_address, ) assert token_events[0]['event'] == ChannelEvent.OPENED registry_address = api1.raiden.default_registry.address # Check that giving a 0 total deposit is not accepted with pytest.raises(DepositMismatch): api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=0, ) # Load the new state with the deposit api1.set_total_channel_deposit( registry_address=registry_address, token_address=token_address, partner_address=api2.address, total_deposit=deposit, ) # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit with pytest.raises(DepositMismatch): api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert any((event['event'] == ChannelEvent.DEPOSIT and is_same_address( event['args']['participant'], to_normalized_address(api1.address), ) and event['args']['total_deposit'] == deposit) for event in event_list2) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_identifier) event_list3 = api1.get_blockchain_events_channel( token_address, channel12.partner_state.address, ) assert len(event_list3) > len(event_list2) assert any((event['event'] == ChannelEvent.CLOSED and is_same_address( event['args']['closing_participant'], to_normalized_address(api1.address), )) for event in event_list3) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED settlement_block = ( channel12.close_transaction.finished_block_number + channel12.settle_timeout + 10 # arbitrary number of additional blocks, used to wait for the settle() call ) node1.raiden.chain.wait_until_block( target_block_number=settlement_block + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS, ) state_changes = node1.raiden.wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) assert search_for_item( state_changes, ContractReceiveChannelSettled, { 'token_network_identifier': token_network_identifier, 'channel_identifier': channel12.identifier, })
def _update(self): #print(bcolors.BOLD + 'manager: block number %d' % (self.web3.eth.blockNumber) + bcolors.ENDC) current_block = self.web3.eth.blockNumber # reset unconfirmed channels in case of reorg if self.wait_sync_event.is_set(): # but not on first sync if current_block < self.cm.state.unconfirmed_head_number: self.log.info( 'chain reorganization detected. ' 'Resyncing unconfirmed events (unconfirmed_head=%d) [@%d]' % (self.cm.state.unconfirmed_head_number, self.web3.eth.blockNumber)) self.cm.reset_unconfirmed() try: # raises if hash doesn't exist (i.e. block has been replaced) self.web3.eth.getBlock(self.cm.state.unconfirmed_head_hash) except ValueError: self.log.info( 'chain reorganization detected. ' 'Resyncing unconfirmed events (unconfirmed_head=%d) [@%d]. ' '(getBlock() raised ValueError)' % (self.cm.state.unconfirmed_head_number, current_block)) self.cm.reset_unconfirmed() # in case of reorg longer than confirmation number fail try: self.web3.eth.getBlock(self.cm.state.confirmed_head_hash) except ValueError: self.log.critical( 'events considered confirmed have been reorganized') assert False # unreachable as long as confirmation level is set high enough if self.cm.state.confirmed_head_number is None: self.cm.state.update_sync_state( confirmed_head_number=self.sync_start_block) if self.cm.state.unconfirmed_head_number is None: self.cm.state.update_sync_state( unconfirmed_head_number=self.sync_start_block) new_unconfirmed_head_number = self.cm.state.unconfirmed_head_number + self.sync_chunk_size new_unconfirmed_head_number = min(new_unconfirmed_head_number, current_block) new_confirmed_head_number = max( new_unconfirmed_head_number - self.n_confirmations, 0) # return if blocks have already been processed if (self.cm.state.confirmed_head_number >= new_confirmed_head_number and self.cm.state.unconfirmed_head_number >= new_unconfirmed_head_number): return # filter for events after block_number filters_confirmed = { 'from_block': self.cm.state.confirmed_head_number + 1, 'to_block': new_confirmed_head_number, 'argument_filters': { '_receiver_address': self.cm.state.receiver } } filters_unconfirmed = { 'from_block': self.cm.state.unconfirmed_head_number + 1, 'to_block': new_unconfirmed_head_number, 'argument_filters': { '_receiver_address': self.cm.state.receiver } } self.log.debug('filtering for events u:%s-%s c:%s-%s @%d', filters_unconfirmed['from_block'], filters_unconfirmed['to_block'], filters_confirmed['from_block'], filters_confirmed['to_block'], current_block) # unconfirmed channel created logs = get_logs(self.channel_manager_contract, 'ChannelCreated', **filters_unconfirmed) for log in logs: assert is_same_address(log['args']['_receiver_address'], self.cm.state.receiver) sender = log['args']['_sender_address'] sender = to_checksum_address(sender) deposit = log['args']['_deposit'] open_block_number = log['blockNumber'] self.log.debug( 'received unconfirmed ChannelCreated event (sender %s, block number %s)', sender, open_block_number) self.cm.unconfirmed_event_channel_opened(sender, open_block_number, deposit) # channel created logs = get_logs(self.channel_manager_contract, 'ChannelCreated', **filters_confirmed) for log in logs: assert is_same_address(log['args']['_receiver_address'], self.cm.state.receiver) sender = log['args']['_sender_address'] sender = to_checksum_address(sender) deposit = log['args']['_deposit'] open_block_number = log['blockNumber'] self.log.debug( 'received ChannelOpened event (sender %s, block number %s)', sender, open_block_number) self.cm.event_channel_opened(sender, open_block_number, deposit) # unconfirmed channel top ups logs = get_logs(self.channel_manager_contract, 'ChannelToppedUp', **filters_unconfirmed) for log in logs: assert is_same_address(log['args']['_receiver_address'], self.cm.state.receiver) txhash = log['transactionHash'] sender = log['args']['_sender_address'] sender = to_checksum_address(sender) open_block_number = log['args']['_open_block_number'] added_deposit = log['args']['_added_deposit'] self.log.debug( 'received top up event (sender %s, block number %s, deposit %s)', sender, open_block_number, added_deposit) self.cm.unconfirmed_event_channel_topup(sender, open_block_number, txhash, added_deposit) # confirmed channel top ups logs = get_logs(self.channel_manager_contract, 'ChannelToppedUp', **filters_confirmed) for log in logs: assert is_same_address(log['args']['_receiver_address'], self.cm.state.receiver) txhash = log['transactionHash'] sender = log['args']['_sender_address'] sender = to_checksum_address(sender) open_block_number = log['args']['_open_block_number'] added_deposit = log['args']['_added_deposit'] self.log.debug( 'received top up event (sender %s, block number %s, added deposit %s)', sender, open_block_number, added_deposit) self.cm.event_channel_topup(sender, open_block_number, txhash, added_deposit) # channel settled event logs = get_logs(self.channel_manager_contract, 'ChannelSettled', **filters_confirmed) for log in logs: assert is_same_address(log['args']['_receiver_address'], self.cm.state.receiver) sender = log['args']['_sender_address'] sender = to_checksum_address(sender) open_block_number = log['args']['_open_block_number'] self.log.debug( 'received ChannelSettled event (sender %s, block number %s)', sender, open_block_number) self.cm.event_channel_settled(sender, open_block_number) # channel close requested logs = get_logs(self.channel_manager_contract, 'ChannelCloseRequested', **filters_confirmed) for log in logs: assert is_same_address(log['args']['_receiver_address'], self.cm.state.receiver) sender = log['args']['_sender_address'] sender = to_checksum_address(sender) open_block_number = log['args']['_open_block_number'] if (sender, open_block_number) not in self.cm.channels: continue balance = log['args']['_balance'] try: #self.log.info('params to get info: %s, %s, %d', sender, self.cm.state.receiver, open_block_number) mtimeout, timeout = self.channel_manager_contract.call( ).getChannelInfo(sender, self.cm.state.receiver, open_block_number)[2:4] print(bcolors.OKGREEN + 'Channel close request:' + '\n\tsender %s' % sender + '\n\tmonitor timeout %d' % mtimeout + '\n\tsettle timeout %d' % timeout + bcolors.ENDC) except BadFunctionCallOutput: self.log.warning( 'received ChannelCloseRequested event for a channel that doesn\'t ' 'exist or has been closed already (sender=%s open_block_number=%d)' % (sender, open_block_number)) self.cm.force_close_channel(sender, open_block_number) continue self.log.debug( 'received ChannelCloseRequested event (sender %s, block number %s)', sender, open_block_number) self.log.info( 'received ChannelCloseRequested event (blocknumber %s, monitor period %s, timeout %s)', self.cm.state.confirmed_head_number, mtimeout, timeout) self.wait_to_dispute[int(mtimeout)] = (sender, open_block_number, balance, mtimeout, timeout) #try: # self.cm.event_channel_close_requested(sender, open_block_number, balance, mtimeout, timeout) #except InsufficientBalance: # self.log.fatal('Insufficient ETH balance of the receiver. ' # "Can't close the channel. " # 'Will retry once the balance is sufficient') # self.insufficient_balance = True # TODO: recover logs = get_logs(self.channel_manager_contract, 'MonitorInterference', **filters_unconfirmed) for log in logs: sender = log['args']['_sender_address'] sender = to_checksum_address(sender) open_block_number = log['args']['open_block_number'] if (sender, open_block_number) not in self.cm.channels: self.log.debug( "monitor interfered in channel that wasn't outsourced (sender %s open_block_number %s)", sender, open_block_number) self.cm.event_monitor_interference(sender, open_block_number) logs = get_logs(self.channel_monitor_contract, 'CustomerDeposit', **filters_unconfirmed) for log in logs: sender = to_checksum_address(log['args']['_sender_address']) deposit = log['args']['_sender_deposit'] if sender == self.cm.receiver: self.cm.event_deposit_unconfirmed(sender, deposit) logs = get_logs(self.channel_monitor_contract, 'CustomerDeposit', **filters_confirmed) for log in logs: sender = to_checksum_address(log['args']['_sender_address']) deposit = log['args']['_sender_deposit'] if sender == self.cm.receiver: self.cm.event_deposit(sender, deposit) logs = get_logs(self.channel_monitor_contract, 'RecourseResult', **filters_unconfirmed) for log in logs: # monitor_balance = log['args']['_monitor_balance'] # closing_balance = log['args']['_closing_balance'] round_number = int(log['args']['_round_number']) receipt_hash = log['args']['_receipt_hash'] cheated = log['args']['_cheated'] self.log.info( 'RECOURSE RESULT: detected unconfirmed recourse result (round_number %d, receipt hash %s), did he cheat? %r', round_number, receipt_hash, cheated) print( bcolors.OKBLUE, 'Recourse result detected', '\n\tCheated: %r' % cheated, '\n\tnew balance: %s' % int(self.web3.eth.getBalance(self.cm.receiver)), bcolors.ENDC) logs = get_logs(self.channel_manager_contract, 'ExtractHash', **filters_unconfirmed) for log in logs: message_hash = log['args']['message_hash'] state_hash = log['args']['state_hash'] signer = to_checksum_address(log['args']['signer']) self.log.info('\n\tmessage_hash %s\n\tstate_hash %s\n\tsigner %s', message_hash, state_hash, signer) logs = get_logs(self.channel_monitor_contract, 'Dispute', **filters_unconfirmed) for log in logs: customer = log['args']['_customer_address'] open_block_number = log['args']['_open_block_number'] sender = log['args']['_sender_address'] self.log.info( 'DETECTED UNCONFIMED DISPUTE from monitor contract (customer %s, sender %s, open_block_number %d)', customer, sender, open_block_number) logs = get_logs(self.channel_monitor_contract, 'Dispute', **filters_confirmed) for log in logs: customer = to_checksum_address(log['args']['_customer_address']) open_block_number = log['args']['_open_block_number'] sender = to_checksum_address(log['args']['_sender_address']) settle_timeout = int(log['data'], 16) self.log.info( 'DETECTED CONFIMED DISPUTE from monitor contract (customer %s, sender %s, open_block_number %d, settle timeout %d, current block %d)', customer, sender, open_block_number, settle_timeout, self.cm.blockchain.web3.eth.blockNumber) self.wait_to_resolve[settle_timeout + 1] = (customer, sender, open_block_number) self.resolve_timeouts[sender, open_block_number] = settle_timeout + 1 logs = get_logs(self.channel_monitor_contract, 'Resolve', **filters_confirmed) for log in logs: customer = to_checksum_address(log['args']['_sender_address']) self.log.info('successfully resolved channel (customer %s)', customer) print(bcolors.OKGREEN + 'Channel successfully resolved....' + bcolors.ENDC) print(bcolors.OKGREEN + '\n\tServer balance: %d' % (self.web3.eth.getBalance(self.cm.receiver))) logs = get_logs(self.channel_monitor_contract, 'Evidence', **filters_confirmed) for log in logs: customer = to_checksum_address(log['args']['_customer_address']) sender = to_checksum_address(log['args']['_sender_address']) pre_image = log['args']['_pre_image'] open_block_number = int(log['data'], 16) if (sender, open_block_number ) not in self.cm.channels or customer != self.cm.receiver: self.log.info('received SET STATE for unknown channel') else: self.log.info( 'Monitor called SET STATE (sender %s, open_block_number %d, pre_image %d)', sender, open_block_number, pre_image) self.cm.event_set_state(customer, sender, open_block_number, pre_image) logs = get_logs(self.channel_manager_contract, 'DebugVerify', **filters_unconfirmed) for log in logs: signer = to_checksum_address(log['args']['_sender']) self.log.info('Signer of customer evidence: %s', signer) logs = get_logs(self.channel_manager_contract, 'RevealHash', **filters_unconfirmed) for log in logs: evidence = encode_hex(log['args']['_evidence']) resolved = encode_hex(log['args']['_resolved']) balance = int(log['args']['_balance']) self.log.info( bcolors.BOLD + "Reveal (balance %s, evidence %s, resolved %s)" + bcolors.ENDC, balance, evidence, resolved) # See which close requests are ready to be responded to # and process them normally. disputed = [] for mtimeout in self.wait_to_dispute: if self.cm.state.confirmed_head_number > mtimeout: try: #print(self.cm.monitor_channels) sender, open_block_number = self.wait_to_dispute[mtimeout][ 0], self.wait_to_dispute[mtimeout][1] self.log.info( 'Processing close request at block %s, mtimeout %s', self.cm.state.confirmed_head_number, mtimeout) self.cm.reveal_monitor_submission( *self.wait_to_dispute[mtimeout]) self.cm.event_channel_close_requested( *self.wait_to_dispute[mtimeout]) except InsufficientBalance: self.log.fatal('Insufficient ETH balance of the receiver. ' "Can't close the channel. " 'Will retry once the balance is sufficient') self.insufficient_balance = True # TODO: recover disputed.append(mtimeout) for dispute in disputed: del self.wait_to_dispute[dispute] resolved = [] for stimeout in self.wait_to_resolve: if self.cm.blockchain.web3.eth.blockNumber > stimeout: self.log.info( 'Processing DISPUTE request at block %s, stimeout %s', self.cm.blockchain.web3.eth.blockNumber, stimeout) customer, sender, open_block_number = self.wait_to_resolve[ stimeout] self.cm.event_dispute(customer, sender, open_block_number) resolved.append(stimeout) for resolve in resolved: del self.wait_to_resolve[resolve] # update head hash and number try: new_unconfirmed_head_hash = self.web3.eth.getBlock( new_unconfirmed_head_number).hash new_confirmed_head_hash = self.web3.eth.getBlock( new_confirmed_head_number).hash except AttributeError: self.log.critical( "RPC endpoint didn't return proper info for an existing block " "(%d,%d)" % (new_unconfirmed_head_number, new_confirmed_head_number)) self.log.critical( "It is possible that the blockchain isn't fully synced. " "This often happens when Parity is run with --fast or --warp sync." ) self.log.critical( "Can't continue - check status of the ethereum node.") sys.exit(1) self.cm.set_head(new_unconfirmed_head_number, new_unconfirmed_head_hash, new_confirmed_head_number, new_confirmed_head_hash) if not self.wait_sync_event.is_set( ) and new_unconfirmed_head_number == current_block: self.wait_sync_event.set()
def process_payment( # pylint: disable=too-many-branches iou: Optional[IOU], pathfinding_service: PathfindingService, service_fee: TokenAmount, one_to_n_address: Address, ) -> None: if service_fee == 0: return if iou is None: raise exceptions.MissingIOU # Basic IOU validity checks if not is_same_address(iou.receiver, pathfinding_service.address): raise exceptions.WrongIOURecipient( expected=pathfinding_service.address) if iou.chain_id != pathfinding_service.chain_id: raise exceptions.UnsupportedChainID( expected=pathfinding_service.chain_id) if iou.one_to_n_address != one_to_n_address: raise exceptions.WrongOneToNAddress(expected=one_to_n_address, got=iou.one_to_n_address) if not iou.is_signature_valid(): raise exceptions.InvalidSignature # Compare with known IOU active_iou = pathfinding_service.database.get_iou(sender=iou.sender, claimed=False) if active_iou: if active_iou.expiration_block != iou.expiration_block: raise exceptions.UseThisIOU(iou=active_iou) expected_amount = active_iou.amount + service_fee else: claimed_iou = pathfinding_service.database.get_iou( sender=iou.sender, expiration_block=iou.expiration_block, claimed=True) if claimed_iou: raise exceptions.IOUAlreadyClaimed min_expiry = pathfinding_service.web3.eth.blockNumber + MIN_IOU_EXPIRY if iou.expiration_block < min_expiry: raise exceptions.IOUExpiredTooEarly(min_expiry=min_expiry) expected_amount = service_fee if iou.amount < expected_amount: raise exceptions.InsufficientServicePayment( expected_amount=expected_amount) # Check client's deposit in UserDeposit contract udc = pathfinding_service.user_deposit_contract latest_block = pathfinding_service.web3.eth.blockNumber udc_balance = get_pessimistic_udc_balance( udc=udc, address=iou.sender, from_block=latest_block - pathfinding_service.required_confirmations, to_block=latest_block, ) required_deposit = round(expected_amount * UDC_SECURITY_MARGIN_FACTOR_PFS) if udc_balance < required_deposit: raise exceptions.DepositTooLow(required_deposit=required_deposit) log.info( "Received service fee", sender=iou.sender, expected_amount=expected_amount, total_amount=iou.amount, added_amount=expected_amount - service_fee, ) # Save latest IOU iou.claimed = False pathfinding_service.database.upsert_iou(iou)
def open_channel(self, receiver_address: str, deposit: int): """ Attempts to open a new channel to the receiver with the given deposit. Blocks until the creation transaction is found in a pending block or timeout is reached. The new channel state is returned. """ assert isinstance(receiver_address, str) assert isinstance(deposit, int) assert deposit > 0 token_balance = self.context.token.call().balanceOf(self.context.address) if token_balance < deposit: log.error( 'Insufficient tokens available for the specified deposit ({}/{})' .format(token_balance, deposit) ) return None current_block = self.context.web3.eth.blockNumber log.info('Creating channel to {} with an initial deposit of {} @{}'.format( receiver_address, deposit, current_block )) data = decode_hex(self.context.address) + decode_hex(receiver_address) tx = create_signed_contract_transaction( self.context.private_key, self.context.token, 'transfer', [ self.context.channel_manager.address, deposit, data ] ) self.context.web3.eth.sendRawTransaction(tx) log.debug('Waiting for channel creation event on the blockchain...') filters = { '_sender_address': self.context.address, '_receiver_address': receiver_address } event = get_event_blocking( self.context.channel_manager, 'ChannelCreated', from_block=current_block + 1, to_block='latest', argument_filters=filters ) if event: log.debug('Event received. Channel created in block {}.'.format(event['blockNumber'])) assert is_same_address(event['args']['_sender_address'], self.context.address) assert is_same_address(event['args']['_receiver_address'], receiver_address) channel = Channel( self.context, self.context.address, receiver_address, event['blockNumber'], event['args']['_deposit'], on_settle=lambda c: self.channels.remove(c) ) self.channels.append(channel) else: log.error('Error: No event received.') channel = None return channel
def test_get_contract_instance(deployed_safe_math): safe_math_package, address = deployed_safe_math contract_instance = safe_math_package.get_contract_instance( "SafeMathLib", address) assert contract_instance.abi is not False assert is_same_address(contract_instance.address, address)
def test_sign_close_contract(channel_manager_contract: Contract): sig = sign_close(RECEIVER_PRIVATE_KEY, SENDER_ADDR, 315832, 13, channel_manager_contract.address) receiver_recovered = channel_manager_contract.call( ).extractClosingSignature(SENDER_ADDR, 315832, 13, sig) assert is_same_address(receiver_recovered, RECEIVER_ADDR)
def test_sign_balance_proof_contract(channel_manager_contract: Contract): sig = sign_balance_proof(SENDER_PRIVATE_KEY, RECEIVER_ADDR, 37, 15, channel_manager_contract.address) sender_recovered = channel_manager_contract.call( ).extractBalanceProofSignature(RECEIVER_ADDR, 37, 15, sig) assert is_same_address(sender_recovered, SENDER_ADDR)
def sync_channels(self): """ Merges locally available channel information, including their current balance signatures, with channel information available on the blockchain to make up for local data loss. Naturally, balance signatures cannot be recovered from the blockchain. """ filters = {'_sender_address': self.context.address} create = get_logs( self.context.channel_manager, 'ChannelCreated', argument_filters=filters ) topup = get_logs( self.context.channel_manager, 'ChannelToppedUp', argument_filters=filters ) close = get_logs( self.context.channel_manager, 'ChannelCloseRequested', argument_filters=filters ) settle = get_logs( self.context.channel_manager, 'ChannelSettled', argument_filters=filters ) channel_key_to_channel = {} def get_channel(event) -> Channel: sender = to_checksum_address(event['args']['_sender_address']) receiver = to_checksum_address(event['args']['_receiver_address']) block = event['args'].get('_open_block_number', event['blockNumber']) assert is_same_address(sender, self.context.address) return channel_key_to_channel.get((sender, receiver, block), None) for c in self.channels: channel_key_to_channel[(c.sender, c.receiver, c.block)] = c for e in create: c = get_channel(e) if c: c.deposit = e['args']['_deposit'] else: c = Channel( self.context, to_checksum_address(e['args']['_sender_address']), to_checksum_address(e['args']['_receiver_address']), e['blockNumber'], e['args']['_deposit'], on_settle=lambda channel: self.channels.remove(channel) ) assert is_same_address(c.sender, self.context.address) channel_key_to_channel[(c.sender, c.receiver, c.block)] = c for e in topup: c = get_channel(e) c.deposit += e['args']['_added_deposit'] for e in close: # Requested closed, not actual closed. c = get_channel(e) c.update_balance(e['args']['_balance']) c.state = Channel.State.settling for e in settle: c = get_channel(e) c.state = Channel.State.closed # Forget closed channels. self.channels = [ c for c in channel_key_to_channel.values() if c.state != Channel.State.closed ] log.debug('Synced a total of {} channels.'.format(len(self.channels)))
def is_suitable_channel(channel: Channel, receiver: str, value: int): return (channel.deposit - channel.balance >= value and is_same_address(channel.receiver, receiver))
def get_channel(event) -> Channel: sender = to_checksum_address(event['args']['_sender_address']) receiver = to_checksum_address(event['args']['_receiver_address']) block = event['args'].get('_open_block_number', event['blockNumber']) assert is_same_address(sender, self.context.address) return channel_key_to_channel.get((sender, receiver, block), None)
def test_withdraw_state(contract_params, channel_params, uraiden_instance, token_instance, get_channel, get_block, print_gas): (sender, receiver, open_block_number) = get_channel()[:3] deposit = channel_params['deposit'] balance1 = 20 balance2 = deposit balance_message_hash = balance_proof_hash(receiver, open_block_number, balance1, uraiden_instance.address) balance_msg_sig, addr = sign.check(balance_message_hash, tester.k2) assert is_same_address(addr, sender) # Memorize balances for tests uraiden_pre_balance = token_instance.call().balanceOf( uraiden_instance.address) sender_pre_balance = token_instance.call().balanceOf(sender) receiver_pre_balance = token_instance.call().balanceOf(receiver) txn_hash = uraiden_instance.transact({ "from": receiver }).withdraw(open_block_number, balance1, balance_msg_sig) # Check channel info channel_info = uraiden_instance.call().getChannelInfo( sender, receiver, open_block_number) # deposit assert channel_info[1] == deposit assert channel_info[2] == 0 assert channel_info[3] == 0 assert channel_info[4] == balance1 # Check token balances post withrawal uraiden_balance = uraiden_pre_balance - balance1 assert token_instance.call().balanceOf( uraiden_instance.address) == uraiden_balance assert token_instance.call().balanceOf(sender) == sender_pre_balance assert token_instance.call().balanceOf( receiver) == receiver_pre_balance + balance1 print_gas(txn_hash, 'withdraw') balance_message_hash = balance_proof_hash(receiver, open_block_number, balance2, uraiden_instance.address) balance_msg_sig, addr = sign.check(balance_message_hash, tester.k2) assert is_same_address(addr, sender) txn_hash = uraiden_instance.transact({ "from": receiver }).withdraw(open_block_number, balance2, balance_msg_sig) channel_info = uraiden_instance.call().getChannelInfo( sender, receiver, open_block_number) # deposit assert channel_info[1] == deposit assert channel_info[2] == 0 assert channel_info[3] == 0 assert channel_info[4] == balance2 # Check token balances post withrawal uraiden_balance = uraiden_pre_balance - deposit assert token_instance.call().balanceOf( uraiden_instance.address) == uraiden_balance assert token_instance.call().balanceOf(sender) == sender_pre_balance assert token_instance.call().balanceOf( receiver) == receiver_pre_balance + deposit print_gas(txn_hash, 'withdraw')
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_config): node1, node2 = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(node1), node1.raiden.default_registry.address, token_address, ) api1 = RaidenAPI(node1.raiden) api2 = RaidenAPI(node2.raiden) registry_address = node1.raiden.default_registry.address # nodes don't have a channel, so they are not healthchecking assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN assert not api1.get_channel_list(registry_address, token_address, api2.address) # open is a synchronous api api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address) channels = api1.get_channel_list(registry_address, token_address, api2.address) assert len(channels) == 1 channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED event_list1 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert event_list1 == [] token_events = api1.get_token_network_events( token_address, channel12.open_transaction.finished_block_number, ) assert token_events[0]['event'] == EVENT_CHANNEL_NEW registry_address = api1.raiden.default_registry.address # Load the new state with the deposit api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) # let's make sure it's idempotent api1.set_total_channel_deposit( registry_address, token_address, api2.address, deposit, ) channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_OPENED assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit assert channel12.our_state.contract_balance == deposit assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12] # there is a channel open, they must be healthchecking each other assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE event_list2 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert any( (event['event'] == EVENT_CHANNEL_NEW_BALANCE and is_same_address( event['args']['registry_address'], to_normalized_address(registry_address), ) and is_same_address( event['args']['participant'], to_normalized_address(api1.address), )) for event in event_list2) api1.channel_close(registry_address, token_address, api2.address) # Load the new state with the channel closed channel12 = get_channelstate(node1, node2, token_network_identifier) event_list3 = api1.get_channel_events( channel12.identifier, channel12.open_transaction.finished_block_number, ) assert len(event_list3) > len(event_list2) assert any((event['event'] == EVENT_CHANNEL_CLOSED and is_same_address( event['args']['registry_address'], to_normalized_address(registry_address), ) and is_same_address( event['args']['closing_address'], to_normalized_address(api1.address), )) for event in event_list3) assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED settlement_block = ( channel12.close_transaction.finished_block_number + channel12.settle_timeout + 10 # arbitrary number of additional blocks, used to wait for the settle() call ) wait_until_block(node1.raiden.chain, settlement_block) # Load the new state with the channel settled channel12 = get_channelstate(node1, node2, token_network_identifier) assert channel.get_status(channel12) == CHANNEL_STATE_SETTLED
def test_token_network_registry( deploy_client: JSONRPCClient, contract_manager: ContractManager, token_network_registry_address: TokenNetworkRegistryAddress, token_contract_name: str, ) -> None: proxy_manager = ProxyManager( rpc_client=deploy_client, contract_manager=contract_manager, metadata=ProxyManagerMetadata( token_network_registry_deployed_at=GENESIS_BLOCK_NUMBER, filters_start_at=GENESIS_BLOCK_NUMBER, ), ) confirmed_block_identifier = deploy_client.get_confirmed_blockhash() token_network_registry_proxy = proxy_manager.token_network_registry( token_network_registry_address, block_identifier=confirmed_block_identifier) assert (token_network_registry_proxy.settlement_timeout_min( BLOCK_ID_LATEST) == TEST_SETTLE_TIMEOUT_MIN) assert (token_network_registry_proxy.settlement_timeout_max( BLOCK_ID_LATEST) == TEST_SETTLE_TIMEOUT_MAX) assert (token_network_registry_proxy.get_token_network_created( block_identifier=BLOCK_ID_LATEST) == 0) bad_token_address = make_token_address() # Registering a non-existing token network should fail with pytest.raises(AddressWithoutCode): token_network_registry_proxy.add_token( token_address=bad_token_address, channel_participant_deposit_limit=TokenAmount(UINT256_MAX), token_network_deposit_limit=TokenAmount(UINT256_MAX), given_block_identifier=confirmed_block_identifier, ) test_token = deploy_token( deploy_client=deploy_client, contract_manager=contract_manager, initial_amount=TokenAmount(1000), decimals=0, token_name="TKN", token_symbol="TKN", token_contract_name=token_contract_name, ) test_token_address = TokenAddress(to_canonical_address(test_token.address)) # Check the proper exception is raised if the token does not comply to the # ERC20 interface. In this case the token does not have the totalSupply() # function implemented #3697 which is validated in the smart contract. with patch.object(Token, "total_supply", return_value=None): with pytest.raises(InvalidToken): token_network_registry_proxy.add_token( token_address=test_token_address, channel_participant_deposit_limit=TokenAmount(UINT256_MAX), token_network_deposit_limit=TokenAmount(UINT256_MAX), given_block_identifier=deploy_client.get_confirmed_blockhash(), ) # Register a valid token preblockhash = deploy_client.get_confirmed_blockhash() token_network_address = token_network_registry_proxy.add_token( token_address=test_token_address, channel_participant_deposit_limit=TokenAmount(UINT256_MAX), token_network_deposit_limit=TokenAmount(UINT256_MAX), given_block_identifier=preblockhash, ) assert token_network_address is not None assert (token_network_registry_proxy.get_token_network_created( block_identifier=BLOCK_ID_LATEST) == 1) # Re-registering the same token should fail with a recoverable error # because it is a race condition. with pytest.raises(RaidenRecoverableError): token_network_registry_proxy.add_token( token_address=test_token_address, channel_participant_deposit_limit=TokenAmount(UINT256_MAX), token_network_deposit_limit=TokenAmount(UINT256_MAX), given_block_identifier=preblockhash, ) logs = token_network_registry_proxy.filter_token_added_events() assert is_same_address(logs[0]["args"]["token_address"], test_token.address) assert is_same_address(logs[0]["args"]["token_network_address"], token_network_address) assert (token_network_registry_proxy.get_token_network( bad_token_address, BLOCK_ID_LATEST) is None) result_address = token_network_registry_proxy.get_token_network( test_token_address, BLOCK_ID_LATEST) assert result_address assert to_normalized_address(result_address) == to_normalized_address( token_network_address) with pytest.raises(ValueError): assert token_network_registry_proxy.get_token_network( None, BLOCK_ID_LATEST # type: ignore ) # These are not registered token addresses assert (token_network_registry_proxy.get_token_network( bad_token_address, BLOCK_ID_LATEST) is None) assert (token_network_registry_proxy.get_token_network( test_token_address, BLOCK_ID_LATEST) is not None) address = token_network_registry_proxy.get_token_network( TokenAddress(token_network_address), BLOCK_ID_LATEST) assert address is None
def test_channel_opening( client: Client, web3: Web3, make_account, channel_manager_contract, token_contract, mine_sync_event, wait_for_blocks, use_tester, state_db_path ): receiver1_privkey = make_account(RECEIVER_ETH_ALLOWANCE, RECEIVER_TOKEN_ALLOWANCE) receiver2_privkey = make_account(RECEIVER_ETH_ALLOWANCE, RECEIVER_TOKEN_ALLOWANCE) receiver_address = privkey_to_addr(receiver1_privkey) # make sure channel_manager1 is terminated properly, otherwise Blockchain will be running # in the background, ruining other tests' results channel_manager1 = ChannelManager( web3, channel_manager_contract, token_contract, receiver1_privkey, n_confirmations=5, state_filename=state_db_path ) start_channel_manager(channel_manager1, use_tester, mine_sync_event) channel_manager2 = ChannelManager( web3, channel_manager_contract, token_contract, receiver2_privkey, n_confirmations=5, state_filename=state_db_path ) start_channel_manager(channel_manager2, use_tester, mine_sync_event) channel_manager1.wait_sync() channel_manager2.wait_sync() blockchain = channel_manager1.blockchain channel = client.open_channel(receiver_address, 10) # should be in unconfirmed channels wait_for_blocks(1) gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) not in channel_manager1.channels assert (channel.sender, channel.block) in channel_manager1.unconfirmed_channels channel_rec = channel_manager1.unconfirmed_channels[channel.sender, channel.block] assert is_same_address(channel_rec.receiver, receiver_address) assert is_same_address(channel_rec.sender, channel.sender) assert channel_rec.mtime == channel_rec.ctime # should be confirmed after n blocks wait_for_blocks(blockchain.n_confirmations) gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager1.channels channel_rec = channel_manager1.channels[channel.sender, channel.block] assert is_same_address(channel_rec.receiver, receiver_address) assert is_same_address(channel_rec.sender, channel.sender) assert channel_rec.balance == 0 assert channel_rec.last_signature is None assert channel_rec.is_closed is False assert channel_rec.settle_timeout == -1 # should not appear in other channel manager assert (channel.sender, channel.block) not in channel_manager2.channels assert (channel.sender, channel.block) not in channel_manager2.unconfirmed_channels channel_manager1.stop() channel_manager2.stop()
def test_EIP2930_transaction_sender_extraction(typed_txn_fixture): transaction = BerlinTransactionBuilder.deserialize(decode_hex(typed_txn_fixture['signed'])) key = keys.PrivateKey(typed_txn_fixture['key']) signer_by_key = key.public_key.to_canonical_address() assert is_same_address(transaction.sender, signer_by_key)
def test_verify_closing_sign(channel_manager_address: str): sig = sign_close(RECEIVER_PRIVATE_KEY, SENDER_ADDR, 315832, 13, channel_manager_address) receiver_recovered = verify_closing_sig(SENDER_ADDR, 315832, 13, sig, channel_manager_address) assert is_same_address(receiver_recovered, RECEIVER_ADDR)