Ejemplo n.º 1
0
    def next_transaction(self):
        with self._condition:
            if self._in_progress_transaction is not None:
                return None

            txn = None
            while txn is None:
                try:
                    txn = self._txn_queue.get()
                except EmptyQueue:
                    if self._final:
                        raise StopIteration()
                    return None
                # Handle this transaction being invalid based on a
                # dependency.
                if any(
                        self._dep_is_known(d) and self._in_invalid_batch(d)
                        for d in self._get_dependencies(txn)):
                    self._set_batch_result(txn.header_signature, False, None)
                    self._check_change_last_good_context_id(txn=txn)
                    txn = None
                    continue
                # Handle fail fast.
                if self._in_invalid_batch(txn.header_signature):
                    self._handle_fail_fast(txn)
                    txn = None

            self._in_progress_transaction = txn.header_signature
            base_contexts = [] if self._previous_context_id is None \
                else [self._previous_context_id]
            txn_info = TxnInformation(txn=txn,
                                      state_hash=self._previous_state_hash,
                                      base_context_ids=base_contexts)
            self._scheduled_transactions.append(txn_info)
            return txn_info
Ejemplo n.º 2
0
    def next_transaction(self):
        with self._condition:
            if self._in_progress_transaction is not None:
                return None

            txn = None
            try:
                while txn is None:
                    txn = self._txn_queue.get(block=False)
                    # Handle this transaction being invalid based on a
                    # dependency.
                    if any(
                            self._dep_is_known(d) and self._dep_is_not_valid(d)
                            for d in self._get_dependencies(txn)):
                        self._set_batch_result(txn.header_signature, False,
                                               None)
                        txn = None
            except queue.Empty:
                return None

            self._in_progress_transaction = txn.header_signature
            base_contexts = [] if self._previous_context_id is None \
                else [self._previous_context_id]
            txn_info = TxnInformation(txn=txn,
                                      state_hash=self._previous_state_hash,
                                      base_context_ids=base_contexts)
            self._scheduled_transactions.append(txn_info)
            return txn_info
Ejemplo n.º 3
0
    def next_transaction(self):
        with self._condition:
            # We return the next transaction which hasn't been scheduled and
            # is not blocked by a dependency.

            next_txn = None

            no_longer_available = []

            for txn_id, txn in self._txns_available.items():
                if (self._has_predecessors(txn_id)
                        or self._is_outstanding(txn_id)):
                    continue

                header = TransactionHeader()
                header.ParseFromString(txn.header)
                deps = tuple(header.dependencies)

                if self._dependency_not_processed(deps):
                    continue

                if self._txn_failed_by_dep(deps):
                    no_longer_available.append(txn_id)
                    self._txn_results[txn_id] = \
                        TxnExecutionResult(
                            signature=txn_id,
                            is_valid=False,
                            context_id=None,
                            state_hash=None)
                    continue

                if not self._txn_is_in_valid_batch(txn_id) and \
                        self._can_fail_fast(txn_id):
                    self._txn_results[txn_id] = \
                        TxnExecutionResult(
                            signature=txn_id,
                            is_valid=False,
                            context_id=None,
                            state_hash=None)
                    no_longer_available.append(txn_id)
                    continue

                next_txn = txn
                break

            for txn_id in no_longer_available:
                del self._txns_available[txn_id]

            if next_txn is not None:
                bases = self._get_initial_state_for_transaction(next_txn)

                info = TxnInformation(
                    txn=next_txn,
                    state_hash=self._first_state_hash,
                    base_context_ids=bases)
                self._scheduled.append(next_txn.header_signature)
                del self._txns_available[next_txn.header_signature]
                self._scheduled_txn_info[next_txn.header_signature] = info
                return info
            return None
Ejemplo n.º 4
0
    def next_transaction(self):
        with self._condition:
            # We return the next transaction which hasn't been scheduled and
            # is not blocked by a dependency.

            next_txn = None
            for txn in self._unscheduled_transactions():
                if not self._has_predecessors(txn) and \
                        not self._is_outstanding(txn) and \
                        not self._dependency_not_processed(txn):
                    if self._txn_failed_by_dep(txn):
                        self._txn_results[txn.header_signature] = \
                            TransactionExecutionResult(False, None, None)
                        continue
                    next_txn = txn
                    break

            if next_txn is not None:
                bases = self._get_initial_state_for_transaction(next_txn)

                info = TxnInformation(txn=next_txn,
                                      state_hash=self._first_state_hash,
                                      base_context_ids=bases)
                self._scheduled.append(next_txn.header_signature)
                self._scheduled_txn_info[next_txn.header_signature] = info
                return info
            return None
Ejemplo n.º 5
0
    def next_transaction(self):
        with self._condition:
            # We return the next transaction which hasn't been scheduled and
            # is not blocked by a dependency.

            next_txn = None
            for txn in self._unscheduled_transactions():
                if not self._has_predecessors(txn) and \
                        not self._is_outstanding(txn) and \
                        not self._dependency_not_processed(txn):
                    if self._txn_failed_by_dep(txn):
                        self._txns_available.remove(txn)
                        self._txn_results[txn.header_signature] = \
                            TxnExecutionResult(
                                signature=txn.header_signature,
                                is_valid=False,
                                context_id=None,
                                state_hash=None)
                        continue
                    txn_id = txn.header_signature
                    if not self._txn_is_in_valid_batch(
                            txn_id) and self._can_fail_fast(txn_id):

                        self._txn_results[
                            txn.header_signature] = TxnExecutionResult(
                                False, None, None)
                        self._txns_available.remove(txn)
                        continue
                    next_txn = txn
                    break

            if next_txn is not None:
                bases = self._get_initial_state_for_transaction(next_txn)
                #
                """
                for DAG self._first_state_hash can be changed real_state_hash and set this state for all transaction into this block 
                so we should update  _first_state_hash only for first computing batch into this block 
                """
                if not self._is_first_state_hash_updated:
                    real_state_hash = self._merkle_root(
                    ) if self._merkle_root else ''
                    LOGGER.debug(
                        'next_transaction: real_state_hash=%s bases=%s',
                        real_state_hash[:8], bases)
                    self._first_state_hash = real_state_hash
                    self._is_first_state_hash_updated = True
                LOGGER.debug('next_transaction: tnx=%s STATE=%s\n',
                             next_txn.header_signature[:8],
                             self._first_state_hash[:8])
                info = TxnInformation(txn=next_txn,
                                      state_hash=self._first_state_hash,
                                      base_context_ids=bases)
                self._scheduled.append(next_txn.header_signature)
                self._txns_available.remove(next_txn)
                self._scheduled_txn_info[next_txn.header_signature] = info
                return info
            return None
Ejemplo n.º 6
0
    def next_transaction(self):
        with self._condition:
            if self._in_progress_transaction is not None:
                return None
            try:
                txn = self._txn_queue.get(block=False)
            except queue.Empty:
                return None

            self._in_progress_transaction = txn.header_signature
            txn_info = TxnInformation(txn, self._last_state_hash)
            self._scheduled_transactions.append(txn_info)
            return txn_info
Ejemplo n.º 7
0
    def next_transaction(self):
        with self._condition:
            if self._in_progress_transaction is not None:
                return None
            try:
                txn = self._txn_queue.get(block=False)
            except queue.Empty:
                return None

            self._in_progress_transaction = txn.header_signature
            base_contexts = [] if self._previous_context_id is None \
                else [self._previous_context_id]
            txn_info = TxnInformation(txn=txn,
                                      state_hash=self._previous_state_hash,
                                      base_context_ids=base_contexts)
            self._scheduled_transactions.append(txn_info)
            return txn_info
Ejemplo n.º 8
0
    def next_transaction(self):
        with self._condition:
            if self._in_progress_transaction is not None:
                return None

            txn = None
            while txn is None:
                try:
                    txn = self._txn_queue.popleft()
                except IndexError:
                    if self._final:
                        self._condition.notify_all()
                        raise StopIteration()
                    return None
                # Handle this transaction being invalid based on a
                # dependency.
                if any(
                        self._dep_is_known(d) and self._in_invalid_batch(d)
                        for d in self._get_dependencies(txn)):
                    self._set_batch_result(txn.header_signature, False, None)
                    self._check_change_last_good_context_id(txn=txn)
                    txn = None
                    continue
                # Handle fail fast.
                if self._in_invalid_batch(txn.header_signature):
                    self._handle_fail_fast(txn)
                    txn = None

            self._in_progress_transaction = txn.header_signature
            base_contexts = [] if self._previous_context_id is None else [
                self._previous_context_id
            ]
            # for DAG we should use real merkle root
            real_state_hash = self._merkle_root() if self._merkle_root else ''
            LOGGER.debug('next_transaction: tnx=%s PREV STATE=%s~%s \n',
                         txn.header_signature[:8],
                         self._previous_state_hash[:8], real_state_hash[:8])
            txn_info = TxnInformation(
                txn=txn,
                state_hash=self._previous_state_hash
                if real_state_hash == '' else real_state_hash,
                base_context_ids=base_contexts)
            self._scheduled_transactions.append(txn_info)
            return txn_info