/ ledger / src / helpers / supply.rs
supply.rs
 1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
 2  // This file is part of the deltavm 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 deltavm_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  }