Substrate has the concept of a transaction_version
and an EXTRINSIC_FORMAT_VERSION
. What are these used for and when are they changed?
1 Answer
The transaction_version
is a field in the RuntimeVersion
struct, specific to a runtime implementation. A bump to this value happens whenever there's a change to a pallet's runtime index and/or when there's a change to the index of a pallet's dispatchable functions. In a world of runtime upgrades, a practical reason for this is that hardware wallets need to know how to correctly encode calls for a given runtime.
The EXTRINSIC_FORMAT_VERSION
is a constant in Substrate's primitives used to track upgrades of the format of an extrinsic, a.k.a. its encoding representation. This would typically be changes in the ordering of an extrinsic's byte fields for example. This version number is more of an indicator for all Substrate chains to ensure compatibility with how extrinsics are formatted for a runtime rather than one unique to a specific chain. From the Rust docs:
It ensures that if the representation is changed and the format is not known, the decoding fails.
In other words, changing the extrinsic format value will break the APIs of libraries like Polkadot JS API or Subxt, as they need to know how to correctly format a call (byte-wise). Whereas bumping the transaction version indicates that there's been a change in the call indices in a node's metadata, which libraries need to know to correctly encode/decode calls.
-
Follow-up question: why does the node advertise the transaction version but not the extrinsic version? Oct 6, 2022 at 17:19