diff --git a/codegen/src/api/mod.rs b/codegen/src/api/mod.rs index 1681ea9919..923c7c019b 100644 --- a/codegen/src/api/mod.rs +++ b/codegen/src/api/mod.rs @@ -147,6 +147,12 @@ impl RuntimeGenerator { "frame_support::traits::misc::WrapperKeepOpaque", parse_quote!(::subxt::WrapperKeepOpaque), ), + // We override this because it's used as a key in a BTreeMap, and so we + // need to implement some extra derives for it for that to compile. + ( + "sp_npos_elections::ElectionScore", + parse_quote!(::subxt::ElectionScore), + ), ] .iter() .map(|(path, substitute): &(&str, syn::TypePath)| { diff --git a/subxt/src/lib.rs b/subxt/src/lib.rs index 21a0cfd494..37376e4401 100644 --- a/subxt/src/lib.rs +++ b/subxt/src/lib.rs @@ -239,3 +239,41 @@ impl PhantomDataSendSync { unsafe impl Send for PhantomDataSendSync {} unsafe impl Sync for PhantomDataSendSync {} + +/// [`ElectionScore`] overrides any generated instance of `sp_npos_elections::ElectionScore` found +/// in the metadata, so that we can add some extra derives required for it to be used as the key +/// in a [`std::collections::BTreeMap`]. +#[derive(Encode, Decode, Debug, PartialEq, Eq)] +pub struct ElectionScore { + /// The minimal winner, in terms of total backing stake. + /// + /// This parameter should be maximized. + pub minimal_stake: u128, + /// The sum of the total backing of all winners. + /// + /// This parameter should maximized + pub sum_stake: u128, + /// The sum squared of the total backing of all winners, aka. the variance. + /// + /// Ths parameter should be minimized. + pub sum_stake_squared: u128, +} + +// These are copied from the original impl; they don't affect encoding/decoding but help +// to keep the ordering the same if we then work with the decoded results. +impl Ord for ElectionScore { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + // we delegate this to the lexicographic cmp of slices`, and to incorporate that we want the + // third element to be minimized, we swap them. + [self.minimal_stake, self.sum_stake, other.sum_stake_squared].cmp(&[ + other.minimal_stake, + other.sum_stake, + self.sum_stake_squared, + ]) + } +} +impl PartialOrd for ElectionScore { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +}