supply.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use alphavm_ledger_block::Transactions; 17 use console::network::Network; 18 19 use anyhow::{Result, anyhow}; 20 21 /// Returns the next total supply in microcredits, given the starting total supply and newly-confirmed transactions. 22 pub fn update_total_supply<N: Network>( 23 starting_total_supply_in_microcredits: u64, 24 block_reward: u64, 25 puzzle_reward: u64, 26 transactions: &Transactions<N>, 27 ) -> Result<u64> { 28 // Initialize the next total supply of microcredits. 29 let mut next_total_supply = starting_total_supply_in_microcredits; 30 // Add the block reward to the total supply. 31 next_total_supply = next_total_supply.saturating_add(block_reward); 32 // Add the puzzle reward to the total supply. 33 next_total_supply = next_total_supply.saturating_add(puzzle_reward); 34 35 // Iterate through the transactions to calculate the next total supply of microcredits. 36 for confirmed in transactions.iter() { 37 // Subtract the fee from the total supply. 38 next_total_supply = next_total_supply 39 .checked_sub(*confirmed.fee_amount()?) 40 .ok_or_else(|| anyhow!("The proposed fee underflows the total supply of microcredits"))?; 41 42 // Iterate over the transitions in the transaction. 43 for transition in confirmed.transaction().transitions() { 44 // If the transition contains a split, subtract the amount from the total supply. 45 if transition.is_split() { 46 // TODO (howardwu): Add a test that calls `split`, checks the output records - input records == 10_000u64. 47 // Subtract the amount split from the total supply. 48 next_total_supply = next_total_supply 49 .checked_sub(10_000u64) 50 .ok_or_else(|| anyhow!("The proposed split underflows the total supply of microcredits"))?; 51 } 52 } 53 } 54 // Return the final total supply in microcredits. 55 Ok(next_total_supply) 56 }