Exemplo n.º 1
0
def finalize_swap(test_case: RPCTestCase,
                  swap: Transfer,
                  account,
                  expected_status=status.HTTP_200_OK,
                  eon_count=1):
    print('FINALIZING {} ({}/{})'.format(swap.id, int(swap.amount),
                                         int(swap.amount_swapped)))

    finalization_authorizations = []
    test_case.assertTrue(swap.complete)

    recipient_view_context = WalletTransferContext(wallet=swap.recipient,
                                                   transfer=swap)

    tx_set_tree = recipient_view_context.authorized_transfers_tree(
        only_appended=False, force_append=True)
    tx_set_hash = crypto.hex_value(tx_set_tree.root_hash())
    transfer_index = tx_set_tree.merkle_tree_nonce_map.get(swap.nonce)
    transfer_proof = tx_set_tree.proof(transfer_index)

    highest_spendings, highest_gains = recipient_view_context.off_chain_actively_sent_received_amounts(
        eon_number=swap.eon_number, only_appended=False)

    print("Finalize spent {} gained {}".format(highest_spendings,
                                               highest_gains))

    for state in ActiveState.objects.filter(wallet=swap.recipient,
                                            eon_number=swap.eon_number):
        print(state.id)
        print("Finalize spent {} gained {}".format(state.updated_spendings,
                                                   state.updated_gains))

    finalization_active_state = ActiveState(
        wallet=swap.recipient,
        updated_spendings=highest_spendings + swap.amount_swapped,
        updated_gains=highest_gains + swap.amount_swapped,
        tx_set_hash=tx_set_hash,
        tx_set_proof_hashes=transfer_proof,
        tx_set_index=transfer_index,
        eon_number=swap.eon_number)

    finalization_authorizations.append({
        'value':
        encode_signature(
            sign_message(finalization_active_state.checksum(),
                         account.get('pk')))
    })

    for i in range(1, eon_count):
        future_spent_gained = max(highest_spendings,
                                  highest_gains) + swap.amount_swapped + 1
        empty_tx_set_hash = crypto.hex_value(NODE_CACHE[0]['hash'])
        finalization_active_state = ActiveState(
            wallet=swap.recipient,
            updated_spendings=future_spent_gained,
            updated_gains=future_spent_gained,
            tx_set_hash=empty_tx_set_hash,
            # any dummy value
            tx_set_proof_hashes='',
            # any dummy value
            tx_set_index=0,
            eon_number=swap.eon_number + i)

        finalization_authorizations.append({
            'value':
            encode_signature(
                sign_message(finalization_active_state.checksum(),
                             account.get('pk')))
        })

    # Make API Request
    url = reverse('finalize-swap-endpoint', kwargs={'pk': swap.id})
    data = {'finalization_signature': finalization_authorizations}

    # Send tx to server
    x = datetime.now()
    response = test_case.client.put(url, data, format='json')
    y = datetime.now()
    delta = y - x

    # Ensure the transaction was recorded
    test_case.assertEqual(response.status_code, expected_status,
                          response.content)

    print('FINALIZE Time: {}s'.format(delta))

    # Log time delta
    return delta
Exemplo n.º 2
0
def cancel_swap(test_case: RPCTestCase,
                swap: Transfer,
                account,
                expected_status=status.HTTP_200_OK,
                eon_count=1):
    sender_cancellation_authorizations = []
    recipient_cancellation_authorizations = []

    sender_view_context = WalletTransferContext(wallet=swap.wallet,
                                                transfer=swap)

    tx_set_tree = sender_view_context.authorized_transfers_tree(
        only_appended=False,
        force_append=False,
        assume_active_state_exists=True)
    tx_set_hash = crypto.hex_value(tx_set_tree.root_hash())
    transfer_index = tx_set_tree.merkle_tree_nonce_map.get(swap.nonce)
    transfer_proof = tx_set_tree.proof(transfer_index)

    sender_highest_spendings, sender_highest_gains = sender_view_context.off_chain_actively_sent_received_amounts(
        eon_number=swap.eon_number, only_appended=False)

    matched_out, _ = swap.matched_amounts()

    sender_highest_gains += swap.amount - matched_out

    sender_cancellation_active_state = ActiveState(
        wallet=swap.wallet,
        updated_spendings=sender_highest_spendings,
        updated_gains=sender_highest_gains,
        tx_set_hash=tx_set_hash,
        tx_set_proof_hashes=transfer_proof,
        tx_set_index=transfer_index,
        eon_number=swap.eon_number)

    recipient_view_context = WalletTransferContext(wallet=swap.recipient,
                                                   transfer=swap)

    tx_set_tree = recipient_view_context.authorized_transfers_tree(
        only_appended=False,
        force_append=False,
        assume_active_state_exists=True)
    tx_set_hash = crypto.hex_value(tx_set_tree.root_hash())
    transfer_index = tx_set_tree.merkle_tree_nonce_map.get(swap.nonce)
    transfer_proof = tx_set_tree.proof(transfer_index)

    recipient_highest_spendings, recipient_highest_gains = recipient_view_context.off_chain_actively_sent_received_amounts(
        eon_number=swap.eon_number, only_appended=False)

    recipient_cancellation_active_state = ActiveState(
        wallet=swap.recipient,
        updated_spendings=recipient_highest_spendings + swap.amount_swapped,
        updated_gains=recipient_highest_gains + swap.amount_swapped,
        tx_set_hash=tx_set_hash,
        tx_set_proof_hashes=transfer_proof,
        tx_set_index=transfer_index,
        eon_number=swap.eon_number)

    sender_cancellation_authorizations.append({
        'value':
        encode_signature(
            sign_message(sender_cancellation_active_state.checksum(),
                         account.get('pk')))
    })
    recipient_cancellation_authorizations.append({
        'value':
        encode_signature(
            sign_message(recipient_cancellation_active_state.checksum(),
                         account.get('pk')))
    })

    for i in range(1, eon_count):
        empty_tx_set_hash = crypto.hex_value(NODE_CACHE[0]['hash'])
        sender_future_spent_gained = max(sender_highest_spendings,
                                         sender_highest_gains) + 1
        recipient_future_spent_gained = max(
            recipient_highest_spendings,
            recipient_highest_gains) + swap.amount_swapped + 1

        sender_cancellation_active_state = ActiveState(
            wallet=swap.wallet,
            updated_spendings=sender_future_spent_gained,
            updated_gains=sender_future_spent_gained,
            tx_set_hash=empty_tx_set_hash,
            # any dummy value
            tx_set_proof_hashes='',
            # any dummy value
            tx_set_index=0,
            eon_number=swap.eon_number + i)

        recipient_cancellation_active_state = ActiveState(
            wallet=swap.recipient,
            updated_spendings=recipient_future_spent_gained,
            updated_gains=recipient_future_spent_gained,
            tx_set_hash=empty_tx_set_hash,
            # any dummy value
            tx_set_proof_hashes='',
            # any dummy value
            tx_set_index=0,
            eon_number=swap.eon_number + i)

        sender_cancellation_authorizations.append({
            'value':
            encode_signature(
                sign_message(sender_cancellation_active_state.checksum(),
                             account.get('pk')))
        })
        recipient_cancellation_authorizations.append({
            'value':
            encode_signature(
                sign_message(recipient_cancellation_active_state.checksum(),
                             account.get('pk')))
        })

    # Make API Request
    url = reverse('cancel-swap-endpoint', kwargs={'pk': swap.id})
    data = {
        'sender_cancellation_signature': sender_cancellation_authorizations,
        'recipient_cancellation_signature':
        recipient_cancellation_authorizations
    }

    # Send tx to server
    x = datetime.now()
    response = test_case.client.put(url, data, format='json')
    y = datetime.now()
    delta = y - x

    # Ensure the transaction was recorded
    test_case.assertEqual(response.status_code, expected_status,
                          response.content)

    print('CANCEL Time: {}s'.format(delta))

    # Log time delta
    return delta
Exemplo n.º 3
0
def send_swap(test_case: RPCTestCase,
              eon_number,
              account,
              token,
              token_swapped,
              amount,
              amount_swapped,
              nonce,
              expected_status=status.HTTP_201_CREATED,
              eon_count=1,
              sell_order=True):
    # Sender account
    sender_wallet = Wallet.objects.get(address=remove_0x_prefix(
        account.get('address')),
                                       token=token)
    # Recipient account
    recipient_wallet = Wallet.objects.get(address=remove_0x_prefix(
        account.get('address')),
                                          token=token_swapped)

    sender_wallet_context = WalletTransferContext(wallet=sender_wallet,
                                                  transfer=None)
    recipient_wallet_context = WalletTransferContext(wallet=recipient_wallet,
                                                     transfer=None)

    initial_sender_balance = sender_wallet_context.available_funds_at_eon(
        eon_number=eon_number, only_appended=False)
    initial_recipient_balance = recipient_wallet_context.available_funds_at_eon(
        eon_number=eon_number, only_appended=False)

    if initial_sender_balance < amount:
        send_transaction(test_case=test_case,
                         eon_number=eon_number,
                         sender=testrpc_accounts.accounts[0],
                         recipient=account,
                         amount=amount - initial_sender_balance,
                         nonce=random.randint(1, 999999),
                         token=token)
    if initial_sender_balance > amount:
        # clear sender account
        send_transaction(test_case=test_case,
                         eon_number=eon_number,
                         sender=account,
                         recipient=testrpc_accounts.accounts[0],
                         amount=initial_sender_balance - amount,
                         nonce=random.randint(1, 999999),
                         token=token)
    if initial_recipient_balance > 0:
        # clear recipient account
        send_transaction(test_case=test_case,
                         eon_number=eon_number,
                         sender=account,
                         recipient=testrpc_accounts.accounts[0],
                         amount=initial_recipient_balance,
                         nonce=random.randint(1, 999999),
                         token=token_swapped)

    sender_balance = sender_wallet_context.available_funds_at_eon(
        eon_number=eon_number, only_appended=False)
    recipient_balance = recipient_wallet_context.available_funds_at_eon(
        eon_number=eon_number, only_appended=False)

    test_case.assertEqual(sender_balance, amount)
    test_case.assertEqual(recipient_balance, 0)

    debit_balance_signatures = []
    debit_signatures = []
    credit_balance_signatures = []
    credit_signatures = []
    fulfillment_signatures = []

    for i in range(eon_count):
        swap = Transfer(wallet=sender_wallet,
                        amount=amount,
                        eon_number=eon_number + i,
                        recipient=recipient_wallet,
                        amount_swapped=amount_swapped,
                        nonce=nonce,
                        processed=False,
                        complete=False,
                        swap=True)

        sender_wallet_context = WalletTransferContext(wallet=sender_wallet,
                                                      transfer=swap)
        recipient_wallet_context = WalletTransferContext(
            wallet=recipient_wallet, transfer=swap)

        sender_highest_spent, sender_highest_gained = sender_wallet_context.off_chain_actively_sent_received_amounts(
            eon_number=eon_number + i, only_appended=False)

        if i == 0:
            tx_set_tree = sender_wallet_context.authorized_transfers_tree(
                only_appended=False, force_append=True)
        else:
            tx_set_tree = WalletTransferContext.authorized_transfers_tree_from_list(
                [
                    swap.shorthand(sender_wallet_context,
                                   is_last_transfer=True,
                                   starting_balance=sender_balance)
                ])

        tx_set_hash = hex_value(tx_set_tree.root_hash())

        debiting_active_state = ActiveState(
            wallet=sender_wallet,
            updated_spendings=sender_highest_spent + amount,
            updated_gains=sender_highest_gained,
            eon_number=eon_number + i,
            tx_set_hash=tx_set_hash)
        debiting_active_state_authorization = sign_message(
            debiting_active_state.checksum(), account.get('pk'))

        debiting_active_state_signature = Signature(
            wallet=sender_wallet,
            checksum=hex_value(debiting_active_state.checksum()),
            value=encode_signature(debiting_active_state_authorization))

        test_case.assertTrue(debiting_active_state_signature.is_valid())

        debit_concise_balance_marker = MinimumAvailableBalanceMarker(
            wallet=sender_wallet, eon_number=eon_number + i, amount=0)
        debit_concise_balance_marker_authorization = sign_message(
            debit_concise_balance_marker.checksum(), account.get('pk'))

        debit_concise_balance_marker_signature = Signature(
            wallet=sender_wallet,
            checksum=hex_value(debit_concise_balance_marker.checksum()),
            value=encode_signature(debit_concise_balance_marker_authorization))

        test_case.assertTrue(debit_concise_balance_marker_signature.is_valid())

        recipient_highest_spent, recipient_highest_gained = recipient_wallet_context.off_chain_actively_sent_received_amounts(
            eon_number=eon_number + i, only_appended=False)

        if i == 0:
            tx_set_tree = recipient_wallet_context.authorized_transfers_tree(
                only_appended=False, force_append=True)
        else:
            tx_set_tree = WalletTransferContext.authorized_transfers_tree_from_list(
                [
                    swap.shorthand(recipient_wallet_context,
                                   is_last_transfer=True,
                                   starting_balance=recipient_balance)
                ])

        tx_set_hash = hex_value(tx_set_tree.root_hash())

        crediting_active_state = ActiveState(
            wallet=recipient_wallet,
            updated_spendings=recipient_highest_spent,
            updated_gains=recipient_highest_gained,
            eon_number=eon_number + i,
            tx_set_hash=tx_set_hash)
        crediting_active_state_authorization = sign_message(
            crediting_active_state.checksum(), account.get('pk'))

        crediting_active_state_signature = Signature(
            wallet=recipient_wallet,
            checksum=hex_value(crediting_active_state.checksum()),
            value=encode_signature(crediting_active_state_authorization))

        test_case.assertTrue(crediting_active_state_signature.is_valid())

        credit_concise_balance_marker = MinimumAvailableBalanceMarker(
            wallet=recipient_wallet, eon_number=eon_number + i, amount=0)
        credit_concise_balance_marker_authorization = sign_message(
            credit_concise_balance_marker.checksum(), account.get('pk'))

        credit_concise_balance_marker_signature = Signature(
            wallet=recipient_wallet,
            checksum=hex_value(credit_concise_balance_marker.checksum()),
            value=encode_signature(
                credit_concise_balance_marker_authorization))

        test_case.assertTrue(
            credit_concise_balance_marker_signature.is_valid())

        swap.processed, swap.complete = True, True

        if i == 0:
            tx_set_tree = recipient_wallet_context.authorized_transfers_tree(
                only_appended=False, force_append=True)
        else:
            tx_set_tree = WalletTransferContext.authorized_transfers_tree_from_list(
                [
                    swap.shorthand(recipient_wallet_context,
                                   is_last_transfer=True,
                                   starting_balance=0)
                ])

        tx_set_hash = hex_value(tx_set_tree.root_hash())

        recipient_fulfillment_active_state = ActiveState(
            wallet=recipient_wallet,
            updated_spendings=recipient_highest_spent,
            updated_gains=recipient_highest_gained + amount_swapped,
            eon_number=eon_number + i,
            tx_set_hash=tx_set_hash)
        recipient_fulfillment_active_state_authorization = sign_message(
            recipient_fulfillment_active_state.checksum(), account.get('pk'))
        swap.processed, swap.complete = False, False

        recipient_fulfillment_active_state_signature = Signature(
            wallet=recipient_wallet,
            checksum=hex_value(recipient_fulfillment_active_state.checksum()),
            value=encode_signature(
                recipient_fulfillment_active_state_authorization))

        test_case.assertTrue(
            recipient_fulfillment_active_state_signature.is_valid())

        debit_balance_signatures.append({
            'value':
            encode_signature(debit_concise_balance_marker_authorization)
        })
        debit_signatures.append(
            {'value': encode_signature(debiting_active_state_authorization)})
        credit_balance_signatures.append({
            'value':
            encode_signature(credit_concise_balance_marker_authorization)
        })
        credit_signatures.append(
            {'value': encode_signature(crediting_active_state_authorization)})
        fulfillment_signatures.append({
            'value':
            encode_signature(recipient_fulfillment_active_state_authorization)
        })

    # Make API Request
    url = reverse('swap-endpoint')
    data = {
        'debit_signature': debit_signatures,
        'debit_balance_signature': debit_balance_signatures,
        'credit_signature': credit_signatures,
        'credit_balance_signature': credit_balance_signatures,
        'credit_fulfillment_signature': fulfillment_signatures,
        'eon_number': eon_number,
        'amount': amount,
        'amount_swapped': amount_swapped,
        'nonce': nonce,
        'wallet': {
            'address': sender_wallet.address,
            'token': sender_wallet.token.address,
        },
        'recipient': {
            'address': recipient_wallet.address,
            'token': recipient_wallet.token.address,
        },
        'sell_order': sell_order
    }

    # Send tx to server
    x = datetime.now()
    response = test_case.client.post(url, data, format='json')
    y = datetime.now()
    delta = y - x

    # Ensure the transaction was recorded
    test_case.assertEqual(response.status_code, expected_status,
                          response.content)

    print('SWAP Time: {}s for {}/{}'.format(delta, amount, amount_swapped))

    # assert that swap created for current eon is confirmed
    tx = json.loads(response.content)
    swap = Transfer.objects.get(id=tx['id'])
    test_case.assertEqual(swap.eon_number, eon_number)
    test_case.assertTrue(swap.is_signed_by_operator())

    # Log time delta
    return delta