Description
Inspired by a bug I introduced in glados, and thoughts about how to make it less likely in the future:
ethereum/glados#335 (review)
The current usage pattern goes something like:
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)
}
An ideal API probably looks something closer to this (at least as an option):
let key = StateContentKey::AccountTrieNode(...);
let trie_node = match StateNetworkApiClient::get_decoded_content(transport, key) {
Ok(trie_node) => trie_node, // only a single type can be returned by any key type, so we can skip the enum
Err(e) => return handle_err(e),
};
// do_something(trie_node)
I don't know the rust magic to make that happen ^ but it should be straightforward to do a middle-ground solution, like:
let key = StateContentKey::AccountTrieNode(...);
let trie_node = match StateNetworkApiClient::get_decoded_content(transport, key) {
Ok(StateContentValue::TrieNode(trie_node)) => trie_node, // only a single type can be returned by any key type, so we can skip the enum
Ok(wrong_type) => panic!("Should never get a different value when looking up a trie node. Got: {wrong_type}"),
Err(e) => return handle_err(e),
};
// do_something(trie_node)
I do see that there could be reasons to keep both get_content
and get_decoded_content
around in the API. Maybe this is pretty low priority, since it amounts to having to make one less function call. (unless we can get the magic solution working)
At the very least, we can add some docs to EncodedTrieNode
that say: if you're trying to decode this by hand after making an RPC request, you're probably doing it wrong, and should be using StateContentValue::decode()
instead
Activity