fn process_storage_logs<'a, I: IntoIterator<Item = &'a StorageLogWithPreviousValue>>(
        &mut self,
        logs: I,
    ) -> Vec<UpdateItem> {
        let mut updates = Vec::new();
        for log in logs.into_iter().filter(|log| log.log.is_write()) {
            let key = log.log.key;
            let initial_value = *self.initial_values.entry(key).or_insert(log.previous_value);
            let was_key_modified = self.modified_key_values.contains_key(&key);
            let modified_value = (initial_value != log.log.value).then_some(log.log.value);

            let is_write_initial = log.log.kind == StorageLogKind::InitialWrite;
            let field_to_change = if is_write_initial {
                &mut self.metrics.initial_storage_writes
            } else {
                &mut self.metrics.repeated_storage_writes
            };

            let total_size = &mut self.metrics.total_updated_values_size;
            match (was_key_modified, modified_value) {
                (true, None) => {
                    let value = self.modified_key_values.remove(&key).unwrap_or_else(|| {
                        panic!("tried removing key: {:?} before insertion", key)
                    });
                    *field_to_change -= 1;
                    *total_size -= value.size;
                    updates.push(UpdateItem {
                        key,
                        update_type: UpdateType::Remove(value),
                        is_write_initial,
                    });
                }
                (true, Some(new_value)) => {
                    let value_size = compress_with_best_strategy(
                        h256_to_u256(initial_value),
                        h256_to_u256(new_value),
                    )
                    .len();
                    let old_value = self
                        .modified_key_values
                        .insert(
                            key,
                            ModifiedSlot {
                                value: new_value,
                                size: value_size,
                            },
                        )
                        .unwrap_or_else(|| {
                            panic!("tried removing key: {:?} before insertion", key)
                        });

                    updates.push(UpdateItem {
                        key,
                        update_type: UpdateType::Update(old_value),
                        is_write_initial,
                    });

                    *total_size -= old_value.size;
                    *total_size += value_size;
                }
                (false, Some(new_value)) => {
                    let value_size = compress_with_best_strategy(
                        h256_to_u256(initial_value),
                        h256_to_u256(new_value),
                    )
                    .len();
                    self.modified_key_values.insert(
                        key,
                        ModifiedSlot {
                            value: new_value,
                            size: value_size,
                        },
                    );
                    *field_to_change += 1;
                    *total_size += value_size;
                    updates.push(UpdateItem {
                        key,
                        update_type: UpdateType::Insert,
                        is_write_initial,
                    });
                }
                _ => {}
            }
        }
        updates
    }
Processes storage logs and returns updates for `modified_keys` and `metrics` fields.
Metrics can be used later to rollback the state.
We don't care about `initial_values` changes as we only inserted values there and they are always valid.
core/lib/multivm/src/utils/deduplicator.rs