# Development Update #6 ## Previous Goals 1. Complete the Content Key SSZ - fix overflowing issue, use new types from ssz_types crate and make sure everything still works, clean up & organize code (make the functions methods, move ContentKey types to separate files) 2. Finish OFFER/ACCEPT implementation - integrate with utp and PortalStorage 3. Continue thinking, designing, tinkering with an architecture of how to handle responses in general ## Progress ### Content Key SSZ Since the last update, I have finally been able to finish this goal and submit a PR for review! The functionality that this PR entails is basically defining what the content keys look like in Rust, and then implementing methods to encode and decode the content keys using SSZ, and doing so appropriately by looking at the `content-id` field. Here is a general explanation of how I understand it works. Basically, for each different type of content-key on state and history, I defined a `struct` that holds the fields of the key. This struct is wrapped within a couple `enum` values. At the top level enum, I just have a `ContentKey` enum, which has 2 variants, `HistoryKey` or `StateKey` to differentiate the keys between networks. These variants are enums themselves, and their variants are the individual key types for each key type on the respective network, and these enums hold the struct I've defined for the particular key. First, to encode a content-key, the client creates the struct with the appriopriate fields, wraps it in the proper enum variants, and then calls `to_bytes` on the type. This method converts the key to bytes according to SSZ serialization in order to send it over the wire. Basically, this method first finds the `content-type` of the key, by calling a method. How do we return the correct `content-type`? Well, by looking at the enum variant of the key passed in, we can determine which exact state/history key the key is, and return the type as defined by the spec. Then, the struct itself is encoded as SSZ bytes, and here we use the SSZ algorithm to turn a `Container` type into bytes. These bytes are appended to the `content-type` byte in a vector, and I believe all of this turns out to be a `Union` SSZ type. Now, to decode a content-key, we are receiving a byte array from the network and would like to get the exact key out. So first we strip the first byte from the array to get the `content-type`, and then based on the type, we can now decode the rest of the payload using SSZ's deserialization algorithm, decoding the bytes into the appropriate struct that I defined previously for the keys. So one thing that I learned is that SSZ uses the struct defined as a sort of schema in order to do the proper decoding and encoding. For example, we just have bytes coming in, and we need to match which bytes go to which fields...this is all done according to the schema (struct). The analogous thing is done for history content keys. Note that history and state have overlapping content types, and the `from_bytes` is an associated function of StateKey and HistoryKey. So, we must know to either call the StateKey `from_bytes` method or HistoryKey `from_bytes` method. Thus, the caller must know whether we are dealing with state network or history network keys. With all of this functionality defined, I now turn to the derivation functions, deriving id's from keys. Currently, the functionality is that the key comes in as a byte array, and within the derivation function, we first decode the key (knowing if it was state or history) and then do the appropriate conversion. Since this is getting long, I'll explain it in the next update. And it might change as well, I'll have to look more into the context in which these methods will be called. Finally, I fixed the overflow issue by doing all intermediate calculations in `U512`, then doing a simple conversion of the final value to `U256`. This is possible since in the derivation, we mod by `2**256`, meaning the final result will always be a value `U256`. ### OFFER/ACCEPT Implementation My goal here was to turn the stub implementation into a full implementation, integrating with utp & portalstorage. Utp is being worked on by a fellow collaborator. I started looking into integrating with storage. Currently, I am blocked on this, since this means that the overlay protocol will need access to PortalStorage, which it does not have, but is being worked on by someone else. To prevent from being blocked, I plan to work on looking into how the `should_store` method should be defined. There might be some changes here, since this method will call the derivation functions, so all of this ties together, from message implementation, to portalstorage, down to the derivation functions. ### Handling Responses Issue This is the broader issue that relates to OFFER/ACCEPT. I've started looking into creating an event loop handler, and will continue to talk and think about this issue this week. ## Next Steps 1. Make changes to content-keys PR as needed by review. Think about the context that derivation functions will need to be called in and make changes as necessary. 2. Think about how OFFER/ACCEPT will integrate with PortalStorage 3. Architect ideas on how to handle ACCEPT response, which ties in with broader issue.