Esempio n. 1
0
    def _execute_phase_1(self, config, current_block_id):
        """
        TODO update all EXEC comments/docs
        * Each node gathers all transactions that may be included in the prospective block and groups them by transaction owner.
        * All transactions owned (or sourced from) a respective node's business unit or system (owned) are grouped for approval.
        * All transactions not owned by the node's business unit or system (others) are grouped for validation.
        * All owned transactions are verified per business rules, configurable, (e.g, existence or non-existence of particular fields, with field value validation logic).
        * All owned and verified transactions are "approved" by executing the Transaction Verification Signing Process defined below.
        * Any transactions deemed "unapproved" will be taken out of the prospective block from a node's perspective by non-inclusion in the signing process, and sent to a system "pool" or "queue" for analysis and alternate processing
        * All other (non-owned) transactions are validated to system wide rules agreed upon for all nodes through business and system processes.
        * All other (non-owned) transactions are declared "valid" by the node by executing the Transaction Verification Signing Process defined below.
        * Any transactions deemed "invalid" will be taken out of the prospective block from a node's perspective by non-inclusion in the signing process, and sent to a system "pool" or "queue" for analysis and alternate processing.
        """
        print("Phase 1 Verify Start.")
        # Group transactions for last 5 seconds into current block id
        block_bound_lower_ts = get_block_time(current_block_id -
                                              BLOCK_FIXATE_OFFSET)
        print("""Time bounds: %i - %i""" %
              (block_bound_lower_ts, block_bound_lower_ts + BLOCK_INTERVAL))
        transaction_db.fixate_block(block_bound_lower_ts,
                                    block_bound_lower_ts + BLOCK_INTERVAL,
                                    current_block_id)

        if 'approve_block' in config:
            return config['approve_block'](config, current_block_id)

        transactions = transaction_db.get_all(block_id=current_block_id)

        # Validate the schema and structure of the transactions
        valid_transactions, invalid_transactions = self.split_items(
            valid_transaction_sig, transactions)

        # Use the custom approval code if configured, otherwise approve all valid transaction
        rejected_transactions = []
        if 'approve_transaction' in config:
            approved_transactions, rejected_transactions = \
                self.split_items(config['approve_transaction'], valid_transactions)
        else:
            approved_transactions = valid_transactions

        if len(approved_transactions) > 0:
            # update status of approved transactions
            for tx in approved_transactions:
                tx["header"]["status"] = "approved"
                transaction_db.update_transaction(tx)

            # stripping payload from all transactions before signing
            self.strip_payload(approved_transactions)

            phase = 1
            # signatory equals origin_id in phase 1
            signatory = origin_id = self.network.this_node.node_id
            prior_block_hash = self.get_prior_hash(origin_id, phase)
            verification_info = approved_transactions

            lower_phase_hash = str(deep_hash(0))

            # sign approved transactions
            block_info = sign_verification_record(
                signatory, prior_block_hash, lower_phase_hash,
                self.service_config['public_key'],
                self.service_config['private_key'], current_block_id, phase,
                origin_id, int(time.time()), verification_info)

            # store signed phase specific data
            verfication_db.insert_verification(
                block_info['verification_record'])

            # pass block info to network to send it to appropriate phase
            self.network.send_block(self.network.phase_1_broadcast, block_info,
                                    phase)
            print("Phase 1 signed " + str(len(approved_transactions)) +
                  " transactions")

        # update status transactions that were rejected
        if len(rejected_transactions) > 0:
            for tx in rejected_transactions:
                tx["header"]["status"] = "rejected"
                transaction_db.update_transaction(tx)
Esempio n. 2
0
    def _execute_phase_1(self, config, current_block_id):
        """
        TODO update all EXEC comments/docs
        * Each node gathers all transactions that may be included in the prospective block and groups them by transaction owner.
        * All transactions owned (or sourced from) a respective node's business unit or system (owned) are grouped for approval.
        * All transactions not owned by the node's business unit or system (others) are grouped for validation.
        * All owned transactions are verified per business rules, configurable, (e.g, existence or non-existence of particular fields, with field value validation logic).
        * All owned and verified transactions are "approved" by executing the Transaction Verification Signing Process defined below.
        * Any transactions deemed "unapproved" will be taken out of the prospective block from a node's perspective by non-inclusion in the signing process, and sent to a system "pool" or "queue" for analysis and alternate processing
        * All other (non-owned) transactions are validated to system wide rules agreed upon for all nodes through business and system processes.
        * All other (non-owned) transactions are declared "valid" by the node by executing the Transaction Verification Signing Process defined below.
        * Any transactions deemed "invalid" will be taken out of the prospective block from a node's perspective by non-inclusion in the signing process, and sent to a system "pool" or "queue" for analysis and alternate processing.
        """
        print("Phase 1 Verify Start.")
        # Group transactions for last 5 seconds into current block id
        block_bound_lower_ts = get_block_time(current_block_id - BLOCK_FIXATE_OFFSET)
        print ("""Time bounds: %i - %i""" % (block_bound_lower_ts, block_bound_lower_ts + BLOCK_INTERVAL))
        transaction_db.fixate_block(block_bound_lower_ts, block_bound_lower_ts + BLOCK_INTERVAL, current_block_id)

        transactions = transaction_db.get_all(block_id=current_block_id)

        # Validate the schema and structure of the transactions
        valid_transactions, invalid_transactions = self.split_items(valid_transaction_sig, transactions)

        rejected_transactions = []
        approved_transactions = []

        for txn in valid_transactions:
            if self.handle_transaction(txn):
                approved_transactions.append(txn)
            else:
                rejected_transactions.append(txn)

        if len(approved_transactions) > 0:
            # update status of approved transactions
            for tx in approved_transactions:
                tx["header"]["status"] = "approved"
                transaction_db.update_transaction(tx)

            # stripping payload from all transactions before signing
            self.strip_payload(approved_transactions)

            phase = 1
            # signatory equals origin_id in phase 1
            signatory = origin_id = self.network.this_node.node_id
            prior_block_hash = self.get_prior_hash(origin_id, phase)
            verification_info = approved_transactions

            lower_hash = str(final_hash([0]))

            # sign approved transactions
            block_info = sign_verification_record(signatory,
                                                  prior_block_hash,
                                                  lower_hash,
                                                  self.service_config['public_key'],
                                                  self.service_config['private_key'],
                                                  current_block_id,
                                                  phase,
                                                  origin_id,
                                                  int(time.time()),
                                                  self.public_transmission,
                                                  verification_info)
            # store signed phase specific data
            verification_id = str(uuid.uuid4())
            verification_db.insert_verification(block_info['verification_record'], verification_id)

            # send block info off for public transmission if configured to do so
            if block_info['verification_record']['public_transmission']['p1_pub_trans']:
                self.network.public_broadcast(block_info, phase)

            # send block info for phase 2 validation
            self.network.send_block(self.network.phase_1_broadcast, block_info, phase)
            print("Phase 1 signed " + str(len(approved_transactions)) + " transactions")

        # update status transactions that were rejected
        if len(rejected_transactions) > 0:
            for tx in rejected_transactions:
                tx["header"]["status"] = "rejected"
                transaction_db.update_transaction(tx)