예제 #1
0
파일: transfer.py 프로젝트: mmuman/sakia
    async def send(self, txdoc, community):
        """
        Send a transaction and update the transfer state to AWAITING if accepted.
        If the transaction was refused (return code != 200), state becomes REFUSED
        The txdoc is saved as the transfer txdoc.

        :param txdoc: A transaction duniterpy object
        :param community: The community target of the transaction
        """
        self.sha_hash = txdoc.sha_hash
        responses = await community.bma_access.broadcast(
            bma.tx.Process, post_args={'transaction': txdoc.signed_raw()})
        blockUID = community.network.current_blockUID
        block = await community.bma_access.future_request(
            bma.blockchain.Block, req_args={'number': blockUID.number})
        signed_raw = "{0}{1}\n".format(block['raw'], block['signature'])
        block_doc = Block.from_signed_raw(signed_raw)
        result = (False, "")
        for r in responses:
            if r.status == 200:
                result = (True, (await r.json()))
            elif not result[0]:
                result = (False, (await r.text()))
            else:
                await r.text()
        self.run_state_transitions(([r.status for r in responses], block_doc))
        self.run_state_transitions(([r.status for r in responses], ))
        return result
예제 #2
0
    async def handle_new_blocks(self, currency, network_blockstamp):
        """
        Initialize blockchain for a given currency if no source exists locally
        :param str currency:
        :param BlockUID network_blockstamp: the blockstamp of the network
        """

        self._logger.debug("Requesting current block")
        try:
            current_block = await self._bma_connector.get(
                currency,
                bma.blockchain.block,
                req_args={'number': network_blockstamp.number})
            signed_raw = "{0}{1}\n".format(current_block['raw'],
                                           current_block['signature'])
            block = Block.from_signed_raw(signed_raw)
            blockchain = self._repo.get_one(currency=currency)
            blockchain.current_buid = block.blockUID
            blockchain.median_time = block.mediantime
            blockchain.current_members_count = block.members_count

            if blockchain.last_ud_time + blockchain.parameters.dt <= blockchain.median_time:
                await self.refresh_dividend_data(currency, blockchain)

            self._repo.update(blockchain)

        except errors.DuniterError as e:
            if e.ucode != errors.NO_CURRENT_BLOCK:
                raise
예제 #3
0
 async def copy_block_to_clipboard(self, number):
     clipboard = QApplication.clipboard()
     block = await self._community.get_block(number)
     if block:
         block_doc = Block.from_signed_raw("{0}{1}\n".format(
             block['raw'], block['signature']))
         clipboard.setText(block_doc.signed_raw())
예제 #4
0
    def test_block_document(self):
        block_document = """Version: 10
Type: Block
Currency: g1
Number: 15145
PoWMin: 80
Time: 1493684276
MedianTime: 1493681245
UnitBase: 0
Issuer: 6fFt4zdvtNyVcfJn7Y41mKLmMDizyK3nVeNW3qdDXzpc
IssuersFrame: 106
IssuersFrameVar: 0
DifferentIssuersCount: 21
PreviousHash: 00000A0CE0AE54F3F6B63383F386067160C477B5338FB93AF3AF0776A959AA32
PreviousIssuer: D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx
MembersCount: 98
Identities:
Joiners:
Actives:
Leavers:
Revoked:
Excluded:
Certifications:
Transactions:
InnerHash: AA01ABD5C6D3F99A189C0CF0E37768DA0F876526AF93FE150E92B135D4AD0D85
Nonce: 10300000099432
"""
        block_signature = "Uxa3L+/m/dWLex2xSh7Jv1beAn4f99BmoYAs7iX3Lr+t1l5jzJpd9m4iI1cHppIizCgbg6ztaiZedQ+Mp6KuDg=="
        block = Block.from_signed_raw(block_document + block_signature + "\n")
        verifying_key = VerifyingKey(block.issuer)
        self.assertTrue(verifying_key.verify_document(block))
예제 #5
0
    async def send(self, txdoc, community):
        """
        Send a transaction and update the transfer state to AWAITING if accepted.
        If the transaction was refused (return code != 200), state becomes REFUSED
        The txdoc is saved as the transfer txdoc.

        :param txdoc: A transaction duniterpy object
        :param community: The community target of the transaction
        """
        self.sha_hash = txdoc.sha_hash
        responses = await community.bma_access.broadcast(bma.tx.Process,
                post_args={'transaction': txdoc.signed_raw()})
        blockUID = community.network.current_blockUID
        block = await community.bma_access.future_request(bma.blockchain.Block,
                                  req_args={'number': blockUID.number})
        signed_raw = "{0}{1}\n".format(block['raw'], block['signature'])
        block_doc = Block.from_signed_raw(signed_raw)
        result = (False, "")
        for r in responses:
            if r.status == 200:
                result = (True, (await r.json()))
            elif not result[0]:
                result = (False, (await r.text()))
            else:
                await r.text()
        self.run_state_transitions(([r.status for r in responses], block_doc))
        self.run_state_transitions(([r.status for r in responses], ))
        return result
예제 #6
0
파일: txhistory.py 프로젝트: mmuman/sakia
 async def _get_block_doc(self, community, number):
     """
     Retrieve the current block document
     :param sakia.core.Community community: The community we look for a block
     :param int number: The block number to retrieve
     :return: the block doc or None if no block was found
     """
     tries = 0
     block_doc = None
     block = None
     while block is None and tries < 3:
         try:
             block = await community.bma_access.future_request(
                 bma.blockchain.Block, req_args={'number': number})
             signed_raw = "{0}{1}\n".format(block['raw'],
                                            block['signature'])
             try:
                 block_doc = Block.from_signed_raw(signed_raw)
             except TypeError:
                 logging.debug("Error in {0}".format(number))
                 block = None
                 tries += 1
         except errors.DuniterError as e:
             if e.ucode == errors.BLOCK_NOT_FOUND:
                 block = None
                 tries += 1
     return block_doc
예제 #7
0
    async def parse_dividends_history(self, connections, blocks, transactions):
        """
        Request transactions from the network to initialize data for a given pubkey
        :param List[sakia.data.entities.Connection] connections: the list of connections found by tx parsing
        :param List[duniterpy.documents.Block] blocks: the list of transactions found by tx parsing
        :param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx parsing
        """
        min_block_number = blocks[0].number
        max_block_number = blocks[-1].number
        dividends = {}
        for connection in connections:
            dividends[connection] = []
            history_data = await self._bma_connector.get(
                self.currency,
                bma.ud.history,
                req_args={'pubkey': connection.pubkey})
            block_numbers = []
            for ud_data in history_data["history"]["history"]:
                dividend = Dividend(currency=self.currency,
                                    pubkey=connection.pubkey,
                                    block_number=ud_data["block_number"],
                                    timestamp=ud_data["time"],
                                    amount=ud_data["amount"],
                                    base=ud_data["base"])
                if max_block_number >= dividend.block_number >= min_block_number:
                    self._logger.debug("Dividend of block {0}".format(
                        dividend.block_number))
                    block_numbers.append(dividend.block_number)
                    if self._dividends_processor.commit(dividend):
                        dividends[connection].append(dividend)

            for tx in transactions[connection]:
                txdoc = TransactionDoc.from_signed_raw(tx.raw)
                for input in txdoc.inputs:
                    # For each dividends inputs, if it is consumed (not present in ud history)
                    if input.source == "D" and input.origin_id == connection.pubkey and input.index not in block_numbers:
                        try:
                            # we try to get the block of the dividend
                            block = next(
                                (b for b in blocks if b.number == input.index))
                        except StopIteration:
                            block_data = await self._bma_connector.get(
                                self.currency,
                                bma.blockchain.block,
                                req_args={'number': input.index})
                            block = Block.from_signed_raw(
                                block_data["raw"] + block_data["signature"] +
                                "\n")
                        dividend = Dividend(currency=self.currency,
                                            pubkey=connection.pubkey,
                                            block_number=input.index,
                                            timestamp=block.mediantime,
                                            amount=block.ud,
                                            base=block.unit_base)
                        self._logger.debug("Dividend of block {0}".format(
                            dividend.block_number))
                        if self._dividends_processor.commit(dividend):
                            dividends[connection].append(dividend)
        return dividends
예제 #8
0
def test_verify_block_signature(signature, block_raw):
    # Check with valid and non-valid signatures block
    invalid_signatures_blocks = []
    block = Block.from_signed_raw(block_raw + signature + "\n")
    verify_block_signature(invalid_signatures_blocks, block)
    if block.number == G1_INVALID_BLOCK_SIG:
        assert invalid_signatures_blocks == [block.number]
    else:
        assert invalid_signatures_blocks == []
예제 #9
0
    async def initialize_blockchain(self, currency):
        """
        Initialize blockchain for a given currency if no source exists locally
        """
        blockchain = self._repo.get_one(currency=currency)
        if not blockchain:
            blockchain = Blockchain(currency=currency)
            self._logger.debug("Requesting blockchain parameters")
            try:
                parameters = await self._bma_connector.get(
                    currency, bma.blockchain.parameters)
                blockchain.parameters.ms_validity = parameters['msValidity']
                blockchain.parameters.avg_gen_time = parameters['avgGenTime']
                blockchain.parameters.c = parameters['c']
                blockchain.parameters.dt = parameters['dt']
                blockchain.parameters.dt_diff_eval = parameters['dtDiffEval']
                blockchain.parameters.median_time_blocks = parameters[
                    'medianTimeBlocks']
                blockchain.parameters.percent_rot = parameters['percentRot']
                blockchain.parameters.idty_window = parameters['idtyWindow']
                blockchain.parameters.ms_window = parameters['msWindow']
                blockchain.parameters.sig_window = parameters['sigWindow']
                blockchain.parameters.sig_period = parameters['sigPeriod']
                blockchain.parameters.sig_qty = parameters['sigQty']
                blockchain.parameters.sig_stock = parameters['sigStock']
                blockchain.parameters.sig_validity = parameters['sigValidity']
                blockchain.parameters.sig_qty = parameters['sigQty']
                blockchain.parameters.sig_period = parameters['sigPeriod']
                blockchain.parameters.ud0 = parameters['ud0']
                blockchain.parameters.ud_time_0 = parameters['udTime0']
                blockchain.parameters.dt_reeval = parameters['dtReeval']
                blockchain.parameters.ud_reeval_time_0 = parameters[
                    'udReevalTime0']
                blockchain.parameters.xpercent = parameters['xpercent']
            except errors.DuniterError as e:
                raise

        self._logger.debug("Requesting current block")
        try:
            current_block = await self._bma_connector.get(
                currency, bma.blockchain.current)
            signed_raw = "{0}{1}\n".format(current_block['raw'],
                                           current_block['signature'])
            block = Block.from_signed_raw(signed_raw)
            blockchain.current_buid = block.blockUID
            blockchain.median_time = block.mediantime
            blockchain.current_members_count = block.members_count
            blockchain.current_mass = current_block['monetaryMass']
        except errors.DuniterError as e:
            if e.ucode != errors.NO_CURRENT_BLOCK:
                raise
        await self.refresh_dividend_data(currency, blockchain)

        try:
            self._repo.insert(blockchain)
        except sqlite3.IntegrityError:
            self._repo.update(blockchain)
예제 #10
0
 async def get_raw_document(self, community):
     """
     Get the raw documents of this transfer
     """
     block = await community.get_block(self.blockUID.number)
     if block:
         block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature']))
         for tx in block_doc.transactions:
             if tx.sha_hash == self.sha_hash:
                 return tx
예제 #11
0
파일: transfer.py 프로젝트: mmuman/sakia
 async def get_raw_document(self, community):
     """
     Get the raw documents of this transfer
     """
     block = await community.get_block(self.blockUID.number)
     if block:
         block_doc = Block.from_signed_raw("{0}{1}\n".format(
             block['raw'], block['signature']))
         for tx in block_doc.transactions:
             if tx.sha_hash == self.sha_hash:
                 return tx
예제 #12
0
    def build_data(self):
        previous_hash = self.previous_hash()
        previous_issuer = self.previous_issuer()
        parameters = self.parameters()
        members_count = self.members_count()
        identities = self.identities()
        joiners = self.joiners()
        actives = self.actives()
        leavers = self.leavers()
        revocations = self.revocations()
        excluded = self.excluded()
        certifications = self.certifications()
        transactions = self.transactions()

        block = Block(10, self.currency, len(self.blocks), 1, int(time.time()),
                      int(time.time()), self.next_dividend(), 0, 
                      self.key.pubkey, 5, 5, 5, previous_hash, previous_issuer, 
                      parameters, members_count, identities, 
                      joiners, actives, leavers, 
                      revocations, excluded, certifications, 
                      transactions, "", 0, None)
        block.inner_hash = block.computed_inner_hash()
        return block
예제 #13
0
 async def get_block(self, currency, number):
     """
     Get block documen at a given number
     :param str currency:
     :param int number:
     :rtype: duniterpy.documents.Block
     """
     block = await self._bma_connector.get(currency,
                                           bma.blockchain.block,
                                           req_args={'number': number})
     if block:
         block_doc = Block.from_signed_raw("{0}{1}\n".format(
             block['raw'], block['signature']))
         return block_doc
예제 #14
0
    async def copy_membership_to_clipboard(self, identity):
        """

        :param sakia.core.registry.Identity identity:
        :return:
        """
        clipboard = QApplication.clipboard()
        try:
            membership = await identity.membership(self._community)
            if membership:
                block_number = membership['written']
                block = await self._community.get_block(block_number)
                block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature']))
                for ms_doc in block_doc.joiners:
                    if ms_doc.issuer == identity.pubkey:
                        clipboard.setText(ms_doc.signed_raw())
        except MembershipNotFoundError:
            logging.debug("Could not find membership")
예제 #15
0
    async def parse_dividends_history(self, connections, start, end, transactions):
        """
        Request transactions from the network to initialize data for a given pubkey
        :param List[sakia.data.entities.Connection] connections: the list of connections found by tx parsing
        :param List[duniterpy.documents.Block] blocks: the list of transactions found by tx parsing
        :param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx parsing
        """
        dividends = {}
        for connection in connections:
            dividends[connection] = []
            history_data = await self._bma_connector.get(self.currency, bma.ud.history,
                                                         req_args={'pubkey': connection.pubkey})
            block_numbers = []
            for ud_data in history_data["history"]["history"]:
                dividend = Dividend(currency=self.currency,
                                    pubkey=connection.pubkey,
                                    block_number=ud_data["block_number"],
                                    timestamp=ud_data["time"],
                                    amount=ud_data["amount"],
                                    base=ud_data["base"])
                if start <= dividend.block_number <= end:
                    self._logger.debug("Dividend of block {0}".format(dividend.block_number))
                    block_numbers.append(dividend.block_number)
                    if self._dividends_processor.commit(dividend):
                        dividends[connection].append(dividend)

            for tx in transactions[connection]:
                txdoc = TransactionDoc.from_signed_raw(tx.raw)
                for input in txdoc.inputs:
                    # For each dividends inputs, if it is consumed (not present in ud history)
                    if input.source == "D" and input.origin_id == connection.pubkey and input.index not in block_numbers:
                        block_data = await self._bma_connector.get(self.currency, bma.blockchain.block,
                                                              req_args={'number': input.index})
                        block = Block.from_signed_raw(block_data["raw"] + block_data["signature"] + "\n")
                        dividend = Dividend(currency=self.currency,
                                            pubkey=connection.pubkey,
                                            block_number=input.index,
                                            timestamp=block.mediantime,
                                            amount=block.ud,
                                            base=block.unit_base)
                        self._logger.debug("Dividend of block {0}".format(dividend.block_number))
                        if self._dividends_processor.commit(dividend):
                            dividends[connection].append(dividend)
        return dividends
예제 #16
0
    async def copy_membership_to_clipboard(self, identity):
        """

        :param sakia.core.registry.Identity identity:
        :return:
        """
        clipboard = QApplication.clipboard()
        try:
            membership = await identity.membership(self._community)
            if membership:
                block_number = membership['written']
                block = await self._community.get_block(block_number)
                block_doc = Block.from_signed_raw("{0}{1}\n".format(
                    block['raw'], block['signature']))
                for ms_doc in block_doc.joiners:
                    if ms_doc.issuer == identity.pubkey:
                        clipboard.setText(ms_doc.signed_raw())
        except MembershipNotFoundError:
            logging.debug("Could not find membership")
예제 #17
0
    async def next_blocks(self, start, filter, currency):
        """
        Get blocks from the network
        :param List[int] numbers: list of blocks numbers to get
        :return: the list of block documents
        :rtype: List[duniterpy.documents.Block]
        """
        blocks = []
        blocks_data = await self._bma_connector.get(currency,
                                                    bma.blockchain.blocks,
                                                    req_args={
                                                        'count': 100,
                                                        'start': start
                                                    })
        for data in blocks_data:
            if data['number'] in filter or data['number'] == start + 99:
                blocks.append(
                    Block.from_signed_raw(data["raw"] + data["signature"] +
                                          "\n"))

        return blocks
예제 #18
0
파일: blocks.py 프로젝트: duniter/silkaj
async def verify_blocks_signatures(from_block, to_block):
    client = Client(EndPoint().BMA_ENDPOINT)
    to_block = await check_passed_blocks_range(client, from_block, to_block)
    invalid_blocks_signatures = list()
    chunks_from = range(from_block, to_block + 1, BMA_MAX_BLOCKS_CHUNK_SIZE)
    with progressbar(chunks_from,
                     label="Processing blocks verification") as bar:
        for chunk_from in bar:
            chunk_size = get_chunk_size(from_block, to_block, chunks_from,
                                        chunk_from)
            logging.info("Processing chunk from block {} to {}".format(
                chunk_from, chunk_from + chunk_size))
            chunk = await get_chunk(client, chunk_size, chunk_from)

            for block in chunk:
                block = Block.from_signed_raw(block["raw"] +
                                              block["signature"] + "\n")
                verify_block_signature(invalid_blocks_signatures, block)

    await client.close()
    display_result(from_block, to_block, invalid_blocks_signatures)
예제 #19
0
    async def send_selfcert(self, password, community):
        """
        Send our self certification to a target community

        :param str password: The account SigningKey password
        :param community: The community target of the self certification
        """
        try:
            block_data = await community.bma_access.simple_request(bma.blockchain.Current)
            signed_raw = "{0}{1}\n".format(block_data['raw'], block_data['signature'])
            block_uid = Block.from_signed_raw(signed_raw).blockUID
        except errors.DuniterError as e:
            if e.ucode == errors.NO_CURRENT_BLOCK:
                block_uid = BlockUID.empty()
            else:
                raise
        selfcert = SelfCertification(PROTOCOL_VERSION,
                                     community.currency,
                                     self.pubkey,
                                     self.name,
                                     block_uid,
                                     None)
        key = SigningKey(self.salt, password)
        selfcert.sign([key])
        logging.debug("Key publish : {0}".format(selfcert.signed_raw()))

        responses = await community.bma_access.broadcast(bma.wot.Add, {}, {'identity': selfcert.signed_raw()})
        result = (False, "")
        for r in responses:
            if r.status == 200:
                result = (True, (await r.json()))
            elif not result[0]:
                result = (False, (await r.text()))
            else:
                await r.release()
        if result[0]:
            (await self.identity(community)).sigdate = block_uid
        return result
예제 #20
0
    async def send_selfcert(self, password, community):
        """
        Send our self certification to a target community

        :param str password: The account SigningKey password
        :param community: The community target of the self certification
        """
        try:
            block_data = await community.bma_access.simple_request(bma.blockchain.Current)
            signed_raw = "{0}{1}\n".format(block_data['raw'], block_data['signature'])
            block_uid = Block.from_signed_raw(signed_raw).blockUID
        except errors.DuniterError as e:
            if e.ucode == errors.NO_CURRENT_BLOCK:
                block_uid = BlockUID.empty()
            else:
                raise
        selfcert = SelfCertification(PROTOCOL_VERSION,
                                     community.currency,
                                     self.pubkey,
                                     self.name,
                                     block_uid,
                                     None)
        key = SigningKey(self.salt, password)
        selfcert.sign([key])
        logging.debug("Key publish : {0}".format(selfcert.signed_raw()))

        responses = await community.bma_access.broadcast(bma.wot.Add, {}, {'identity': selfcert.signed_raw()})
        result = (False, "")
        for r in responses:
            if r.status == 200:
                result = (True, (await r.json()))
            elif not result[0]:
                result = (False, (await r.text()))
            else:
                await r.release()
        if result[0]:
            (await self.identity(community)).sigdate = block_uid
        return result
예제 #21
0
    async def initialize_blockchain(self, currency, log_stream):
        """
        Initialize blockchain for a given currency if no source exists locally
        """
        blockchain = self._repo.get_one(currency=currency)
        if not blockchain:
            blockchain = Blockchain(currency=currency)
            log_stream("Requesting blockchain parameters")
            try:
                parameters = await self._bma_connector.get(
                    currency, bma.blockchain.parameters)
                blockchain.parameters.ms_validity = parameters['msValidity']
                blockchain.parameters.avg_gen_time = parameters['avgGenTime']
                blockchain.parameters.c = parameters['c']
                blockchain.parameters.dt = parameters['dt']
                blockchain.parameters.dt_diff_eval = parameters['dtDiffEval']
                blockchain.parameters.median_time_blocks = parameters[
                    'medianTimeBlocks']
                blockchain.parameters.percent_rot = parameters['percentRot']
                blockchain.parameters.idty_window = parameters['idtyWindow']
                blockchain.parameters.ms_window = parameters['msWindow']
                blockchain.parameters.sig_window = parameters['sigWindow']
                blockchain.parameters.sig_period = parameters['sigPeriod']
                blockchain.parameters.sig_qty = parameters['sigQty']
                blockchain.parameters.sig_stock = parameters['sigStock']
                blockchain.parameters.sig_validity = parameters['sigValidity']
                blockchain.parameters.sig_qty = parameters['sigQty']
                blockchain.parameters.sig_period = parameters['sigPeriod']
                blockchain.parameters.ud0 = parameters['ud0']
                blockchain.parameters.dt_reeval = parameters['dtReeval']
                blockchain.parameters.ud_reeval_time_0 = parameters[
                    'udReevalTime0']
                blockchain.parameters.xpercent = parameters['xpercent']
            except errors.DuniterError as e:
                raise

        log_stream("Requesting current block")
        try:
            current_block = await self._bma_connector.get(
                currency, bma.blockchain.current)
            signed_raw = "{0}{1}\n".format(current_block['raw'],
                                           current_block['signature'])
            block = Block.from_signed_raw(signed_raw)
            blockchain.current_buid = block.blockUID
            blockchain.median_time = block.mediantime
            blockchain.current_members_count = block.members_count
        except errors.DuniterError as e:
            if e.ucode != errors.NO_CURRENT_BLOCK:
                raise

        log_stream("Requesting blocks with dividend")
        with_ud = await self._bma_connector.get(currency, bma.blockchain.ud)
        blocks_with_ud = with_ud['result']['blocks']

        if len(blocks_with_ud) > 0:
            log_stream("Requesting last block with dividend")
            try:
                index = max(len(blocks_with_ud) - 1, 0)
                block_number = blocks_with_ud[index]
                block_with_ud = await self._bma_connector.get(
                    currency,
                    bma.blockchain.block,
                    req_args={'number': block_number})
                if block_with_ud:
                    blockchain.last_members_count = block_with_ud[
                        'membersCount']
                    blockchain.last_ud = block_with_ud['dividend']
                    blockchain.last_ud_base = block_with_ud['unitbase']
                    blockchain.last_ud_time = block_with_ud['medianTime']
                    blockchain.current_mass = block_with_ud['monetaryMass']
            except errors.DuniterError as e:
                if e.ucode != errors.NO_CURRENT_BLOCK:
                    raise

            log_stream("Requesting previous block with dividend")
            try:
                index = max(len(blocks_with_ud) - 2, 0)
                block_number = blocks_with_ud[index]
                block_with_ud = await self._bma_connector.get(
                    currency,
                    bma.blockchain.block,
                    req_args={'number': block_number})
                blockchain.previous_mass = block_with_ud['monetaryMass']
                blockchain.previous_members_count = block_with_ud[
                    'membersCount']
                blockchain.previous_ud = block_with_ud['dividend']
                blockchain.previous_ud_base = block_with_ud['unitbase']
                blockchain.previous_ud_time = block_with_ud['medianTime']
            except errors.DuniterError as e:
                if e.ucode != errors.NO_CURRENT_BLOCK:
                    raise

        try:
            self._repo.insert(blockchain)
        except sqlite3.IntegrityError:
            self._repo.update(blockchain)
예제 #22
0
파일: txhistory.py 프로젝트: mmuman/sakia
    async def _refresh(self, community, block_number_from, block_to,
                       received_list):
        """
        Refresh last transactions

        :param sakia.core.Community community: The community
        :param list received_list: List of transactions received
        """
        new_transfers = []
        new_dividends = []
        try:
            logging.debug("Refresh from : {0} to {1}".format(
                block_number_from, block_to['number']))
            dividends = await self.request_dividends(community,
                                                     block_number_from)
            with_tx_data = await community.bma_access.future_request(
                bma.blockchain.TX)
            blocks_with_tx = with_tx_data['result']['blocks']
            while block_number_from <= block_to['number']:
                udid = 0
                for d in [
                        ud for ud in dividends
                        if ud['block_number'] == block_number_from
                ]:
                    state = TransferState.VALIDATED if block_number_from + MAX_CONFIRMATIONS <= block_to['number'] \
                        else TransferState.VALIDATING

                    if d['block_number'] not in [
                            ud['block_number'] for ud in self._dividends
                    ]:
                        d['id'] = udid
                        d['state'] = state
                        new_dividends.append(d)

                        udid += 1
                    else:
                        known_dividend = [
                            ud for ud in self._dividends
                            if ud['block_number'] == d['block_number']
                        ][0]
                        known_dividend['state'] = state

                # We parse only blocks with transactions
                if block_number_from in blocks_with_tx:
                    transfers = await self._parse_block(
                        community, block_number_from, received_list,
                        udid + len(new_transfers))
                    new_transfers += transfers

                self.wallet.refresh_progressed.emit(block_number_from,
                                                    block_to['number'],
                                                    self.wallet.pubkey)
                block_number_from += 1

            signed_raw = "{0}{1}\n".format(block_to['raw'],
                                           block_to['signature'])
            block_to = Block.from_signed_raw(signed_raw)
            for transfer in [
                    t for t in self._transfers + new_transfers
                    if t.state == TransferState.VALIDATING
            ]:
                transfer.run_state_transitions(
                    (False, block_to, MAX_CONFIRMATIONS))

            # We check if latest parsed block_number is a new high number
            if block_number_from > self.latest_block:
                self.available_sources = await self.wallet.sources(community)
                if self._stop_coroutines:
                    return
                self.latest_block = block_number_from

            parameters = await community.parameters()
            for transfer in [
                    t for t in self._transfers
                    if t.state == TransferState.AWAITING
            ]:
                transfer.run_state_transitions(
                    (False, block_to, parameters['avgGenTime'],
                     parameters['medianTimeBlocks']))
        except (MalformedDocumentError, NoPeerAvailable) as e:
            logging.debug(str(e))
            self.wallet.refresh_finished.emit([])
            return

        self._transfers = self._transfers + new_transfers
        self._dividends = self._dividends + new_dividends

        self.wallet.refresh_finished.emit(received_list)
예제 #23
0
 async def copy_block_to_clipboard(self, number):
     clipboard = QApplication.clipboard()
     block = await self._community.get_block(number)
     if block:
         block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature']))
         clipboard.setText(block_doc.signed_raw())