1

I have the following error while building:

error[E0599]: no function or associated item named `generate_with_phrase` found for struct `crain_pow::app::Pair` in the current scope
   --> node/src/service.rs:211:49
    |
211 |         let (pair, phrase, _) = crain_pow::app::Pair::generate_with_phrase(None);
    |                                                       ^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `crain_pow::app::Pair`
    |
    = help: items from traits can only be used if the trait is in scope

A Pair type is declared using app_crypto! macro in another file:

pub mod app {
    use sp_application_crypto::{app_crypto, sr25519};
    use sp_core::crypto::KeyTypeId;

    pub const ID: KeyTypeId = KeyTypeId(*b"crn1");
    app_crypto!(sr25519, ID);
}

Which enables another macro which implements the generate_with_phrase function (code from substrate's github repo):

/// Implements functions for the `Pair` trait when `feature = "std"` is enabled.
#[doc(hidden)]
#[cfg(feature = "std")]
#[macro_export]
macro_rules! app_crypto_pair_functions_if_std {
    ($pair:ty) => {
        fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) {
            let r = <$pair>::generate_with_phrase(password);
            (Self(r.0), r.1, r.2)
        }

        fn from_phrase(
            phrase: &str,
            password: Option<&str>,
        ) -> Result<(Self, Self::Seed), $crate::SecretStringError> {
            <$pair>::from_phrase(phrase, password).map(|r| (Self(r.0), r.1))
        }
    };
}

I see that is requires sp-application-crypto's std feature to be enabled (#[cfg(feature = "std")]). So I enable it in my package's Cargo.toml:

[dependencies]
sp-application-crypto = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.19" }
***snip***
[features]
default = ["std"]
std = [
    "sp-application-crypto/std", # enables sp-application-crypto/full_crypto as well
]

So the std (and full_crypto as well) feature requirement is satisfied. But I still get the error saying that generate_with_phrase function is not implemented.

What might be the problem?

(P.S. This is a MR adding that function long time ago into primitives)

9
  • Where are you trying to declare this app crypto type? You have made default-features=false which implies this may be inside the runtime, in which case, the runtime must compile without std, so you cannot declare such a macro in your runtime.
    – Shawn Tabrizi
    May 19, 2022 at 15:14
  • app_crypto! macro is used in pow/src/lib.rs/ like here. Cargo.toml lines I've provided are from pow/Cargo.toml. pow crate is in the same directory as node, pallets, runtime, etc.
    – CREESTL
    May 19, 2022 at 15:32
  • I've tried removing default-features = false, tried adding features = ["full_crypto"] in that .toml, tried deleting whole [features] section of that .toml - nothing helped
    – CREESTL
    May 19, 2022 at 15:39
  • pow crate is imported to the node crate
    – CREESTL
    May 19, 2022 at 15:56
  • You should just add the dependency like: sp-application-crypto = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.19" }. With no features or anything. This should work, otherwise, you will need to share more details about your project, and the changes you made.
    – Shawn Tabrizi
    May 19, 2022 at 16:10

2 Answers 2

0

The issue here seems to be with how you are importing this crate.

Rust's feature system is quite strange in behavior, and if there is any situation where you try to use the app_crypto! macro outside of std, you will hit this kind of error.

I suggest that you simply import this crate like so:

[dependencies]
sp-application-crypto = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.19" }

Which involves no features at all, and due to the configuration of the sp-application-crypto, this will imply std by default.

4
  • I did exactly what you suggested and imported sp-application-crypto like that. It did not fix the bug. To me it seems completely obvious that std of that crate should be enabled in that case, and thus full-crypto should be enabled making this and this macros work. But it doesn't. I'm literally out of ideas now.
    – CREESTL
    May 21, 2022 at 19:56
  • I also checked that none of these function are callable. Which means that app_crypto_pair macro was not called which means that this version of app_crypto was called which means that full_crypto was not enabled
    – CREESTL
    May 21, 2022 at 20:03
  • You can check my code out
    – CREESTL
    May 21, 2022 at 20:07
  • Even explicitly enabling both std and full_crypto features doesn't help: sp-application-crypto = { version = "6.0.0", features = ["std", "full_crypto"], git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.19" }
    – CREESTL
    May 21, 2022 at 21:40
0

Ok. I've found the solution.

Rust has quite a weird behavior of traits. Let's say we have:
libA with traitA (which hash show() function),
libB with struct structB and impl traitA for structB
libC with code: structB::show()

The last line won't compile. Because, as it turns out, you have to first import traitA into libC with use libA::traitA.

In my case:
libA was sp_core,
libB was pow crate,
libC was node crate,

The solution:
(in the beginning of node/src/service.rs)
use sp_core::Pair;
That's it! It had nothing to do with Cargo.toml's at all!

Your Answer

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

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