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

Fix inconsistencies when de/serializing CommitmentPrefix #1229

Closed
seanchen1991 opened this issue May 16, 2024 · 1 comment · Fixed by #1230
Closed

Fix inconsistencies when de/serializing CommitmentPrefix #1229

seanchen1991 opened this issue May 16, 2024 · 1 comment · Fixed by #1230
Assignees

Comments

@seanchen1991
Copy link
Contributor

Feature Summary

Raised by @soareschen:

It looks like there are some inconsistencies between the JSON serialization and deserialization of ConnectionEnd in ibc-rs. I tried to query for the connection end from sov-ibc, and when try to parse the response using QueryConnectionResponse, I got the error:

Error: ParseError(Error("invalid type: string \"ibc\", expected struct CommitmentPrefix", line: 1, column: 139))

So it seems like the commitment_prefix field is serialized into string during serialization, but is expected to be wrapped inside a CommitmentPrefix wrapper field during JSON deserialization.

I think the culprit is probably here:

#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
pub struct CommitmentPrefix {
    bytes: Vec<u8>,
}

#[cfg(feature = "serde")]
impl serde::Serialize for CommitmentPrefix {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        format!("{self:?}").serialize(serializer)
    }
}

The Deserialize instance is auto derived using serde, but the Serialize instance is manually implemented to serialize it as string

Proposal

Either auto-derive serde::Serialize as well for CommitmentPrefix, or manually deserialize it so that parsing is consistent.

@soareschen
Copy link
Collaborator

Note that the current manually derived Serialize instance for CommitmentPrefix is also incorrectly implemented. It uses the Debug instance of CommitmentPrefix, but the Debug implementation serializes a commitment prefix with invalid UTF-8 as "<not valid UTF8: {:?}>".

impl fmt::Debug for CommitmentPrefix {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let converted = core::str::from_utf8(self.as_bytes());
        match converted {
            Ok(s) => write!(f, "{s}"),
            Err(_e) => write!(f, "<not valid UTF8: {:?}>", self.as_bytes()),
        }
    }
}

For safe and correct serialization, we should revert the behavior and serialize it as bytes, not string.

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 a pull request may close this issue.

2 participants