Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add get_decoded_content to NetworkClientApi #1658

Closed
wants to merge 0 commits into from

Conversation

7suyash7
Copy link

@7suyash7 7suyash7 commented Feb 1, 2025

Fix: #1578

Add get_decoded_content to NetworkClientApi to simplify content retrieval.

Instead of having to manually handle content fetching and decoding in multiple steps like this:

let key = StateContentKey::AccountTrieNode(...);
let response = match StateNetworkApiClient::get_content(transport, key) {
    Ok(response) => response,
    Err(e) => return handle_err(e),
};
let decoded = match StateContentValue::decode(key, response.content) {
    Ok(decoded) => decoded,
    Err(e) => return handle_err(e),
};
if let StateContentValue::TrieNode(trie_node) = decoded {
    // do_something(trie_node)
}

You can now just do:

let key = StateContentKey::AccountTrieNode(...);
let decoded = match StateNetworkApiClient::get_decoded_content(transport, key) {
    Ok(value) => value,
    Err(e) => return handle_err(e),
};
// decoded value is ready to use

@KolbyML KolbyML requested review from morph-dev and carver February 2, 2025 16:26
@morph-dev
Copy link
Collaborator

There are few issues with this PR, but there are also good stuff.

  1. We probably want the same functionality for all subnetworks (not just state). So whatever we do, we will have to do for other types as well. Therefore, newly introduced types should probably be moved to shared location and should be more general
  2. StateContentValue shouldn't be (de)serialized as key-value object. Instead, it should be pure hex string. As such, it can't be deserialized directly, because the same hex string can be the valid representation of multiple content types. For this reason, we have somewhat complicated logic for encoding/decoding and serialization/deserialization where content_key is needed for correct decoding/deserialization.
  3. The ContentKeyType is something that I believe we can reuse. I don't think we need both try_decode_primary and try_decode_proof as they are always used one after another (except in tests).

With comments above, I propose the following changes:

  1. Move ContentKeyType into crates/ethportal-api/src/types/content_key/overlay.rs (or maybe separate file) and make it more generic, something like:
    pub trait ContentKey {
        type K: OverlayContentKey;
    
        fn decode(&self, buf: &[u8]) -> Result<Self::K, ContentKeyError>;
    }
    • This can be enriched to include more logic that is shared between types
  2. Remove get_decoded_content from StateNetworkApi as StateContentValue can't be (de)serializable
  3. Introduce new trait that will have function similar to get_decoded_content, but be generic. This would remove restrictions on returning object being (de)serializable
    • This trait should be implemented by all <Subnetwork>NetworkApi structures

I think this work should be split into separate PRs for easier review and discussion. For example, I would start with just step 1 from above. I understand that it can be difficult to work on step 1 without knowing the exact usecase from step 2. Usually my workflow would be one of:

  • Do step 1 as well as possible, clearly explaining future use for it. And if needed, adapt/fix if when working on step 2
  • Work on both steps at the same time, but commit changes in separate commits and send two PRs at the same time (one PR would contain only first commit, and other would contain both)

@7suyash7
Copy link
Author

7suyash7 commented Feb 5, 2025

Hi, @morph-dev, thanks for the review!

  1. I'll remove the Serialize/Deserialize from the StateContentValue and make try_decoded_primary + try_decode_proof into a single decode() method. Also, move the new trait to a shared file (like content_key/overlay.rs) or maybe a new file, so it's not state-specific. This will be PR-1
  2. Remove the get_decoded_content method from the JSON-RPC and keep it as a local trait that would implement single-step decoding so the network-level API remains raw bytes only. This would be PR-2
  3. Then if we want to do the same approach for History or Beacon, I can follow up with additional PRs reusing the new trait design.

If this looks good, I'll close this PR and work on it separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improvements to *NetworkApiClient ergonomics
2 participants