pub fn do_calculate_reward(cid: &MerkleRoot, curr_bn: BlockNumber)
    {
        // 1. File must exist
        if Self::files(cid).is_none() { return; }
        
        // 2. File must already started
        let (mut file_info, mut used_info) = Self::files(cid).unwrap_or_default();
        
        // 3. File already expired
        if file_info.expired_on <= file_info.calculated_at { return; }

        // 4. Update used_info and files_size
        let prev_reported_group_count = used_info.reported_group_count;
        used_info.reported_group_count = Self::count_reported_groups(&mut used_info.groups, curr_bn); // use curr_bn here since we want to check the latest status
        Self::update_groups_used_info(file_info.file_size, &mut used_info);
        Self::update_files_size(file_info.file_size, prev_reported_group_count, used_info.reported_group_count);

        let calculated_block = curr_bn.min(file_info.expired_on);
        let target_reward_count = file_info.replicas.len().min(T::FileReplica::get() as usize) as u32;
        
        // 5. Calculate payouts, check replicas and update the file_info
        if target_reward_count > 0 {
            // 5.1 Get 1 payout amount and sub 1 to make sure that we won't get overflow
            let one_payout_amount = (Perbill::from_rational_approximation(calculated_block - file_info.calculated_at,
                                                                          (file_info.expired_on - file_info.calculated_at) * target_reward_count) * file_info.amount).saturating_sub(1u32.into());
            let mut rewarded_amount = Zero::zero();
            let mut rewarded_count = 0u32;
            let mut new_replicas: Vec<Replica<T::AccountId>> = Vec::with_capacity(file_info.replicas.len());
            let mut invalid_replicas: Vec<Replica<T::AccountId>> = Vec::with_capacity(file_info.replicas.len());
            
            // 5.2. Loop replicas
            for replica in file_info.replicas.iter() {
                // a. didn't report in prev slot, push back to the end of replica
                if !T::TarsInterface::is_wr_reported(&replica.anchor, curr_bn) {
                    let mut invalid_replica = replica.clone();
                    // update the valid_at to the curr_bn
                    invalid_replica.valid_at = curr_bn;
                    invalid_replica.is_reported = false;
                    // move it to the end of replica
                    invalid_replicas.push(invalid_replica);
                    // TODO: kick this anchor out of used info
                // b. keep the replica's sequence
                } else {
                    let mut valid_replica = replica.clone();
                    valid_replica.is_reported = true;
                    new_replicas.push(valid_replica);
                    
                    // if payouts is full, just continue
                    if rewarded_count == target_reward_count {
                        continue;
                    }
                    
                    // if that guy is poor, just pass him ☠️
                    // Only the first member in the groups can accept the storage reward.
                    if Self::maybe_reward_merchant(&replica.who, &one_payout_amount, used_info.groups.contains_key(&replica.anchor)) {
                        rewarded_amount += one_payout_amount.clone();
                        rewarded_count +=1;
                    }
                }
            }

            // 5.3 Update file info
            file_info.amount = file_info.amount.saturating_sub(rewarded_amount);
            file_info.reported_replica_count = new_replicas.len() as u32;
            new_replicas.append(&mut invalid_replicas);
            file_info.replicas = new_replicas;
        }

        // 6. File status might become ready to be closed if calculated_block == expired_on
        file_info.calculated_at = calculated_block;
        // 7. Update files
        <Files<T>>::insert(cid, (file_info, used_info));
    }
/// Calculate reward from file's replica
/// This function will calculate the file's reward, update replicas
/// and (maybe) insert file's status(files_size and delete file)
/// input:
///     cid: MerkleRoot
///     curr_bn: BlockNumber
Calculate reward from file's replica
This function will calculate the file's reward, update replicas
and (maybe) insert file's status(files_size and delete file)
input:
cid: MerkleRoot
curr_bn: BlockNumber
Calculate reward from file ' s replica This function will calculate the file ' s reward update replicas and ( maybe ) insert file ' s status ( files_size and delete file ) input : cid : MerkleRoot curr_bn : BlockNumber
pub fn do_calculate_reward(cid: &MerkleRoot, curr_bn: BlockNumber)
    {
        // 1. File must exist
        if Self::files(cid).is_none() { return; }
        // 2. File must already started
        let (mut file_info, mut used_info) = Self::files(cid).unwrap_or_default();
        // 3. File already expired
        if file_info.expired_on <= file_info.calculated_at { return; }
        // 4. Update used_info and files_size
        let prev_reported_group_count = used_info.reported_group_count;
        used_info.reported_group_count = Self::count_reported_groups(&mut used_info.groups, curr_bn); // use curr_bn here since we want to check the latest status
        Self::update_groups_used_info(file_info.file_size, &mut used_info);
        Self::update_files_size(file_info.file_size, prev_reported_group_count, used_info.reported_group_count);
        let calculated_block = curr_bn.min(file_info.expired_on);
        let target_reward_count = file_info.replicas.len().min(T::FileReplica::get() as usize) as u32;
        // 5. Calculate payouts, check replicas and update the file_info
        if target_reward_count > 0 {
            // 5.1 Get 1 payout amount and sub 1 to make sure that we won't get overflow
            let one_payout_amount = (Perbill::from_rational_approximation(calculated_block - file_info.calculated_at,
                                                                          (file_info.expired_on - file_info.calculated_at) * target_reward_count) * file_info.amount).saturating_sub(1u32.into());
            let mut rewarded_amount = Zero::zero();
            let mut rewarded_count = 0u32;
            let mut new_replicas: Vec<Replica<T::AccountId>> = Vec::with_capacity(file_info.replicas.len());
            let mut invalid_replicas: Vec<Replica<T::AccountId>> = Vec::with_capacity(file_info.replicas.len());
            // 5.2. Loop replicas
            for replica in file_info.replicas.iter() {
                // a. didn't report in prev slot, push back to the end of replica
                if !T::TarsInterface::is_wr_reported(&replica.anchor, curr_bn) {
                    let mut invalid_replica = replica.clone();
                    // update the valid_at to the curr_bn
                    invalid_replica.valid_at = curr_bn;
                    invalid_replica.is_reported = false;
                    // move it to the end of replica
                    invalid_replicas.push(invalid_replica);
                    // TODO: kick this anchor out of used info
                // b. keep the replica's sequence
                } else {
                    let mut valid_replica = replica.clone();
                    valid_replica.is_reported = true;
                    new_replicas.push(valid_replica);
                    // if payouts is full, just continue
                    if rewarded_count == target_reward_count {
                        continue;
                    }
                    // if that guy is poor, just pass him ☠️
                    // Only the first member in the groups can accept the storage reward.
                    if Self::maybe_reward_merchant(&replica.who, &one_payout_amount, used_info.groups.contains_key(&replica.anchor)) {
                        rewarded_amount += one_payout_amount.clone();
                        rewarded_count +=1;
                    }
                }
            }
            // 5.3 Update file info
            file_info.amount = file_info.amount.saturating_sub(rewarded_amount);
            file_info.reported_replica_count = new_replicas.len() as u32;
            new_replicas.append(&mut invalid_replicas);
            file_info.replicas = new_replicas;
        }
        // 6. File status might become ready to be closed if calculated_block == expired_on
        file_info.calculated_at = calculated_block;
        // 7. Update files
        <Files<T>>::insert(cid, (file_info, used_info));
    }
pub fn do_calculate_reward ( cid : & MerkleRoot , curr_bn : BlockNumber ) { // 1. File must exist if Self :: files ( cid ) . is_none ( ) { return ; } // 2. File must already started let ( mut file_info , mut used_info ) = Self :: files ( cid ) . unwrap_or_default ( ) ; // 3. File already expired if file_info . expired_on <= file_info . calculated_at { return ; } // 4. Update used_info and files_size let prev_reported_group_count = used_info . reported_group_count ; used_info . reported_group_count = Self :: count_reported_groups ( & mut used_info . groups , curr_bn ) ; // use curr_bn here since we want to check the latest status Self :: update_groups_used_info ( file_info . file_size , & mut used_info ) ; Self :: update_files_size ( file_info . file_size , prev_reported_group_count , used_info . reported_group_count ) ; let calculated_block = curr_bn . min ( file_info . expired_on ) ; let target_reward_count = file_info . replicas . len ( ) . min ( T :: FileReplica :: get ( ) as usize ) as u32 ; // 5. Calculate payouts, check replicas and update the file_info if target_reward_count > 0 { // 5.1 Get 1 payout amount and sub 1 to make sure that we won't get overflow let one_payout_amount = ( Perbill :: from_rational_approximation ( calculated_block - file_info . calculated_at , ( file_info . expired_on - file_info . calculated_at ) * target_reward_count ) * file_info . amount ) . saturating_sub ( 1u32 . into ( ) ) ; let mut rewarded_amount = Zero :: zero ( ) ; let mut rewarded_count = 0u32 ; let mut new_replicas : Vec < Replica < T :: AccountId > > = Vec :: with_capacity ( file_info . replicas . len ( ) ) ; let mut invalid_replicas : Vec < Replica < T :: AccountId > > = Vec :: with_capacity ( file_info . replicas . len ( ) ) ; // 5.2. Loop replicas for replica in file_info . replicas . iter ( ) { // a. didn't report in prev slot, push back to the end of replica if ! T :: TarsInterface :: is_wr_reported ( & replica . anchor , curr_bn ) { let mut invalid_replica = replica . clone ( ) ; // update the valid_at to the curr_bn invalid_replica . valid_at = curr_bn ; invalid_replica . is_reported = false ; // move it to the end of replica invalid_replicas . push ( invalid_replica ) ; // TODO: kick this anchor out of used info // b. keep the replica's sequence } else { let mut valid_replica = replica . clone ( ) ; valid_replica . is_reported = true ; new_replicas . push ( valid_replica ) ; // if payouts is full, just continue if rewarded_count == target_reward_count { continue ; } // if that guy is poor, just pass him ☠️ // Only the first member in the groups can accept the storage reward. if Self :: maybe_reward_merchant ( & replica . who , & one_payout_amount , used_info . groups . contains_key ( & replica . anchor ) ) { rewarded_amount += one_payout_amount . clone ( ) ; rewarded_count += 1 ; } } } // 5.3 Update file info file_info . amount = file_info . amount . saturating_sub ( rewarded_amount ) ; file_info . reported_replica_count = new_replicas . len ( ) as u32 ; new_replicas . append ( & mut invalid_replicas ) ; file_info . replicas = new_replicas ; } // 6. File status might become ready to be closed if calculated_block == expired_on file_info . calculated_at = calculated_block ; // 7. Update files < Files < T > > :: insert ( cid , ( file_info , used_info ) ) ; }
Calculate reward from file's replica
This function will calculate the file's reward, update replicas
and (maybe) insert file's status(files_size and delete file)
input:
cid: MerkleRoot
curr_bn: BlockNumber
Calculate reward from file ' s replica This function will calculate the file ' s reward update replicas and ( maybe ) insert file ' s status ( files_size and delete file ) input : cid : MerkleRoot curr_bn : BlockNumber
cid
&MerkleRoot
curr_bn
BlockNumber