diff --git a/CHANGELOG.md b/CHANGELOG.md index 397f3c7eb9..57dbe3b550 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -182,8 +182,11 @@ while let Some(events) = event_sub.next().await { } ``` +Note that when working with a single event, the method `event.bytes()` previously returned just the bytes associated with the event fields. Now, `event.bytes()` returns _all_ of the bytes associated with the event. There is a separate method, `event.field_bytes()`, that returns the bytes for just the fields in the event. This change will **not** lead to a compile error, and so it's worth keeping an eye out for any uses of `.bytes()` to update them to `.field_bytes()`. + See the `examples/examples/subscribe_all_events.rs` example for more. + The general pattern, as seen above, is that we break apart constructing a query/address and using it. You can now construct queries dynamically instead and forego all static codegen by using the functionality exposed in the `subxt::dynamic` module instead. Other smaller breaking changes have happened, but they should be easier to address by following compile errors. diff --git a/examples/examples/custom_type_derives.rs b/examples/examples/custom_type_derives.rs index ac73aed6c7..dbff1a62ff 100644 --- a/examples/examples/custom_type_derives.rs +++ b/examples/examples/custom_type_derives.rs @@ -11,7 +11,7 @@ // a comma separated list to the below attribute. Most useful for adding `Clone`. // The derives that we can add ultimately is limited to the traits that the base // types relied upon by the codegen implement. - derive_for_all_types = "Clone, PartialEq", + derive_for_all_types = "Clone, PartialEq, Eq", // To apply derives to specific generated types, add a `derive_for_type` per type, // mapping the type path to the derives which should be added for that type only. diff --git a/subxt/src/events/events_type.rs b/subxt/src/events/events_type.rs index 8020d2a82b..bdac4b3ad4 100644 --- a/subxt/src/events/events_type.rs +++ b/subxt/src/events/events_type.rs @@ -364,7 +364,7 @@ pub(crate) mod test_utils { use std::convert::TryFrom; /// An "outer" events enum containing exactly one event. - #[derive(Encode, Decode, TypeInfo, Clone, Debug, PartialEq)] + #[derive(Encode, Decode, TypeInfo, Clone, Debug, PartialEq, Eq)] pub enum AllEvents { Test(Ev), } @@ -773,7 +773,7 @@ mod tests { #[test] fn event_containing_explicit_index() { - #[derive(Clone, Debug, PartialEq, Decode, Encode, TypeInfo)] + #[derive(Clone, Debug, PartialEq, Eq, Decode, Encode, TypeInfo)] #[repr(u8)] #[allow(trivial_numeric_casts, clippy::unnecessary_cast)] // required because the Encode derive produces a warning otherwise pub enum MyType { diff --git a/subxt/src/metadata/metadata_type.rs b/subxt/src/metadata/metadata_type.rs index 6c199470fa..9e19a4e6ec 100644 --- a/subxt/src/metadata/metadata_type.rs +++ b/subxt/src/metadata/metadata_type.rs @@ -25,7 +25,7 @@ use std::{ }; /// Metadata error originated from inspecting the internal representation of the runtime metadata. -#[derive(Debug, thiserror::Error, PartialEq)] +#[derive(Debug, thiserror::Error, PartialEq, Eq)] pub enum MetadataError { /// Module is not in metadata. #[error("Pallet not found")] diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs index 5265608422..1be869e122 100644 --- a/subxt/src/rpc.rs +++ b/subxt/src/rpc.rs @@ -112,7 +112,7 @@ use sp_runtime::{ /// /// The primary motivation for having this type is to avoid overflows when using big integers in /// JavaScript (which we consider as an important RPC API consumer). -#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] +#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] #[serde(untagged)] pub enum NumberOrHex { /// The number represented directly. @@ -158,7 +158,7 @@ pub type SystemProperties = serde_json::Map; /// /// This is copied from `sp-transaction-pool` to avoid a dependency on that crate. Therefore it /// must be kept compatible with that type from the target substrate version. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum SubstrateTxStatus { /// Transaction is part of the future queue. @@ -187,7 +187,7 @@ pub enum SubstrateTxStatus { /// This contains the runtime version information necessary to make transactions, as obtained from /// the RPC call `state_getRuntimeVersion`, -#[derive(Debug, Clone, PartialEq, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RuntimeVersion { /// Version of the runtime specification. A full-node will not attempt to use its native @@ -218,7 +218,7 @@ pub struct RuntimeVersion { /// /// This is copied from `sc-rpc-api` to avoid a dependency on that crate. Therefore it /// must be kept compatible with that type from the target substrate version. -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ReadProof { /// Block hash used to generate the proof @@ -228,7 +228,7 @@ pub struct ReadProof { } /// Statistics of a block returned by the `dev_getBlockStats` RPC. -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BlockStats { /// The length in bytes of the storage proof produced by executing the block. @@ -248,7 +248,7 @@ pub struct BlockStats { } /// Health struct returned by the RPC -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Health { /// Number of connected peers diff --git a/testing/integration-tests/src/events/mod.rs b/testing/integration-tests/src/events/mod.rs index 3abfffffe7..1012e15240 100644 --- a/testing/integration-tests/src/events/mod.rs +++ b/testing/integration-tests/src/events/mod.rs @@ -82,6 +82,49 @@ async fn subscription_produces_events_each_block() -> Result<(), subxt::Error> { Ok(()) } +// Iterate all of the events in a few blocks to ensure we can decode them properly. +#[tokio::test] +async fn decoding_all_events_in_a_block_works() -> Result<(), subxt::Error> { + let ctx = test_context().await; + let api = ctx.client(); + + wait_for_blocks(&api).await; + + let mut event_sub = api.events().subscribe().await?; + + tokio::spawn(async move { + let alice = pair_signer(AccountKeyring::Alice.pair()); + let bob = AccountKeyring::Bob.to_account_id(); + let transfer_tx = node_runtime::tx() + .balances() + .transfer(bob.clone().into(), 10_000); + + // Make a load of transfers to get lots of events going. + for _i in 0..10 { + api.tx() + .sign_and_submit_then_watch_default(&transfer_tx, &alice) + .await + .expect("can submit_transaction"); + } + }); + + for _ in 0..4 { + let events = event_sub + .next() + .await + .expect("events expected each block")?; + + for event in events.iter() { + // make sure that we can get every event properly. + let event = event.expect("valid event decoded"); + // make sure that we can decode the field values from every event. + event.field_values().expect("can decode fields"); + } + } + + Ok(()) +} + // Check that our subscription receives events, and we can filter them based on // it's Stream impl, and ultimately see the event we expect. #[tokio::test]