コード例 #1
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}
コード例 #2
0
def get_regticket():
    image = ImageData(
        dictionary={
            "image": png_1x1_data,
            "lubychunks": ImageData.generate_luby_chunks(png_1x1_data),
            "thumbnail": ImageData.generate_thumbnail(png_1x1_data),
        })

    return RegistrationTicket(
        dictionary={
            "artist_name": '',
            "artist_website": '',
            "artist_written_statement": '',
            "artwork_title": '',
            "artwork_series_name": '',
            "artwork_creation_video_youtube_url": '',
            "artwork_keyword_set": '',
            "total_copies": 0,
            "fingerprints": image.generate_fingerprints(),
            "lubyhashes": image.get_luby_hashes(),
            "lubyseeds": image.get_luby_seeds(),
            "thumbnailhash": image.get_thumbnail_hash(),
            "author":
            'jXZDyqqMDXSz1ycBLCZJ82U2GCSL7m8KTet3i685pFroMdjGaPvdCmVZWrkxoKn1H7wSHibVEohHV7u5juDrne',
            "order_block_txid":
            '77996c90fd99ee60788333da62f7586e2f7b1c61d399484c2379927cba8f1356',
            "blocknum": 500,
            "imagedata_hash": image.get_artwork_hash(),
        })
コード例 #3
0
    def test_prepare_cnode_artticket_data(self):
        regticket = generate_test_regticket()

        signatures_dict = {
            "artist": {'pastelid': 'signature'},
            "mn2": {'pastelid': 'signature'},
            "mn3": {'pastelid': 'signature'}
        }

        # write final ticket into blockchain
        art_ticket_data = {
            'cnode_package': regticket.get_cnode_package(),
            'signatures_dict': signatures_dict,
            'key1': 'somekey1',  # artist_signature.pastelid,
            'key2': 'somekey2',
            'art_block': 1,
            'fee': 100
        }
        self.assertEqual(type(art_ticket_data['cnode_package']), str)
        cnode_package_dict = json.loads(base64.b64decode(art_ticket_data['cnode_package']))
        self.assertEqual(cnode_package_dict['version'], 1)
        self.assertEqual(cnode_package_dict['author'], regticket.author)
        self.assertEqual(cnode_package_dict['blocknum'], regticket.blocknum)
        app_ticket = RegistrationTicket(serialized_base64=regticket.get_cnode_package())
        self.assertEqual(app_ticket.author, regticket.author)
        self.assertEqual(app_ticket.imagedata_hash, regticket.imagedata_hash)
コード例 #4
0
 def test_create_regticket(self):
     regticket = generate_test_regticket()
     serialized = regticket.serialize_base64()
     self.assertEqual(type(serialized), str)
     restored = RegistrationTicket(serialized_base64=serialized)
     self.assertEqual(restored.artist_name, regticket.artist_name)
     self.assertEqual(restored.fingerprints, regticket.fingerprints)
     self.assertEqual(restored.imagedata_hash, regticket.imagedata_hash)
コード例 #5
0
ファイル: database.py プロジェクト: ANIME-AnimeCoin/StoVaCore
    def __is_burn_10_tx_height_valid(self, txid):
        regticket = RegistrationTicket(serialized=self.regticket)
        raw_tx_data = mnd.blockchain.getrawtransaction(txid, verbose=1)
        if not raw_tx_data:
            self.__errors.append('Burn 10% txid is invalid')
            return False

        if raw_tx_data['expiryheight'] < regticket.blocknum:
            self.__errors.append('Fee transaction is older then regticket.')
            return False
コード例 #6
0
ファイル: database.py プロジェクト: pastelnetwork/stovacore
    def write_to_blockchain(self):
        ticket = RegistrationTicket(serialized=self.regticket)
        current_block = get_blockchain_connection().getblockcount()
        # verify if confirmation receive for 5 blocks or less from regticket creation.
        if current_block - ticket.blocknum > Settings.MAX_CONFIRMATION_DISTANCE_IN_BLOCKS:
            self.status = REGTICKET_STATUS_ERROR
            error_msg = 'Second confirmation received too late - current block {}, regticket block: {}'. \
                format(current_block, ticket.blocknum)
            self.error = error_msg
            raise Exception(error_msg)

        artist_signature = Signature(serialized=self.artists_signature_ticket)
        mn2_signature = Signature(serialized=self.mn1_serialized_signature)
        mn3_signature = Signature(serialized=self.mn2_serialized_signature)

        signatures_dict = {
            "artist": {
                artist_signature.pastelid: artist_signature.signature
            },
            "mn2": {
                mn2_signature.pastelid: mn2_signature.signature
            },
            "mn3": {
                mn3_signature.pastelid: mn3_signature.signature
            }
        }

        # write final ticket into blockchain
        art_ticket_data = {
            'cnode_package': ticket.serialize_base64(),
            'signatures_dict': signatures_dict,
            'key1': ticket.base64_imagedatahash,  # artist_signature.pastelid,
            'key2': ticket.base64_imagedatahash,
            'fee': int(self.localfee)
        }

        bc_response = get_blockchain_connection().register_art_ticket(
            **art_ticket_data)
        return bc_response
コード例 #7
0
    def generate_regticket(cls, image_data: bytes, regticket_data: dict):
        image = ImageData(
            dictionary={
                "image": image_data,
                "lubychunks": ImageData.generate_luby_chunks(image_data),
                "thumbnail": ImageData.generate_thumbnail(image_data),
            })

        image.validate()
        blocknum = get_blockchain_connection().getblockcount()
        return RegistrationTicket(
            dictionary={
                "artist_name":
                regticket_data.get('artist_name', ''),
                "artist_website":
                regticket_data.get('artist_website', ''),
                "artist_written_statement":
                regticket_data.get('artist_written_statement', ''),
                "artwork_title":
                regticket_data.get('artwork_title', ''),
                "artwork_series_name":
                regticket_data.get('artwork_series_name', ''),
                "artwork_creation_video_youtube_url":
                regticket_data.get('artwork_creation_video_youtube_url', ''),
                "artwork_keyword_set":
                regticket_data.get('artwork_keyword_set', ''),
                "total_copies":
                int(regticket_data.get('total_copies', 0)),
                # "copy_price": copy_price,
                "fingerprints":
                image.generate_fingerprints(),
                "lubyhashes":
                image.get_luby_hashes(),
                "lubyseeds":
                image.get_luby_seeds(),
                "thumbnailhash":
                image.get_thumbnail_hash(),
                "author":
                get_blockchain_connection().pastelid,
                "order_block_txid":
                get_blockchain_connection().getbestblockhash(),
                "blocknum":
                blocknum,
                "imagedata_hash":
                image.get_artwork_hash(),
            })
コード例 #8
0
ファイル: tasks.py プロジェクト: pastelnetwork/stovacore
def get_registration_ticket_object_from_data(ticket):
    return RegistrationTicket(serialized_base64=ticket['ticket']['art_ticket'])
コード例 #9
0
    async def get_artworks_data(self):
        reg_tickets_txids = get_blockchain_connection().list_tickets(
            'act')  # list
        txid_list = set(
            map(lambda x: x['ticket']['reg_txid'], reg_tickets_txids))
        db_txid_list = set([a.reg_ticket_txid for a in Artwork.select()])
        # get act ticket txids which are in blockchain and not in db_txid_list
        reg_ticket_txid_to_fetch = txid_list - db_txid_list
        if len(reg_ticket_txid_to_fetch):
            client = Masternode.select()[0].get_rpc_client()
            # fetch missing data from the blockchain and write to DB
            for txid in reg_ticket_txid_to_fetch:
                try:
                    ticket = get_blockchain_connection().get_ticket(
                        txid)  # it's registration ticket here
                except JSONRPCException as e:
                    self.__logger.exception(
                        'Error obtain registration ticket txid: {}'.format(
                            txid))
                    # to avoid processing invalid txid multiple times - write in to the DB with height=-1
                    Artwork.create(reg_ticket_txid=txid, blocknum=-1)
                    continue
                try:
                    act_ticket = get_blockchain_connection().find_ticket(
                        'act', txid)
                except JSONRPCException as e:
                    self.__logger.exception(
                        'Error obtain act ticket by key: {}'.format(txid))
                    # to avoid processing invalid txid multiple times - write in to the DB with height=-1
                    Artwork.create(reg_ticket_txid=txid, blocknum=-1)
                    continue

                regticket = RegistrationTicket(
                    serialized_base64=ticket['ticket']['art_ticket'])
                artist_pastelid = list(
                    ticket['ticket']['signatures']['artist'].keys())[0]

                # get thumbnail
                response = await client.rpc_download_thumbnail(
                    regticket.thumbnailhash)
                thumbnail_data = b''
                if response['status'] == "SUCCESS":
                    thumbnail_data = response['image_data']
                elif response['status'] == "ERROR":
                    if 'masternodes' in response:
                        # try to fetch thumbnail from recommended masternodes
                        for pastelid in response['masternodes']:
                            try:
                                rpc_client = Masternode.select().get(
                                    Masternode.pastel_id ==
                                    pastelid).get_rpc_client()
                                response = await rpc_client.rpc_download_thumbnail(
                                    regticket.thumbnailhash)
                                if response['status'] == "SUCCESS":
                                    thumbnail_data = response['image_data']
                                    break
                                elif response['status'] == "ERROR":
                                    continue
                            except Exception:
                                continue

                thumbnail_filename = '{}.png'.format(txid)
                thumbnail_path = os.path.join(get_thumbnail_dir(),
                                              thumbnail_filename)
                with open(thumbnail_path, 'wb') as f:
                    f.write(thumbnail_data)
                # store artwork data to DB
                Artwork.create(
                    reg_ticket_txid=txid,
                    act_ticket_txid=act_ticket['txid'],
                    artist_pastelid=artist_pastelid,
                    artwork_title=regticket.artwork_title,
                    total_copies=regticket.total_copies,
                    artist_name=regticket.artist_name,
                    artist_website=regticket.artist_website,
                    artist_written_statement=regticket.
                    artist_written_statement,
                    artwork_series_name=regticket.artwork_series_name,
                    artwork_creation_video_youtube_url=regticket.
                    artwork_creation_video_youtube_url,
                    artwork_keyword_set=regticket.artwork_keyword_set,
                    imagedata_hash=regticket.imagedata_hash,
                    blocknum=regticket.blocknum,
                    order_block_txid=regticket.order_block_txid)
        result = []
        for artwork in Artwork.select().where(Artwork.blocknum > 0):
            sale_data = {'forSale': False, 'price': -1, 'sell_txid': None}
            response = get_blockchain_connection().find_ticket(
                'sell', artwork.act_ticket_txid)

            if response == 'Key is not found':
                sell_ticket = SellticketDB.get_or_none(
                    SellticketDB.act_ticket_txid == artwork.act_ticket_txid)
                if sell_ticket:
                    sale_data = {
                        'forSale': True,
                        'price': sell_ticket.price,
                        'sell_txid': None
                    }

            elif type(response) == list:
                resp_json = response[0]
                sale_data = {
                    'forSale': True,
                    'price': resp_json['ticket']['asked_price'],
                    'sell_txid': resp_json['txid']
                }
            elif type(response) == str:
                resp_json = json.loads(response)
                sale_data = {
                    'forSale': True,
                    'price': resp_json['ticket']['asked_price'],
                    'sell_txid': response['txid']
                }
            result.append({
                'artistPastelId': artwork.artist_pastelid,
                'name': artwork.artwork_title,
                'numOfCopies': artwork.total_copies,
                'copyPrice': -1,
                'thumbnailPath': artwork.get_thumbnail_path(),
                'artistName': artwork.artist_name,
                'artistWebsite': artwork.artist_website,
                'artistWrittenStatement': artwork.artist_written_statement,
                'artworkSeriesName': artwork.artwork_series_name,
                'artworkCreationVideoYoutubeUrl':
                artwork.artwork_creation_video_youtube_url,
                'artworkKeywordSet': artwork.artwork_keyword_set,
                'imageHash': artwork.get_image_hash_digest(),
                'blocknum': artwork.blocknum,
                'orderBlockTxid': artwork.order_block_txid,
                'actTicketTxid': artwork.act_ticket_txid,
                'saleData': sale_data
            })
        return result
コード例 #10
0
def generate_test_regticket():
    regticket = RegistrationTicket(dictionary=get_test_regticket_data())
    return regticket
コード例 #11
0
    async def register_image(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):
        # generate image ticket
        image = ImageData(dictionary={
            "image": image_data,
            "lubychunks": ImageData.generate_luby_chunks(image_data),
            "thumbnail": ImageData.generate_thumbnail(image_data),
        })

        image.validate()

        # generate registration ticket
        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": self.__chainwrapper.get_last_block_number(),
            "imagedata_hash": image.get_artwork_hash(),
        })

        # Current validation never passes - skip it for now.
        # Probably we should not validate any created tickets
        # Other nodes (ArtRegistrationServer) will validate, but client pushed ticket
        # to the network 'as is'.
        # regticket.validate(self.__chainwrapper)

        # get masternode ordering from regticket
        art_reg_client_logger.info('Get masternode ordering')
        masternode_ordering = self.__nodemanager.get_masternode_ordering(regticket.order_block_txid)
        art_reg_client_logger.info('Get masternode ordering ... done')
        mn0, mn1, mn2 = masternode_ordering

        # sign ticket
        # FIXME: No need to sign ticket here, cause every message sent to MN is signed in `pack_and_sign` method.
        # mn_ticket_logger.info('Sign ticket')
        signature_regticket = self.__generate_signed_ticket(regticket)
        # mn_ticket_logger.info('Sign ticket .... done')

        art_reg_client_logger.info('Initially sending regticket to the first masternode')
        upload_code = await mn0.call_masternode("REGTICKET_REQ", "REGTICKET_RESP",
                                                regticket.serialize())
        art_reg_client_logger.info('Upload code received: {}'.format(upload_code))

        # TODO: upload image to MN0 using upload code
        # TODO: (design upload_code logic/behaviour) - implement in MN code/art regisgration server
        # TODO: get final fee from MN0

        worker_fee = await mn0.call_masternode("IMAGE_UPLOAD_REQ", "IMAGE_UPLOAD_RESP",
                                               {'image_data': image_data, 'upload_code': upload_code})

        art_reg_client_logger.info('Worker fee received: {}'.format(worker_fee))

        # TODO: below is old code, which is being replaced with new one

        # have masternodes sign the ticket
        art_reg_client_logger.info('Collect signatures')
        mn_signatures = await self.__collect_mn_regticket_signatures(signature_regticket, regticket,
                                                                     masternode_ordering)
        art_reg_client_logger.info('Collect signatures ... done')
        # assemble final regticket
        final_regticket = self.__generate_final_ticket(FinalRegistrationTicket, regticket, signature_regticket,
                                                       mn_signatures)
        # ask first MN to store regticket on chain
        regticket_txid = await mn0.call_masternode("PLACEONBLOCKCHAIN_REQ", "PLACEONBLOCKCHAIN_RESP",
                                                   ["regticket", final_regticket.serialize()])

        # wait for regticket to show up on the chain
        self.__wait_for_ticket_on_blockchain(regticket_txid)

        # generate activation ticket
        actticket = ActivationTicket(dictionary={
            "author": self.__pubkey,
            "order_block_txid": regticket.order_block_txid,
            "registration_ticket_txid": regticket_txid,
        })
        actticket.validate(self.__chainwrapper, image)

        # sign actticket
        signature_actticket = self.__generate_signed_ticket(actticket)

        # place image in chunkstorage
        await mn0.call_masternode("PLACEINCHUNKSTORAGE_REQ", "PLACEINCHUNKSTORAGE_RESP",
                                  [regticket_txid, image.serialize()])

        # have masternodes sign the ticket
        mn_signatures = await self.__collect_mn_actticket_signatures(signature_actticket, actticket, image,
                                                                     masternode_ordering)

        # create combined activation ticket
        final_actticket = self.__generate_final_ticket(FinalActivationTicket, actticket, signature_actticket,
                                                       mn_signatures)

        # ask first MN to store regticket on chain
        actticket_txid = await mn0.call_masternode("PLACEONBLOCKCHAIN_REQ", "PLACEONBLOCKCHAIN_RESP",
                                                   ["actticket", final_actticket.serialize()])

        return actticket_txid