cargo check
Sometimes errors from macro expansion are too opaque to debug.
To see errors with the expanded macro set RUSTFLAGS
like so:
RUSTFLAGS="-Z external-macro-backtrace" cargo +nightly [test|check]
# new version
RUSTFLAGS="-Zproc-macro-backtrace" cargo +nightly check
Need to borrow a field from &self
, however the &self
could not be used as a &'static
lifetime
Solution was to move
the borrowed value into ownership by the future
error: lifetime may not live long enough
--> ethy-gadget/rpc/src/lib.rs:102:61
|
87 | fn subscribe_event_proofs(&self, pending: PendingSubscription) {
| - let's call the lifetime of this reference `'1`
...
102 | self.executor.spawn("ethy-rpc-subscription", Some("rpc"), fut.boxed());
| ^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
solution (tip from here: https://users.rust-lang.org/t/help-with-static-lifetime-on-self-when-using-async/31482/4)
// thing is an `Arc<T>`
fn method(&self) {
let my_borrow = self.thing.clone()
// ...
// this moves the `my_borrow` to ownership of the closure thus giving the 'static lifetime
.map(move |x| do_something(my_borrow, x))
// ...
}
The schnorrkelKeypairFromSeed
function requires a length 32 UintArray seed
It will throw wasm unreachable errors otherwise
schnorrkelKeypairFromSeed(seed: Uint8Array);
When changing generic types or adding trait bounds in Substrate quite often an error occurs that looks like the following:
error[E0599]: no function or associated item named `execute_block` found for type `srml_executive::doughnut::DoughnutExecutive<Runtime, sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256, Log>, cennznet_primitives::cennznet_extrinsic::CennznetExtrinsic<substrate_primitives::sr25519::Public, srml_indices::address::Address<substrate_primitives::sr25519::Public, u32>, u64, Call, sr_primitives::AnySignature, u128, doughnut_rs::v0::parity::DoughnutV0>>, srml_system::ChainContext<Runtime>, fee::ExtrinsicFeeCharger, (srml_aura::Module<Runtime>, srml_timestamp::Module<Runtime>, prml_generic_asset::Module<Runtime>, srml_consensus::Module<Runtime>, srml_indices::Module<Runtime>, srml_session::Module<Runtime>, srml_staking::Module<Runtime>, srml_democracy::Module<Runtime>, srml_council::seats::Module<Runtime>, srml_council::voting::Module<Runtime>, srml_council::motions::Module<Runtime>, srml_grandpa::Module<Runtime>, srml_contract::Module<Runtime>, srml_sudo::Module<Runtime>, prml_fees::Module<Runtime>, crml_rewards::Module<Runtime>, prml_attestation::Module<Runtime>, crml_cennzx_spot::Module<Runtime>, crml_sylo::groups::Module<Runtime>, crml_sylo::e2ee::Module<Runtime>, crml_sylo::device::Module<Runtime>, crml_sylo::inbox::Module<Runtime>, crml_sylo::response::Module<Runtime>, crml_sylo::vault::Module<Runtime>)>` in the current scope
--> /Users/jordanbeauchamp/Projects/cennznet/runtime/src/lib.rs:313:15
|
313 | Executive::execute_block(block)
| ^^^^^^^^^^^^^ function or associated item not found in `srml_executive::doughnut::DoughnutExecutive<Runtime, sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256, Log>, cennznet_primitives::cennznet_extrinsic::CennznetExtrinsic<substrate_primitives::sr25519::Public, srml_indices::address::Address<substrate_primitives::sr25519::Public, u32>, u64, Call, sr_primitives::AnySignature, u128, doughnut_rs::v0::parity::DoughnutV0>>, srml_system::ChainContext<Runtime>, fee::ExtrinsicFeeCharger, (srml_aura::Module<Runtime>, srml_timestamp::Module<Runtime>, prml_generic_asset::Module<Runtime>, srml_consensus::Module<Runtime>, srml_indices::Module<Runtime>, srml_session::Module<Runtime>, srml_staking::Module<Runtime>, srml_democracy::Module<Runtime>, srml_council::seats::Module<Runtime>, srml_council::voting::Module<Runtime>, srml_council::motions::Module<Runtime>, srml_grandpa::Module<Runtime>, srml_contract::Module<Runtime>, srml_sudo::Module<Runtime>, prml_fees::Module<Runtime>, crml_rewards::Module<Runtime>, prml_attestation::Module<Runtime>, crml_cennzx_spot::Module<Runtime>, crml_sylo::groups::Module<Runtime>, crml_sylo::e2ee::Module<Runtime>, crml_sylo::device::Module<Runtime>, crml_sylo::inbox::Module<Runtime>, crml_sylo::response::Module<Runtime>, crml_sylo::vault::Module<Runtime>)>`
|
= note: the method `execute_block` exists but the following trait bounds were not satisfied:
`cennznet_primitives::cennznet_extrinsic::CennznetExtrinsic<substrate_primitives::sr25519::Public, srml_indices::address::Address<substrate_primitives::sr25519::Public, u32>, u64, Call, sr_primitives::AnySignature, u128, doughnut_rs::v0::parity::DoughnutV0> : sr_primitives::traits::Checkable<srml_system::ChainContext<Runtime>>
This is usually down to a type being wrong or more specifically a trait bound not being satisfied by the given types. In the example above
`cennznet_primitives::cennznet_extrinsic::CennznetExtrinsic<substrate_primitives::sr25519::Public, srml_indices::address::Address<substrate_primitives::sr25519::Public, u32>, u64, Call, sr_primitives::AnySignature, u128, doughnut_rs::v0::parity::DoughnutV0> : sr_primitives::traits::Checkable<srml_system::ChainContext<Runtime>>
Is saying the CennnznetExtrinsic<_>
(generic params elided for brevity) type does not implement Checkable
.
Checkable is a trait bound required by the extrinsic type required by the Executive trait
which is why this error is raised there also.
The heart of the issue in this case above was that a trait bound on the CennznetExtrinsic
Signature type was not satisfied.
impl Checkable for CennznetExtrinsic<_, Signature, _>
where
//..
Signature: Borrow<u8; 64>
{
// ...
}
One way of debugging this problem is to remove andy modified trait bounds or types one-by-one until the error disappears.
This will highlight which exact bound or type is causing the problem.
Sometimes an error is caused by missing cargo features from dependent crates.
The crate is imported implemented and in-scope but this error appears.
error[E0405]: cannot find trait `OffchainWorkerApi` in module `offchain_primitives`
--> runtime/src/lib.rs:357:28
|
357 | impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
| ^^^^^^^^^^^^^^^^^ not found in `offchain_primitives`
help: possible candidate is found in another module, you can import it into scope
|
22 | use offchain_primitives::runtime_decl_for_OffchainWorkerApi::OffchainWorkerApi;
|
error[E0425]: cannot find function `offchain_worker_call_api_at` in module `offchain_primitives::runtime_decl_for_OffchainWorkerApi`
--> runtime/src/lib.rs:304:1
|
304 | / impl_runtime_apis! {
305 | | impl client_api::Core<Block> for Runtime {
306 | | fn version() -> RuntimeVersion {
307 | | VERSION
... |
407 | | }
408 | | }
| |_^ not found in `offchain_primitives::runtime_decl_for_OffchainWorkerApi`
error[E0425]: cannot find function `offchain_worker_native_call_generator` in module `offchain_primitives::runtime_decl_for_OffchainWorkerApi`
--> runtime/src/lib.rs:304:1
304 | / impl_runtime_apis! {
305 | | impl client_api::Core<Block> for Runtime {
306 | | fn version() -> RuntimeVersion {
307 | | VERSION
... |
407 | | }
408 | | }
| |_^ not found in `offchain_primitives::runtime_decl_for_OffchainWorkerApi`
It doesn't makes sense becase the trait is defined in the module but not in the version of the module
cargo is trying to compile. This is caused by gated features in Cargo.toml
that are missing.
Solution is to add them to the feature in Cargo.toml
std = [
"my-missing-module/std"
]
This strange error was solved by adding a missing type Doughnut = ()
to a impl system::Trait for Runtime {}
block
conflicting implementations of trait `std::convert::Into<std::result::Result<system::RawOrigin<_, [type error]>, Origin>>` for type `Origin`:
--> srml/support/test/tests/instance.rs:251:1
|
251 | / srml_support::construct_runtime!(
252 | | pub enum Runtime where
253 | | Block = Block,
254 | | NodeBlock = Block,
... |
275 | | }
276 | | );
| |__^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> std::convert::Into<U> for T
where U: std::convert::From<T>;
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
Sometimes a cargo crate gets updated and you want to rollback. A simple solution is as follows:
- Checkout the project
Cargo.lock
- Remove the relevant folder from
~/.cargo/[git|registry]/<bad-crate-12391230123>
- run
cargo build
Substrate uses a single token represented by the Balances module.
This functions as the staking and reward token for consensus.
In CENNZnet, we use a dual token economy (CENNZ, CENTRAPAY). This meant some unit-tests in the substrate
staking module had been ignored (#[ignore]
) because they tested balance changes using a single token in the Balance module, whereas CENNZnet relies on it's generic-asset module to manage token balances.
During the process of merging upgrades to Substrate 2.0 for plug-blockchain, a new test was added which used a reward calculation, this meant it was failing but simply needed to be ignored. The real solution to reinstate the tests was to check whether reward currency == staking currency and let tests environment use a single token setup (plug-blockchain). It would be desirable to test rewards for dual token in CENNZnet with the generic-asset module.
The PR paritytech/substrate#3102 changed the way extrinsics are extended on substrate chanins.
Previously, a new extrinsic struct was defined and implemented a bespoke codec.
The change introduces a trait SignedExtension
and a generic type Extra
on extrinsics.
Extra
is a struct (currently a big tuple struct) of all extensible fields includable in a transaction.
pub type SignedExtra = (
system::CheckGenesis<Runtime>,
system::CheckEra<Runtime>,
system::CheckNonce<Runtime>,
system::CheckWeight<Runtime>,
balances::TakeFees<Runtime>,
);
The type of an extrinsic then becomes
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
Structs of interest can be embedded into the SignedExtra
type and have logic associated with them for validation and unpacking by implementing SignedExtension
for the type e.g.
impl<T: Trait> SignedExtension for CheckNonce<T> {
type AccountId = T::AccountId;
type AdditionalSigned = ();
fn additional_signed(&self) -> rstd::result::Result<Self::AdditionalSigned, &'static str> { Ok(()) }
fn pre_dispatch(
self,
who: &Self::AccountId,
_info: DispatchInfo,
_len: usize,
) -> Result<(), DispatchError> {
let expected = <AccountNonce<T>>::get(who);
if self.0 != expected {
return Err(
if self.0 < expected { DispatchError::Stale } else { DispatchError::Future }
)
}
<AccountNonce<T>>::insert(who, expected + T::Index::one());
Ok(())
}
Doughnuts are a proof of delegation, showing an issuing party has given some permissions to a holding party. This is acheived using public key cryptography and simply including the holding party's public key in a message with permissions with a signature from the issuing party.
While Doughnut is a decentralized mechanism for delegated proofs we have an implementation for CENNZnet which supports some permission delegation based on the runtime module structure at the heart of substrate chains.
The real challenge is providing meaning to the permissions part of the doughnut.
The spec caters for this by allowing arbitraty permission "domains" to exist whithin a doughnut. A domain is simply a top level key to a data payload, the contents of which are open to interpretation by the given domain.
In CENNZnet the doughnut has a permission domain "cennznet" which uses ascii strings to target a runtime module, method, and arguments. It is also intended to support bytecode interpretation, allowing the expression of logical constraints on arguments e.g. amount < 100
.
Doughnut support is acheived in these chains by allowing users to provide a doughnut certificate as a data field in an extrinsic. It is expected that the extrinsic signer is the holder of an attached doughnut, these validations are provided by an auxilliary crate https://github.com/cennznet/doughnut-rs.