/// `funds` figures out given a plan, by tracking ICPT movements and
/// anticipates transfers that will fail to materialise as transactions.
`funds` figures out given a plan, by tracking ICPT movements and
anticipates transfers that will fail to materialise as transactions.
` funds ` figures out given a plan by tracking ICPT movements and anticipates transfers that will fail to materialise as transactions .
fn funds(ptr: &Result<PrincipalId, u32>, plan: &Plan) -> Tokens {
    match plan {
        Plan::Empty => {
            if *ptr == Err(0) || *ptr == link(&Err(0), plan, plan) {
                Tokens::from_e8s(1000000000000) // LIFELINE start balance
            } else {
                Tokens::ZERO
            }
        }
        Plan::IdentityAccount(_, tail) | Plan::CanisterAccount(_, tail) => funds(ptr, tail),
        Plan::Transfer((from0, amount, to), tail) => {
            let mut balance = funds(ptr, tail);
            let from = from0.map(|owner| match owner {
                Ok(princ) => princ,
                Err((_, public)) => ed25519_public_to_principal(&public),
            });
            let minimal_balance = (Tokens::from_e8s(*amount) + TRANSACTION_FEE).unwrap();
            if from != *to {
                // checking for account exhaustion
                let source = funds(&from, tail);
                if source < minimal_balance {
                    // transfer not covered (traps)
                    return balance;
                }
            } else if balance < minimal_balance {
                // transfer not covered (traps)
                // even for a self-transfer
                return balance;
            }
            // at this point we know that addition won't overflow,
            // as the total sum invariant holds
            if ptr == to {
                balance = (balance + Tokens::from_e8s(*amount)).unwrap()
            }
            if *ptr == from {
                balance =
                    ((balance - Tokens::from_e8s(*amount)).unwrap() - TRANSACTION_FEE).unwrap()
            }
            balance
        }
    }
}
fn funds ( ptr : & Result < PrincipalId , u32 > , plan : & Plan ) -> Tokens { match plan { Plan :: Empty => { if * ptr == Err ( 0 ) || * ptr == link ( & Err ( 0 ) , plan , plan ) { Tokens :: from_e8s ( 1000000000000 ) // LIFELINE start balance } else { Tokens :: ZERO } } Plan :: IdentityAccount ( _ , tail ) | Plan :: CanisterAccount ( _ , tail ) => funds ( ptr , tail ) , Plan :: Transfer ( ( from0 , amount , to ) , tail ) => { let mut balance = funds ( ptr , tail ) ; let from = from0 . map ( | owner | match owner { Ok ( princ ) => princ , Err ( ( _ , public ) ) => ed25519_public_to_principal ( & public ) , } ) ; let minimal_balance = ( Tokens :: from_e8s ( * amount ) + TRANSACTION_FEE ) . unwrap ( ) ; if from != * to { // checking for account exhaustion let source = funds ( & from , tail ) ; if source < minimal_balance { // transfer not covered (traps) return balance ; } } else if balance < minimal_balance { // transfer not covered (traps) // even for a self-transfer return balance ; } // at this point we know that addition won't overflow, // as the total sum invariant holds if ptr == to { balance = ( balance + Tokens :: from_e8s ( * amount ) ) . unwrap ( ) } if * ptr == from { balance = ( ( balance - Tokens :: from_e8s ( * amount ) ) . unwrap ( ) - TRANSACTION_FEE ) . unwrap ( ) } balance } } }
`funds` figures out given a plan, by tracking ICPT movements and
anticipates transfers that will fail to materialise as transactions.
` funds ` figures out given a plan by tracking ICPT movements and anticipates transfers that will fail to materialise as transactions .
ptr
&Result<PrincipalId, u32>
plan
&Plan