Newer
Older
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
if let Err(e) = Self::pre_dispatch_checks(*score, *era) {
debug::native::debug!(
target: "staking",
"validate unsigned failed due to {:?}.",
e,
);
let invalid: InvalidTransaction = e.into();
return invalid.into();
}
debug::native::debug!(
target: "staking",
"Validated an unsigned transaction from the local node for era {}.",
era,
);
Ok(ValidTransaction {
// The higher the score[0], the better a solution is.
priority: score[0].saturated_into(),
// no requires.
requires: vec![],
// Defensive only. A single solution can exist in the pool per era. Each validator
// will run OCW at most once per era, hence there should never exist more than one
// transaction anyhow.
provides: vec![("StakingOffchain", era).encode()],
// Note: this can be more accurate in the future. We do something like
// `era_end_block - current_block` but that is not needed now as we eagerly run
// offchain workers now and the above should be same as `T::ElectionLookahead`
// without the need to query more storage in the validation phase. If we randomize
// offchain worker, then we might re-consider this.
longevity: TryInto::<u64>::try_into(T::ElectionLookahead::get()).unwrap_or(DEFAULT_LONGEVITY),
// We don't propagate this. This can never the validated at a remote node.
propagate: false,
})
} else {
InvalidTransaction::Call.into()
}
}
fn pre_dispatch(_: &Self::Call) -> Result<(), TransactionValidityError> {
// IMPORTANT NOTE: By default, a sane `pre-dispatch` should always do the same checks as
// `validate_unsigned` and overriding this should be done with care. this module has only
// one unsigned entry point, in which we call into `<Module<T>>::pre_dispatch_checks()`
// which is all the important checks that we do in `validate_unsigned`. Hence, we can safely
// override this to save some time.
Ok(())
}
}
/// Check that list is sorted and has no duplicates.
fn is_sorted_and_unique(list: &[u32]) -> bool {
list.windows(2).all(|w| w[0] < w[1])
}