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)
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)
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)]
def get_block_info(block_num): bi = BlockInfo() bi.ParseFromString(get_state(create_block_address(block_num))) return bi
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")
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