Esempio n. 1
0
    def write_blocks(self):
        """
        Write blocks to the bigchain
        """

        # create bigchain instance
        b = Bigchain()

        # Write blocks
        while True:
            block = self.q_block.get()

            # poison pill
            if block == 'stop':
                return

            b.write_block(block)
Esempio n. 2
0
    def write_blocks(self):
        """
        Write blocks to the bigchain
        """

        # create bigchain instance
        b = Bigchain()

        # Write blocks
        while True:
            block = self.q_block.get()

            # poison pill
            if block == 'stop':
                return

            b.write_block(block)
Esempio n. 3
0
def bft():
    # Cryptographic Identities Generation
    alice, bob = generate_keypair(), generate_keypair()
    print(" ")
    # Digital Asset Definition (e.g. bicycle)
    asset = Asset(data={
        "bicycle": {
            "manufacturer": "bkfab",
            "serial_number": "abcd1234"
        }
    })

    # Metadata Definition
    metadata = {'planet': 'earth'}

    # create trnsaction  TODO : owners_before might be node_pubkey in v0.8.0
    tx = Transaction.create([alice.public_key], [([alice.public_key], 1)],
                            metadata=metadata,
                            asset=asset)

    # sign with private key
    tx = tx.sign([alice.private_key])
    tx_id = tx.to_dict()['id']
    print("tx_id                       : ", tx_id)

    # create block
    b = Bigchain()
    block = b.create_block([tx])

    print("valid block       timestamp : ",
          block.to_dict()['block']['timestamp'])
    # tamper block
    block.timestamp = '1'
    print("tamper block.timestamp to 1 : ")
    block_id = block.to_dict()['id']
    block_voters = block.to_dict()['block']['voters']

    print("invalid block     timestamp : ",
          block.to_dict()['block']['timestamp'])
    print("tamper_block_id             : ", block_id)

    print("db response of block        : ", b.write_block(block))
    sleep(0)

    last_voted_id = b.get_last_voted_block().id
    vote = b.vote(block_id, last_voted_id, True)
    print("crate vote 'True'           : ", vote)
    print("db response of vote         : ", b.write_vote(vote))

    print("tamper_block status         : ",
          b.block_election_status(block_id, block_voters))
    print("blocks_status_containing_tx : ",
          b.get_blocks_status_containing_tx(tx_id))
    print("wait for 20 sec             : ")
    sleep(20)
    print("blocks_status_containing_tx : ",
          b.get_blocks_status_containing_tx(tx_id))
    print(" ")
Esempio n. 4
0
def tamper_block():
    # Cryptographic Identities Generation
    alice, bob = generate_keypair(), generate_keypair()
    print(" ")
    # Digital Asset Definition (e.g. bicycle)
    asset = Asset(data={
        "bicycle": {
            "manufacturer": "bkfab",
            "serial_number": "abcd1234"
        }
    })

    # Metadata Definition
    metadata = {'planet': 'earth'}

    # create trnsaction  TODO : owners_before might be node_pubkey in v0.8.0
    tx = Transaction.create([alice.public_key], [([alice.public_key], 1)],
                            metadata=metadata,
                            asset=asset)

    # did not sign with private key
    # tx = tx.sign([alice.private_key])
    tx_id = tx.to_dict()['id']
    print("dummy tx id                 : ", tx_id)

    # create block
    b = Bigchain()
    block = b.create_block([tx])
    print("block voters right now      : ", block.to_dict()['block']['voters'])
    # tamper block
    block.voters = [bob.public_key]
    block_id = block.to_dict()['id']
    block_voters = block.to_dict()['block']['voters']

    print("tamper block voters         : ", block.to_dict()['block']['voters'])
    print("tamper block id             : ", block_id)
    print("db response                 : ", b.write_block(block))
    sleep(delay)
    print("tamper_block status         : ",
          b.block_election_status(block_id, block_voters))
    print("blocks_status_containing_tx : ",
          b.get_blocks_status_containing_tx(tx_id))
    print(" ")
Esempio n. 5
0
class Block:
    """This class encapsulates the logic to create blocks.

    Note:
        Methods of this class will be executed in different processes.
    """

    def __init__(self):
        """Initialize the Block creator"""
        self.bigchain = Bigchain()
        self.txs = []

    def filter_tx(self, tx):
        """Filter a transaction.

        Args:
            tx (dict): the transaction to process.

        Returns:
            The transaction if assigned to the current node,
            ``None`` otherwise.
        """

        if tx['assignee'] == self.bigchain.me:
            tx.pop('assignee')
            tx.pop('assignment_timestamp')
            return tx

    def validate_tx(self, tx):
        """Validate a transaction.

        Also checks if the transaction already exists in the blockchain. If it
        does, or it's invalid, it's deleted from the backlog immediately.

        Args:
            tx (dict): the transaction to validate.

        Returns:
            The transaction if valid, ``None`` otherwise.
        """
        if self.bigchain.transaction_exists(tx['id']):
            # if the transaction already exists, we must check whether
            # it's in a valid or undecided block
            tx, status = self.bigchain.get_transaction(tx['id'],
                                                       include_status=True)
            if status == self.bigchain.TX_VALID \
               or status == self.bigchain.TX_UNDECIDED:
                # if the tx is already in a valid or undecided block,
                # then it no longer should be in the backlog, or added
                # to a new block. We can delete and drop it.
                r.table('backlog').get(tx['id']) \
                        .delete(durability='hard') \
                        .run(self.bigchain.conn)
                return None

        tx_validated = self.bigchain.is_valid_transaction(tx)
        if tx_validated:
            return tx
        else:
            # if the transaction is not valid, remove it from the
            # backlog
            r.table('backlog').get(tx['id']) \
                    .delete(durability='hard') \
                    .run(self.bigchain.conn)
            return None 

    def create(self, tx, timeout=False):
        """Create a block.

        This method accumulates transactions to put in a block and outputs
        a block when one of the following conditions is true:
        - the size limit of the block has been reached, or
        - a timeout happened.

        Args:
            tx (dict): the transaction to validate, might be None if
                a timeout happens.
            timeout (bool): ``True`` if a timeout happened
                (Default: ``False``).

        Returns:
            The block, if a block is ready, or ``None``.
        """
        if tx:
            self.txs.append(tx)
        if len(self.txs) == 1000 or (timeout and self.txs):
            block = self.bigchain.create_block(self.txs)
            self.txs = []
            return block

    def write(self, block):
        """Write the block to the Database.

        Args:
            block (dict): the block of transactions to write to the database.

        Returns:
            The block.
        """
        logger.info('Write new block %s with %s transactions',
                    block['id'],
                    len(block['block']['transactions']))
        self.bigchain.write_block(block)
        return block

    def delete_tx(self, block):
        """Delete transactions.

        Args:
            block (dict): the block containg the transactions to delete.

        Returns:
            The block.
        """
        r.table('backlog')\
         .get_all(*[tx['id'] for tx in block['block']['transactions']])\
         .delete(durability='hard')\
         .run(self.bigchain.conn)

        return block
Esempio n. 6
0
class Block:
    """This class encapsulates the logic to create blocks.

    Note:
        Methods of this class will be executed in different processes.
    """

    def __init__(self):
        """Initialize the Block creator"""
        self.bigchain = Bigchain()
        self.txs = []

    def filter_tx(self, tx):
        """Filter a transaction.

        Args:
            tx (dict): the transaction to process.

        Returns:
            The transaction if assigned to the current node,
            ``None`` otherwise.
        """

        if tx['assignee'] == self.bigchain.me:
            tx.pop('assignee')
            tx.pop('assignment_timestamp')
            return tx

    def validate_tx(self, tx):
        """Validate a transaction.
        Also checks if the transaction already exists in the blockchain. If it
        does, or it's invalid, it's deleted from the backlog immediately.
        Args:
            tx (dict): the transaction to validate.
        Returns:
            The transaction if valid, ``None`` otherwise.
        """
        if self.bigchain.transaction_exists(tx['id']):
            # if the transaction already exists, we must check whether
            # it's in a valid or undecided block
            tx, status = self.bigchain.get_transaction(tx['id'],
                                                       include_status=True)
            if status == self.bigchain.TX_VALID \
               or status == self.bigchain.TX_UNDECIDED:
                # if the tx is already in a valid or undecided block,
                # then it no longer should be in the backlog, or added
                # to a new block. We can delete and drop it.
                r.table('backlog').get(tx['id']) \
                        .delete(durability='hard') \
                        .run(self.bigchain.conn)
                return None

        tx_validated = self.bigchain.is_valid_transaction(tx)
        if tx_validated:
            return tx
        else:
            # if the transaction is not valid, remove it from the
            # backlog
            r.table('backlog').get(tx['id']) \
                    .delete(durability='hard') \
                    .run(self.bigchain.conn)
            return None

    def create(self, tx, timeout=False):
        """Create a block.

        This method accumulates transactions to put in a block and outputs
        a block when one of the following conditions is true:
        - the size limit of the block has been reached, or
        - a timeout happened.

        Args:
            tx (dict): the transaction to validate, might be None if
                a timeout happens.
            timeout (bool): ``True`` if a timeout happened
                (Default: ``False``).

        Returns:
            The block, if a block is ready, or ``None``.
        """
        if tx:
            self.txs.append(tx)
        if len(self.txs) == 1000 or (timeout and self.txs):
            block = self.bigchain.create_block(self.txs)
            self.txs = []
            return block

    def write(self, block):
        """Write the block to the Database.

        Args:
            block (dict): the block of transactions to write to the database.

        Returns:
            The block.
        """
        logger.info('Write new block %s with %s transactions',
                    block['id'],
                    len(block['block']['transactions']))
        self.bigchain.write_block(block)
        return block

    def delete_tx(self, block):
        """Delete transactions.
        Args:
            block (dict): the block containg the transactions to delete.
        Returns:
            The block.
        """
        r.table('backlog')\
         .get_all(*[tx['id'] for tx in block['block']['transactions']])\
         .delete(durability='hard')\
         .run(self.bigchain.conn)

        return block
Esempio n. 7
0
class BlockPipeline:
    """This class encapsulates the logic to create blocks.

    Note:
        Methods of this class will be executed in different processes.
    """
    def __init__(self):
        """Initialize the BlockPipeline creator"""
        self.bigchain = Bigchain()
        self.txs = tx_collector()

    def filter_tx(self, tx):
        """Filter a transaction.

        Args:
            tx (dict): the transaction to process.

        Returns:
            dict: The transaction if assigned to the current node,
            ``None`` otherwise.
        """
        if tx['assignee'] == self.bigchain.me:
            tx.pop('assignee')
            tx.pop('assignment_timestamp')
            return tx

    def validate_tx(self, tx):
        """Validate a transaction.

        Also checks if the transaction already exists in the blockchain. If it
        does, or it's invalid, it's deleted from the backlog immediately.

        Args:
            tx (dict): the transaction to validate.

        Returns:
            :class:`~bigchaindb.models.Transaction`: The transaction if valid,
            ``None`` otherwise.
        """
        try:
            tx = Transaction.from_dict(tx)
        except ValidationError:
            return None

        # If transaction is in any VALID or UNDECIDED block we
        # should not include it again
        if not self.bigchain.is_new_transaction(tx.id):
            self.bigchain.delete_transaction(tx.id)
            return None

        # If transaction is not valid it should not be included
        try:
            # Do not allow an externally submitted GENESIS transaction.
            # A simple check is enough as a pipeline is started only after the
            # creation of GENESIS block, or after the verification of a GENESIS
            # block. Voting will fail at a later stage if the GENESIS block is
            # absent.
            if tx.operation == Transaction.GENESIS:
                raise GenesisBlockAlreadyExistsError(
                    'Duplicate GENESIS transaction')

            tx.validate(self.bigchain)
            return tx
        except ValidationError as e:
            logger.warning('Invalid tx: %s', e)
            self.bigchain.delete_transaction(tx.id)
            return None

    def create(self, tx, timeout=False):
        """Create a block.

        This method accumulates transactions to put in a block and outputs
        a block when one of the following conditions is true:
        - the size limit of the block has been reached, or
        - a timeout happened.

        Args:
            tx (:class:`~bigchaindb.models.Transaction`): the transaction
                to validate, might be None if a timeout happens.
            timeout (bool): ``True`` if a timeout happened
                (Default: ``False``).

        Returns:
            :class:`~bigchaindb.models.Block`: The block,
            if a block is ready, or ``None``.
        """
        txs = self.txs.send(tx)
        if len(txs) == 1000 or (timeout and txs):
            block = self.bigchain.create_block(txs)
            self.txs = tx_collector()
            return block

    def write(self, block):
        """Write the block to the Database.

        Args:
            block (:class:`~bigchaindb.models.Block`): the block of
                transactions to write to the database.

        Returns:
            :class:`~bigchaindb.models.Block`: The Block.
        """
        logger.info('Write new block %s with %s transactions', block.id,
                    len(block.transactions))
        self.bigchain.write_block(block)
        self.bigchain.statsd.incr('pipelines.block.throughput',
                                  len(block.transactions))
        return block

    def delete_tx(self, block):
        """Delete transactions.

        Args:
            block (:class:`~bigchaindb.models.Block`): the block
                containg the transactions to delete.

        Returns:
            :class:`~bigchaindb.models.Block`: The block.
        """
        self.bigchain.delete_transaction(*[tx.id for tx in block.transactions])
        return block
Esempio n. 8
0
class Block:
    """This class encapsulates the logic to create blocks.

    Note:
        Methods of this class will be executed in different processes.
    """
    def __init__(self):
        """Initialize the Block creator"""
        self.bigchain = Bigchain()
        self.txs = []

    def filter_tx(self, tx):
        """Filter a transaction.

        Args:
            tx (dict): the transaction to process.

        Returns:
            The transaction if assigned to the current node,
            ``None`` otherwise.
        """

        if tx['assignee'] == self.bigchain.me:
            tx.pop('assignee')
            return tx

    def delete_tx(self, tx):
        """Delete a transaction.

        Args:
            tx (dict): the transaction to delete.

        Returns:
            The transaction.
        """
        r.table('backlog')\
         .get(tx['id'])\
         .delete(durability='hard')\
         .run(self.bigchain.conn)

        return tx

    def validate_tx(self, tx):
        """Validate a transaction.

        Args:
            tx (dict): the transaction to validate.

        Returns:
            The transaction if valid, ``None`` otherwise.
        """
        tx = self.bigchain.is_valid_transaction(tx)
        if tx:
            return tx

    def create(self, tx, timeout=False):
        """Create a block.

        This method accumulates transactions to put in a block and outputs
        a block when one of the following conditions is true:
        - the size limit of the block has been reached, or
        - a timeout happened.

        Args:
            tx (dict): the transaction to validate, might be None if
                a timeout happens.
            timeout (bool): ``True`` if a timeout happened
                (Default: ``False``).

        Returns:
            The block, if a block is ready, or ``None``.
        """
        if tx:
            self.txs.append(tx)
        if len(self.txs) == 1000 or (timeout and self.txs):
            block = self.bigchain.create_block(self.txs)
            self.txs = []
            return block

    def write(self, block):
        """Write the block to the Database.

        Args:
            block (dict): the block of transactions to write to the database.

        Returns:
            The block.
        """
        logger.info('Write new block %s with %s transactions', block['id'],
                    len(block['block']['transactions']))
        self.bigchain.write_block(block)
        return block
Esempio n. 9
0
class BlockPipeline:
    """This class encapsulates the logic to create blocks.

    Note:
        Methods of this class will be executed in different processes.
    """

    def __init__(self):
        """Initialize the BlockPipeline creator"""
        self.bigchain = Bigchain()
        self.txs = tx_collector()

    def filter_tx(self, tx):
        """Filter a transaction.

        Args:
            tx (dict): the transaction to process.

        Returns:
            dict: The transaction if assigned to the current node,
            ``None`` otherwise.
        """
        if tx['assignee'] == self.bigchain.me:
            tx.pop('assignee')
            tx.pop('assignment_timestamp')
            return tx

    def validate_tx(self, tx):
        """Validate a transaction.

        Also checks if the transaction already exists in the blockchain. If it
        does, or it's invalid, it's deleted from the backlog immediately.

        Args:
            tx (dict): the transaction to validate.

        Returns:
            :class:`~bigchaindb.models.Transaction`: The transaction if valid,
            ``None`` otherwise.
        """
        try:
            tx = Transaction.from_dict(tx)
        except ValidationError:
            return None

        # If transaction is in any VALID or UNDECIDED block we
        # should not include it again
        if not self.bigchain.is_new_transaction(tx.id):
            self.bigchain.delete_transaction(tx.id)
            return None

        # If transaction is not valid it should not be included
        try:
            # Do not allow an externally submitted GENESIS transaction.
            # A simple check is enough as a pipeline is started only after the
            # creation of GENESIS block, or after the verification of a GENESIS
            # block. Voting will fail at a later stage if the GENESIS block is
            # absent.
            if tx.operation == Transaction.GENESIS:
                raise GenesisBlockAlreadyExistsError('Duplicate GENESIS transaction')

            tx.validate(self.bigchain)
            return tx
        except ValidationError as e:
            logger.warning('Invalid tx: %s', e)
            self.bigchain.delete_transaction(tx.id)
            return None

    def create(self, tx, timeout=False):
        """Create a block.

        This method accumulates transactions to put in a block and outputs
        a block when one of the following conditions is true:
        - the size limit of the block has been reached, or
        - a timeout happened.

        Args:
            tx (:class:`~bigchaindb.models.Transaction`): the transaction
                to validate, might be None if a timeout happens.
            timeout (bool): ``True`` if a timeout happened
                (Default: ``False``).

        Returns:
            :class:`~bigchaindb.models.Block`: The block,
            if a block is ready, or ``None``.
        """
        txs = self.txs.send(tx)
        if len(txs) == 1000 or (timeout and txs):
            block = self.bigchain.create_block(txs)
            self.txs = tx_collector()
            return block

    def write(self, block):
        """Write the block to the Database.

        Args:
            block (:class:`~bigchaindb.models.Block`): the block of
                transactions to write to the database.

        Returns:
            :class:`~bigchaindb.models.Block`: The Block.
        """
        logger.info('Write new block %s with %s transactions',
                    block.id, len(block.transactions))
        self.bigchain.write_block(block)
        self.bigchain.statsd.incr('pipelines.block.throughput',
                                  len(block.transactions))
        return block

    def delete_tx(self, block):
        """Delete transactions.

        Args:
            block (:class:`~bigchaindb.models.Block`): the block
                containg the transactions to delete.

        Returns:
            :class:`~bigchaindb.models.Block`: The block.
        """
        self.bigchain.delete_transaction(*[tx.id for tx in block.transactions])
        return block
Esempio n. 10
0
class BlockPipeline:
    """This class encapsulates the logic to create blocks.

    Note:
        Methods of this class will be executed in different processes.
    """
    def __init__(self):
        """Initialize the BlockPipeline creator"""
        self.bigchain = Bigchain()
        self.txs = []

    def filter_tx(self, tx):
        """Filter a transaction.

        Args:
            tx (dict): the transaction to process.

        Returns:
            dict: The transaction if assigned to the current node,
            ``None`` otherwise.
        """
        if tx['assignee'] == self.bigchain.me:
            tx.pop('assignee')
            tx.pop('assignment_timestamp')
            return tx

    def validate_tx(self, tx):
        """Validate a transaction.

        Also checks if the transaction already exists in the blockchain. If it
        does, or it's invalid, it's deleted from the backlog immediately.

        Args:
            tx (dict): the transaction to validate.

        Returns:
            :class:`~bigchaindb.models.Transaction`: The transaction if valid,
            ``None`` otherwise.
        """
        try:
            tx = Transaction.from_dict(tx)
        except (SchemaValidationError, InvalidHash, InvalidSignature,
                AmountError):
            return None

        # If transaction is in any VALID or UNDECIDED block we
        # should not include it again
        if not self.bigchain.is_new_transaction(tx.id):
            self.bigchain.delete_transaction(tx.id)
            return None

        # If transaction is not valid it should not be included
        if not self.bigchain.is_valid_transaction(tx):
            self.bigchain.delete_transaction(tx.id)
            return None

        return tx

    def create(self, tx, timeout=False):
        """Create a block.

        This method accumulates transactions to put in a block and outputs
        a block when one of the following conditions is true:
        - the size limit of the block has been reached, or
        - a timeout happened.

        Args:
            tx (:class:`~bigchaindb.models.Transaction`): the transaction
                to validate, might be None if a timeout happens.
            timeout (bool): ``True`` if a timeout happened
                (Default: ``False``).

        Returns:
            :class:`~bigchaindb.models.Block`: The block,
            if a block is ready, or ``None``.
        """
        if tx:
            self.txs.append(tx)
        if len(self.txs) == 1000 or (timeout and self.txs):
            block = self.bigchain.create_block(self.txs)
            self.txs = []
            return block

    def write(self, block):
        """Write the block to the Database.

        Args:
            block (:class:`~bigchaindb.models.Block`): the block of
                transactions to write to the database.

        Returns:
            :class:`~bigchaindb.models.Block`: The Block.
        """
        logger.info('Write new block %s with %s transactions', block.id,
                    len(block.transactions))
        self.bigchain.write_block(block)
        return block

    def delete_tx(self, block):
        """Delete transactions.

        Args:
            block (:class:`~bigchaindb.models.Block`): the block
                containg the transactions to delete.

        Returns:
            :class:`~bigchaindb.models.Block`: The block.
        """
        self.bigchain.delete_transaction(*[tx.id for tx in block.transactions])
        return block
Esempio n. 11
0
class Block:
    """This class encapsulates the logic to create blocks.

    Note:
        Methods of this class will be executed in different processes.
    """

    def __init__(self):
        """Initialize the Block creator"""
        self.bigchain = Bigchain()
        self.txs = []

    def filter_tx(self, tx):
        """Filter a transaction.

        Args:
            tx (dict): the transaction to process.

        Returns:
            The transaction if assigned to the current node,
            ``None`` otherwise.
        """

        if tx['assignee'] == self.bigchain.me:
            tx.pop('assignee')
            return tx

    def delete_tx(self, tx):
        """Delete a transaction.

        Args:
            tx (dict): the transaction to delete.

        Returns:
            The transaction.
        """
        r.table('backlog')\
         .get(tx['id'])\
         .delete(durability='hard')\
         .run(self.bigchain.conn)

        return tx

    def validate_tx(self, tx):
        """Validate a transaction.

        Args:
            tx (dict): the transaction to validate.

        Returns:
            The transaction if valid, ``None`` otherwise.
        """
        tx = self.bigchain.is_valid_transaction(tx)
        if tx:
            return tx

    def create(self, tx, timeout=False):
        """Create a block.

        This method accumulates transactions to put in a block and outputs
        a block when one of the following conditions is true:
        - the size limit of the block has been reached, or
        - a timeout happened.

        Args:
            tx (dict): the transaction to validate, might be None if
                a timeout happens.
            timeout (bool): ``True`` if a timeout happened
                (Default: ``False``).

        Returns:
            The block, if a block is ready, or ``None``.
        """
        if tx:
            self.txs.append(tx)
        if len(self.txs) == 1000 or (timeout and self.txs):
            block = self.bigchain.create_block(self.txs)
            self.txs = []
            return block

    def write(self, block):
        """Write the block to the Database.

        Args:
            block (dict): the block of transactions to write to the database.

        Returns:
            The block.
        """
        logger.info('Write new block %s with %s transactions',
                    block['id'],
                    len(block['block']['transactions']))
        self.bigchain.write_block(block)
        return block