Ejemplo n.º 1
0
def on_transfer_confirmation(transaction_id):
    transfer = Transfer.objects.get(id=transaction_id, swap=False)
    transfer_data = TransferSerializer(transfer, read_only=True).data

    # send transfer confirmed notification to both wallets
    # to cover use cases where multiple clients might be listening for the same wallet's state
    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(
                          transfer.recipient.token.address,
                          transfer.recipient.address),
                      event_name=TRANSFER_CONFIRMATION,
                      data=transfer_data)

    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(transfer.wallet.token.address,
                                               transfer.wallet.address),
                      event_name=TRANSFER_CONFIRMATION,
                      data=transfer_data)

    operator_celery.send_task(
        'synchronizer.tasks.trigger_hook',
        args=[
            ConciseTransactionSerializer(transfer).data,
        ],
    )
Ejemplo n.º 2
0
    def interpret(self,
                  decoded_event,
                  txid,
                  block_number,
                  eon_number,
                  verbose=False):
        wallet_address = hex_address(decoded_event.get(u'recipient'))

        try:
            wallet = Wallet.objects.get(token__address__iexact=hex_address(
                decoded_event.get(u'token')),
                                        address__iexact=wallet_address)
        except Wallet.DoesNotExist:
            logger.warning(
                "UNKNOWN WALLET PERFORMING DEPOSIT {}".format(wallet_address))
            BlacklistEntry.objects.get_or_create(address=wallet_address)
            return

        with wallet.lock(auto_renewal=True):
            deposit = Deposit.objects.create(
                wallet=wallet,
                amount=decoded_event.get(u'amount'),
                eon_number=eon_number,
                block=block_number,
                txid=remove_0x_prefix(txid))

            # send deposit added notification to sender
            send_notification(stream_prefix="wallet",
                              stream_id="{}/{}".format(wallet.token.address,
                                                       wallet.address),
                              event_name=CONFIRMED_DEPOSIT,
                              data=DepositSerializer(deposit,
                                                     read_only=True).data)
Ejemplo n.º 3
0
    def interpret(self, decoded_event, txid, block_number, eon_number, verbose=False):
        token_address = decoded_event.get(u'token')
        wallet_address = decoded_event.get(u'requestor')
        amount = decoded_event.get(u'amount')

        try:
            wallet = Wallet.objects.get(
                token__address__iexact=hex_address(token_address),
                address__iexact=hex_address(wallet_address))
        except Wallet.DoesNotExist:
            return

        # get all unconfirmed unslashed withdrawal requests for this wallet
        # sorted in ascending order by the date they were added
        unslashed_unconfirmed_requests = WithdrawalRequest.objects \
            .filter(wallet=wallet, slashed=False, withdrawal__isnull=True) \
            .order_by('id')

        withdrawal_requests = []
        accumulator = 0

        # add withdrawal requests until confirmation amount is reached
        # from older to newer requests
        for withdrawal_request in unslashed_unconfirmed_requests:
            if accumulator < amount:
                withdrawal_requests.append(withdrawal_request)
                accumulator += withdrawal_request.amount
            else:
                break

        # if accumulator is not equal to confirmed amount there is something very wrong going on
        if accumulator != amount:
            logger.error(
                'CONFIRMED WITHDRAWALS BY {} FOR TOKEN {} DID NOT SUM UP TO EXPECTED AMOUNT {}'
                .format(hex_address(wallet_address), hex_address(token_address), amount))

        # create a withdrawal object for every confirmed withdrawal request
        for withdrawal_request in withdrawal_requests:
            confirmation = Withdrawal(
                wallet=wallet,
                amount=withdrawal_request.amount,
                eon_number=eon_number,
                request=withdrawal_request,
                block=block_number,
                txid=remove_0x_prefix(txid))

            # send withdrawal confirmed notification to wallet
            send_notification(
                stream_prefix="wallet",
                stream_id="{}/{}".format(wallet.token.address, wallet.address),
                event_name=CONFIRMED_WITHDRAWAL,
                data=WithdrawalSerializer(
                    confirmation, read_only=True).data
            )

            if verbose:
                print(withdrawal_request)
                print(confirmation)

            confirmation.save()
Ejemplo n.º 4
0
    def interpret(self, decoded_event, txid, block_number, eon_number, verbose=False):
        try:
            wallet = Wallet.objects.get(
                token__address__iexact=hex_address(
                    decoded_event.get(u'token')),
                address__iexact=hex_address(decoded_event.get(u'requestor')))
        except Wallet.DoesNotExist:
            # TODO this is a problem
            logger.error("UNKNOWN WALLET REQUESTING WITHDRAWAL {}".format(
                hex_address(decoded_event.get(u'requestor'))))
            return

        with wallet.lock(auto_renewal=True):
            withdrawal_request = WithdrawalRequest.objects.create(
                wallet=wallet,
                amount=decoded_event.get(u'amount'),
                eon_number=eon_number,
                block=block_number,
                txid=remove_0x_prefix(txid))

            # send withdrawal requested notification to wallet
            send_notification(
                stream_prefix="wallet",
                stream_id="{}/{}".format(wallet.token.address, wallet.address),
                event_name=REQUESTED_WITHDRAWAL,
                data=WithdrawalRequestSerializer(
                    withdrawal_request, read_only=True).data
            )

        logger.warning(withdrawal_request)

        if verbose:
            print(withdrawal_request)
Ejemplo n.º 5
0
def broadcast_wallet_data():
    eon_number = LocalViewInterface.latest().eon_number()
    for wallet in Wallet.objects.all():

        request_model = MockModel(eon_number=eon_number,
                                  wallet=wallet,
                                  transfer_id=0)

        data = WalletStateSerializer(request_model).data

        send_notification(stream_prefix='wallet',
                          stream_id="{}/{}".format(wallet.token.address,
                                                   wallet.address),
                          event_name=CHECKPOINT_CREATED,
                          data=data)
Ejemplo n.º 6
0
def on_swap_finalization(transaction_id):
    swap = Transfer.objects.get(id=transaction_id, swap=True)
    swap_data = SwapFinalizationSerializer(swap, read_only=True).data

    # send swap cancellation notification to both wallets
    # to cover use cases where multiple clients might be listening for the same wallet's state
    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(swap.recipient.token.address,
                                               swap.recipient.address),
                      event_name=SWAP_FINALIZATION,
                      data=swap_data)

    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(swap.wallet.token.address,
                                               swap.wallet.address),
                      event_name=SWAP_FINALIZATION,
                      data=swap_data)
Ejemplo n.º 7
0
def on_swap_confirmation(transaction_id):
    swap = Transfer.objects.get(id=transaction_id, swap=True)
    swap_data = SwapSerializer(swap, read_only=True).data

    # send swap confirmed notification to both wallets
    # to cover use cases where multiple clients might be listening for the same wallet's state
    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(swap.recipient.token.address,
                                               swap.recipient.address),
                      event_name=SWAP_CONFIRMATION,
                      data=swap_data)

    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(swap.wallet.token.address,
                                               swap.wallet.address),
                      event_name=SWAP_CONFIRMATION,
                      data=swap_data)

    # send swap incoming notification to clients interested in pairs
    send_notification(stream_prefix="tokenpair",
                      stream_id="{}/{}".format(swap.wallet.token.address,
                                               swap.recipient.token.address),
                      event_name=INCOMING_SWAP,
                      data=swap_data)
Ejemplo n.º 8
0
def on_swap_matching(swap_id, opposite_id):
    swap = Transfer.objects.get(id=swap_id, swap=True)
    opposite = Transfer.objects.get(id=opposite_id, swap=True)

    swap_data = SwapSerializer(swap, read_only=True).data
    opposite_data = SwapSerializer(opposite, read_only=True).data

    # send swap matched notification to recipient
    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(
                          opposite.recipient.token.address,
                          opposite.recipient.address),
                      event_name=MATCHED_SWAP,
                      data=opposite_data)
    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(swap.recipient.token.address,
                                               swap.recipient.address),
                      event_name=MATCHED_SWAP,
                      data=swap_data)

    # send swap matched notification to sender
    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(opposite.wallet.token.address,
                                               opposite.wallet.address),
                      event_name=MATCHED_SWAP,
                      data=opposite_data)
    send_notification(stream_prefix="wallet",
                      stream_id="{}/{}".format(swap.wallet.token.address,
                                               swap.wallet.address),
                      event_name=MATCHED_SWAP,
                      data=swap_data)

    # send swap matched notification to tokenpair listeners
    send_notification(stream_prefix="tokenpair",
                      stream_id="{}/{}".format(opposite.wallet.token.address,
                                               swap.wallet.token.address),
                      event_name=MATCHED_SWAP,
                      data=opposite_data)
    # send swap matched notification to tokenpair listeners
    send_notification(stream_prefix="tokenpair",
                      stream_id="{}/{}".format(swap.wallet.token.address,
                                               opposite.wallet.token.address),
                      event_name=MATCHED_SWAP,
                      data=swap_data)
Ejemplo n.º 9
0
def process_admissions_for_latest_eon():
    latest_eon_number = LocalViewInterface.latest().eon_number()
    checkpoint_created = RootCommitment.objects.filter(
        eon_number=latest_eon_number).exists()

    to_update_records = []
    to_delete_ids = []
    wallet_offsets = {}
    operator_wallets = {}

    with transaction.atomic():
        pending_approval = Wallet.objects.select_for_update().filter(
            registration_operator_authorization__isnull=True)

        for token in Token.objects.all():
            wallet_offsets[token.id] = Wallet.objects.filter(
                registration_operator_authorization__isnull=False,
                token=token).count()

            try:
                operator_wallets[token.id] = Wallet.objects.get(
                    address=remove_0x_prefix(
                        settings.HUB_OWNER_ACCOUNT_ADDRESS),
                    token=token)
            except Wallet.DoesNotExist:
                logger.error(
                    'Could not admit client wallets for token {}. Owner wallet {} not yet registered.'
                    .format(token.address, settings.HUB_OWNER_ACCOUNT_ADDRESS))
                return

        for wallet in pending_approval:
            try:
                if wallet.registration_operator_authorization is not None:
                    logger.error('Wallet {} already admitted.'.format(
                        wallet.address))
                    continue
                if should_void_admission(wallet, latest_eon_number,
                                         checkpoint_created):
                    to_delete_ids.append(wallet.id)
                    continue

                wallet.trail_identifier = wallet_offsets[wallet.token.id]

                wallet.registration_operator_authorization = wallet.sign_admission(
                    eon_number=latest_eon_number,
                    operator_wallet=operator_wallets[wallet.token.id],
                    private_key=settings.HUB_OWNER_ACCOUNT_KEY)

                wallet_offsets[wallet.token.id] += 1
                to_update_records.append(wallet)

            except IntegrityError as error:
                logger.error('Admission Verification Integrity Error')
                logger.error(error)
                break

        pending_approval.filter(pk__in=to_delete_ids).delete()

        Wallet.objects.bulk_update(
            to_update_records,
            ['registration_operator_authorization', 'trail_identifier'])

    for wallet in to_update_records:
        send_notification(stream_prefix="wallet",
                          stream_id="{}/{}".format(wallet.token.address,
                                                   wallet.address),
                          event_name=REGISTERED_WALLET,
                          data=AdmissionSerializer(wallet,
                                                   read_only=True).data)
        logger.info('Wallet {} admitted.'.format(wallet.address))