예제 #1
0
    def test_cancel_multi_eon_swap(self):
        commit_eon(test_case=self, eon_number=1)

        advance_to_next_eon(test_case=self, eon_number=1)
        commit_eon(test_case=self, eon_number=2)

        buy_lqd_nonce = random.randint(1, 999999)
        sell_lqd_nonce = random.randint(1, 999999)

        total_remaining_eons = 5
        # make persistent swap
        buy_lqd = send_swap(  # Buy LQD at 0.5 ETH
            test_case=self,
            eon_number=2,
            account=self.testrpc_accounts[1],
            token=self.eth_token,
            token_swapped=self.lqd_token,
            amount=1,
            amount_swapped=2,
            nonce=buy_lqd_nonce,
            eon_count=total_remaining_eons)

        swap = Transfer.objects.filter(
            swap=True, wallet__token=self.eth_token).order_by('id')[0]
        swap_tx_id = swap.tx_id
        wallet_transfer_context = WalletTransferContext(wallet=swap.wallet,
                                                        transfer=None)
        recipient_transfer_context = WalletTransferContext(
            wallet=swap.recipient, transfer=None)

        wallet_funds_before = 1
        recipient_funds_before = 0

        # process swaps
        confirm_swaps_for_eon(operator_eon_number=2)
        cancel_finalize_swaps_for_eon(operator_eon_number=2)
        process_swaps_for_eon(operator_eon_number=2)

        # skip some eons
        for i in range(3, 5):
            # proceed to next eon
            advance_to_next_eon(test_case=self, eon_number=i - 1)
            commit_eon(test_case=self, eon_number=i)
            total_remaining_eons -= 1

            # process swaps
            confirm_swaps_for_eon(operator_eon_number=i)
            cancel_finalize_swaps_for_eon(operator_eon_number=i)
            process_swaps_for_eon(operator_eon_number=i)

            self.assertEqual(
                wallet_transfer_context.available_funds_at_eon(i, False),
                wallet_funds_before)
            self.assertEqual(
                recipient_transfer_context.available_funds_at_eon(i, False),
                recipient_funds_before)
            self.assertEqual(
                wallet_transfer_context.balance_as_of_eon(i).amount(),
                wallet_funds_before)

        swap = Transfer.objects.get(swap=True, tx_id=swap_tx_id, eon_number=4)
        freeze_swap(test_case=self,
                    swap=swap,
                    account=self.testrpc_accounts[1])
        swap = Transfer.objects.get(swap=True, tx_id=swap_tx_id, eon_number=4)
        cancel_swap(test_case=self,
                    swap=swap,
                    account=self.testrpc_accounts[1],
                    eon_count=total_remaining_eons)
        self.assertEqual(
            Transfer.objects.filter(tx_id=swap_tx_id,
                                    eon_number__gt=4,
                                    swap=True,
                                    voided=False).count(), 0)

        swap = Transfer.objects.filter(swap=True)[0]
        self.assertTrue(swap.cancelled)
        self.assertTrue(swap.processed)
        self.assertTrue(swap.appended)
        self.assertTrue(swap.sender_cancellation_active_state.
                        operator_signature is not None)

        # proceed to next eon
        advance_to_next_eon(test_case=self, eon_number=4)
        commit_eon(test_case=self, eon_number=5)
        total_remaining_eons -= 1

        # process swaps
        confirm_swaps_for_eon(operator_eon_number=5)
        cancel_finalize_swaps_for_eon(operator_eon_number=5)
        process_swaps_for_eon(operator_eon_number=5)

        swap = Transfer.objects.filter(swap=True)[0]
        self.assertTrue(swap.cancelled)
        self.assertTrue(swap.processed)
        self.assertTrue(swap.appended)
        self.assertEqual(swap.eon_number, 4)
        self.assertEqual(
            wallet_transfer_context.balance_as_of_eon(5).amount(),
            wallet_funds_before)

        self.assertEqual(
            wallet_transfer_context.available_funds_at_eon(5, False),
            wallet_funds_before)
        self.assertEqual(
            recipient_transfer_context.available_funds_at_eon(5, False),
            recipient_funds_before)

        # make opposite swap
        sell_lqd = send_swap(  # Sell LQD at 0.5 ETH
            test_case=self,
            eon_number=5,
            account=self.testrpc_accounts[2],
            token=self.lqd_token,
            token_swapped=self.eth_token,
            amount=2,
            amount_swapped=1,
            nonce=sell_lqd_nonce,
            eon_count=1)

        # process swaps
        confirm_swaps_for_eon(operator_eon_number=5)
        cancel_finalize_swaps_for_eon(operator_eon_number=5)
        process_swaps_for_eon(operator_eon_number=5)

        self.assertEqual(
            wallet_transfer_context.available_funds_at_eon(5, False),
            wallet_funds_before)
        self.assertEqual(
            recipient_transfer_context.available_funds_at_eon(5, False),
            recipient_funds_before)

        commit_eon(test_case=self, eon_number=5)
예제 #2
0
def place_parallel_withdrawals(test_case: RPCTestCase,
                               token,
                               wallet_address,
                               current_eon,
                               dishonest=False):
    token_commitment = TokenCommitment.objects.get(
        token=token, root_commitment__eon_number=current_eon - 1)

    wallet = Wallet.objects.get(token=token,
                                address=remove_0x_prefix(wallet_address))
    wallet_transfer_context = WalletTransferContext(wallet=wallet,
                                                    transfer=None)
    allotment = wallet_transfer_context.balance_as_of_eon(
        eon_number=current_eon - 1)

    passive_checksum, passive_amount, passive_marker = wallet_transfer_context.get_passive_values(
        eon_number=current_eon - 1)

    available_balance = wallet_transfer_context.loosely_available_funds_at_eon(
        eon_number=current_eon,
        current_eon_number=current_eon,
        is_checkpoint_created=True,
        only_appended=True)

    overdraw = dishonest and available_balance < allotment.amount()

    if overdraw:
        total_draw = max(available_balance, allotment.amount()) // 4
    else:
        total_draw = min(available_balance, allotment.amount()) // 4

    total_amount = 0

    if (total_draw == 0):
        return (total_amount, [], False)

    withdrawal_amounts = [total_draw // 4, total_draw // 2, total_draw // 4]

    for withdrawal_amount in withdrawal_amounts:

        cyan([
            wallet.address, wallet.token.address, withdrawal_amount,
            available_balance
        ])

        test_case.contract_interface.withdraw(
            token_address=wallet.token.address,
            wallet=wallet.address,
            active_state_checksum=crypto.zfill(
                allotment.active_state_checksum()),
            trail=int(allotment.merkle_proof_trail),
            allotment_chain=[
                crypto.zfill(crypto.decode_hex(checksum))
                for checksum in long_string_to_list(
                    allotment.merkle_proof_hashes, 64)
            ],
            membership_chain=[
                crypto.zfill(crypto.decode_hex(checksum))
                for checksum in long_string_to_list(
                    token_commitment.membership_hashes, 64)
            ],
            values=csf_to_list(allotment.merkle_proof_values, int),
            exclusive_allotment_interval=[
                int(allotment.left), int(allotment.right)
            ],
            withdrawal_amount=int(withdrawal_amount),
            passive_checksum=passive_checksum,
            passive_amount=passive_amount,
            passive_marker=passive_marker)

        total_amount += int(withdrawal_amount)

    return (total_amount, withdrawal_amounts, overdraw)
예제 #3
0
파일: swap.py 프로젝트: niespodd/nocust-hub
def init_swap_challenge(test_case: RPCTestCase, swap: Transfer, eon_number):
    sender_transfer_context = WalletTransferContext(wallet=swap.wallet,
                                                    transfer=None)

    if Transfer.objects.filter(eon_number=swap.eon_number - 1,
                               tx_id=swap.tx_id).exists():
        starting_balance = int(swap.sender_starting_balance)
    else:
        starting_balance = int(
            sender_transfer_context.starting_balance_in_eon(eon_number))

    transfers_list_nonce_index_map = {}
    transfers_list = sender_transfer_context.authorized_transfers_list_shorthand(
        only_appended=True,
        force_append=False,
        eon_number=eon_number,
        last_transfer_is_finalized=True,
        index_map=transfers_list_nonce_index_map,
        starting_balance=starting_balance)

    sender_active_state = sender_transfer_context.last_appended_active_state(
        eon_number=eon_number)

    transfer_tree = TransactionMerkleTree(transfers_list)
    transfer_index = transfers_list_nonce_index_map.get(int(swap.nonce))
    transfer_node = transfer_tree.merkle_tree_leaf_map.get(transfer_index)
    transfer_proof = [
        node.get('hash')
        for node in calculate_merkle_proof(transfer_index, transfer_node)
    ]

    test_case.assertEqual(sender_active_state.tx_set_hash,
                          crypto.hex_value(transfer_tree.root_hash()))

    tx_set_root = crypto.zfill(
        crypto.decode_hex(sender_active_state.tx_set_hash))
    deltas = [
        int(sender_active_state.updated_spendings),
        int(sender_active_state.updated_gains)
    ]

    test_case.assertTrue(
        test_case.contract_interface.check_merkle_membership_proof(
            trail=int(transfer_index),
            chain=[crypto.zfill(x) for x in transfer_proof],
            node=transfer_node.get('hash'),
            merkle_root=tx_set_root))

    token_commitment = TokenCommitment.objects.get(
        token=swap.wallet.token, root_commitment__eon_number=eon_number + 1)

    v, r, s = sender_active_state.operator_signature.vrs()

    # swap_sender_balance = sender_transfer_context.balance_as_of_eon(
    #     eon_number)
    sender_balance = sender_transfer_context.balance_as_of_eon(eon_number + 1)

    passive_checksum, passive_amount, passive_marker = sender_transfer_context.get_passive_values(
        eon_number=eon_number + 1)

    swap_order = [
        int(swap.amount),  # sell
        int(swap.amount_swapped),  # buy
        # int(swap_sender_balance.right - swap_sender_balance.left),
        starting_balance,  # balance
        int(swap.nonce)
    ]  # nonce

    chain_transition_checksum = test_case.contract_interface.check_proof_of_transition_agreement(
        token_address=swap.wallet.token.address,
        holder=swap.wallet.address,
        trail_identifier=swap.wallet.trail_identifier,
        eon_number=eon_number,
        tx_set_root=tx_set_root,
        deltas=deltas,
        attester=settings.HUB_OWNER_ACCOUNT_ADDRESS,
        r=crypto.uint256(r),
        s=crypto.uint256(s),
        v=v)
    test_case.assertEqual(crypto.hex_value(sender_active_state.checksum()),
                          crypto.hex_value(chain_transition_checksum))

    node_hash = merkle_tree.leaf_hash(
        merkle_tree.wallet_leaf_inner_hash, {
            'contract': settings.HUB_LQD_CONTRACT_ADDRESS,
            'token': swap.wallet.token.address,
            'wallet': swap.wallet.address,
            'left': sender_balance.left,
            'right': sender_balance.right,
            'active_state_checksum': sender_active_state.checksum(),
            'passive_checksum': passive_checksum,
            'passive_amount': passive_amount,
            'passive_marker': passive_marker,
        })
    checkpoint = RootCommitment.objects.get(eon_number=eon_number + 1)
    test_case.contract_interface.check_exclusive_allotment_proof(
        allotment_trail=int(sender_balance.merkle_proof_trail),
        membership_trail=swap.wallet.token.trail,
        node=node_hash,
        merkle_root=crypto.decode_hex(checkpoint.merkle_root),
        allotment_chain=[
            crypto.zfill(crypto.decode_hex(v)) for v in long_string_to_list(
                sender_balance.merkle_proof_hashes, 64)
        ],
        membership_chain=[
            crypto.zfill(crypto.decode_hex(checksum))
            for checksum in long_string_to_list(
                token_commitment.membership_hashes, 64)
        ],
        value=csf_to_list(sender_balance.merkle_proof_values, int),
        left=int(sender_balance.left),
        right=int(sender_balance.right))

    test_case.contract_interface.issue_swap_challenge(
        token_pair=[swap.wallet.token.address, swap.recipient.token.address],
        wallet=swap.wallet.address,
        swap_order=swap_order,
        sender_tx_recipient_trails=[
            swap.wallet.trail_identifier,
            int(transfer_index), swap.recipient.trail_identifier
        ],
        allotment_chain=[
            crypto.zfill(crypto.decode_hex(v)) for v in long_string_to_list(
                sender_balance.merkle_proof_hashes, 64)
        ],
        membership_chain=[
            crypto.zfill(crypto.decode_hex(checksum))
            for checksum in long_string_to_list(
                token_commitment.membership_hashes, 64)
        ],
        tx_chain=[crypto.zfill(x) for x in transfer_proof],
        values=csf_to_list(sender_balance.merkle_proof_values, int),
        l_r=[int(sender_balance.left),
             int(sender_balance.right)],
        tx_set_root=tx_set_root,
        deltas=deltas,
        passive_checksum=passive_checksum,
        passive_amount=passive_amount,
        passive_marker=passive_marker)