In our project, we have on-chain storage items equivalent to the type AuthorityId which is the Public type coming out of the app_crypto! macro in sp-authority-discovery.

We would like to configure the runtime in a way that the <Runtime as frame_system::Config>::AccountId is AuthorityId, because our dispatchable function needs to be able to associate the caller aka origin: OriginFor<T> with the stored AuthorityId.

As the signature check let who = ensure_signed!(origin)?; gives us T::AccountId or concretely <Runtime as frame_system::Config>::AccountId we set type AccountId = AuthorityId in the impl frame_system::Config for Runtime block, which should allow us to make sure that each caller of extrinsics is identified using AuthorityId.

This results in the following:

error[E0599]: the function or associated item `execute_block` exists for struct `Executive<Runtime, Block<Header<u32, BlakeTwo256>, UncheckedExtrinsic<Public, ..., ..., ...>>, ..., ..., ...>`, but its trait bounds were not satisfied
     --> /home/magewe/rust/gensyn/node/chain_node/runtime/src/lib.rs:699:15
  699 |             Executive::execute_block(block);
      |                        ^^^^^^^^^^^^^ function or associated item cannot be called due to unsatisfied trait bounds
     ::: /home/magewe/.cargo/git/checkouts/substrate-7e08433d4c370a21/76fed9b/primitives/runtime/src/generic/unchecked_extrinsic.rs:44:1
  44  | pub struct UncheckedExtrinsic<Address, Call, Signature, Extra>
      | -------------------------------------------------------------- doesn't satisfy `_: Checkable<ChainContext<Runtime>>`
      = note: the full type name has been written to '/home/magewe/rust/gensyn/node/chain_node/target/debug/wbuild/gensyn-runtime/target/wasm32-unknown-unknown/release/deps/gensyn_runtime-13d0535547ae2d3c.long-type-6182207052186516563.txt'
      = note: the following trait bounds were not satisfied:
              `_sp_runtime::generic::UncheckedExtrinsic<sp_authority_discovery::app::Public, RuntimeCall, sp_authority_discovery::app::Signature, (CheckNonZeroSender<Runtime>, CheckSpecVersion<Runtime>, CheckTxVersion<Runtime>, CheckGenesis<Runtime>, CheckEra<Runtime>, CheckNonce<Runtime>, CheckWeight<Runtime>, ChargeTransactionPayment<Runtime>)>: Checkable<ChainContext<Runtime>>`

This indicates to me that using app_crypto! types does not work out of the box here, as the extrinsics do not implement Checkable<_>.

What is the proper way of using types such as AuthorityId as AccountId?


Alternatively specifying the associated type as such: type AccountId = <<AuthoritySignature as Verify>::Signer as IdentifyAccound>::AccountId; gives hundreds of errors including the following, potentially more useful error:

error[E0277]: the trait bound `sp_authority_discovery::app::Signature: _sp_runtime::traits::Verify` is not satisfied
     --> /home/magewe/rust/gensyn/node/chain_node/runtime/src/lib.rs:876:3
  876 | /         fn authorities() -> Vec<AuthorityDiscoveryId> {
  877 | |             let current_session_index = <pallet_session_info::Pallet<Runtime>>::session_index();
  878 | |             let earliest_stored_session = <pallet_session_info::Pallet<Runtime>>::earliest_stored_session();
  879 | |
  ...   |
  897 | |
  898 | |         }
      | |_________^ the trait `_sp_runtime::traits::Verify` is not implemented for `sp_authority_discovery::app::Signature`
      = help: the following other types implement trait `_sp_runtime::traits::Verify`:

Manually implementing Verify here seems weird as I would have expected that a Signature should always be verifiable.

1 Answer 1


The solution that works inside the extrinsic is the following:

let who = ensure_signed(origin)?;
let who: AuthorityId = sp_application_crypto::sr25519::Public::from_raw(who.into()).into();

This keeps the AccountId as:

pub type AccountId = <MultiSignature as Verify>::Signer as IdentifyAccount>::AccountId;

I hope this solution is the right way to do the conversion.

If not, please let me know!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.