diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 292f15f85..0ec2d5285 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -47,12 +47,32 @@ jobs: - uses: actions-rs/cargo@v1 with: command: build - args: --all --all-targets + args: --workspace --all-targets - uses: actions-rs/cargo@v1 with: command: test args: --all-features --no-fail-fast + test-integration-ignored: + runs-on: ubuntu-latest + services: + tendermint: + image: interchainio/tendermint + ports: + - 26656:26656 + - 26657:26657 + - 26660:26660 + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: test + args: -p tendermint --test integration --no-fail-fast -- --ignored + test-nightly-coverage: runs-on: ubuntu-latest steps: diff --git a/CHANGES.md b/CHANGES.md index 1c9933dfe..7fa9ceeb3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,7 +3,7 @@ Dependencies - Update to bytes `0.5` and amino_rs `0.5`. - Tokens for amino_rs are now fully non-conflicting with prost. Allowing both to be used together - +- Made RPC type values optional for full compatibility with tendermint-go@v0.32: `abci_info`, `abci_query` [#120] ## [0.11.0] (2019-12-11) diff --git a/tendermint/src/genesis.rs b/tendermint/src/genesis.rs index 5fb785d90..74c068964 100644 --- a/tendermint/src/genesis.rs +++ b/tendermint/src/genesis.rs @@ -23,5 +23,5 @@ pub struct Genesis { pub app_hash: Option, /// App state - pub app_state: AppState, + pub app_state: Option, } diff --git a/tendermint/src/rpc/endpoint/abci_info.rs b/tendermint/src/rpc/endpoint/abci_info.rs index b88be5fb8..c8e312b91 100644 --- a/tendermint/src/rpc/endpoint/abci_info.rs +++ b/tendermint/src/rpc/endpoint/abci_info.rs @@ -27,41 +27,60 @@ impl rpc::Response for Response {} /// ABCI information #[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(default)] pub struct AbciInfo { /// Name of the application pub data: String, /// Version + #[serde(skip_serializing_if = "Option::is_none")] pub version: Option, - /// Last block height - pub last_block_height: block::Height, + /// Last block height, omit empty + #[serde(skip_serializing_if = "Option::is_none")] + pub last_block_height: Option, - /// Last app hash for the block + /// Last app hash for the block, omit empty #[serde( serialize_with = "serialize_app_hash", - deserialize_with = "parse_app_hash" + deserialize_with = "parse_app_hash", + skip_serializing_if = "Option::is_none" )] - pub last_block_app_hash: Hash, + pub last_block_app_hash: Option, } /// Parse Base64-encoded app hash -pub(crate) fn parse_app_hash<'de, D>(deserializer: D) -> Result +pub(crate) fn parse_app_hash<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let bytes = base64::decode(String::deserialize(deserializer)?.as_bytes()) .map_err(|e| D::Error::custom(format!("{}", e)))?; - Hash::new(hash::Algorithm::Sha256, &bytes).map_err(|e| D::Error::custom(format!("{}", e))) + Hash::new(hash::Algorithm::Sha256, &bytes) // This never returns None + .map(Some) // Return Option (syntactic sugar so the value can be omitted in the struct) + .map_err(|e| D::Error::custom(format!("{}", e))) // or return custom Error } /// Serialize Base64-encoded app hash -pub(crate) fn serialize_app_hash(hash: &Hash, serializer: S) -> Result +pub(crate) fn serialize_app_hash(hash: &Option, serializer: S) -> Result where S: Serializer, { - String::from_utf8(base64::encode(hash.as_bytes())) + String::from_utf8(base64::encode(hash.unwrap().as_bytes())) .unwrap() .serialize(serializer) } + +/// Default trait implements default values for the optional last_block_height and last_block_app_hash +/// for cases where they were omitted from the JSON. +impl Default for AbciInfo { + fn default() -> Self { + AbciInfo { + data: "".to_string(), + version: None, + last_block_height: None, + last_block_app_hash: None, + } + } +} diff --git a/tendermint/src/rpc/endpoint/abci_query.rs b/tendermint/src/rpc/endpoint/abci_query.rs index 2995948bc..e4ae3d269 100644 --- a/tendermint/src/rpc/endpoint/abci_query.rs +++ b/tendermint/src/rpc/endpoint/abci_query.rs @@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request { /// Path to the data + #[serde(skip_serializing_if = "Option::is_none")] path: Option, /// Data to query @@ -20,6 +21,7 @@ pub struct Request { data: Vec, /// Block height + #[serde(skip_serializing_if = "Option::is_none")] height: Option, /// Include proof in response diff --git a/tendermint/tests/integration.rs b/tendermint/tests/integration.rs index 1490ac662..aebdc025d 100644 --- a/tendermint/tests/integration.rs +++ b/tendermint/tests/integration.rs @@ -31,7 +31,7 @@ mod rpc { async fn abci_info() { let abci_info = localhost_rpc_client().abci_info().await.unwrap(); - assert_eq!(&abci_info.data, "GaiaApp"); + assert_eq!(&abci_info.data, "{\"size\":0}"); } /// `/abci_query` endpoint diff --git a/tendermint/tests/rpc.rs b/tendermint/tests/rpc.rs index 6251f975d..b0fe05b25 100644 --- a/tendermint/tests/rpc.rs +++ b/tendermint/tests/rpc.rs @@ -21,7 +21,7 @@ mod endpoints { .response; assert_eq!(response.data.as_str(), EXAMPLE_APP); - assert_eq!(response.last_block_height.value(), 488_120); + assert_eq!(response.last_block_height.unwrap().value(), 488_120); } #[test]