Esempio n. 1
0
def test_receive_payment_with_travel_rule_metadata_and_invalid_reference_id(
    sender_account: AccountResource,
    receiver_account: AccountResource,
    currency: str,
    hrp: str,
    stub_config: AppConfig,
    diem_client: jsonrpc.Client,
    pending_income_account: AccountResource,
    invalid_ref_id: Optional[str],
) -> None:
    """
    There is no way to create travel rule metadata with invalid reference id when the payment
    amount meets travel rule threshold, because the metadata signature is verified by transaction
    script.
    Also, if metadata signature is provided, transaction script will also verify it regardless
    whether the amount meets travel rule threshold, thus no need to test invalid metadata
    signature case.

    This test bypasses the transaction script validation by sending payment amount under the
    travel rule threshold without metadata signature, and receiver should handle it properly and refund.

    Test Plan:

    1. Generate a valid account identifier from receiver account as payee.
    2. Submit payment under travel rule threshold transaction from sender to receiver on-chain account.
    3. Wait for the transaction executed successfully.
    4. Assert the payment is refund eventually.

    Note: the refund payment will be received by pending income account of the MiniWallet Stub, because
    no account owns the original invalid payment transaction which is sent by test.

    """

    receiver_account_identifier = receiver_account.generate_account_identifier(
    )
    receiver_account_address = identifier.decode_account_address(
        receiver_account_identifier, hrp)

    sender_account_identifier = sender_account.generate_account_identifier()
    sender_address = identifier.decode_account_address(
        sender_account_identifier, hrp)
    metadata, _ = txnmetadata.travel_rule(invalid_ref_id, sender_address,
                                          amount)  # pyre-ignore
    original_payment_txn: jsonrpc.Transaction = stub_config.account.submit_and_wait_for_txn(
        diem_client,
        stdlib.encode_peer_to_peer_with_metadata_script(
            currency=utils.currency_code(currency),
            amount=amount,
            payee=receiver_account_address,
            metadata=metadata,
            metadata_signature=b"",
        ),
    )

    pending_income_account.wait_for_event(
        "created_transaction",
        status=Transaction.Status.completed,
        refund_diem_txn_version=original_payment_txn.version,
    )
    assert receiver_account.balance(currency) == 0
def test_travel_rule_metadata_and_sig_message(factory):
    cmd = factory.new_sender_payment_command()
    metadata, sig_msg = txnmetadata.travel_rule(
        cmd.payment.reference_id, cmd.sender_account_address(factory.hrp()),
        cmd.payment.action.amount)

    assert metadata == cmd.travel_rule_metadata(factory.hrp())
    assert sig_msg == cmd.travel_rule_metadata_signature_message(factory.hrp())
Esempio n. 3
0
def test_travel_rule_metadata():
    address = utils.account_address("f72589b71ff4f8d139674a3f7369c69b")
    metadata, sig_msg = txnmetadata.travel_rule("off chain reference id", address, 1000)

    assert metadata.hex() == "020001166f666620636861696e207265666572656e6365206964"
    assert (
        sig_msg.hex()
        == "020001166f666620636861696e207265666572656e6365206964f72589b71ff4f8d139674a3f7369c69be803000000000000404024244449454d5f41545445535424244040"
    )
Esempio n. 4
0
 def p2p_by_travel_rule(
     self,
     currency: str,
     amount: int,
     receiver_vasp_address: str,
     off_chain_reference_id: str,
     metadata_signature: bytes,
 ) -> jsonrpc.Transaction:
     metadata, _ = txnmetadata.travel_rule(
         off_chain_reference_id,
         self.config.vasp_account_address(),
         amount,
     )
     return self._p2p_transfer(currency, amount, receiver_vasp_address,
                               metadata, metadata_signature)
Esempio n. 5
0
def test_process_incoming_travel_rule_txn() -> None:
    account = create_account("fake_account")
    sender_addr = "46db232847705e05525db0336fd9f337"
    receiver_addr = "lrw_vasp"
    sender_subaddr = generate_new_subaddress(account.id)
    amount = 1000 * 1_000_000
    sender = account_address(sender_addr)
    sequence = 1
    currency = DiemCurrency.XUS
    blockchain_version = 1

    off_chain_reference_id = "off_chain_reference_id"
    metadata, _ = travel_rule(off_chain_reference_id, sender, amount)

    storage.add_transaction(
        amount=amount,
        currency=currency,
        payment_type=TransactionType.OFFCHAIN,
        status=TransactionStatus.OFF_CHAIN_READY,
        source_id=account.id,
        source_address=sender_addr,
        source_subaddress=sender_subaddr,
        destination_address=receiver_addr,
        reference_id=off_chain_reference_id,
    )

    process_incoming_transaction(
        sender_address=sender_addr,
        receiver_address=receiver_addr,
        sequence=sequence,
        amount=amount,
        currency=currency,
        metadata=diem_types.Metadata__TravelRuleMetadata.bcs_deserialize(
            metadata),
        blockchain_version=blockchain_version,
    )

    # successfully parse meta and sequence
    tx = storage.get_transaction_by_details(source_address=sender_addr,
                                            source_subaddress=sender_subaddr,
                                            sequence=sequence)
    assert tx is not None
    assert tx.sequence == sequence
    assert tx.blockchain_version == blockchain_version
Esempio n. 6
0
async def test_p2p_above_threshold_by_reference_id():
    client = create_client()
    faucet = Faucet(client)

    sender = await faucet.gen_account()
    receiver = await faucet.gen_account()
    await receiver.rotate_dual_attestation_info(client,
                                                base_url="http://localhost")

    amount = 20_000_000_000
    reference_id = str(uuid.uuid4())

    metadata, metadata_signing_msg = txnmetadata.travel_rule(
        reference_id, sender.account_address, amount)
    metadata_signature = receiver.compliance_key.sign(metadata_signing_msg)
    payload = stdlib.encode_peer_to_peer_with_metadata_script_function(
        currency=utils.currency_code(XUS),
        payee=receiver.account_address,
        amount=amount,
        metadata=metadata,
        metadata_signature=metadata_signature,
    )

    seq_num = await client.get_account_sequence(sender.account_address)
    txn = diem_types.RawTransaction(
        sender=sender.account_address,
        sequence_number=seq_num,
        payload=payload,
        max_gas_amount=1_000_000,
        gas_unit_price=0,
        gas_currency_code=XUS,
        expiration_timestamp_secs=int(time.time()) + 30,
        chain_id=chain_ids.TESTNET,
    )

    signed_txn = sender.sign(txn)
    await client.submit(signed_txn)
    executed_txn = await client.wait_for_transaction(signed_txn)
    assert executed_txn is not None
Esempio n. 7
0
    def send_transaction_travel_rule(
        self,
        currency: DiemCurrency,
        amount: int,
        source_sub_address: str,
        dest_vasp_address: str,
        dest_sub_address: str,
        off_chain_reference_id: str,
        metadata_signature: bytes,
    ) -> Tuple[int, int]:
        account_info = self.fetch_account_info()
        if not account_info:
            raise RuntimeError(f"Could not find account {self.address_str}")

        sender = utils.account_address(self.address_str)
        metadata, metadata_sig = txnmetadata.travel_rule(
            off_chain_reference_id, sender, amount
        )

        # sender constructs transaction after off chain communication
        script = stdlib.encode_peer_to_peer_with_metadata_script(
            currency=utils.currency_code(currency.value),
            payee=utils.account_address(dest_vasp_address),
            amount=amount,
            metadata=metadata,
            metadata_signature=metadata_signature,
        )

        tx = self._custody.create_transaction(
            self._custody_account_name,
            account_info.sequence_number,
            script,
            currency.value,
        )
        self._diem_client.submit(tx)

        onchain_tx = self._diem_client.wait_for_transaction(tx, 30)
        return onchain_tx.version, account_info.sequence_number
Esempio n. 8
0
def test_p2p_by_travel_rule():
    sender = context.generate(1)
    receiver = context.generate(2)
    faucet = testnet.Faucet(sender.jsonrpc_client)
    faucet.mint(sender.auth_key().hex(), 2_000_000_000,
                sender.config.gas_currency_code)
    faucet.mint(receiver.auth_key().hex(), 1_000,
                receiver.config.gas_currency_code)
    receiver.reset_dual_attestation_info()

    reference_id = "reference_id"
    amount = 1_800_000_000
    metadata, sig_msg = txnmetadata.travel_rule(
        reference_id,
        sender.config.vasp_account_address(),
        amount,
    )
    metadata_signature = receiver.config.compliance_private_key().sign(sig_msg)
    txn = sender.p2p_by_travel_rule(
        receiver.config.vasp_address,
        testnet.TEST_CURRENCY_CODE,
        amount,
        metadata,
        metadata_signature,
    )

    assert txn
    assert txn.transaction.sender.lower() == sender.config.vasp_address
    script = txn.transaction.script
    assert script.receiver.lower() == receiver.config.vasp_address
    assert script.amount == amount
    assert script.metadata_signature == metadata_signature.hex()

    metadata = diem_types.Metadata.bcs_deserialize(
        bytes.fromhex(script.metadata))
    assert isinstance(metadata, diem_types.Metadata__TravelRuleMetadata)
    assert metadata.value.value.off_chain_reference_id == reference_id
Esempio n. 9
0
def test_custodial_to_custodial_above_threshold():
    client = testnet.create_client()
    faucet = testnet.Faucet(client)

    sender_custodial = CustodialApp.create(faucet.gen_account())
    receiver_custodial = CustodialApp.create(faucet.gen_account())
    receiver_custodial.init_compliance_keys()

    intent_id = receiver_custodial.payment(user_id=0, amount=2_000_000_000)

    intent = identifier.decode_intent(intent_id, identifier.TDM)

    sender = sender_custodial.available_child_vasp()
    # sender & receiver communicate by off chain APIs
    off_chain_reference_id = "32323abc"
    metadata, metadata_signing_msg = txnmetadata.travel_rule(
        off_chain_reference_id, sender.account_address, intent.amount)
    metadata_signature = receiver_custodial.compliance_key.sign(
        metadata_signing_msg)

    # sender constructs transaction after off chain communication
    script = stdlib.encode_peer_to_peer_with_metadata_script(
        currency=utils.currency_code(intent.currency_code),
        payee=utils.account_address(intent.account_address),
        amount=intent.amount,
        metadata=metadata,
        metadata_signature=metadata_signature,
    )

    seq_num = client.get_account_sequence(sender.account_address)
    txn = create_transaction(sender, seq_num, script, intent.currency_code)

    signed_txn = sender.sign(txn)
    client.submit(signed_txn)
    executed_txn = client.wait_for_transaction(signed_txn)
    assert executed_txn is not None