Update version, tweak docs, and write up changelog (#616)

This commit is contained in:
James Wilson
2022-08-11 15:04:50 +01:00
committed by GitHub
parent 7e51b3ed66
commit a3ea12663e
11 changed files with 241 additions and 24 deletions
+204
View File
@@ -4,6 +4,210 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.23.0] - 2022-08-11
This is one of the most significant releases to date in Subxt, and carries with it a number of significant breaking changes, but in exchange, a number of significant improvements. The most significant PR is [#593](https://github.com/paritytech/subxt/pull/593); the fundamental change that this makes is to separate creating a query/transaction/address from submitting it. This gives us flexibility when creating queries; they can be either dynamically or statically generated, but also flexibility in our client, enabling methods to be exposed for online or offline use.
The best place to look to get a feel for what's changed, aside from the documentation itself, is the `examples` folder. What follows are some examples of the changes you'll need to make, which all follow a similar pattern:
### Submitting a transaction
Previously, we'd build a client which is tied to the static codegen, and then use the client to build and submit a transaction like so:
```rust
let api = ClientBuilder::new()
.build()
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<_>>>();
let balance_transfer = api
.tx()
.balances()
.transfer(dest, 10_000)?
.sign_and_submit_then_watch_default(&signer)
.await?
.wait_for_finalized_success()
.await?;
```
Now, we build a transaction separately (in this case, using static codegen to guide us as before) and then submit it to a client like so:
``` rust
let api = OnlineClient::<PolkadotConfig>::new().await?;
let balance_transfer_tx = polkadot::tx().balances().transfer(dest, 10_000);
let balance_transfer = api
.tx()
.sign_and_submit_then_watch_default(&balance_transfer_tx, &signer)
.await?
.wait_for_finalized_success()
.await?;
```
See the `examples/examples/submit_and_watch.rs` example for more.
### Fetching a storage entry
Previously, we build and submit a storage query in one step:
```rust
let api = ClientBuilder::new()
.build()
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
let entry = api.storage().staking().bonded(&addr, None).await;
```
Now, we build the storage query separately and submit it to the client:
```rust
let api = OnlineClient::<PolkadotConfig>::new().await?;
let staking_bonded = polkadot::storage().staking().bonded(&addr);
let entry = api.storage().fetch(&staking_bonded, None).await;
```
Note that previously, the generated code would do the equivalent of `fetch_or_default` if possible, or `fetch` if no default existed. You must now decide whether to:
- fetch an entry, returning `None` if it's not found (`api.storage().fetch(..)`), or
- fetch an entry, returning the default if it's not found (`api.storage().fetch_or_default(..)`).
The static types will protect you against using `fetch_or_default` when no such default exists, and so the recommendation is to try changing all storage requests to use `fetch_or_default`, falling back to using `fetch` where doing so leads to compile errors.
See `examples/examples/concurrent_storage_requests.rs` for an example of fetching entries.
### Iterating over storage entries
Previously:
```rust
let api = ClientBuilder::new()
.build()
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
let mut iter = api
.storage()
.xcm_pallet()
.version_notifiers_iter(None)
.await?;
while let Some((key, value)) = iter.next().await? {
// ...
}
```
Now, as before, building the storage query to iterate over is separate from using it:
```rust
let api = OnlineClient::<PolkadotConfig>::new().await?;
let key_addr = polkadot::storage()
.xcm_pallet()
.version_notifiers_root();
let mut iter = api
.storage()
.iter(key_addr, 10, None).await?;
while let Some((key, value)) = iter.next().await? {
// ...
}
```
Note that the `_root()` suffix on generated storage queries accesses the root entry at that address,
and is available when the address is a map that can be iterated over. By not appending `_root()`, you'll
be asked to provide the values needed to access a specific entry in the map.
See the `examples/examples/storage_iterating.rs` example for more.
### Accessing constants
Before, we'd build a client and use the client to select and query a constant:
```rust
let api = ClientBuilder::new()
.build()
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
let existential_deposit = api
.constants()
.balances()
.existential_deposit()?;
```
Now, similar to the other examples, we separately build a constant _address_ and provide that address to the client to look it up:
```rust
let api = OnlineClient::<PolkadotConfig>::new().await?;
let address = polkadot::constants()
.balances()
.existential_deposit();
let existential_deposit = api.constants().at(&address)?;
```
See the `examples/examples/fetch_constants.rs` example for more.
### Subscribing to events
Event subscriptions themselves are relatively unchanged (although the data you can access/get back has changed a little). Before:
```rust
let api = ClientBuilder::new()
.build()
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
let mut event_sub = api.events().subscribe().await?;
while let Some(events) = event_sub.next().await {
// ...
}
```
Now, we simply swap the client out for our new one, and the rest is similar:
```rust
let api = OnlineClient::<PolkadotConfig>::new().await?;
let mut event_sub = api.events().subscribe().await?;
while let Some(events) = event_sub.next().await {
// ...
}
```
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.
For more details about all of the changes, the full commit history since the last release is as follows:
### Added
- Expose the extrinsic hash from TxProgress ([#614](https://github.com/paritytech/subxt/pull/614))
- Add support for `ws` in `subxt-cli` ([#579](https://github.com/paritytech/subxt/pull/579))
- Expose the SCALE encoded call data of an extrinsic ([#573](https://github.com/paritytech/subxt/pull/573))
- Validate absolute path for `substitute_type` ([#577](https://github.com/paritytech/subxt/pull/577))
### Changed
- Rework Subxt API to support offline and dynamic transactions ([#593](https://github.com/paritytech/subxt/pull/593))
- Use scale-decode to help optimise event decoding ([#607](https://github.com/paritytech/subxt/pull/607))
- Decode raw events using scale_value and return the decoded Values, too ([#576](https://github.com/paritytech/subxt/pull/576))
- dual license ([#590](https://github.com/paritytech/subxt/pull/590))
- Don't hash constant values; only their types ([#587](https://github.com/paritytech/subxt/pull/587))
- metadata: Exclude `field::type_name` from metadata validation ([#595](https://github.com/paritytech/subxt/pull/595))
- Bump Swatinem/rust-cache from 1.4.0 to 2.0.0 ([#597](https://github.com/paritytech/subxt/pull/597))
- Update jsonrpsee requirement from 0.14.0 to 0.15.1 ([#603](https://github.com/paritytech/subxt/pull/603))
## [0.22.0] - 2022-06-20
With this release, subxt can subscribe to the node's runtime upgrades to ensure that the metadata is updated and
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "subxt-cli"
version = "0.22.0"
version = "0.23.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
@@ -16,9 +16,9 @@ path = "src/main.rs"
[dependencies]
# perform subxt codegen
subxt-codegen = { version = "0.22.0", path = "../codegen" }
subxt-codegen = { version = "0.23.0", path = "../codegen" }
# perform node compatibility
subxt-metadata = { version = "0.22.0", path = "../metadata" }
subxt-metadata = { version = "0.23.0", path = "../metadata" }
# parse command line args
structopt = "0.3.25"
# colourful error reports
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "subxt-codegen"
version = "0.22.0"
version = "0.23.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
@@ -20,7 +20,7 @@ proc-macro-error = "1.0.4"
quote = "1.0.8"
syn = "1.0.58"
scale-info = { version = "2.0.0", features = ["bit-vec"] }
subxt-metadata = { version = "0.22.0", path = "../metadata" }
subxt-metadata = { version = "0.23.0", path = "../metadata" }
[dev-dependencies]
bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "subxt-examples"
version = "0.22.0"
version = "0.23.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
publish = false
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "subxt-macro"
version = "0.22.0"
version = "0.23.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
autotests = false
@@ -19,4 +19,4 @@ darling = "0.14.0"
proc-macro-error = "1.0.4"
syn = "1.0.58"
subxt-codegen = { path = "../codegen", version = "0.22.0" }
subxt-codegen = { path = "../codegen", version = "0.23.0" }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "subxt-metadata"
version = "0.22.0"
version = "0.23.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
autotests = false
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "subxt"
version = "0.22.0"
version = "0.23.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
@@ -33,8 +33,8 @@ thiserror = "1.0.24"
tracing = "0.1.34"
parking_lot = "0.12.0"
subxt-macro = { version = "0.22.0", path = "../macro" }
subxt-metadata = { version = "0.22.0", path = "../metadata" }
subxt-macro = { version = "0.23.0", path = "../macro" }
subxt-metadata = { version = "0.23.0", path = "../metadata" }
sp-core = { version = "6.0.0", default-features = false }
sp-runtime = "6.0.0"
+20 -7
View File
@@ -34,10 +34,13 @@
//!
//! # Generating runtime types
//!
//! Subxt can generate types at compile time to help you interact with a node. The metadata can be downloaded using the
//! [subxt-cli](https://crates.io/crates/subxt-cli) tool.
//! Subxt can optionally generate types at compile time to help you interact with a node. These types are
//! generated using metadata which can be downloaded from a node using the [subxt-cli](https://crates.io/crates/subxt-cli)
//! tool. These generated types provide a degree of type safety when interacting with a node that is compatible with
//! the metadata that they were generated using. We also do runtime checks in case the node you're talking to has
//! deviated from the types you're using to communicate with it (see below).
//!
//! To generate the types, use the `subxt` attribute which points at downloaded static metadata.
//! To generate the types, use the `subxt` macro and point it at the metadata you've downloaded, like so:
//!
//! ```ignore
//! #[subxt::subxt(runtime_metadata_path = "metadata.scale")]
@@ -47,9 +50,12 @@
//! For more information, please visit the [subxt-codegen](https://docs.rs/subxt-codegen/latest/subxt_codegen/)
//! documentation.
//!
//! You can opt to skip this step and use dynamic queries to talk to nodes instead, which can be useful in some cases,
//! but doesn't provide any type safety.
//!
//! # Interacting with the API
//!
//! Once instantiated, a client, exposes four functions:
//! Once instantiated, a client exposes four core functions:
//! - `.tx()` for submitting extrinsics/transactions. See [`crate::tx::TxClient`] for more details, or see
//! the [balance_transfer](../examples/examples/balance_transfer.rs) example.
//! - `.storage()` for fetching and iterating over storage entries. See [`crate::storage::StorageClient`] for more details, or see
@@ -86,13 +92,20 @@
//! }
//! # }
//! ```
//! ## Opting out of static validation
//!
//! The static types that are used to query/access information are validated by default, to make sure that they are
//! compatible with the node being queried. You can generally call `.unvalidated()` on these static types to
//! disable this validation.
//!
//! # Runtime Updates
//!
//! There are cases when the node would perform a runtime update, and the runtime node's metadata would be
//! out of sync with the subxt's metadata.
//! The node you're connected to may occasionally perform runtime updates while you're connected, which would ordinarily
//! leave the runtime state of the node out of sync with the information Subxt requires to do things like submit
//! transactions.
//!
//! The `UpdateClient` API keeps the `RuntimeVersion` and `Metadata` of the client synced with the target node.
//! If this is a concern, you can use the `UpdateClient` API to keep the `RuntimeVersion` and `Metadata` of the client
//! synced with the target node.
//!
//! Please visit the [subscribe_runtime_updates](../examples/examples/subscribe_runtime_updates.rs) example for more details.
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "integration-tests"
version = "0.22.0"
version = "0.23.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
@@ -26,8 +26,8 @@ sp-core = { version = "6.0.0", default-features = false }
sp-keyring = "6.0.0"
sp-runtime = "6.0.0"
syn = "1.0.0"
subxt = { version = "0.22.0", path = "../../subxt" }
subxt-codegen = { version = "0.22.0", path = "../../codegen" }
subxt = { version = "0.23.0", path = "../../subxt" }
subxt-codegen = { version = "0.23.0", path = "../../codegen" }
test-runtime = { path = "../test-runtime" }
tokio = { version = "1.8", features = ["macros", "time"] }
tracing = "0.1.34"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "test-runtime"
version = "0.22.0"
version = "0.23.0"
edition = "2021"
[dependencies]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "ui-tests"
version = "0.22.0"
version = "0.23.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html