# Ethereum CDAP Development Update #2
## Implementing Portal Network Storage Functionality
Since last update, I've worked on the design and implementation of a storage layer for the Trin client.
The purpose of this storage layer is to provide to the higher-level layers (such as Portal Network request handlers) simple functionality related to storing and retrieving Portal Network data from the node's database. This layer is necessary because it abstracts away all of the logic related to enforcing the node's storage capacity.
Portal Network nodes use a Kademlia model to store data in a distributed fashion. The storage logic works roughly as follows:
* Initially all data that is offered from other nodes is accepted and stored until the node's storage capacity is reached.
* After this point, a simple bitwise XOR is used as a distance function to measure the "distance" between the Node's 256 bit ID and the 256 bit ID of the "farthest" piece of data in the database. This value becomes the node's radius and from then on only data with a distance from the Node's ID that is less than the data radius are stored, otherwise rejected.
* Each time a new piece of data within the radius is added to the database, the current farthest piece of data is deleted from the database in order to maintain storage capacity. The new farthest data is found, and then the node's new data radius is calculated. This results in the node's data radius shrinking over time until each node in the network stores a specific subsection of the network's data.
The storage layer is implmemented as a Rust struct called PortalStorage.
The Rust methods provided by this storage layer are:
`new(config: PortalStorageConfig) -> PortalStorage`: The constructor takes a PortalStorageConfig, which allows user to specify the client's max capacity in kb
`should_store(key: String) -> bool`: used for determining whether to respond with an ACCEPT to an OFFER request
`store(key: String, value: String) -> Result` for storing a new piece of content from a STORE request. This function automatically takes into account the capacity and, if necessary, drops the farthest piece of data, finds the new farthest and updates the radius.
`get(key: String) -> Result`: Gets the value for the key if it exists in our DB.
`get_current_radius() -> u64`: Gets the node's current radius.
The functionality described above has been implemented, and was successfully tested via a Rust binary that I wrote in the Trin repo called `generate-data`. I'm using it to store twice the node's set capacity and ensuring that the node respects that capacity by deleting data, and that the radius shrinks as it should over time.
Things left to be done are:
- Make it so that the node measures the amount of storage being used based off of the cumulative size of the actual Portal Network data being stored, rather than the size of the specific storage implementation on disk. This came up because I found that RocksDB's size on disk doesn't necessarily grow/shrink at the exact time you add/delete data like I hoped it would.
- Configurable distance function: an instance of this storage layer should be usable by each of the Portal Network subnetworks, and the state network uses a different distance function than the history network. Currently the storage layer only supports the history's XOR distance function, ultimately the distance function will be configurable.
- Improve Rust error/Option handling: My Rust error handling skills are currently sub-par. Going to get rid of most of the `unwrap()`s and do things in a way that would make the most seasoned Rustaceans proud.