# 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