I could not find much information/documentation on how to use the provides
/requires
tags (TransactionTag
) Can someone please provide an example? The tag is a vector of bytes. Should I assume these are user-defined strings? Where/how do you specify them when creating a transaction?
1 Answer
AFAIK the most common example cited for explaining this where the requires
/provides
tag is used to provide nonce information for the current transaction in order to be properly considered a valid tx. The provides
tag for a tx with nonce N
would be the requires
for a tx with nonce N+1
.
Here's an example which constructs the provides
and requires
tag for a the checking correct nonce of a transaction:
fn validate(
&self,
who: &Self::AccountId,
_call: &Self::Call,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
// check index
let account = crate::Account::<T>::get(who);
if self.0 < account.nonce {
return InvalidTransaction::Stale.into()
}
let provides = vec![Encode::encode(&(who, self.0))];
let requires = if account.nonce < self.0 {
vec![Encode::encode(&(who, self.0 - One::one()))]
} else {
vec![]
};
Ok(ValidTransaction {
priority: 0,
requires,
provides,
longevity: TransactionLongevity::max_value(),
propagate: true,
})
}
-
What would these tags look like? Where are the tags set? Where (file/function) in the Substrate code is the dependency graph built/evaluated? Commented Nov 21, 2022 at 12:53
-
Good question, and I don't have an answer for you. But my guess would be to look at where Transactions are built. Check out this doc: paritytech.github.io/substrate/master/frame_support/… and look for uses of
with_tag_prefix
Commented Nov 21, 2022 at 13:06 -
I found one example that shows that they are strings. e.g.
ValidTransaction::with_tag_prefix("BabeEquivocation")
Commented Nov 21, 2022 at 19:33 -
1
-
1Yes, as you can see from the code
pub struct CheckNonce<T: Config>(#[codec(compact)] pub T::Index);
, It's a tuple containing the Nonce, referred to asIndex
here. Commented Nov 29, 2022 at 11:15