def test_balance_proof_invalid_attributes(): invalid_nonces = [-10, 0, UINT64_MAX + 1] invalid_transferred_amounts = [-1, UINT256_MAX + 1] invalid_locksroots = [urandom(31), urandom(33)] invalid_signatures = [urandom(64), urandom(66)] properties_unsigned = factories.BalanceProofProperties() properties_signed = factories.BalanceProofSignedStateProperties( signature=urandom(64)) for properties in (properties_unsigned, properties_signed): for nonce in invalid_nonces: with pytest.raises(ValueError): factories.create(factories.replace(properties, nonce=nonce)) for amount in invalid_transferred_amounts: with pytest.raises(ValueError): factories.create( factories.replace(properties, transferred_amount=amount)) for locksroot in invalid_locksroots: with pytest.raises(ValueError): factories.create( factories.replace(properties, locksroot=locksroot)) for signature in invalid_signatures: with pytest.raises(ValueError): factories.create( factories.replace(properties_signed, signature=signature))
def test_get_secret(): secret1 = factories.make_secret() secret2 = factories.make_secret() secrethash3 = factories.make_keccak_hash() secrethash4 = factories.make_keccak_hash() lock_state = HashTimeLockState(amount=10, expiration=10, secrethash=factories.UNIT_SECRETHASH) end_state = factories.create(factories.NettingChannelEndStateProperties()) end_state = factories.replace( end_state, secrethashes_to_lockedlocks={secrethash3: lock_state}, secrethashes_to_unlockedlocks={ sha3(secret1): UnlockPartialProofState(lock=lock_state, secret=secret1) }, secrethashes_to_onchain_unlockedlocks={ sha3(secret2): UnlockPartialProofState(lock=lock_state, secret=secret2) }, ) assert get_secret( end_state, sha3(secret1)) == secret1 # known secret from offchain unlock assert get_secret( end_state, sha3(secret2)) == secret2 # known secret from offchain unlock assert get_secret(end_state, secrethash3) is None # known lock but not unlocked yet assert get_secret(end_state, secrethash4) is None # unknown secrethash
def test_events_for_onchain_secretreveal_with_unfit_channels(): settle = factories.TransactionExecutionStatusProperties() settled = factories.create( factories.NettingChannelStateProperties(settle_transaction=settle)) secret = factories.UNIT_SECRET block_hash = factories.make_block_hash() events = events_for_onchain_secretreveal(settled, secret, 10, block_hash) assert not events, "Secret reveal event should not be generated for settled channel" settle = factories.replace(settle, result=TransactionExecutionStatus.FAILURE) unusable = factories.create( factories.NettingChannelStateProperties(settle_transaction=settle)) events = events_for_onchain_secretreveal(unusable, secret, 10, block_hash) assert not events, "Secret reveal event should not be generated for unusable channel."
def update(self, amount, lock): self._pending_locks = channel.compute_locks_with(self._pending_locks, lock) if self.properties: self.properties = factories.replace( self.properties, locked_amount=self.properties.locked_amount + amount, locksroot=compute_locksroot(self._pending_locks), nonce=self.properties.nonce + 1, ) else: self.properties = factories.BalanceProofProperties( transferred_amount=0, locked_amount=amount, nonce=1, locksroot=compute_locksroot(self._pending_locks), canonical_identifier=self._canonical_identifier, )
def update(self, amount, lockhash): self._merkletree = channel.compute_merkletree_with( self._merkletree, lockhash) if self.properties: self.properties = factories.replace( self.properties, locked_amount=self.properties.locked_amount + amount, locksroot=merkleroot(self._merkletree), nonce=self.properties.nonce + 1, ) else: self.properties = factories.BalanceProofProperties( transferred_amount=0, locked_amount=amount, nonce=1, locksroot=merkleroot(self._merkletree), canonical_identifier=self._canonical_identifier, )
def make_mediated_transfer_state_change( transfer_amount: int, allocated_fee_amount: FeeAmount, channel_capacity: TokenAmount) -> TransitionResult: transfer = factories.replace(factories.UNIT_TRANSFER_DESCRIPTION, amount=transfer_amount) channel_set = factories.make_channel_set_from_amounts( [channel_capacity]) mediating_channel = channel_set.channels[0] pnrg = random.Random() nodeaddresses_to_networkstates = { mediating_channel.partner_state.address: NetworkState.REACHABLE } addresses_to_channel = { ( UNIT_TOKEN_NETWORK_ADDRESS, mediating_channel.partner_state.address, ): mediating_channel } routes = [[ factories.UNIT_OUR_ADDRESS, mediating_channel.partner_state.address, factories.UNIT_TRANSFER_TARGET, ]] init_action = factories.initiator_make_init_action( channels=channel_set, routes=routes, transfer=transfer, estimated_fee=allocated_fee_amount, ) return initiator_manager.handle_init( payment_state=None, state_change=init_action, addresses_to_channel=addresses_to_channel, nodeaddresses_to_networkstates=nodeaddresses_to_networkstates, pseudo_random_generator=pnrg, block_number=BlockNumber(1), )
def test_request_monitoring() -> None: properties = factories.BalanceProofSignedStateProperties( pkey=PARTNER_PRIVKEY) balance_proof = factories.create(properties) partner_signed_balance_proof = SignedBlindedBalanceProof.from_balance_proof_signed_state( balance_proof) request_monitoring = RequestMonitoring( balance_proof=partner_signed_balance_proof, non_closing_participant=ADDRESS, reward_amount=TokenAmount(55), signature=EMPTY_SIGNATURE, monitoring_service_contract_address=MSC_ADDRESS, ) assert request_monitoring request_monitoring.sign(signer) as_dict = DictSerializer.serialize(request_monitoring) assert DictSerializer.deserialize(as_dict) == request_monitoring # RequestMonitoring can be created directly from BalanceProofSignedState direct_created = RequestMonitoring.from_balance_proof_signed_state( balance_proof=balance_proof, non_closing_participant=ADDRESS, reward_amount=TokenAmount(55), monitoring_service_contract_address=MSC_ADDRESS, ) # `direct_created` is not signed while request_monitoring is assert DictSerializer().serialize( direct_created) != DictSerializer().serialize(request_monitoring) direct_created.sign(signer) # Instances created from same balance proof are equal assert direct_created == request_monitoring other_balance_proof = factories.create( factories.replace(properties, message_hash=keccak(b"2"))) other_instance = RequestMonitoring.from_balance_proof_signed_state( balance_proof=other_balance_proof, non_closing_participant=ADDRESS, reward_amount=TokenAmount(55), monitoring_service_contract_address=MSC_ADDRESS, ) other_instance.sign(signer) # different balance proof ==> non-equality assert other_instance != request_monitoring # test signature verification assert request_monitoring.non_closing_signature reward_proof_data = pack_reward_proof( token_network_address=request_monitoring.balance_proof. token_network_address, chain_id=request_monitoring.balance_proof.chain_id, reward_amount=request_monitoring.reward_amount, monitoring_service_contract_address=MSC_ADDRESS, non_closing_participant=ADDRESS, non_closing_signature=request_monitoring.non_closing_signature, ) assert request_monitoring.reward_proof_signature assert recover(reward_proof_data, request_monitoring.reward_proof_signature) == ADDRESS blinded_data = pack_signed_balance_proof( msg_type=MessageTypeId.BALANCE_PROOF_UPDATE, nonce=request_monitoring.balance_proof.nonce, balance_hash=request_monitoring.balance_proof.balance_hash, additional_hash=request_monitoring.balance_proof.additional_hash, canonical_identifier=factories.make_canonical_identifier( chain_identifier=request_monitoring.balance_proof.chain_id, token_network_address=request_monitoring.balance_proof. token_network_address, channel_identifier=request_monitoring.balance_proof. channel_identifier, ), partner_signature=request_monitoring.balance_proof.signature, ) assert recover(blinded_data, request_monitoring.non_closing_signature) == ADDRESS balance_proof_data = pack_balance_proof( nonce=request_monitoring.balance_proof.nonce, balance_hash=request_monitoring.balance_proof.balance_hash, additional_hash=request_monitoring.balance_proof.additional_hash, canonical_identifier=factories.make_canonical_identifier( chain_identifier=request_monitoring.balance_proof.chain_id, token_network_address=request_monitoring.balance_proof. token_network_address, channel_identifier=request_monitoring.balance_proof. channel_identifier, ), ) assert (recover( balance_proof_data, request_monitoring.balance_proof.signature) == PARTNER_ADDRESS) assert request_monitoring.verify_request_monitoring( PARTNER_ADDRESS, ADDRESS)
def test_request_monitoring(): properties = factories.BalanceProofSignedStateProperties( pkey=PARTNER_PRIVKEY) balance_proof = factories.create(properties) partner_signed_balance_proof = SignedBlindedBalanceProof.from_balance_proof_signed_state( balance_proof) request_monitoring = RequestMonitoring( onchain_balance_proof=partner_signed_balance_proof, reward_amount=55) assert request_monitoring with pytest.raises(ValueError): request_monitoring.to_dict() request_monitoring.sign(signer) as_dict = request_monitoring.to_dict() assert RequestMonitoring.from_dict(as_dict) == request_monitoring request_monitoring_packed = request_monitoring.packed() request_monitoring.pack(request_monitoring_packed) assert RequestMonitoring.unpack( request_monitoring_packed) == request_monitoring # RequestMonitoring can be created directly from BalanceProofSignedState direct_created = RequestMonitoring.from_balance_proof_signed_state( balance_proof, reward_amount=55) with pytest.raises(ValueError): # equality test uses `validated` packed format assert direct_created == request_monitoring direct_created.sign(signer) # Instances created from same balance proof are equal assert direct_created == request_monitoring other_balance_proof = factories.create( factories.replace(properties, message_hash=sha3(b"2"))) other_instance = RequestMonitoring.from_balance_proof_signed_state( other_balance_proof, reward_amount=55) other_instance.sign(signer) # different balance proof ==> non-equality assert other_instance != request_monitoring # test signature verification reward_proof_data = pack_reward_proof( canonical_identifier=factories.make_canonical_identifier( chain_identifier=request_monitoring.balance_proof.chain_id, token_network_address=request_monitoring.balance_proof. token_network_address, channel_identifier=request_monitoring.balance_proof. channel_identifier, ), reward_amount=request_monitoring.reward_amount, nonce=request_monitoring.balance_proof.nonce, ) assert recover(reward_proof_data, request_monitoring.reward_proof_signature) == ADDRESS blinded_data = pack_balance_proof_update( nonce=request_monitoring.balance_proof.nonce, balance_hash=request_monitoring.balance_proof.balance_hash, additional_hash=request_monitoring.balance_proof.additional_hash, canonical_identifier=factories.make_canonical_identifier( chain_identifier=request_monitoring.balance_proof.chain_id, token_network_address=request_monitoring.balance_proof. token_network_address, channel_identifier=request_monitoring.balance_proof. channel_identifier, ), partner_signature=request_monitoring.balance_proof.signature, ) assert recover(blinded_data, request_monitoring.non_closing_signature) == ADDRESS balance_proof_data = pack_balance_proof( nonce=request_monitoring.balance_proof.nonce, balance_hash=request_monitoring.balance_proof.balance_hash, additional_hash=request_monitoring.balance_proof.additional_hash, canonical_identifier=factories.make_canonical_identifier( chain_identifier=request_monitoring.balance_proof.chain_id, token_network_address=request_monitoring.balance_proof. token_network_address, channel_identifier=request_monitoring.balance_proof. channel_identifier, ), ) assert (recover( balance_proof_data, request_monitoring.balance_proof.signature) == PARTNER_ADDRESS) assert request_monitoring.verify_request_monitoring( PARTNER_ADDRESS, ADDRESS)
def test_message_handler(): """ Test for MessageHandler.on_message and the different methods it dispatches into. Each of them results in a call to a RaidenService method, which is checked with a Mock. """ our_address = factories.make_address() sender_privkey, sender = factories.make_privkey_address() signer = LocalSigner(sender_privkey) message_handler = MessageHandler() mock_raiden = Mock( address=our_address, default_secret_registry=Mock(is_secret_registered=lambda **_: False) ) properties = factories.LockedTransferProperties(sender=sender, pkey=sender_privkey) locked_transfer = factories.create(properties) message_handler.on_message(mock_raiden, locked_transfer) assert_method_call(mock_raiden, "mediate_mediated_transfer", locked_transfer) locked_transfer_for_us = factories.create(factories.replace(properties, target=our_address)) message_handler.on_message(mock_raiden, locked_transfer_for_us) assert_method_call(mock_raiden, "target_mediated_transfer", locked_transfer_for_us) mock_raiden.default_secret_registry.is_secret_registered = lambda **_: True message_handler.on_message(mock_raiden, locked_transfer) assert not mock_raiden.mediate_mediated_transfer.called assert not mock_raiden.target_mediated_transfer.called mock_raiden.default_secret_registry.is_secret_registered = lambda **_: False params = dict( payment_identifier=13, amount=14, expiration=15, secrethash=factories.UNIT_SECRETHASH ) secret_request = SecretRequest( message_identifier=16, signature=factories.EMPTY_SIGNATURE, **params ) secret_request.sign(signer) receive = ReceiveSecretRequest(sender=sender, **params) message_handler.on_message(mock_raiden, secret_request) assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive]) secret = factories.make_secret() reveal_secret = RevealSecret( message_identifier=100, signature=factories.EMPTY_SIGNATURE, secret=secret ) reveal_secret.sign(signer) receive = ReceiveSecretReveal(sender=sender, secret=secret) message_handler.on_message(mock_raiden, reveal_secret) assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive]) properties: factories.UnlockProperties = factories.create_properties( factories.UnlockProperties() ) unlock = factories.create(properties) unlock.sign(signer) balance_proof = factories.make_signed_balance_proof_from_unsigned( factories.create(properties.balance_proof), signer, unlock.message_hash ) receive = ReceiveUnlock( message_identifier=properties.message_identifier, secret=properties.secret, balance_proof=balance_proof, sender=sender, ) message_handler.on_message(mock_raiden, unlock) assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive]) properties: factories.LockExpiredProperties = factories.create_properties( factories.LockExpiredProperties() ) lock_expired = factories.create(properties) lock_expired.sign(signer) balance_proof = factories.make_signed_balance_proof_from_unsigned( factories.create(properties.balance_proof), signer, lock_expired.message_hash ) receive = ReceiveLockExpired( balance_proof=balance_proof, message_identifier=properties.message_identifier, secrethash=properties.secrethash, # pylint: disable=no-member sender=sender, ) message_handler.on_message(mock_raiden, lock_expired) assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive]) delivered = Delivered(delivered_message_identifier=1, signature=factories.EMPTY_SIGNATURE) delivered.sign(signer) receive = ReceiveDelivered(message_identifier=1, sender=sender) message_handler.on_message(mock_raiden, delivered) assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive]) processed = Processed(message_identifier=42, signature=factories.EMPTY_SIGNATURE) processed.sign(signer) receive = ReceiveProcessed(message_identifier=42, sender=sender) message_handler.on_message(mock_raiden, processed) assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])