コード例 #1
0
ファイル: models.py プロジェクト: niespodd/nocust-hub
 def digest(self):
     return remove_0x_prefix(
         encode_hex(
             hash_array([
                 decode_hex(self.terms_of_service_digest),
                 decode_hex(self.privacy_policy_digest)
             ])))
コード例 #2
0
def normalize_tokens(transactions):
    return normalize_size(transactions, {
        'left': 0,
        'merkle_root': '0x0000000000000000000000000000000000000000',
        'right': 0,
        'hash': crypto.decode_hex(ZERO_CHECKSUM)
    })
コード例 #3
0
def normalize_transfers(transfers, upper_bound):
    return normalize_size(
        transfers, {
            'wallet': '0x0000000000000000000000000000000000000000',
            'left': int(upper_bound),
            'right': int(upper_bound),
            'nonce': 0,
            'hash': crypto.decode_hex(ZERO_CHECKSUM)
        })
コード例 #4
0
ファイル: tx_merkle_tree.py プロジェクト: niespodd/nocust-hub
def normalize_transactions(transactions):
    return normalize_size(
        transactions, {
            'wallet': '0x0000000000000000000000000000000000000000',
            'amount': 0,
            'recipient_trail_identifier': 0,
            'nonce': 0,
            'hash': crypto.decode_hex(ZERO_CHECKSUM)
        })
コード例 #5
0
    def checksum(self):
        representation = [
            keccak(crypto.address(settings.HUB_LQD_CONTRACT_ADDRESS)),
            keccak(crypto.address(self.wallet.token.address)),
            keccak(crypto.address(self.wallet.address)),
            crypto.uint64(self.wallet.trail_identifier if self.wallet.
                          trail_identifier is not None else 0),
            crypto.uint256(self.eon_number),
            crypto.decode_hex(self.tx_set_hash),
            crypto.uint256(self.updated_spendings),
            crypto.uint256(self.updated_gains)
        ]

        return crypto.hash_array(representation)
コード例 #6
0
def build_stack_from_cache(merkle_hash_cache, merkle_height_cache):
    if merkle_hash_cache == '' or merkle_hash_cache is None:
        return []

    merkle_hash_stack = merkle_hash_cache.split(',')
    merkle_height_stack = merkle_height_cache.split(',')

    assert (len(merkle_hash_stack) == len(merkle_height_stack))

    merkle_hash_stack = [crypto.decode_hex(item) for item in merkle_hash_stack]
    merkle_height_stack = [int(item) for item in merkle_height_stack]

    return [{
        'hash': hash_value,
        'height': height_value
    } for hash_value, height_value in zip(merkle_hash_stack,
                                          merkle_height_stack)]
コード例 #7
0
 def is_valid(self):
     return crypto.verify_message_signature(crypto.address(self.wallet.address),
                                            crypto.decode_hex(
                                                self.checksum),
                                            self.vrs())
コード例 #8
0
ファイル: withdrawal.py プロジェクト: niespodd/nocust-hub
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)
コード例 #9
0
def respond_to_challenges():
    contract_interface = NOCUSTContractInterface()

    contract_interface.get_current_eon_number()

    latest_root_commitment = RootCommitment.objects\
        .all()\
        .order_by('eon_number')\
        .last()

    if latest_root_commitment is None:
        return

    with Challenge.global_lock():
        challenges = Challenge.objects\
            .filter(rebuted=False, eon_number__lte=latest_root_commitment.eon_number)\
            .order_by('block')
        for challenge in challenges:
            token = challenge.wallet.token
            challenge_entry_token = token.address

            if challenge.wallet.token != challenge.recipient.token:
                try:
                    tp = TokenPair.objects.get(
                        token_from=challenge.wallet.token,
                        token_to=challenge.recipient.token)
                except TokenPair.DoesNotExist:
                    logger.warning(
                        "Skipping challenge for {}. token pair not found!".
                        format(challenge.wallet.address))
                    continue

                token = challenge.recipient.token
                challenge_entry_token = to_checksum_address(tp.conduit)

            challenge_entry = contract_interface.get_challenge_record(
                token_address=challenge_entry_token,
                recipient=challenge.recipient.address,
                sender=challenge.wallet.address)

            if not challenge_entry.challengeStage:
                logger.warning(
                    "Skipping answered challenge for {}. Where is the answer tx_id?"
                    .format(challenge.wallet.address))
                continue

            try:
                recipient_balance = ExclusiveBalanceAllotment.objects.get(
                    wallet=challenge.recipient,
                    eon_number=challenge.eon_number)
            except ExclusiveBalanceAllotment.DoesNotExist:
                logger.error("Could not find balance for {} at eon {}.".format(
                    challenge.wallet.address, challenge.eon_number))
                send_admin_email(subject='DISPUTE! NO BALANCE!',
                                 content='{}'.format(challenge.wallet.address))
                return

            token_commitment = TokenCommitment.objects.get(
                token=token, root_commitment__eon_number=challenge.eon_number)

            # state update challenge
            if challenge.wallet.token == challenge.recipient.token and challenge.wallet.address == challenge.recipient.address:

                v_0, r_0, s_0 = recipient_balance.wallet_v_r_s()
                v_1, r_1, s_1 = recipient_balance.operator_v_r_s()

                recipient_transfer_context = WalletTransferContext(
                    wallet=challenge.recipient, transfer=None)

                passive_checksum, passive_amount, passive_marker = recipient_transfer_context.get_passive_values(
                    eon_number=challenge_entry.initialStateEon)

                logger.info(
                    "Answering challenge for {} with balance {}.".format(
                        challenge.wallet.address, recipient_balance.amount()))
                logger.info("{}{}{}, {}{}{}".format(v_0, r_0, s_0, v_1, r_1,
                                                    s_1))
                send_admin_email(subject='DISPUTE! Sate Update.',
                                 content='{}'.format(challenge.wallet.address))

                # TODO signal critical failure if this does not succeed!
                transaction = contract_interface.queue_answer_state_update_challenge(
                    challenge=challenge,
                    allotment_chain=[
                        crypto.zfill(crypto.decode_hex(checksum))
                        for checksum in long_string_to_list(
                            recipient_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)
                    ],
                    values=csf_to_list(recipient_balance.merkle_proof_values,
                                       int),
                    l_r=[
                        int(recipient_balance.left),
                        int(recipient_balance.right)
                    ],
                    tx_set_root=crypto.zfill(
                        crypto.decode_hex(
                            recipient_balance.transaction_set_root())),
                    deltas=[d for d in recipient_balance.deltas()],
                    r=[crypto.uint256(r_0),
                       crypto.uint256(r_1)],
                    s=[crypto.uint256(s_0),
                       crypto.uint256(s_1)],
                    v=[v_0, v_1],
                    passive_checksum=passive_checksum,
                    passive_amount=passive_amount,
                    passive_marker=passive_marker)

            # transfer challenge
            elif challenge.wallet.token == challenge.recipient.token and challenge.wallet.address != challenge.recipient.address:
                try:
                    transfer = Transfer.objects.get(
                        recipient=challenge.recipient,
                        eon_number=challenge_entry.initialStateEon,
                        nonce=challenge_entry.deliveredTxNonce)
                except Transfer.DoesNotExist:
                    logger.error(
                        "Could not find transfer for {} at eon {} with nonce {}."
                        .format(challenge.recipient.address,
                                challenge.eon_number,
                                challenge_entry.deliveredTxNonce))
                    send_admin_email(
                        subject='DISPUTE! NO TRANSFER!',
                        content=
                        "Could not find transfer for {} at eon {} with nonce {}."
                        .format(challenge.recipient.address,
                                challenge.eon_number,
                                challenge_entry.deliveredTxNonce))
                    return

                recipient_transfer_context = WalletTransferContext(
                    wallet=challenge.recipient, transfer=None)

                transfers_list_nonce_index_map = {}
                transfers_list = recipient_transfer_context.authorized_transfers_list_shorthand(
                    only_appended=True,
                    force_append=False,
                    eon_number=challenge_entry.initialStateEon,
                    last_transfer_is_finalized=False,
                    index_map=transfers_list_nonce_index_map)

                transfer_tree = TransactionMerkleTree(transfers_list)
                transfer_index = transfers_list_nonce_index_map.get(
                    transfer.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)
                ]

                passive_checksum, passive_amount, passive_marker = recipient_transfer_context.get_passive_values(
                    eon_number=challenge_entry.initialStateEon)

                send_admin_email(subject='DISPUTE! Transfer Delivery.',
                                 content='{} {} {}'.format(
                                     challenge.wallet.address,
                                     challenge.recipient.address,
                                     transfer_index))

                # TODO signal critical failure if this does not succeed!
                transaction = contract_interface.queue_answer_delivery_challenge(
                    challenge=challenge,
                    tx_trail=transfer_index,
                    allotment_chain=[
                        crypto.zfill(crypto.decode_hex(v))
                        for v in long_string_to_list(
                            recipient_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)
                    ],
                    values=csf_to_list(recipient_balance.merkle_proof_values,
                                       int),
                    l_r=[
                        int(recipient_balance.left),
                        int(recipient_balance.right)
                    ],
                    deltas=[d for d in recipient_balance.deltas()],
                    tx_set_root=crypto.decode_hex(
                        recipient_balance.transaction_set_root()),
                    tx_chain=[crypto.zfill(x) for x in transfer_proof],
                    passive_checksum=passive_checksum,
                    passive_amount=passive_amount,
                    passive_marker=passive_marker)

            # swap challenge
            elif challenge.wallet.token != challenge.recipient.token and challenge.wallet.address == challenge.recipient.address:
                try:
                    transfer = Transfer.objects.get(
                        recipient=challenge.recipient,
                        eon_number=challenge_entry.initialStateEon,
                        nonce=challenge_entry.deliveredTxNonce)
                except Transfer.DoesNotExist:
                    logger.error(
                        "Could not find transfer for {} at eon {} with nonce {}."
                        .format(challenge.recipient.address,
                                challenge.eon_number,
                                challenge_entry.deliveredTxNonce))
                    send_admin_email(
                        subject='DISPUTE! NO SWAP!',
                        content=
                        "Could not find transfer for {} at eon {} with nonce {}."
                        .format(challenge.recipient.address,
                                challenge.eon_number,
                                challenge_entry.deliveredTxNonce))
                    return

                recipient_transfer_context = WalletTransferContext(
                    wallet=challenge.recipient, transfer=None)

                # if not initial transfer in a multi eon swap
                # override starting balance to cached starting balance
                if Transfer.objects.filter(eon_number=transfer.eon_number - 1,
                                           tx_id=transfer.tx_id).exists():
                    starting_balance = int(transfer.recipient_starting_balance)
                else:
                    starting_balance = int(
                        recipient_transfer_context.starting_balance_in_eon(
                            challenge_entry.initialStateEon))

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

                transfer_tree = TransactionMerkleTree(transfers_list)
                transfer_index = transfers_list_nonce_index_map.get(
                    transfer.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)
                ]

                passive_checksum, passive_amount, passive_marker = recipient_transfer_context.get_passive_values(
                    eon_number=challenge_entry.initialStateEon)

                send_admin_email(subject='DISPUTE! Swap Delivery.',
                                 content='{} {} {}'.format(
                                     challenge.wallet.address,
                                     challenge.recipient.address,
                                     transfer_index))

                is_cancelled = transfer.cancelled and transfer.recipient_cancellation_active_state is not None
                if transfer.complete or is_cancelled:
                    starting_balance = 2**256 - 1

                # TODO signal critical failure if this does not succeed!
                transaction = contract_interface.queue_answer_swap_challenge(
                    challenge=challenge,
                    token_pair=[
                        challenge.wallet.token.address,
                        challenge.recipient.token.address
                    ],
                    balance_at_start_of_eon=starting_balance,
                    tx_trail=int(transfer_index),
                    allotment_chain=[
                        crypto.zfill(crypto.decode_hex(v))
                        for v in long_string_to_list(
                            recipient_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)
                    ],
                    values=csf_to_list(recipient_balance.merkle_proof_values,
                                       int),
                    l_r=[
                        int(recipient_balance.left),
                        int(recipient_balance.right)
                    ],
                    deltas=[d for d in recipient_balance.deltas()],
                    tx_set_root=crypto.zfill(
                        crypto.decode_hex(
                            recipient_balance.transaction_set_root())),
                    tx_chain=[crypto.zfill(x) for x in transfer_proof],
                    passive_checksum=passive_checksum,
                    passive_amount=passive_amount,
                    passive_marker=passive_marker)

            challenge.rebuted = True
            challenge.save()
            logger.warning(transaction)
コード例 #10
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)