informalsystems / tendermint-rs

Client libraries for Tendermint/CometBFT in Rust!
Apache License 2.0
598 stars 224 forks source link

Last block deserialization from SEI tendermint nodes is failing #1443

Open xoac opened 1 month ago

xoac commented 1 month ago

What went wrong?

When query sei tendermint node last_block serialization failed

Reproduce code:

Cargo.toml

[package]
name = "tendermint_tx_search"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# async 
tokio = { version = "1.13.1", features = [
    "rt-multi-thread",
    "time",
    "sync",
    "macros",
] }

# cosmos like chain
tendermint-rpc = { version = "0.37", features = ["http-client"] }
tendermint = { version = "0.37" }

# error
anyhow = "1"

main.rs

use std::time::Duration;

use anyhow::Context;
use tendermint_rpc::client::Client;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // list of possible addresses: https://cosmos.directory/sei/nodes
    let mut c = tendermint_rpc::client::HttpClient::new("https://sei-rpc.polkachu.com/")?;

    tokio::time::sleep(Duration::from_secs(1)).await;
    let abci_info = c.abci_info().await.context("abci_info")?;
    tokio::time::sleep(Duration::from_secs(2)).await;

    println!("{abci_info:?}");
    c.set_compat_mode(tendermint_rpc::client::CompatMode::V0_34);

    let last_block = c.latest_block().await.context("getting last block")?;
    println!("{last_block:?}");

    Ok(())
}

then

cargo run

Example result:

Error: getting last block

Caused by:
    0: serde parse error

       Caused by:
           invalid length 0, expected struct EvidenceList with 1 element at line 1 column 5314

       Location:
           /home/sr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flex-error-0.4.4/src/tracer_impl/eyre.rs:10:9
    1: serde parse error
    2: invalid length 0, expected struct EvidenceList with 1 element at line 1 column 5314

Definition of "done"

De-serialization of last block from SEI tendermint is parsed correctly. The crate works for other chains so I am not sure if this is issue on this crate or tendermint implementation.

romac commented 1 month ago

Thanks for reporting this and for the reproducible example.

It looks we are failing to parse

"evidence": []

into

pub evidence: ::core::option::Option<EvidenceList>,

Here is what tendermint-rs expects for an empty evidence list, as returned by eg. Osmosis:

"evidence": {
  "evidence": []
},

This would also work:

"evidence": null

As far as I know, SEI uses a custom fork of Tendermint, which may explain why the output does not match what we are expecting.

Nonetheless, we should probably ensure we accept [] as a valid empty evidence list.