Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
261b95c
Fancy compact encode/decode impl for compact solution
kianenigma Jul 23, 2020
973bd25
Merge branch 'master' of github.com:paritytech/substrate into kiz-cod…
kianenigma Aug 3, 2020
0ff952c
Make it optional
kianenigma Aug 3, 2020
8c7b07a
Remove extra file
kianenigma Aug 3, 2020
41ad894
Update primitives/npos-elections/compact/src/lib.rs
kianenigma Aug 6, 2020
03ce657
Final fixes.
kianenigma Aug 6, 2020
82641f9
Merge branch 'kiz-codec-for-compact' of github.com:paritytech/substra…
kianenigma Aug 6, 2020
1524c5b
Merge branch 'master' of github.com:paritytech/substrate into kiz-cod…
kianenigma Aug 6, 2020
6fcb09e
getSize rpc should work for maps as well
kianenigma Aug 7, 2020
ba19fd3
Fix future types
kianenigma Aug 10, 2020
ba3eacd
Remove minimum_validator_count stale const
kianenigma Aug 10, 2020
b889970
Update client/rpc/src/state/mod.rs
kianenigma Aug 11, 2020
66586a4
"Optimize" `storage_size`
bkchr Aug 11, 2020
754098a
Remove unused import
bkchr Aug 11, 2020
85532e1
Merge branch 'kiz-rpc-for-map-len' of github.com:paritytech/substrate…
kianenigma Aug 11, 2020
11ff7ee
Update doc
kianenigma Aug 11, 2020
fcc7f0c
Merge branch 'master' of github.com:paritytech/substrate into kiz-cod…
kianenigma Aug 11, 2020
41663f4
Merge branch 'kiz-rpc-for-map-len' of github.com:paritytech/substrate…
kianenigma Aug 11, 2020
e12e6c9
Merge branch 'master' of github.com:paritytech/substrate into kiz-rpc…
kianenigma Aug 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fancy compact encode/decode impl for compact solution
  • Loading branch information
kianenigma committed Jul 23, 2020
commit 261b95c2d0d335e6595dfc04fc19db7ffddc2231
36 changes: 17 additions & 19 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,19 +369,9 @@ pub type EraIndex = u32;
pub type RewardPoint = u32;

// Note: Maximum nomination limit is set here -- 16.
generate_compact_solution_type!(pub GenericCompactAssignments, 16);

/// Information regarding the active era (era in used in session).
#[derive(Encode, Decode, RuntimeDebug)]
pub struct ActiveEraInfo {
/// Index of era.
pub index: EraIndex,
/// Moment of start expressed as millisecond from `$UNIX_EPOCH`.
///
/// Start can be none if start hasn't been set for the era yet,
/// Start is set on the first on_finalize of the era to guarantee usage of `Time`.
start: Option<u64>,
}
generate_compact_solution_type!(
pub struct CompactAssignments::<NominatorIndex, ValidatorIndex, OffchainAccuracy>(16)
);

/// Accuracy used for on-chain election.
pub type ChainAccuracy = Perbill;
Expand All @@ -393,15 +383,23 @@ pub type OffchainAccuracy = PerU16;
pub type BalanceOf<T> =
<<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;

/// The compact type for election solutions.
pub type CompactAssignments =
GenericCompactAssignments<NominatorIndex, ValidatorIndex, OffchainAccuracy>;

type PositiveImbalanceOf<T> =
<<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::PositiveImbalance;
type NegativeImbalanceOf<T> =
<<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;

/// Information regarding the active era (era in used in session).
#[derive(Encode, Decode, RuntimeDebug)]
pub struct ActiveEraInfo {
/// Index of era.
pub index: EraIndex,
/// Moment of start expressed as millisecond from `$UNIX_EPOCH`.
///
/// Start can be none if start hasn't been set for the era yet,
/// Start is set on the first on_finalize of the era to guarantee usage of `Time`.
start: Option<u64>,
}

/// Reward points of an era. Used to split era total payout between validators.
///
/// This points will be used to reward validators and their respective nominators.
Expand Down Expand Up @@ -1238,12 +1236,12 @@ decl_storage! {
decl_event!(
pub enum Event<T> where Balance = BalanceOf<T>, <T as frame_system::Trait>::AccountId {
/// The era payout has been set; the first balance is the validator-payout; the second is
/// the remainder from the maximum amount of reward.
/// the remainder from the maximum amount of reward.
/// [era_index, validator_payout, remainder]
EraPayout(EraIndex, Balance, Balance),
/// The staker has been rewarded by this amount. [stash, amount]
Reward(AccountId, Balance),
/// One validator (and its nominators) has been slashed by the given amount.
/// One validator (and its nominators) has been slashed by the given amount.
/// [validator, amount]
Slash(AccountId, Balance),
/// An old slashing report from a prior era was discarded because it could
Expand Down
80 changes: 34 additions & 46 deletions primitives/npos-elections/compact/src/assignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Code generation for the ratio assignment type.
//! Code generation for the ratio assignment type' compact representation.

use crate::field_name_for;
use proc_macro2::TokenStream as TokenStream2;
use syn::GenericArgument;
use quote::quote;

fn from_impl(count: usize) -> TokenStream2 {
let from_impl_single = {
let name = field_name_for(1);
quote!(1 => compact.#name.push(
(
index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?,
index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?,
index_of_voter(&who).or_invalid_index()?,
index_of_target(&distribution[0].0).or_invalid_index()?,
)
),)
};
Expand All @@ -37,29 +36,29 @@ fn from_impl(count: usize) -> TokenStream2 {
let name = field_name_for(2);
quote!(2 => compact.#name.push(
(
index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?,
index_of_voter(&who).or_invalid_index()?,
(
index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?,
index_of_target(&distribution[0].0).or_invalid_index()?,
distribution[0].1,
),
index_of_target(&distribution[1].0).ok_or(_phragmen::Error::CompactInvalidIndex)?,
index_of_target(&distribution[1].0).or_invalid_index()?,
)
),)
};

let from_impl_rest = (3..=count).map(|c| {
let inner = (0..c-1).map(|i|
quote!((index_of_target(&distribution[#i].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, distribution[#i].1),)
quote!((index_of_target(&distribution[#i].0).or_invalid_index()?, distribution[#i].1),)
).collect::<TokenStream2>();

let field_name = field_name_for(c);
let last_index = c - 1;
let last = quote!(index_of_target(&distribution[#last_index].0).ok_or(_phragmen::Error::CompactInvalidIndex)?);
let last = quote!(index_of_target(&distribution[#last_index].0).or_invalid_index()?);

quote!(
#c => compact.#field_name.push(
(
index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?,
index_of_voter(&who).or_invalid_index()?,
[#inner],
#last,
)
Expand All @@ -74,15 +73,15 @@ fn from_impl(count: usize) -> TokenStream2 {
)
}

fn into_impl(count: usize) -> TokenStream2 {
fn into_impl(count: usize, per_thing: syn::Type) -> TokenStream2 {
let into_impl_single = {
let name = field_name_for(1);
quote!(
for (voter_index, target_index) in self.#name {
assignments.push(_phragmen::Assignment {
who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?,
who: voter_at(voter_index).or_invalid_index()?,
distribution: vec![
(target_at(target_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, Accuracy::one())
(target_at(target_index).or_invalid_index()?, #per_thing::one())
],
})
}
Expand All @@ -93,21 +92,21 @@ fn into_impl(count: usize) -> TokenStream2 {
let name = field_name_for(2);
quote!(
for (voter_index, (t1_idx, p1), t2_idx) in self.#name {
if p1 >= Accuracy::one() {
if p1 >= #per_thing::one() {
return Err(_phragmen::Error::CompactStakeOverflow);
}

// defensive only. Since Percent doesn't have `Sub`.
let p2 = _phragmen::sp_arithmetic::traits::Saturating::saturating_sub(
Accuracy::one(),
#per_thing::one(),
p1,
);

assignments.push( _phragmen::Assignment {
who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?,
who: voter_at(voter_index).or_invalid_index()?,
distribution: vec![
(target_at(t1_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p1),
(target_at(t2_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p2),
(target_at(t1_idx).or_invalid_index()?, p1),
(target_at(t2_idx).or_invalid_index()?, p2),
]
});
}
Expand All @@ -118,30 +117,30 @@ fn into_impl(count: usize) -> TokenStream2 {
let name = field_name_for(c);
quote!(
for (voter_index, inners, t_last_idx) in self.#name {
let mut sum = Accuracy::zero();
let mut sum = #per_thing::zero();
let mut inners_parsed = inners
.iter()
.map(|(ref t_idx, p)| {
sum = _phragmen::sp_arithmetic::traits::Saturating::saturating_add(sum, *p);
let target = target_at(*t_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?;
let target = target_at(*t_idx).or_invalid_index()?;
Ok((target, *p))
})
.collect::<Result<Vec<(A, Accuracy)>, _phragmen::Error>>()?;
.collect::<Result<Vec<(A, #per_thing)>, _phragmen::Error>>()?;

if sum >= Accuracy::one() {
if sum >= #per_thing::one() {
return Err(_phragmen::Error::CompactStakeOverflow);
}

// defensive only. Since Percent doesn't have `Sub`.
let p_last = _phragmen::sp_arithmetic::traits::Saturating::saturating_sub(
Accuracy::one(),
#per_thing::one(),
sum,
);

inners_parsed.push((target_at(t_last_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p_last));
inners_parsed.push((target_at(t_last_idx).or_invalid_index()?, p_last));

assignments.push(_phragmen::Assignment {
who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?,
who: voter_at(voter_index).or_invalid_index()?,
distribution: inners_parsed,
});
}
Expand All @@ -157,39 +156,28 @@ fn into_impl(count: usize) -> TokenStream2 {

pub(crate) fn assignment(
ident: syn::Ident,
voter_type: GenericArgument,
target_type: GenericArgument,
voter_type: syn::Type,
target_type: syn::Type,
weight_type: syn::Type,
count: usize,
) -> TokenStream2 {

let from_impl = from_impl(count);
let into_impl = into_impl(count);
let into_impl = into_impl(count, weight_type.clone());

quote!(
impl<
#voter_type: _phragmen::codec::Codec + Default + Copy,
#target_type: _phragmen::codec::Codec + Default + Copy,
Accuracy:
_phragmen::codec::Codec + Default + Clone + _phragmen::sp_arithmetic::PerThing +
PartialOrd,
>
#ident<#voter_type, #target_type, Accuracy>
{
impl #ident {
pub fn from_assignment<FV, FT, A>(
assignments: Vec<_phragmen::Assignment<A, Accuracy>>,
assignments: Vec<_phragmen::Assignment<A, #weight_type>>,
index_of_voter: FV,
index_of_target: FT,
) -> Result<Self, _phragmen::Error>
where
A: _phragmen::IdentifierT,
for<'r> FV: Fn(&'r A) -> Option<#voter_type>,
for<'r> FT: Fn(&'r A) -> Option<#target_type>,
A: _phragmen::IdentifierT,
{
let mut compact: #ident<
#voter_type,
#target_type,
Accuracy,
> = Default::default();
let mut compact: #ident = Default::default();

for _phragmen::Assignment { who, distribution } in assignments {
match distribution.len() {
Expand All @@ -207,8 +195,8 @@ pub(crate) fn assignment(
self,
voter_at: impl Fn(#voter_type) -> Option<A>,
target_at: impl Fn(#target_type) -> Option<A>,
) -> Result<Vec<_phragmen::Assignment<A, Accuracy>>, _phragmen::Error> {
let mut assignments: Vec<_phragmen::Assignment<A, Accuracy>> = Default::default();
) -> Result<Vec<_phragmen::Assignment<A, #weight_type>>, _phragmen::Error> {
let mut assignments: Vec<_phragmen::Assignment<A, #weight_type>> = Default::default();
#into_impl
Ok(assignments)
}
Expand Down
Loading