def test_1_depth_dict_db(self, context, key_value_db, keys, old_values, new_values, value_type): context_db = ContextDatabase(key_value_db, is_shared=False) score_address = Address(AddressPrefix.CONTRACT, os.urandom(20)) score_db = IconScoreDatabase(score_address, context_db) self._init_context(context, score_address) self._set_revision(context, Revision.USE_RLP.value - 1) name = "dict_db_depth_1" dict_db = DictDB(name, score_db, depth=1, value_type=value_type) # Put two items to dict_db for i in range(2): k, v = keys[i], old_values[i] dict_db[k] = v assert dict_db[k] == v key = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k), use_rlp=False ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) self._set_revision(context, Revision.USE_RLP.value) # Read old-formatted data on Revision.USE_RLP for i in range(2): k, v = keys[i], old_values[i] assert dict_db[k] == v key = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k), use_rlp=False ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) # Put 4 items to dict_db for i, k in enumerate(keys): old_v = old_values[i] new_v = new_values[i] dict_db[k] = new_v assert dict_db[k] == new_v assert dict_db[k] != old_v key = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k), use_rlp=True ) assert key_value_db.get(key) == ContainerUtil.encode_value(new_v) # If there is no value for a given key, default value is returned for k in keys: del dict_db[k] assert dict_db[k] == get_default_value(value_type) assert len(key_value_db) == 0
def test_2_depth_dict_db(self, context, key_value_db, keys1, keys2, old_values, new_values, value_type): context_db = ContextDatabase(key_value_db, is_shared=False) score_address = Address(AddressPrefix.CONTRACT, os.urandom(20)) score_db = IconScoreDatabase(score_address, context_db) self._init_context(context, score_address) self._set_revision(context, Revision.USE_RLP.value - 1) name = "dict_db_depth_2" dict_db = DictDB(name, score_db, depth=2, value_type=value_type) # To assign a value to middle-layer dict_db is forbidden for k1, v in zip(keys1, old_values): with pytest.raises(InvalidContainerAccessException): dict_db[k1] = v # Assign values to dict_db on Revision.USE_RLP - 1 for k1 in keys1: for k2, v in zip(keys2, old_values): dict_db[k1][k2] = v assert len(key_value_db) == len(keys1) * len(keys2) for k1 in keys1: for k2, v in zip(keys2, old_values): assert dict_db[k1][k2] == v key: bytes = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerTag.DICT, ContainerUtil.encode_key(k1), ContainerUtil.encode_key(k2), use_rlp=False ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) self._set_revision(context, Revision.USE_RLP.value) # Check if reading old-formatted key:value data works on Revision.USE_RLP for k1 in keys1: for k2, v in zip(keys2, old_values): assert dict_db[k1][k2] == v # Replace all old_values with new_values on Revision.USE_RLP for k1 in keys1: for k2, v in zip(keys2, new_values): dict_db[k1][k2] = v # old_values + new_values assert len(key_value_db) == len(keys1) * len(keys2) * 2 for k1 in keys1: for k2, v in zip(keys2, new_values): assert dict_db[k1][k2] == v key: bytes = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k1), ContainerUtil.encode_key(k2), use_rlp=True ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) for k1 in keys1: for k2 in keys2: del dict_db[k1][k2] assert dict_db[k1][k2] == get_default_value(value_type) assert len(key_value_db) == 0