---
# System prepended metadata

title: Storage Write API notes

---

# Storage Write API notes

## Standard write that already exists
- `wl_storage`
    - `fn write_bytes` —> `protocol_write` serialized val on `write_log_mut`
    - Inserts into `block_write_log` the key and `StorageModification::Write{ val }`
    - Has some error conditions

## Commit block (`commit_block`)
- `wl_storage`
    - Updates epoch in merkle tree if it’s a new epoch
    - Calls `write_log.commit_block` and then `storage.commit_block`
- `write_log`
    - For writes, calls `storage.batch_write_subspace_val`
    - For deletes, calls `storage.batch_delete_subspace_val`
- `storage`
    - Builds the block’s state, which contains its merkle tree stores, header, hash, height, etc
    - If it is the first height or a new epoch, prune the merkle tree stores
    - Execute batch write, which contains at least a write to the block db

## Storage::batch_write_subspace_val
- Update merkle tree then
- `DB::batch_write_subspace_val`
    - `RocksDB`
        - Writes the subspace diff with `batch_write_subspace_diff`
        - Then writes the val in the subspace
    - `MockDB`
        - Manual write subspace val
        - Then write manually the diffs by block height, including the old val and new val

## Write into write_log, with diffs but without merklizing
- No current applications
- Why not currently possible?
    - `storage.batch_write_subspace_val`, called during `write_log.commit_block`, updates the merkle tree, then calls `DB::batch_write_subspace_val`, which writes the diffs and the subspace vals
- Ideas for impl
    - Pass a flag/enum into `Storage::batch_write_subspace_val` that determines that determines if merkle tree is updated
        - Would perhaps require some method `write_without_merklizing` that would require expanding `StorageModification::Write` to take a value AND the flag as fields

## Write into write_log, without diffs or without merklizing
- Replay protection
- Currently there is a `write_replay_protection` `DB` trait method that specifically writes to the `REPLAY_PROTECTION_CF`
    - Since this is not writing any values to the subspace, perhaps we want to keep this?
- Can expand the write API with same flag/enum as in the one that writes diffs without merklizing for any future applications outside of replay protection

## Write to storage directly
- Some testing applications
- Looks like the `write` method for `impl Storage` already directly writes to the storage subspace, diffs, and merklizes without going thru write log

## Summary of thoughts
- Yuji [commented](https://github.com/anoma/namada/issues/2265#issuecomment-1852750111) that we should review all data written to storage, as we may not need extra APIs
    - would be good to get some assistance for this, because I currently don't see a pressing need to modify the APIs with only the existing code
        - a special replay protection write already exsts
        - currently no applications for a write that includes diffs but no merklization
        - the `write` method in `impl Storage` (not from trait) looks like it already writes and commits directly to storage (pls correct me if I missed something!)
    - could see how it could be useful to generalize the APIs if there are certain planned upgrades / modifications
- If we are going to try to generalize the APIs, my idea would be to have different `write` methods, each of which creates a `StorageModification::Write{ val, flag }`, where `flag` is an enum that can tell `commit_block` what to do exactly
    - Methods such as `write`, `write_no_merkl`, `write_no_diffs_merkl`
    - An enum `WriteActions` with variants `All`, `NoMerkl`, `NoDiffsOrMerkl`
    - Corresponding extensions for `delete` as well