Skip to content

Commit 2b6dbad

Browse files
committed
Make websocket subscriptions work: fix router and event deserialization error
Ported fix from cometbft/tendermint-rs#1433
1 parent 03f689b commit 2b6dbad

File tree

7 files changed

+242
-131
lines changed

7 files changed

+242
-131
lines changed

cometbft/src/abci/response/finalize_block.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::serializers::null_to_empty_vec;
12
use serde::{Deserialize, Serialize};
23

34
use crate::abci::{types::ExecTxResult, Event};
@@ -16,6 +17,7 @@ pub struct FinalizeBlock {
1617
pub tx_results: Vec<ExecTxResult>,
1718
/// A list of updates to the validator set.
1819
/// These will reflect the validator set at current height + 2.
20+
#[serde(default, deserialize_with = "null_to_empty_vec")]
1921
pub validator_updates: Vec<validator::Update>,
2022
/// Updates to the consensus params, if any.
2123
#[serde(default)]

cometbft/src/serializers.rs

+12
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,22 @@
55
//! CAUTION: There are no guarantees for backwards compatibility, this module should be considered
66
//! an internal implementation detail which can vanish without further warning. Use at your own
77
//! risk.
8+
use serde::{Deserialize, Deserializer};
9+
use std::vec::Vec;
10+
811
pub use cometbft_proto::serializers::*;
912

1013
pub mod apphash;
1114
pub mod apphash_base64;
1215
pub mod hash;
1316
pub mod option_hash;
1417
pub mod time;
18+
19+
pub fn null_to_empty_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
20+
where
21+
D: Deserializer<'de>,
22+
T: Deserialize<'de>,
23+
{
24+
let opt = Option::deserialize(deserializer)?;
25+
Ok(opt.unwrap_or_else(Vec::new))
26+
}

rpc/Cargo.toml

+35-30
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
[package]
2-
name = "cometbft-rpc"
3-
version = "0.1.0-alpha.2"
4-
edition = "2021"
5-
license = "Apache-2.0"
6-
homepage = "https://cometbft.com/"
2+
name = "cometbft-rpc"
3+
version = "0.1.0-alpha.2"
4+
edition = "2021"
5+
license = "Apache-2.0"
6+
homepage = "https://cometbft.com/"
77
repository = "https://github.com/cometbft/cometbft-rs"
8-
readme = "README.md"
9-
keywords = ["blockchain", "cosmos", "cometbft", "tendermint"]
8+
readme = "README.md"
9+
keywords = ["blockchain", "cosmos", "cometbft", "tendermint"]
1010
categories = ["cryptography::cryptocurrencies", "network-programming"]
11-
authors = [
11+
authors = [
1212
"Informal Systems <[email protected]>",
1313
"Ismail Khoffi <[email protected]>",
1414
"Alexander Simmerl <[email protected]>",
@@ -26,23 +26,13 @@ all-features = true
2626
[[bin]]
2727
name = "cometbft-rpc"
2828
path = "src/client/bin/main.rs"
29-
required-features = [ "cli" ]
29+
required-features = ["cli"]
3030

3131
[features]
3232
default = ["flex-error/std", "flex-error/eyre_tracer"]
33-
cli = [
34-
"http-client",
35-
"structopt",
36-
"tracing-subscriber",
37-
"websocket-client"
38-
]
39-
http-client = [
40-
"futures",
41-
"reqwest",
42-
"tokio/macros",
43-
"tracing"
44-
]
45-
secp256k1 = [ "cometbft/secp256k1" ]
33+
cli = ["http-client", "structopt", "tracing-subscriber", "websocket-client"]
34+
http-client = ["futures", "reqwest", "tokio/macros", "tracing"]
35+
secp256k1 = ["cometbft/secp256k1"]
4636
websocket-client = [
4737
"async-tungstenite",
4838
"futures",
@@ -51,7 +41,7 @@ websocket-client = [
5141
"tokio/macros",
5242
"tokio/sync",
5343
"tokio/time",
54-
"tracing"
44+
"tracing",
5545
]
5646

5747
[dependencies]
@@ -64,28 +54,43 @@ bytes = { version = "1.0", default-features = false }
6454
getrandom = { version = "0.2", default-features = false, features = ["js"] }
6555
peg = { version = "0.8", default-features = false }
6656
pin-project = { version = "1.0.1", default-features = false }
67-
serde = { version = "1", default-features = false, features = [ "derive" ] }
57+
serde = { version = "1", default-features = false, features = ["derive"] }
6858
serde_bytes = { version = "0.11", default-features = false }
6959
serde_json = { version = "1", default-features = false, features = ["std"] }
7060
thiserror = { version = "1", default-features = false }
71-
time = { version = "0.3", default-features = false, features = ["macros", "parsing"] }
61+
time = { version = "0.3", default-features = false, features = [
62+
"macros",
63+
"parsing",
64+
] }
7265
uuid = { version = "1.7", default-features = false }
7366
rand = { version = "0.8" }
74-
subtle-encoding = { version = "0.5", default-features = false, features = ["bech32-preview"] }
67+
subtle-encoding = { version = "0.5", default-features = false, features = [
68+
"bech32-preview",
69+
] }
7570
url = { version = "2.4.1", default-features = false }
7671
walkdir = { version = "2.3", default-features = false }
7772
flex-error = { version = "0.4.4", default-features = false }
7873
subtle = { version = "2", default-features = false }
7974
semver = { version = "1.0", default-features = false }
75+
ordered-float = { version = "4.0", default-features = false }
8076

8177
# Optional dependencies
82-
async-tungstenite = { version = "0.24", default-features = false, features = ["tokio-runtime", "tokio-rustls-native-certs"], optional = true }
78+
async-tungstenite = { version = "0.24", default-features = false, features = [
79+
"tokio-runtime",
80+
"tokio-rustls-native-certs",
81+
], optional = true }
8382
futures = { version = "0.3", optional = true, default-features = false }
84-
reqwest = { version = "0.11.20", optional = true, default-features = false, features = ["rustls-tls-native-roots"] }
83+
reqwest = { version = "0.11.20", optional = true, default-features = false, features = [
84+
"rustls-tls-native-roots",
85+
] }
8586
structopt = { version = "0.3", optional = true, default-features = false }
86-
tokio = { version = "1.0", optional = true, default-features = false, features = ["rt-multi-thread"] }
87+
tokio = { version = "1.0", optional = true, default-features = false, features = [
88+
"rt-multi-thread",
89+
] }
8790
tracing = { version = "0.1", optional = true, default-features = false }
88-
tracing-subscriber = { version = "0.3", optional = true, default-features = false, features = ["fmt"] }
91+
tracing-subscriber = { version = "0.3", optional = true, default-features = false, features = [
92+
"fmt",
93+
] }
8994

9095
[dev-dependencies]
9196
http = { version = "1", default-features = false, features = ["std"] }

rpc/src/client/transport/mock.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl MockClientDriver {
164164
self.subscribe(id, query, subscription_tx, result_tx);
165165
}
166166
DriverCommand::Unsubscribe { query, result_tx } => {
167-
self.unsubscribe(query, result_tx);
167+
self.unsubscribe(&query, result_tx);
168168
}
169169
DriverCommand::Publish(event) => self.publish(*event),
170170
DriverCommand::Terminate => return Ok(()),
@@ -184,7 +184,7 @@ impl MockClientDriver {
184184
result_tx.send(Ok(())).unwrap();
185185
}
186186

187-
fn unsubscribe(&mut self, query: Query, result_tx: ChannelTx<Result<(), Error>>) {
187+
fn unsubscribe(&mut self, query: &Query, result_tx: ChannelTx<Result<(), Error>>) {
188188
self.router.remove_by_query(query);
189189
result_tx.send(Ok(())).unwrap();
190190
}

0 commit comments

Comments
 (0)