/// Distribute the reward
/// according to the accumulated work
/// associated with the ids.
/// Also returns those who got 0 reward
/// (when their work or total_reward wasn't high enough).
Distribute the reward
according to the accumulated work
associated with the ids.
Also returns those who got 0 reward
(when their work or total_reward wasn't high enough).
Distribute the reward according to the accumulated work associated with the ids . Also returns those who got 0 reward ( when their work or total_reward wasn ' t high enough ) .
fn distribute(
        &self,
        total_reward: Money,
        accounts_work: HashMap<AccountId, Work>,
    ) -> HashMap<AccountId, Money> {
        //
        let total_reward = total_reward.as_nano();
        let all_work: Work = accounts_work.values().sum();
        let mut shares_sum = 0;
        let mut shares: Vec<(AccountId, u64)> = Default::default();
        for (id, work) in &accounts_work {
            let share = (total_reward as f64 / (all_work as f64 / *work as f64)).round() as u64;
            shares.push((*id, share));
            shares_sum += share;
        }
        // Add/remove diff.
        match total_reward.cmp(&shares_sum) {
            Ordering::Greater => {
                // Does not cover probabilistic distribution
                // (i.e. when total_reward < number of accounts),
                // since we do not have a shared random value here.
                // We could put it at the acc closest to the data hash though.. TBD
                if !shares.is_empty() {
                    shares.sort_by_key(|t| t.1);
                    let index = 0; // for now, remainder goes to top worker
                    let (id, share) = shares[index];
                    let remainder = total_reward - shares_sum;
                    let new_share = share + remainder;
                    shares[index] = (id, new_share);
                }
            }
            Ordering::Less => {
                let mut diff = shares_sum - total_reward;
                shares.sort_by_key(|t| t.1);
                while diff > 0 {
                    for i in 0..shares.len() {
                        let (id, share) = shares[i];
                        if 0 == diff {
                            break;
                        } else if share >= 1 {
                            shares[i] = (id, share - 1);
                            diff -= 1;
                        }
                    }
                }
            }
            Ordering::Equal => (),
        };
        let shares_sum = (&shares).iter().map(|(_, share)| share).sum();
        if total_reward != shares_sum {
            panic!("total_reward: {}, shares_sum: {}", total_reward, shares_sum);
        }
        shares
            .into_iter()
            .map(|(i, s)| (i, Money::from_nano(s)))
            .collect()
    }
fn distribute ( & self , total_reward : Money , accounts_work : HashMap < AccountId , Work > , ) -> HashMap < AccountId , Money > { // let total_reward = total_reward . as_nano ( ) ; let all_work : Work = accounts_work . values ( ) . sum ( ) ; let mut shares_sum = 0 ; let mut shares : Vec < ( AccountId , u64 ) > = Default :: default ( ) ; for ( id , work ) in & accounts_work { let share = ( total_reward as f64 / ( all_work as f64 / * work as f64 ) ) . round ( ) as u64 ; shares . push ( ( * id , share ) ) ; shares_sum += share ; } // Add/remove diff. match total_reward . cmp ( & shares_sum ) { Ordering :: Greater => { // Does not cover probabilistic distribution // (i.e. when total_reward < number of accounts), // since we do not have a shared random value here. // We could put it at the acc closest to the data hash though.. TBD if ! shares . is_empty ( ) { shares . sort_by_key ( | t | t . 1 ) ; let index = 0 ; // for now, remainder goes to top worker let ( id , share ) = shares [ index ] ; let remainder = total_reward - shares_sum ; let new_share = share + remainder ; shares [ index ] = ( id , new_share ) ; } } Ordering :: Less => { let mut diff = shares_sum - total_reward ; shares . sort_by_key ( | t | t . 1 ) ; while diff > 0 { for i in 0 .. shares . len ( ) { let ( id , share ) = shares [ i ] ; if 0 == diff { break ; } else if share >= 1 { shares [ i ] = ( id , share - 1 ) ; diff -= 1 ; } } } } Ordering :: Equal => ( ) , } ; let shares_sum = ( & shares ) . iter ( ) . map ( | ( _ , share ) | share ) . sum ( ) ; if total_reward != shares_sum { panic ! ( " " total_reward shares_sum ) ; } shares . into_iter ( ) . map ( | ( i , s ) | ( i , Money :: from_nano ( s ) ) ) . collect ( ) }
Distribute the reward
according to the accumulated work
associated with the ids.
Distribute the reward according to the accumulated work associated with the ids .
&self
total_reward
Money
accounts_work
HashMap<AccountId, Work>