def restore_sources(self, pubkey, tx): """ Restore the sources of a cancelled tx :param sakia.entities.Transaction tx: """ txdoc = TransactionDoc.from_signed_raw(tx.raw) for offset, output in enumerate(txdoc.outputs): if output.conditions.left.pubkey == pubkey: source = Source(currency=self.currency, pubkey=pubkey, identifier=txdoc.sha_hash, type='T', noffset=offset, amount=output.amount, base=output.base) self._sources_processor.drop(source) for index, input in enumerate(txdoc.inputs): source = Source(currency=self.currency, pubkey=txdoc.issuers[0], identifier=input.origin_id, type=input.source, noffset=input.index, amount=input.amount, base=input.base) if source.pubkey == pubkey: self._sources_processor.insert(source)
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
async def process(self, request): data = await request.post() if self.reject_next_post: self.reject_next_post = False return {'ucode': errors.UNHANDLED, 'message': "Rejected"}, 400 transaction = Transaction.from_signed_raw(data["transaction"]) self.forge.pool.append(transaction) return {}, 200
async def initialize_dividends(self, connection, transactions, log_stream, progress): """ Request transactions from the network to initialize data for a given pubkey :param sakia.data.entities.Connection connection: :param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx processor :param function log_stream: :param function progress: progress callback """ blockchain = self._blockchain_repo.get_one( currency=connection.currency) avg_blocks_per_month = int(30 * 24 * 3600 / blockchain.parameters.avg_gen_time) start = blockchain.current_buid.number - avg_blocks_per_month history_data = await self._bma_connector.get( connection.currency, bma.ud.history, req_args={'pubkey': connection.pubkey}) block_numbers = [] dividends = [] for ud_data in history_data["history"]["history"]: if ud_data["block_number"] > start: dividend = Dividend(currency=connection.currency, pubkey=connection.pubkey, block_number=ud_data["block_number"], timestamp=ud_data["time"], amount=ud_data["amount"], base=ud_data["base"]) log_stream("Dividend of block {0}".format( dividend.block_number)) block_numbers.append(dividend.block_number) try: dividends.append(dividend) self._repo.insert(dividend) except sqlite3.IntegrityError: log_stream("Dividend already registered in database") for tx in transactions: txdoc = Transaction.from_signed_raw(tx.raw) for input in txdoc.inputs: if input.source == "D" and input.origin_id == connection.pubkey \ and input.index not in block_numbers and input.index > start: diff_blocks = blockchain.current_buid.number - input.index ud_mediantime = blockchain.median_time - diff_blocks * blockchain.parameters.avg_gen_time dividend = Dividend(currency=connection.currency, pubkey=connection.pubkey, block_number=input.index, timestamp=ud_mediantime, amount=input.amount, base=input.base) log_stream("Dividend of block {0}".format( dividend.block_number)) try: dividends.append(dividend) self._repo.insert(dividend) except sqlite3.IntegrityError: log_stream("Dividend already registered in database") return dividends
async def initialize_dividends(self, connection, transactions, log_stream): """ Request transactions from the network to initialize data for a given pubkey :param sakia.data.entities.Connection connection: :param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx processor :param function log_stream: """ history_data = await self._bma_connector.get( connection.currency, bma.ud.history, req_args={'pubkey': connection.pubkey}) log_stream("Found {0} available dividends".format( len(history_data["history"]["history"]))) block_numbers = [] dividends = [] for ud_data in history_data["history"]["history"]: dividend = Dividend(currency=connection.currency, pubkey=connection.pubkey, block_number=ud_data["block_number"], timestamp=ud_data["time"], amount=ud_data["amount"], base=ud_data["base"]) log_stream("Dividend of block {0}".format(dividend.block_number)) block_numbers.append(dividend.block_number) try: dividends.append(dividend) self._repo.insert(dividend) except sqlite3.IntegrityError: log_stream("Dividend already registered in database") for tx in transactions: txdoc = Transaction.from_signed_raw(tx.raw) for input in txdoc.inputs: if input.source == "D" and input.origin_id == connection.pubkey and input.index not in block_numbers: block = await self._bma_connector.get( connection.currency, bma.blockchain.block, req_args={'number': input.index}) await asyncio.sleep(0.5) dividend = Dividend(currency=connection.currency, pubkey=connection.pubkey, block_number=input.index, timestamp=block["medianTime"], amount=block["dividend"], base=block["unitbase"]) log_stream("Dividend of block {0}".format( dividend.block_number)) try: dividends.append(dividend) self._repo.insert(dividend) except sqlite3.IntegrityError: log_stream("Dividend already registered in database") return dividends
async def initialize_dividends(self, connection, transactions, log_stream, progress): """ Request transactions from the network to initialize data for a given pubkey :param sakia.data.entities.Connection connection: :param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx processor :param function log_stream: :param function progress: progress callback """ blockchain = self._blockchain_repo.get_one(currency=connection.currency) avg_blocks_per_month = int(30 * 24 * 3600 / blockchain.parameters.avg_gen_time) start = blockchain.current_buid.number - avg_blocks_per_month history_data = await self._bma_connector.get(connection.currency, bma.ud.history, req_args={'pubkey': connection.pubkey}) block_numbers = [] dividends = [] for ud_data in history_data["history"]["history"]: if ud_data["block_number"] > start: dividend = Dividend(currency=connection.currency, pubkey=connection.pubkey, block_number=ud_data["block_number"], timestamp=ud_data["time"], amount=ud_data["amount"], base=ud_data["base"]) log_stream("Dividend of block {0}".format(dividend.block_number)) block_numbers.append(dividend.block_number) try: dividends.append(dividend) self._repo.insert(dividend) except sqlite3.IntegrityError: log_stream("Dividend already registered in database") for tx in transactions: txdoc = Transaction.from_signed_raw(tx.raw) for input in txdoc.inputs: if input.source == "D" and input.origin_id == connection.pubkey \ and input.index not in block_numbers and input.index > start: diff_blocks = blockchain.current_buid.number - input.index ud_mediantime = blockchain.median_time - diff_blocks*blockchain.parameters.avg_gen_time dividend = Dividend(currency=connection.currency, pubkey=connection.pubkey, block_number=input.index, timestamp=ud_mediantime, amount=input.amount, base=input.base) log_stream("Dividend of block {0}".format(dividend.block_number)) try: dividends.append(dividend) self._repo.insert(dividend) except sqlite3.IntegrityError: log_stream("Dividend already registered in database") return dividends
def parse_transaction_inputs(self, pubkey, transaction): """ Parse a transaction :param sakia.data.entities.Transaction transaction: """ txdoc = TransactionDoc.from_signed_raw(transaction.raw) for index, input in enumerate(txdoc.inputs): source = Source(currency=self.currency, pubkey=txdoc.issuers[0], identifier=input.origin_id, type=input.source, noffset=input.index, amount=input.amount, base=input.base) if source.pubkey == pubkey: self._sources_processor.drop(source)
def parse_transaction_outputs(self, pubkey, transaction): """ Parse a transaction :param sakia.data.entities.Transaction transaction: """ txdoc = TransactionDoc.from_signed_raw(transaction.raw) for offset, output in enumerate(txdoc.outputs): if output.conditions.left.pubkey == pubkey: source = Source(currency=self.currency, pubkey=pubkey, identifier=txdoc.sha_hash, type='T', noffset=offset, amount=output.amount, base=output.base) self._sources_processor.insert(source)
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
def txdoc(self): """ :rtype: duniterpy.documents.Transaction """ return TransactionDoc.from_signed_raw(self.raw)