Пример #1
0
def create_block_info(block_num, signer_pubkey="2" * 66,
                      header_signature="1" * 128, timestamp=None,
                      previous_block_id="0" * 128):
    if timestamp is None:
        timestamp = int(time.time())

    return BlockInfo(
        block_num=block_num, signer_pubkey=signer_pubkey,
        header_signature=header_signature, timestamp=timestamp,
        previous_block_id=previous_block_id)
Пример #2
0
    def do_test_injector_blockinfoinject_create_batch():
        block_info = BlockInfo(block_num=100,
                               signer_public_key=BLOCKINFO_SIGNER_PUBLIC_KEY,
                               header_signature=BLOCKINFO_HEADER_SIGNATURE,
                               timestamp=2364657,
                               previous_block_id=BLOCKINFO_PREVIOUS_BLOCKID)

        btm = BlockTreeManager()
        batch_injector_factory=DefaultBatchInjectorFactory(\
                            block_store=btm.block_store,\
                            state_view_factory=MockStateViewFactory(btm.state_db),\
                            signer=btm.identity_signer)

        blockinjector = BlockInfoInjector(batch_injector_factory._block_store, \
        batch_injector_factory._state_view_factory, batch_injector_factory._signer)
        blockinjector.create_batch(block_info=block_info)
Пример #3
0
    def block_start(self, previous_block):
        """Returns an ordered list of batches to inject at the beginning of the
        block. Can also return None if no batches should be injected.

        Args:
            previous_block_id (str): The signature of the previous block.

        Returns:
            A list of batches to inject.
        """
        previous_header = previous_block.header

        block_info = BlockInfo(
            block_num=previous_header.block_num,
            previous_block_id=previous_header.previous_block_id,
            signer_public_key=previous_header.signer_public_key,
            header_signature=previous_block.header_signature,
            timestamp=int(time.time()))

        return [self.create_batch(block_info)]
Пример #4
0
def get_block_info(block_num):
    bi = BlockInfo()
    bi.ParseFromString(get_state(create_block_address(block_num)))
    return bi
Пример #5
0
 def test_missing_fields(self):
     """Tests that an invalid transaction is handled correctly."""
     block_info = BlockInfo()
     self._send_request(block=block_info)
     self._expect_response("INVALID_TRANSACTION")
Пример #6
0
    def apply(self, transaction, context):
        # Unpack payload
        txn = BlockInfoTxn()
        txn.ParseFromString(transaction.payload)
        next_block = txn.block

        # Validate block info fields
        if next_block.block_num < 0:
            raise InvalidTransaction(
                "Invalid block num '{}'".format(next_block.block_num))

        if not (validate_hex(next_block.previous_block_id, 128)
                or next_block.previous_block_id == "0000000000000000"):
            raise InvalidTransaction("Invalid previous block id '{}'".format(
                next_block.previous_block_id))

        if not validate_hex(next_block.signer_public_key, 66):
            raise InvalidTransaction("Invalid signer public_key '{}'".format(
                next_block.signer_public_key))

        if not validate_hex(next_block.header_signature, 128):
            raise InvalidTransaction("Invalid header signature '{}'".format(
                next_block.header_signature))

        if next_block.timestamp <= 0:
            raise InvalidTransaction(
                "Invalid timestamp '{}'".format(next_block.timestamp))

        # Get config and previous block (according to the block info in the
        # transaction) from state
        entries = context.get_state([CONFIG_ADDRESS])

        deletes = []
        sets = []
        config = BlockInfoConfig()

        # If there is no config in state, we don't know anything about what's
        # in state, so we have to treat this as the first entry
        if not entries:
            # If sync tolerance or target count were not specified in the txn,
            # use default values.
            config.sync_tolerance = \
                DEFAULT_SYNC_TOLERANCE if txn.sync_tolerance == 0 \
                else txn.sync_tolerance

            config.target_count = \
                DEFAULT_TARGET_COUNT if txn.target_count == 0 \
                else txn.target_count

            config.latest_block = next_block.block_num
            config.oldest_block = next_block.block_num

            validate_timestamp(next_block.timestamp, config.sync_tolerance)

            sets.append((CONFIG_ADDRESS, config.SerializeToString()))
            sets.append((
                create_block_address(next_block.block_num),
                next_block.SerializeToString()))

        else:
            config.ParseFromString(entries[0].data)

            # If the config was changed in this transaction
            if txn.sync_tolerance != 0:
                config.sync_tolerance = txn.sync_tolerance
            if txn.target_count != 0:
                config.target_count = txn.target_count

            if next_block.block_num - 1 != config.latest_block:
                raise InvalidTransaction(
                    "Block number must be one more than previous block's."
                    " Got {} expected {}".format(
                        next_block.block_num, config.latest_block + 1))

            validate_timestamp(next_block.timestamp, config.sync_tolerance)

            entries = context.get_state(
                [create_block_address(config.latest_block)])
            if not entries:
                raise InternalError(
                    "Config and state out of sync. Latest block not found in"
                    " state.")

            prev_block = BlockInfo()
            prev_block.ParseFromString(entries[0].data)
            if prev_block.block_num != config.latest_block:
                raise InternalError(
                    "Block info stored at latest block has incorrect block"
                    " num.")

            if next_block.previous_block_id != prev_block.header_signature:
                raise InvalidTransaction(
                    "Previous block id must match header signature of previous"
                    " block. Go {} expected {}".format(
                        next_block.previous_block_id,
                        prev_block.header_signature))

            if next_block.timestamp < prev_block.timestamp:
                raise InvalidTransaction(
                    "Timestamp must be greater than previous block's."
                    " Got {}, expected >{}".format(
                        next_block.timestamp, prev_block.timestamp))

            config.latest_block = next_block.block_num
            while (config.latest_block - config.oldest_block) \
                    > config.target_count:
                deletes.append(create_block_address(config.oldest_block))
                config.oldest_block = config.oldest_block + 1

            sets.append((CONFIG_ADDRESS, config.SerializeToString()))
            sets.append((
                create_block_address(next_block.block_num),
                next_block.SerializeToString()))

        # If this is not true, something else has modified global state
        if deletes:
            if set(deletes) != set(context.delete_state(deletes)):
                raise InternalError(
                    "Blocks should have been in state but weren't: {}".format(
                        deletes))

        if sets:
            addresses = set([k for k, _ in sets])
            addresses_set = set(context.set_state(
                {k: v for k, v in sets}))
            if addresses != addresses_set:
                raise InternalError("Failed to set addresses.")

        return None