mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 04:28:01 +00:00
Unsigned Validation best practices (#5563)
* Configurable Unsigned Priority. * Use the new builder. * Fix tests. * Fix benches. * Remove unused import. * Rename for_pallet
This commit is contained in:
@@ -53,9 +53,10 @@ use sp_runtime::{
|
||||
traits::Zero,
|
||||
transaction_validity::{
|
||||
InvalidTransaction, ValidTransaction, TransactionValidity, TransactionSource,
|
||||
TransactionPriority,
|
||||
},
|
||||
};
|
||||
use sp_std::{vec, vec::Vec};
|
||||
use sp_std::vec::Vec;
|
||||
use lite_json::json::JsonValue;
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -106,6 +107,12 @@ pub trait Trait: frame_system::Trait {
|
||||
///
|
||||
/// This ensures that we only accept unsigned transactions once, every `UnsignedInterval` blocks.
|
||||
type UnsignedInterval: Get<Self::BlockNumber>;
|
||||
|
||||
/// A configuration for base priority of unsigned transactions.
|
||||
///
|
||||
/// This is exposed so that it can be tuned for particular runtime, when
|
||||
/// multiple pallets send unsigned transactions.
|
||||
type UnsignedPriority: Get<TransactionPriority>;
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
@@ -537,32 +544,33 @@ impl<T: Trait> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
.map(|price| if &price > new_price { price - new_price } else { new_price - price })
|
||||
.unwrap_or(0);
|
||||
|
||||
Ok(ValidTransaction {
|
||||
ValidTransaction::with_tag_prefix("ExampleOffchainWorker")
|
||||
// We set base priority to 2**20 to make sure it's included before any other
|
||||
// transactions in the pool. Next we tweak the priority depending on how much
|
||||
// it differs from the current average. (the more it differs the more priority it
|
||||
// has).
|
||||
priority: (1 << 20) + avg_price as u64,
|
||||
.priority(T::UnsignedPriority::get().saturating_add(avg_price as _))
|
||||
// This transaction does not require anything else to go before into the pool.
|
||||
// In theory we could require `previous_unsigned_at` transaction to go first,
|
||||
// but it's not necessary in our case.
|
||||
requires: vec![],
|
||||
//.and_requires()
|
||||
|
||||
// We set the `provides` tag to be the same as `next_unsigned_at`. This makes
|
||||
// sure only one transaction produced after `next_unsigned_at` will ever
|
||||
// get to the transaction pool and will end up in the block.
|
||||
// We can still have multiple transactions compete for the same "spot",
|
||||
// and the one with higher priority will replace other one in the pool.
|
||||
provides: vec![codec::Encode::encode(&(KEY_TYPE.0, next_unsigned_at))],
|
||||
.and_provides(next_unsigned_at)
|
||||
// The transaction is only valid for next 5 blocks. After that it's
|
||||
// going to be revalidated by the pool.
|
||||
longevity: 5,
|
||||
.longevity(5)
|
||||
// It's fine to propagate that transaction to other peers, which means it can be
|
||||
// created even by nodes that don't produce blocks.
|
||||
// Note that sometimes it's better to keep it for yourself (if you are the block
|
||||
// producer), since for instance in some schemes others may copy your solution and
|
||||
// claim a reward.
|
||||
propagate: true,
|
||||
})
|
||||
.propagate(true)
|
||||
.build()
|
||||
} else {
|
||||
InvalidTransaction::Call.into()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user