v0.26.0
[0.26.0] - 2022-01-24
This release adds a number of improvements, most notably:
- We make Substrate dependencies optional (#760), which makes WASM builds both smaller and more reliable. To do this, we re-implement some core types like
AccountId32
,MultiAddress
andMultiSignature
internally. - Allow access to storage entries (#774) and runtime API's (#777) from some block. This is part of a move towards a more "block centric" interface, which will better align with the newly available
chainHead
style RPC interface. - Add RPC methods for the new
chainHead
style interface (see https://paritytech.github.io/json-rpc-interface-spec/). These are currently unstable, but will allow users to start experimenting with this new API if their nodes support it. - More advanced type substitution is now possible in the codegen interface (#735).
This release introduces a number of breaking changes that can be generally be fixed with mechanical tweaks to your code. The notable changes are described below.
Make Storage API more Block-centric
See #774. This PR makes the Storage API more consistent with the Events API, and allows access to it from a given block as part of a push to provide a more block centric API that will hopefully be easier to understand, and will align with the new RPC chainHead
style RPC interface.
Before, your code will look like:
let a = api.storage().fetch(&staking_bonded, None).await?;
After, it should look like:
let a = api.storage().at(None).await?.fetch(&staking_bonded).await?;
Essentially, the final parameter for choosing which block to call some method at has been moved out of the storage method itself and is now provided to instantiate the storage API, either explicitly via an .at(optional_block_hash)
as above, or implicitly when calling block.storage()
to access the same storage methods for some block.
An alternate way to access the same storage (primarily used if you have subscribed to blocks or otherwise are working with some block) now is:
let block = api.blocks().at(None).await?
let a = block.storage().fetch(&staking_bonded, None).await?;
More advanced type substitution in codegen
See #735. Previously, you could perform basic type substitution like this:
#[subxt::subxt(runtime_metadata_path = "../polkadot_metadata.scale")]
pub mod node_runtime {
#[subxt::subxt(substitute_type = "sp_arithmetic::per_things::Foo")]
use crate::Foo;
}
This example would use crate::Foo
every time an sp_arithmetic::per_things::Foo
was encountered in the codegen. However, this was limited; the substitute type had to have the name number and order of generic parameters for this to work.
We've changed the interface above into:
#[subxt::subxt(
runtime_metadata_path = "../polkadot_metadata.scale",
substitute_type(
type = "sp_arithmetic::per_things::Foo<A, B, C>",
with = "crate::Foo<C>"
)
)]
pub mod node_runtime {}
In this example, we can (optionally) specify the generic parameters we expect to see on the original type ("type"), and then of those, decide which should be present on the substitute type ("with"). If no parameters are provided at all, we'll get the same behaviour as before. This allows much more flexibility when defining substitute types.
Optional Substrate dependencies
See #760. Subxt now has a "substrate-compat" feature (enabled by default, and disabled for WASM builds). At present, enabling this feature simply exposes the PairSigner
(which was always available before), allowing transactions to be signed via Substrate signer logic (as before). When disabled, you (currently) must bring your own signer implementation, but in return we can avoid bringing in a substantial number of Substrate dependencies in the process.
Regardless, this change also tidied up and moved various bits and pieces around to be consistent with this goal. To address some common moves, previously we'd have:
use subxt::{
ext::{
sp_core::{ sr25519, Pair },
sp_runtime::{ AccountId32, generic::Header },
},
tx::{
Era,
PlainTip,
PolkadotExtrinsicParamsBuilder
}
};
And now this would look more like:
// `sp_core` and `sp_runtime` are no longer exposed via `ext`; add the crates yourself at matching versions to use:
use sp_core::{
sr25519,
Pair,
};
use subxt::{
// You'll often want to use the "built-in" `AccountId32` now instead of the `sp_runtime` version:
utils::AccountId32,
// traits used in our `Config` trait are now provided directly in this module:
config::Header,
// Polkadot and Substrate specific Config types are now in the relevant Config section:
config::polkadot::{
Era,
PlainTip,
PolkadotExtrinsicParamsBuilder
}
}
Additionally, the type Hashing
in the Config
trait is now called Hasher
, to clarify what it is, and types returned directly from the RPC calls now all live in crate::rpc::types
, rather than sometimes living in Substrate crates.
Some other note worthy PRs that were merged since the last release:
Added
- Add block-centric Storage API (#774)
- Add
chainHead
RPC methods (#766) - Allow for remapping type parameters in type substitutions (#735)
- Add ability to set custom metadata etc on OnlineClient (#794)
- Add
Cargo.lock
for deterministic builds (#795) - Add API to execute runtime calls (#777)
- Add bitvec-like generic support to the scale-bits type for use in codegen (#718)
- Add
--derive-for-type
to cli (#708)
Changed
- rename subscribe_to_updates() to updater() (#792)
- Expose
Update
(#791) - Expose version info in CLI tool with build-time obtained git hash (#787)
- Implement deserialize on AccountId32 (#773)
- Codegen: Preserve attrs and add #[allow(clippy::all)] (#784)
- make ChainBlockExtrinsic cloneable (#778)
- Make sp_core and sp_runtime dependencies optional, and bump to latest (#760)
- Make verbose rpc error display (#758)
- rpc: Expose the
subscription ID
forRpcClientT
(#733) - events: Fetch metadata at arbitrary blocks (#727)