Exemplo n.º 1
0
async def image_registration_cancel(request):
    """
    Input {regticket_id}
    """
    data = await request.json()
    RegticketDB.get(RegticketDB.id == data['regticket_id']).delete_instance()
    return web.json_response({})
Exemplo n.º 2
0
    async def send_regticket_and_image_to_mn0(self, image_data, regticket):
        # Sign ticket using authors pastelid
        regticket_signature = self.generate_signed_ticket(regticket)

        regticket_db = RegticketDB.create(
            created=datetime.now(),
            blocknum=regticket.blocknum,
            serialized_regticket=regticket.serialize(),
            serialized_signature=regticket_signature.serialize(),
            image_hash=regticket.imagedata_hash)

        mn0 = get_masternode_ordering()[0]
        art_reg_client_logger.debug('Top masternode received: {}'.format(
            mn0.server_ip))
        # send ticket; get upload code
        upload_code = await mn0.call_masternode(
            "REGTICKET_REQ", "REGTICKET_RESP",
            [regticket.serialize(),
             regticket_signature.serialize()])
        # send image
        worker_fee = await mn0.call_masternode("IMAGE_UPLOAD_MN0_REQ",
                                               "IMAGE_UPLOAD_MN0_RESP", {
                                                   'image_data': image_data,
                                                   'upload_code': upload_code
                                               })
        regticket_db.worker_fee = worker_fee
        regticket_db.upload_code_mn0 = upload_code
        regticket_db.save()
        # return fee offered by MN0
        return {'regticket_id': regticket_db.id, 'worker_fee': worker_fee}
Exemplo n.º 3
0
async def image_registration_step_2(request):
    """
    - Send regticket to MN0
    - Receive upload_code
    - Upload image
    - Receive worker's fee
    - Store regticket metadata to loca db
    Input {image: path_to_image_file, title: image_title}
    Returns {workers_fee, regticket_id}
    """
    global pastel_client
    data = await request.json()
    image_path = data['image']
    title = data['title']
    with open(image_path, 'rb') as f:
        content = f.read()
    try:
        result = await get_pastel_client().image_registration_step_2(
            title, content)
    except Exception as ex:
        return web.json_response({'error': str(ex)}, status=400)
    regticket_db = RegticketDB.get(RegticketDB.id == result['regticket_id'])
    regticket_db.path_to_image = image_path
    regticket_db.save()
    print('Fee received: {}'.format(result['worker_fee']))
    return web.json_response({
        'fee': result['worker_fee'],
        'regticket_id': regticket_db.id
    })
Exemplo n.º 4
0
    async def get_workers_fee(self, image_data, artist_name=None, artist_website=None, artist_written_statement=None,
                              artwork_title=None, artwork_series_name=None, artwork_creation_video_youtube_url=None,
                              artwork_keyword_set=None, total_copies=None):
        image = ImageData(dictionary={
            "image": image_data,
            "lubychunks": ImageData.generate_luby_chunks(image_data),
            "thumbnail": ImageData.generate_thumbnail(image_data),
        })

        image.validate()
        blocknum = self.__chainwrapper.get_last_block_number()
        regticket = RegistrationTicket(dictionary={
            "artist_name": artist_name,
            "artist_website": artist_website,
            "artist_written_statement": artist_written_statement,

            "artwork_title": artwork_title,
            "artwork_series_name": artwork_series_name,
            "artwork_creation_video_youtube_url": artwork_creation_video_youtube_url,
            "artwork_keyword_set": artwork_keyword_set,
            "total_copies": total_copies,

            "fingerprints": image.generate_fingerprints(),
            "lubyhashes": image.get_luby_hashes(),
            "lubyseeds": image.get_luby_seeds(),
            "thumbnailhash": image.get_thumbnail_hash(),

            "author": self.__pubkey,
            "order_block_txid": self.__chainwrapper.get_last_block_hash(),
            "blocknum": blocknum,
            "imagedata_hash": image.get_artwork_hash(),
        })
        regticket_signature = self.__generate_signed_ticket(regticket)
        regticket_db = RegticketDB.create(created=datetime.now(), blocknum=blocknum,
                                          serialized_regticket=regticket.serialize(),
                                          serialized_signature=regticket_signature.serialize())

        mn0, mn1, mn2 = self.__nodemanager.get_masternode_ordering()
        art_reg_client_logger.debug(
            'Received to 3 masternodes: {}, {}, {}'.format(MASTERNODE_NAMES.get(mn0.server_ip),
                                                           MASTERNODE_NAMES.get(mn1.server_ip),
                                                           MASTERNODE_NAMES.get(mn2.server_ip)))
        upload_code = await mn0.call_masternode("REGTICKET_REQ", "REGTICKET_RESP",
                                                [regticket.serialize(), regticket_signature.serialize()])
        worker_fee = await mn0.call_masternode("IMAGE_UPLOAD_MN0_REQ", "IMAGE_UPLOAD_MN0_RESP",
                                               {'image_data': image_data, 'upload_code': upload_code})
        regticket_db.worker_fee = worker_fee
        regticket_db.upload_code_mn0 = upload_code
        regticket_db.save()
        return {'regticket_id': regticket_db.id, 'worker_fee': worker_fee}
Exemplo n.º 5
0
    async def send_regticket_to_mn2_mn3(self, regticket_id):
        regticket_db = RegticketDB.get(RegticketDB.id == regticket_id)
        with open(regticket_db.path_to_image, 'rb') as f:
            image_data = f.read()

        mn0, mn1, mn2 = get_masternode_ordering(regticket_db.blocknum)[:3]

        async def send_regticket_to_mn(mn, serialized_regticket,
                                       serialized_signature, img_data):
            """
            Here we push ticket to given masternode, receive upload_code, then push image.
            Masternode will return fee, but we ignore it here.
            """
            try:
                upload_code = await mn.call_masternode(
                    "REGTICKET_REQ", "REGTICKET_RESP",
                    [serialized_regticket, serialized_signature])
                worker_fee = await mn.call_masternode(
                    "IMAGE_UPLOAD_REQ", "IMAGE_UPLOAD_RESP", {
                        'image_data': img_data,
                        'upload_code': upload_code
                    })
            except Exception as ex:
                return None, str(ex)
            return upload_code, None

        # Send regticket and image to MN1 and MN2
        result_mn1, result_mn2 = await asyncio.gather(
            send_regticket_to_mn(mn1, regticket_db.serialized_regticket,
                                 regticket_db.serialized_signature,
                                 image_data),
            send_regticket_to_mn(mn2, regticket_db.serialized_regticket,
                                 regticket_db.serialized_signature,
                                 image_data),
            return_exceptions=True)
        upload_code_mn1, err_mn1 = result_mn1
        upload_code_mn2, err_mn2 = result_mn2
        art_reg_client_logger.warn('Upload code1: {}'.format(upload_code_mn1))
        art_reg_client_logger.warn('Upload code2: {}'.format(upload_code_mn2))
        if not upload_code_mn1:
            return False, err_mn1
        if not upload_code_mn2:
            return False, err_mn2
        regticket_db.upload_code_mn1 = upload_code_mn1
        regticket_db.upload_code_mn2 = upload_code_mn2
        regticket_db.save()
        return True, None
Exemplo n.º 6
0
async def download_image(request):
    """
    Input {regticket_id}  - id from local DB.
    """
    data = await request.json()
    regticket_db = RegticketDB.get(RegticketDB.id == data['regticket_id'])
    response = await get_pastel_client().download_image(regticket_db.image_hash
                                                        )
    if response is not None:
        filename = os.path.join(get_artwork_dir(),
                                '{}.jpg'.format(data['regticket_id']))
        with open(filename, 'wb') as f:
            f.write(response)
        return web.json_response({'status': 'SUCCESS', 'filename': filename})
    return web.json_response({
        'status': 'error',
        'msg': 'Image not found on masternodes'
    })
Exemplo n.º 7
0
async def image_registration_step_2(request):
    """
    - Send regticket to MN0
    - Receive upload_code
    - Upload image
    - Receive worker's fee
    - Store regticket metadata to local db
    Input {image: path_to_image_file, title: image_title}
    Returns {workers_fee, regticket_id}
    """
    # FIXME: current input from electron
    #  Document
    #  Pass this data further
    """
        const pyApiData = {
        image: data.filePath,
        title: data.name,
        num_copies: data.numCopies,
        copy_price: data.copyPrice
    };
    """
    data = await request.json()
    image_path = data.pop('image')
    with open(image_path, 'rb') as f:
        content = f.read()

    # Send regticket and image to MN0; Receive worker's fee
    try:
        result = await get_pastel_client().image_registration_step_2(
            regticket_data=data, image_data=content)
    except Exception as ex:
        return web.json_response({'error': str(ex)}, status=400)

    # Store regticket metadata to local db
    regticket_db = RegticketDB.get(RegticketDB.id == result['regticket_id'])
    regticket_db.path_to_image = image_path
    regticket_db.save()

    print('Fee received: {}'.format(result['worker_fee']))
    return web.json_response({
        'fee': result['worker_fee'],
        'regticket_id': regticket_db.id
    })
Exemplo n.º 8
0
    async def image_registration_step_3(self, regticket_id):
        artreg = ArtRegistrationClient(self.__privkey, self.__pubkey,
                                       self.__chainwrapper, self.__nodemanager)

        success, err = await artreg.send_regticket_to_mn2_mn3(regticket_id)
        if not success:
            return {'status': 'ERROR', 'msg': err}
        regticket_db = RegticketDB.get(RegticketDB.id == regticket_id)
        amount = "{0:.5f}".format(regticket_db.worker_fee * 0.1)
        # burn 10% of worker's fee
        # TODO: current BURN_ADDRESS is taken from MN3. Pick another burn address.
        self.__logger.warn(
            'Sending to BURN_ADDRESS, amount: {}'.format(amount))
        burn_10_percent_txid = self.__send_to_address(BURN_ADDRESS, amount)
        self.__logger.warn('Burn txid is {}'.format(burn_10_percent_txid))
        # store txid in DB
        regticket_db.burn_tx_id = burn_10_percent_txid
        regticket_db.save()

        mn0, mn1, mn2 = self.__nodemanager.get_masternode_ordering(
            regticket_db.blocknum)

        async def send_txid_10_req_to_mn(mn, data):
            """
            Here we push ticket to given masternode, receive upload_code, then push image.
            Masternode will return fee, but we ignore it here.
            :return (result, status)
            """
            try:
                result = await mn.call_masternode("TXID_10_REQ",
                                                  "TXID_10_RESP", data)
                return result, True
            except RPCException as ex:
                return str(ex), False

        mn0_response, mn1_response, mn2_response = await asyncio.gather(
            send_txid_10_req_to_mn(
                mn0, [burn_10_percent_txid, regticket_db.upload_code_mn0]),
            send_txid_10_req_to_mn(
                mn1, [burn_10_percent_txid, regticket_db.upload_code_mn1]),
            send_txid_10_req_to_mn(
                mn2, [burn_10_percent_txid, regticket_db.upload_code_mn2]),
            return_exceptions=True)
        self.__logger.warn('MN0: {}'.format(mn0_response))
        self.__logger.warn('MN1: {}'.format(mn1_response))
        self.__logger.warn('MN2: {}'.format(mn2_response))
        return {
            'status':
            'SUCCESS' if mn0_response[1] and mn1_response[1]
            and mn2_response[1] else 'ERROR',
            'mn_data': {
                'mn0': {
                    'status': 'SUCCESS' if mn0_response[1] else 'ERROR',
                    'msg': mn0_response[0]
                },
                'mn1': {
                    'status': 'SUCCESS' if mn1_response[1] else 'ERROR',
                    'msg': mn1_response[0]
                },
                'mn2': {
                    'status': 'SUCCESS' if mn2_response[1] else 'ERROR',
                    'msg': mn2_response[0]
                }
            }
        }
Exemplo n.º 9
0
    async def image_registration_step_3(self, regticket_id):
        artreg = ArtRegistrationClient()

        success, err = await artreg.send_regticket_to_mn2_mn3(regticket_id)
        if not success:
            return {'status': 'ERROR', 'msg': err}

        regticket_db = RegticketDB.get(RegticketDB.id == regticket_id)
        amount = "{0:.5f}".format(regticket_db.worker_fee * 0.1)

        # burn 10% of worker's fee
        # TODO: current BURN_ADDRESS is taken from MN3. Pick another burn address.
        self.__logger.warn(
            'Sending to BURN_ADDRESS, amount: {}'.format(amount))
        burn_10_percent_txid = self.__send_to_address(BURN_ADDRESS, amount)
        self.__logger.warn('Burn txid is {}'.format(burn_10_percent_txid))
        # store txid in DB
        regticket_db.burn_tx_id = burn_10_percent_txid
        regticket_db.save()

        # Send txid of burnt 10% to MN0, MN1 and MN2
        mn0, mn1, mn2 = get_masternode_ordering(regticket_db.blocknum)[:3]

        async def send_txid_10_req_to_mn(mn, data):
            """
            Here we push ticket to given masternode, receive upload_code, then push image.
            Masternode will return fee, but we ignore it here.
            :return (result, status)
            """
            try:
                result = await mn.call_masternode("TXID_10_REQ",
                                                  "TXID_10_RESP", data)
                return result, True
            except RPCException as ex:
                return str(ex), False

        mn0_response, mn1_response, mn2_response = await asyncio.gather(
            send_txid_10_req_to_mn(
                mn0, [burn_10_percent_txid, regticket_db.upload_code_mn0]),
            send_txid_10_req_to_mn(
                mn1, [burn_10_percent_txid, regticket_db.upload_code_mn1]),
            send_txid_10_req_to_mn(
                mn2, [burn_10_percent_txid, regticket_db.upload_code_mn2]),
            return_exceptions=True)
        self.__logger.warn('MN0: {}'.format(mn0_response))
        self.__logger.warn('MN1: {}'.format(mn1_response))
        self.__logger.warn('MN2: {}'.format(mn2_response))
        if mn0_response[1] and mn1_response[1] and mn2_response[1]:
            # all responses indicate success. Mn1 or mn2 response should container txid
            if 'txid' in mn1_response[0]:
                txid = mn1_response[0]['txid']
            elif 'txid' in mn2_response[0]:
                txid = mn2_response[0]['txid']
            else:
                # raise Exception('Txid not found neither in mn1 nor in mn2 response!')
                return {
                    'status':
                    'ERROR',
                    'msg':
                    'Txid not found neither in mn1 nor in mn2 response!, '
                    'Responses: MN0: {}, MN1: {}, MN2: {}'.format(
                        mn0_response, mn1_response, mn2_response)
                }
            return {
                'status': 'SUCCESS',
                'txid': txid,
                'fee': regticket_db.worker_fee,
                'blocknum': regticket_db.blocknum,
                'pastel_id': self.pastelid,
                'passphrase': self.passphrase
            }
        else:
            # some error happened, return details
            return {
                'status': 'ERROR',
                'msg': {
                    'mn_data': {
                        'mn0': {
                            'status':
                            'SUCCESS' if mn0_response[1] else 'ERROR',
                            'msg': mn0_response[0]
                        },
                        'mn1': {
                            'status':
                            'SUCCESS' if mn1_response[1] else 'ERROR',
                            'msg': mn1_response[0]
                        },
                        'mn2': {
                            'status':
                            'SUCCESS' if mn2_response[1] else 'ERROR',
                            'msg': mn2_response[0]
                        }
                    }
                }
            }