예제 #1
0
    def gettransactions(self, address, after_txid='', limit=MAX_TRANSACTIONS):
        assert(limit > 0)
        txs = []
        while True:
            variables = {'limit': limit, 'after': after_txid}
            res = self.compose_request('tx', 'address', address, variables)
            for tx in res:
                txs.append(self._parse_transaction(tx))
            if not txs or len(txs) >= limit:
                break
            if len(res) == limit:
                after_txid = res[limit-1]['hash']
            else:
                break

        # Check which outputs are spent/unspent for this address
        if not after_txid and len(txs) != limit:
            txs = transaction_update_spents(txs, address)
        return txs
예제 #2
0
    def gettransactions(self, address, after_txid='', limit=MAX_TRANSACTIONS):
        """
        Get all transactions for specified address.

        Sorted from old to new, so transactions with highest number of confirmations first.

        :param address: Address string
        :type address: str
        :param after_txid: Transaction ID of last known transaction. Only check for transactions after given tx id. Default: Leave empty to return all transaction. If used only provide a single address
        :type after_txid: str
        :param limit: Maximum number of transactions to return
        :type limit: int

        :return list: List of Transaction objects
        """
        self._reset_results()
        self.results_cache_n = 0
        if not address:
            return []
        if not isinstance(address, TYPE_TEXT):
            raise ServiceError("Address parameter must be of type text")
        if after_txid is None:
            after_txid = ''
        db_addr = self.cache.getaddress(address)
        txs_cache = []
        qry_after_txid = after_txid

        # Retrieve transactions from cache
        caching_enabled = True
        if self.min_providers > 1:  # Disable cache if comparing providers
            caching_enabled = False

        if caching_enabled:
            txs_cache = self.cache.gettransactions(address, after_txid,
                                                   limit) or []
            if txs_cache:
                self.results_cache_n = len(txs_cache)
                if len(txs_cache) == limit:
                    return txs_cache
                limit = limit - len(txs_cache)
                qry_after_txid = txs_cache[-1:][0].txid

        # Get (extra) transactions from service providers
        txs = []
        if not (db_addr and db_addr.last_block and db_addr.last_block >=
                self.blockcount()) or not caching_enabled:
            txs = self._provider_execute('gettransactions', address,
                                         qry_after_txid, limit)
            if txs is False:
                raise ServiceError(
                    "Error when retrieving transactions from service provider")

        # Store transactions and address in cache
        # - disable cache if comparing providers or if after_txid is used and no cache is available
        last_block = None
        last_txid = None
        if self.min_providers <= 1 and not (after_txid and
                                            not db_addr) and caching_enabled:
            last_block = self.blockcount()
            last_txid = qry_after_txid
            self.complete = True
            if len(txs) == limit:
                self.complete = False
                last_block = txs[-1:][0].block_height
            if len(txs):
                last_txid = txs[-1:][0].txid
            if len(self.results):
                order_n = 0
                for t in txs:
                    if t.confirmations != 0:
                        res = self.cache.store_transaction(t,
                                                           order_n,
                                                           commit=False)
                        order_n += 1
                        # Failure to store transaction: stop caching transaction and store last tx block height - 1
                        if res is False:
                            if t.block_height:
                                last_block = t.block_height - 1
                            break
                self.cache.session.commit()
                self.cache.store_address(address,
                                         last_block,
                                         last_txid=last_txid,
                                         txs_complete=self.complete)

        all_txs = txs_cache + txs
        # If we have txs for this address update spent and balance information in cache
        if self.complete:
            all_txs = transaction_update_spents(all_txs, address)
            if caching_enabled:
                self.cache.store_address(address,
                                         last_block,
                                         last_txid=last_txid,
                                         txs_complete=True)
                for t in all_txs:
                    self.cache.store_transaction(t, commit=False)
                self.cache.session.commit()
        return all_txs