def test_save_and_load_channel(ms_database): token_network_address = get_random_address() ms_database.conn.execute("INSERT INTO token_network (address) VALUES (?)", [token_network_address]) for update_status in [ None, OnChainUpdateStatus( update_sender_address=Address(get_random_address()), nonce=random.randint(0, UINT256_MAX), ), ]: channel = Channel( token_network_address=TokenNetworkAddress(token_network_address), identifier=ChannelID(random.randint(0, UINT256_MAX)), participant1=Address(get_random_address()), participant2=Address(get_random_address()), settle_timeout=random.randint(0, UINT256_MAX), state=random.choice(list(ChannelState)), closing_block=BlockNumber(random.randint(0, UINT256_MAX)), closing_participant=Address(get_random_address()), closing_tx_hash=TransactionHash('%d' % random.randint(0, UINT64_MAX)), claim_tx_hash=TransactionHash('%d' % random.randint(0, UINT64_MAX)), update_status=update_status, ) ms_database.upsert_channel(channel) loaded_channel = ms_database.get_channel( token_network_address=channel.token_network_address, channel_id=channel.identifier) assert loaded_channel == channel
def f(): contract_address = get_random_address() channel_identifier = get_random_identifier() balance_hash_data = '%d' % random.randint(0, UINT64_MAX) additional_hash_data = '%d' % random.randint(0, UINT64_MAX) balance_hash = encode_hex((balance_hash_data.encode())) nonce = random.randint(0, UINT64_MAX) additional_hash = encode_hex(keccak(additional_hash_data.encode())) chain_id = 1 privkey = get_random_privkey() privkey_non_closing = get_random_privkey() bp = HashedBalanceProof( # type: ignore channel_identifier=channel_identifier, token_network_address=contract_address, chain_id=chain_id, balance_hash=balance_hash, nonce=nonce, additional_hash=additional_hash, priv_key=privkey, ) monitor_request = UnsignedMonitorRequest.from_balance_proof( bp, reward_amount=TokenAmount(0)).sign(privkey_non_closing) return monitor_request, privkey, privkey_non_closing
def test_process_payment_errors(pathfinding_service_web3_mock, web3, deposit_to_udc, create_account, get_private_key): pfs = pathfinding_service_web3_mock pfs.service_fee = 1 sender = create_account() privkey = get_private_key(sender) # expires too early iou = make_iou(privkey, pfs.address, expiration_block=web3.eth.blockNumber + 5) with pytest.raises(exceptions.IOUExpiredTooEarly): process_payment(iou, pfs) # it fails it the no deposit is in the UDC iou = make_iou(privkey, pfs.address) with pytest.raises(exceptions.DepositTooLow): process_payment(iou, pfs) # must succeed if we add enough deposit to UDC deposit_to_udc(sender, 10) iou = make_iou(privkey, pfs.address) process_payment(iou, pfs) # wrong recipient iou = make_iou(privkey, get_random_address()) with pytest.raises(exceptions.WrongIOURecipient): process_payment(iou, pfs) # payment too low pfs.service_fee = 2 iou = make_iou(privkey, pfs.address) with pytest.raises(exceptions.InsufficientServicePayment): process_payment(iou, pfs)
def test_process_payment_errors( pathfinding_service_mocked_listeners, web3, deposit_to_udc, create_account, get_private_key, ): pfs = pathfinding_service_mocked_listeners pfs.service_fee = 1 sender = create_account() privkey = get_private_key(sender) # expires too early iou = make_iou(privkey, pfs.address, expiration_block=web3.eth.blockNumber + 5) with pytest.raises(exceptions.IOUExpiredTooEarly): process_payment(iou, pfs) # it fails it the no deposit is in the UDC iou = make_iou(privkey, pfs.address) with pytest.raises(exceptions.DepositTooLow): process_payment(iou, pfs) # must succeed if we add enough deposit to UDC deposit_to_udc(sender, 10) iou = make_iou(privkey, pfs.address) process_payment(iou, pfs) # malformed iou = make_iou(privkey, pfs.address) del iou['amount'] with pytest.raises(exceptions.InvalidRequest): process_payment(iou, pfs) # wrong recipient iou = make_iou(privkey, get_random_address()) with pytest.raises(exceptions.WrongIOURecipient): process_payment(iou, pfs) # bad signature iou = make_iou(privkey, pfs.address) iou['signature'] = hex(int(iou['signature'], 16) + 1) with pytest.raises(exceptions.InvalidSignature): process_payment(iou, pfs) # payment too low pfs.service_fee = 2 iou = make_iou(privkey, pfs.address) with pytest.raises(exceptions.InsufficientServicePayment): process_payment(iou, pfs)
def test_crash(tmpdir, get_accounts, get_private_key, mockchain): # pylint: disable=too-many-locals """ Process blocks and compare results with/without crash A somewhat meaninful crash handling is simulated by not including the UpdatedHeadBlockEvent in every block. """ channel_identifier = ChannelID(3) c1, c2 = get_accounts(2) token_network_address = TokenNetworkAddress( to_canonical_address(get_random_address())) balance_proof = HashedBalanceProof( nonce=Nonce(1), transferred_amount=TokenAmount(2), priv_key=get_private_key(c1), channel_identifier=channel_identifier, token_network_address=token_network_address, chain_id=ChainID(1), additional_hash="0x%064x" % 0, locked_amount=0, locksroot=encode_hex(LOCKSROOT_OF_NO_LOCKS), ) monitor_request = balance_proof.get_monitor_request( get_private_key(c2), reward_amount=TokenAmount(0), msc_address=TEST_MSC_ADDRESS) events = [ [ ReceiveChannelOpenedEvent( token_network_address=token_network_address, channel_identifier=channel_identifier, participant1=c1, participant2=c2, settle_timeout=20, block_number=BlockNumber(0), ) ], [UpdatedHeadBlockEvent(BlockNumber(1))], [ ActionMonitoringTriggeredEvent( token_network_address=token_network_address, channel_identifier=channel_identifier, non_closing_participant=c2, ) ], [UpdatedHeadBlockEvent(BlockNumber(3))], ] mockchain(events) server_private_key = get_random_privkey() contracts = { CONTRACT_TOKEN_NETWORK_REGISTRY: ContractMock(), CONTRACT_MONITORING_SERVICE: ContractMock(), CONTRACT_USER_DEPOSIT: ContractMock(), CONTRACT_SERVICE_REGISTRY: ContractMock(), } def new_ms(filename): ms = MonitoringService( web3=Web3Mock(), private_key=server_private_key, contracts=contracts, db_filename=os.path.join(tmpdir, filename), ) msc = Mock() ms.context.monitoring_service_contract = msc ms.monitor_mock = msc.functions.monitor.return_value.transact # type: ignore ms.monitor_mock.return_value = bytes(0) # type: ignore return ms # initialize both monitoring services stable_ms = new_ms("stable.db") crashy_ms = new_ms("crashy.db") for ms in [stable_ms, crashy_ms]: ms.database.conn.execute( "INSERT INTO token_network(address) VALUES (?)", [to_checksum_address(token_network_address)], ) ms.context.ms_state.blockchain_state.token_network_addresses = [ token_network_address ] ms.database.upsert_monitor_request(monitor_request) ms.database.conn.commit() # process each block and compare results between crashy and stable ms for to_block in range(len(events)): crashy_ms = new_ms("crashy.db") # new instance to simulate crash stable_ms.monitor_mock.reset_mock() # clear calls from last block result_state: List[dict] = [] for ms in [stable_ms, crashy_ms]: ms._process_new_blocks(to_block) # pylint: disable=protected-access result_state.append( dict( blockchain_state=ms.context.ms_state.blockchain_state, db_dump=list(ms.database.conn.iterdump()), monitor_calls=ms.monitor_mock.mock_calls, )) # both instances should have the same state after processing for stable_state, crashy_state in zip(result_state[0].values(), result_state[1].values()): # do asserts for each key separately to get better error messages assert stable_state == crashy_state
def __init__(self, **kwargs): super().__init__(**kwargs) if "address" not in kwargs: self.address = get_random_address()