예제 #1
0
    def do_txn(self, args):
        """
        txn -- Command to create IntegerKey transactions
            txn <expr> [ && <expr> ]*
        """
        txn = integer_key.IntegerKeyTransaction()

        # pylint: disable=line-too-long
        pattern = re.compile(
            r"^\s*(?P<name>[a-zA-Z0-9]+)\s*(?P<verb>[+-]?=)\s*(?P<value>[0-9]+)\s*$"
        )  # noqa
        expressions = args.split('&&')
        for expression in expressions:
            match = pattern.match(expression)
            if not match:
                print 'unable to parse the transaction; {0}'.format(expression)
                return

            update = integer_key.Update()
            update.Verb = self._TxnVerbMap[match.group('verb')]
            update.Name = match.group('name')
            update.Value = long(match.group('value'))
            txn.Updates.append(update)

        txn.sign_from_node(self.LocalNode)

        msg = integer_key.IntegerKeyTransactionMessage()
        msg.Transaction = txn

        self.sign_and_post(msg)
    def _sendtxn(self, update):
        """
        Build a transaction for the update, wrap it in a message with all
        of the appropriate signatures and post it to the validator
        """

        txn = integer_key.IntegerKeyTransaction()
        txn.Updates = [update]

        # add the last transaction submitted to ensure that the ordering
        # in the journal matches the order in which we generated them
        if self.LastTransaction:
            txn.Dependencies = [self.LastTransaction]

        update.Transaction = txn
        txn.sign_from_node(self.LocalNode)
        txnid = txn.Identifier

        if not txn.is_valid(self.CurrentState.State):
            logger.warn('transaction failed to apply')
            return None

        msg = integer_key.IntegerKeyTransactionMessage()
        msg.Transaction = txn
        msg.SenderID = self.LocalNode.Identifier
        msg.sign_from_node(self.LocalNode)

        try:
            logger.debug('Posting transaction: %s', txnid)
            result = self.postmsg(msg.MessageType, msg.dump())

        except MessageException as me:
            return None

        except:
            logger.debug('message post failed for some unusual reason')
            return None

        # if there was no exception thrown then all transactions should return
        # a value which is a dictionary with the message that was sent
        assert result

        # if the message was successfully posted, then save the transaction
        # id for future dependencies this could be a problem if the transaction
        # fails during application
        self.LastTransaction = txnid
        txn.apply(self.CurrentState.State)

        return txnid