# 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