def test_smaller_target_count(self): """Tests that setting a new, smaller target count works correctly.""" block_num = 122351345 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info, target_count=128) config = create_config(latest_block=block_num - 1) self._expect_config_get(config) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) deletes = [ create_block_address(i) for i in range(config.oldest_block, config.latest_block - 128 + 1) ] self._expect_delete(deletes) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config( latest_block=block_num, oldest_block=block_num - 128, target_count=128), }) self._expect_response("OK")
def _expect_block_get(self, block): received = self.validator.expect(self.factory.create_get_request( addresses=[create_block_address(block.block_num)])) self.validator.respond(self.factory.create_get_response({ create_block_address(block.block_num): block.SerializeToString() }), received)
def test_smaller_target_count(self): """Tests that setting a new, smaller target count works correctly.""" block_num = 122351345 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info, target_count=128) config = create_config(latest_block=block_num - 1) self._expect_config_get(config) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) deletes = [ create_block_address(i) for i in range(config.oldest_block, config.latest_block - 128 + 1) ] self._expect_delete(deletes) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config( latest_block=block_num, oldest_block=block_num - 128, target_count=128), }) self._expect_response("OK")
def _expect_block_get(self, block): received = self.validator.expect( self.factory.create_get_request( addresses=[create_block_address(block.block_num)])) self.validator.respond( self.factory.create_get_response({ create_block_address(block.block_num): block.SerializeToString() }), received)
def test_first_block_info(self): """Tests that the first block info is set correctly, without changing sync tolerance or target count.""" block_info = create_block_info(block_num=1) self._send_request(block=block_info) self._expect_config_get() self._expect_set({ create_block_address(1): block_info, CONFIG_ADDRESS: create_config(latest_block=1, oldest_block=1), }) self._expect_response("OK")
def test_first_block_info(self): """Tests that the first block info is set correctly, without changing sync tolerance or target count.""" block_info = create_block_info(block_num=1) self._send_request(block=block_info) self._expect_config_get() self._expect_set({ create_block_address(1): block_info, CONFIG_ADDRESS: create_config(latest_block=1, oldest_block=1), }) self._expect_response("OK")
def test_new_sync_tolerance(self): """Tests that setting a new sync tolerance works correctly.""" block_num = 163134613422 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info, sync_tolerance=450) self._expect_config_get(create_config(latest_block=block_num - 1)) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) self._expect_delete([ create_block_address(block_num - 1 - DEFAULT_TARGET_COUNT), ]) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config( latest_block=block_num, sync_tolerance=450), }) self._expect_response("OK")
def test_new_sync_tolerance(self): """Tests that setting a new sync tolerance works correctly.""" block_num = 163134613422 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info, sync_tolerance=450) self._expect_config_get(create_config(latest_block=block_num - 1)) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) self._expect_delete([ create_block_address(block_num - 1 - DEFAULT_TARGET_COUNT), ]) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config( latest_block=block_num, sync_tolerance=450), }) self._expect_response("OK")
def test_new_block_info(self): """Tests that a new block info is set correctly, without changing sync tolerance or target count.""" block_num = 8923521 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info) self._expect_config_get(create_config(latest_block=block_num - 1)) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) self._expect_delete([ create_block_address(block_num - 1 - DEFAULT_TARGET_COUNT), ]) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config(latest_block=block_num), }) self._expect_response("OK")
def test_new_block_info(self): """Tests that a new block info is set correctly, without changing sync tolerance or target count.""" block_num = 8923521 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info) self._expect_config_get(create_config(latest_block=block_num - 1)) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) self._expect_delete([ create_block_address(block_num - 1 - DEFAULT_TARGET_COUNT), ]) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config(latest_block=block_num), }) self._expect_response("OK")
def test_bigger_target_count(self): """Tests that setting a new, bigger target count works correctly.""" block_num = 122351345 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info, target_count=512) config = create_config(latest_block=block_num - 1) self._expect_config_get(config) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config( latest_block=block_num, oldest_block=config.oldest_block, target_count=512), }) self._expect_response("OK")
def test_bigger_target_count(self): """Tests that setting a new, bigger target count works correctly.""" block_num = 122351345 block_info = create_block_info(block_num=block_num) self._send_request(block=block_info, target_count=512) config = create_config(latest_block=block_num - 1) self._expect_config_get(config) prev_block_info = create_block_info( block_num=block_num - 1, header_signature="0" * 128, timestamp=int(time.time() - 3)) self._expect_block_get(prev_block_info) self._expect_set({ create_block_address(block_num): block_info, CONFIG_ADDRESS: create_config( latest_block=block_num, oldest_block=config.oldest_block, target_count=512), }) self._expect_response("OK")
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
def do_test_common_create_block_address(): block_num = random.randint(50000, 5000000) create_block_address(block_num=block_num)
def get_block_info(block_num): bi = BlockInfo() bi.ParseFromString(get_state(create_block_address(block_num))) return bi
def get_block_info(block_num): bi = BlockInfo() bi.ParseFromString(get_state(create_block_address(block_num))) return bi
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